????
| Current Path : /var/lib/dkms/file_protector/1.1-1578/source/ |
| Current File : //var/lib/dkms/file_protector/1.1-1578/source/file_path_tools.h |
/**
@file file_path_tools.h
@brief Tools for creating and working with file paths
@details Copyright (c) 2024 Acronis International GmbH
@author Denis Kopyrin (denis.kopyrin@acronis.com)
@since $Id: $
*/
#pragma once
#include "compat.h"
#include "memory.h"
#include "si_common.h"
typedef struct {
char* buf;
SiSizedString str;
} path_info_t;
// init_empty initialize message enough so 'free' can work
static inline void path_info_init_empty(path_info_t* info) {
info->buf = NULL;
}
static inline long path_info_make_with_alloc_flags(path_info_t* info, const struct path* path, bool dir, bool nowait) {
long ret = -EFAULT;
char* str;
info->buf = (char*) kmem_cache_alloc(names_cachep, mem_flags(nowait));
if (!info->buf) {
goto err;
}
str = d_absolute_path_compat(path, info->buf, PATH_MAX - (dir ? 1 : 0));
if (IS_ERR(str)) {
ret = PTR_ERR(str);
kmem_cache_free(names_cachep, info->buf);
info->buf = NULL;
goto err;
}
info->str.value = str;
info->str.length = strlen(info->str.value);
if (dir) {
if (str[info->str.length - 1] != '/') {
str[info->str.length] = '/';
str[info->str.length + 1] = '\0';
info->str.length++;
}
}
return 0;
err:
info->str = (SiSizedString) {};
return ret;
}
static inline long path_info_make(path_info_t* info, const struct path* path, bool dir) {
return path_info_make_with_alloc_flags(info, path, dir, false /*nowait*/);
}
static inline long path_info_make_nowait(path_info_t* info, const struct path* path, bool dir) {
return path_info_make_with_alloc_flags(info, path, dir, true /*nowait*/);
}
static inline long path_info_make_from_valid(path_info_t* info, const struct path* path) {
return path_info_make_with_alloc_flags(info, path, S_ISDIR(path->dentry->d_inode->i_mode), false /*nowait*/);
}
static inline long path_info_make_from_valid_nowait(path_info_t* info, const struct path* path) {
return path_info_make_with_alloc_flags(info, path, S_ISDIR(path->dentry->d_inode->i_mode), true /*nowait*/);
}
static inline void path_info_free(const path_info_t* info) {
if (info->buf) {
kmem_cache_free(names_cachep, info->buf);
}
}