mirror of
https://github.com/apache/nuttx.git
synced 2026-08-01 20:28:58 +00:00
fs/tmpfs: Add user identity and permission enforcement
Store uid/gid/mode on tmpfs objects, support chstat, enforce open and path permissions via fs_checkmode()/fs_checkopenperm(), and inherit creator identity on file creation. Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
This commit is contained in:
parent
33f5cf9525
commit
0e662be70a
2 changed files with 326 additions and 30 deletions
|
|
@ -106,13 +106,15 @@ static int tmpfs_remove_dirent(FAR struct tmpfs_directory_s *tdo,
|
|||
static int tmpfs_add_dirent(FAR struct tmpfs_directory_s *tdo,
|
||||
FAR struct tmpfs_object_s *to, FAR const char *name);
|
||||
static FAR struct tmpfs_file_s *
|
||||
tmpfs_alloc_file(FAR struct tmpfs_directory_s *parent);
|
||||
tmpfs_alloc_file(FAR struct tmpfs_directory_s *parent, mode_t mode);
|
||||
static int tmpfs_create_file(FAR struct tmpfs_s *fs,
|
||||
FAR const char *relpath, FAR struct tmpfs_file_s **tfo);
|
||||
FAR const char *relpath, mode_t mode,
|
||||
FAR struct tmpfs_file_s **tfo);
|
||||
static FAR struct tmpfs_directory_s *
|
||||
tmpfs_alloc_directory(FAR struct tmpfs_directory_s *parent);
|
||||
tmpfs_alloc_directory(FAR struct tmpfs_directory_s *parent, mode_t mode);
|
||||
static int tmpfs_create_directory(FAR struct tmpfs_s *fs,
|
||||
FAR const char *relpath, FAR struct tmpfs_directory_s **tdo);
|
||||
FAR const char *relpath, mode_t mode,
|
||||
FAR struct tmpfs_directory_s **tdo);
|
||||
static int tmpfs_find_object(FAR struct tmpfs_s *fs,
|
||||
FAR const char *relpath, size_t len,
|
||||
FAR struct tmpfs_object_s **object,
|
||||
|
|
@ -146,6 +148,8 @@ static int tmpfs_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
|
|||
static int tmpfs_sync(FAR struct file *filep);
|
||||
static int tmpfs_dup(FAR const struct file *oldp, FAR struct file *newp);
|
||||
static int tmpfs_fstat(FAR const struct file *filep, FAR struct stat *buf);
|
||||
static int tmpfs_fchstat(FAR const struct file *filep,
|
||||
FAR const struct stat *buf, int flags);
|
||||
static int tmpfs_truncate(FAR struct file *filep, off_t length);
|
||||
static int tmpfs_mmap(FAR struct file *filep,
|
||||
FAR struct mm_map_entry_s *map);
|
||||
|
|
@ -174,6 +178,8 @@ static void tmpfs_stat_common(FAR struct tmpfs_object_s *to,
|
|||
FAR struct stat *buf);
|
||||
static int tmpfs_stat(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
FAR struct stat *buf);
|
||||
static int tmpfs_chstat(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
FAR const struct stat *buf, int flags);
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
|
|
@ -196,7 +202,7 @@ const struct mountpt_operations g_tmpfs_operations =
|
|||
tmpfs_sync, /* sync */
|
||||
tmpfs_dup, /* dup */
|
||||
tmpfs_fstat, /* fstat */
|
||||
NULL, /* fchstat */
|
||||
tmpfs_fchstat, /* fchstat */
|
||||
|
||||
tmpfs_opendir, /* opendir */
|
||||
tmpfs_closedir, /* closedir */
|
||||
|
|
@ -212,7 +218,7 @@ const struct mountpt_operations g_tmpfs_operations =
|
|||
tmpfs_rmdir, /* rmdir */
|
||||
tmpfs_rename, /* rename */
|
||||
tmpfs_stat, /* stat */
|
||||
NULL /* chstat */
|
||||
tmpfs_chstat /* chstat */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -555,12 +561,162 @@ static int tmpfs_add_dirent(FAR struct tmpfs_directory_s *tdo,
|
|||
return OK;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FS_PERMISSION
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tmpfs_init_object
|
||||
****************************************************************************/
|
||||
|
||||
static void tmpfs_init_object(FAR struct tmpfs_object_s *to, mode_t mode)
|
||||
{
|
||||
FAR struct tcb_s *rtcb;
|
||||
|
||||
to->to_mode = mode & 07777;
|
||||
rtcb = nxsched_self();
|
||||
if ((rtcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_KERNEL ||
|
||||
rtcb->group == NULL)
|
||||
{
|
||||
to->to_uid = 0;
|
||||
to->to_gid = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
to->to_uid = rtcb->group->tg_euid;
|
||||
to->to_gid = rtcb->group->tg_egid;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tmpfs_check_pathperm
|
||||
****************************************************************************/
|
||||
|
||||
static int tmpfs_check_pathperm(FAR struct tmpfs_s *fs,
|
||||
FAR const char *relpath, size_t relpathlen,
|
||||
int final_amode)
|
||||
{
|
||||
FAR struct tmpfs_directory_s *tdo;
|
||||
FAR struct tmpfs_object_s *to;
|
||||
size_t begin = 0;
|
||||
size_t end;
|
||||
int ret;
|
||||
|
||||
while (begin < relpathlen && relpath[begin] == '/')
|
||||
{
|
||||
begin++;
|
||||
}
|
||||
|
||||
if (begin >= relpathlen)
|
||||
{
|
||||
to = fs->tfs_root.tde_object;
|
||||
return fs_checkmode(to->to_uid, to->to_gid,
|
||||
to->to_mode | S_IFDIR, final_amode);
|
||||
}
|
||||
|
||||
for (end = begin; end <= relpathlen; end++)
|
||||
{
|
||||
if (end < relpathlen && relpath[end] != '/')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = tmpfs_find_directory(fs, relpath, end, &tdo, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
to = (FAR struct tmpfs_object_s *)tdo;
|
||||
ret = fs_checkmode(to->to_uid, to->to_gid,
|
||||
to->to_mode | S_IFDIR,
|
||||
end >= relpathlen ? final_amode : X_OK);
|
||||
tdo->tdo_refs--;
|
||||
tmpfs_unlock_directory(tdo);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tmpfs_check_parentperm
|
||||
****************************************************************************/
|
||||
|
||||
static int tmpfs_check_parentperm(FAR struct tmpfs_s *fs,
|
||||
FAR const char *relpath, int amode)
|
||||
{
|
||||
FAR const char *slash;
|
||||
FAR struct tmpfs_object_s *to;
|
||||
size_t parentlen;
|
||||
|
||||
slash = strrchr(relpath, '/');
|
||||
if (slash == NULL || slash == relpath)
|
||||
{
|
||||
to = fs->tfs_root.tde_object;
|
||||
return fs_checkmode(to->to_uid, to->to_gid,
|
||||
to->to_mode | S_IFDIR, amode);
|
||||
}
|
||||
|
||||
parentlen = slash - relpath;
|
||||
return tmpfs_check_pathperm(fs, relpath, parentlen, amode);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tmpfs_chstat_object
|
||||
****************************************************************************/
|
||||
|
||||
static int tmpfs_chstat_object(FAR struct tmpfs_object_s *to,
|
||||
FAR const struct stat *buf, int flags)
|
||||
{
|
||||
FAR struct tcb_s *rtcb;
|
||||
uid_t euid;
|
||||
|
||||
rtcb = nxsched_self();
|
||||
if ((rtcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL &&
|
||||
rtcb->group != NULL)
|
||||
{
|
||||
euid = rtcb->group->tg_euid;
|
||||
|
||||
if ((flags & (CH_STAT_UID | CH_STAT_GID)) != 0 && euid != 0)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if ((flags & CH_STAT_MODE) != 0 &&
|
||||
euid != 0 && euid != to->to_uid)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & CH_STAT_MODE) != 0)
|
||||
{
|
||||
to->to_mode = buf->st_mode & 07777;
|
||||
}
|
||||
|
||||
if ((flags & CH_STAT_UID) != 0)
|
||||
{
|
||||
to->to_uid = buf->st_uid;
|
||||
}
|
||||
|
||||
if ((flags & CH_STAT_GID) != 0)
|
||||
{
|
||||
to->to_gid = buf->st_gid;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_FS_PERMISSION */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tmpfs_alloc_file
|
||||
****************************************************************************/
|
||||
|
||||
static FAR struct tmpfs_file_s *
|
||||
tmpfs_alloc_file(FAR struct tmpfs_directory_s *parent)
|
||||
tmpfs_alloc_file(FAR struct tmpfs_directory_s *parent, mode_t mode)
|
||||
{
|
||||
FAR struct tmpfs_file_s *tfo;
|
||||
|
||||
|
|
@ -584,6 +740,12 @@ tmpfs_alloc_file(FAR struct tmpfs_directory_s *parent)
|
|||
tfo->tfo_size = 0;
|
||||
tfo->tfo_data = NULL;
|
||||
|
||||
#ifdef CONFIG_FS_PERMISSION
|
||||
tmpfs_init_object((FAR struct tmpfs_object_s *)tfo, mode);
|
||||
#else
|
||||
UNUSED(mode);
|
||||
#endif
|
||||
|
||||
nxrmutex_init(&tfo->tfo_lock);
|
||||
tmpfs_lock_file(tfo);
|
||||
|
||||
|
|
@ -595,7 +757,7 @@ tmpfs_alloc_file(FAR struct tmpfs_directory_s *parent)
|
|||
****************************************************************************/
|
||||
|
||||
static int tmpfs_create_file(FAR struct tmpfs_s *fs,
|
||||
FAR const char *relpath,
|
||||
FAR const char *relpath, mode_t mode,
|
||||
FAR struct tmpfs_file_s **tfo)
|
||||
{
|
||||
FAR struct tmpfs_directory_s *parent;
|
||||
|
|
@ -670,7 +832,7 @@ static int tmpfs_create_file(FAR struct tmpfs_s *fs,
|
|||
* one reference count.
|
||||
*/
|
||||
|
||||
newtfo = tmpfs_alloc_file(parent);
|
||||
newtfo = tmpfs_alloc_file(parent, mode);
|
||||
if (newtfo == NULL)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
|
|
@ -712,7 +874,7 @@ errout_with_parent:
|
|||
****************************************************************************/
|
||||
|
||||
static FAR struct tmpfs_directory_s *
|
||||
tmpfs_alloc_directory(FAR struct tmpfs_directory_s *parent)
|
||||
tmpfs_alloc_directory(FAR struct tmpfs_directory_s *parent, mode_t mode)
|
||||
{
|
||||
FAR struct tmpfs_directory_s *tdo;
|
||||
|
||||
|
|
@ -733,6 +895,12 @@ tmpfs_alloc_directory(FAR struct tmpfs_directory_s *parent)
|
|||
tdo->tdo_nentries = 0;
|
||||
tdo->tdo_entry = NULL;
|
||||
|
||||
#ifdef CONFIG_FS_PERMISSION
|
||||
tmpfs_init_object((FAR struct tmpfs_object_s *)tdo, mode);
|
||||
#else
|
||||
UNUSED(mode);
|
||||
#endif
|
||||
|
||||
nxrmutex_init(&tdo->tdo_lock);
|
||||
|
||||
return tdo;
|
||||
|
|
@ -743,7 +911,7 @@ tmpfs_alloc_directory(FAR struct tmpfs_directory_s *parent)
|
|||
****************************************************************************/
|
||||
|
||||
static int tmpfs_create_directory(FAR struct tmpfs_s *fs,
|
||||
FAR const char *relpath,
|
||||
FAR const char *relpath, mode_t mode,
|
||||
FAR struct tmpfs_directory_s **tdo)
|
||||
{
|
||||
FAR struct tmpfs_directory_s *parent;
|
||||
|
|
@ -817,7 +985,7 @@ static int tmpfs_create_directory(FAR struct tmpfs_s *fs,
|
|||
* the new directory and the object is not locked.
|
||||
*/
|
||||
|
||||
newtdo = tmpfs_alloc_directory(parent);
|
||||
newtdo = tmpfs_alloc_directory(parent, mode);
|
||||
if (newtdo == NULL)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
|
|
@ -1369,6 +1537,9 @@ static int tmpfs_open(FAR struct file *filep, FAR const char *relpath,
|
|||
FAR struct inode *inode;
|
||||
FAR struct tmpfs_s *fs;
|
||||
FAR struct tmpfs_file_s *tfo;
|
||||
#ifdef CONFIG_FS_PERMISSION
|
||||
FAR struct tmpfs_object_s *to;
|
||||
#endif
|
||||
off_t offset;
|
||||
int ret;
|
||||
|
||||
|
|
@ -1392,10 +1563,6 @@ static int tmpfs_open(FAR struct file *filep, FAR const char *relpath,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Skip over any leading directory separators (shouldn't be any) */
|
||||
|
||||
for (; *relpath == '/'; relpath++);
|
||||
|
||||
/* Find the file object associated with this relative path.
|
||||
* If successful, this action will lock both the parent directory and
|
||||
* the file object, adding one to the reference count of both.
|
||||
|
|
@ -1420,9 +1587,23 @@ static int tmpfs_open(FAR struct file *filep, FAR const char *relpath,
|
|||
goto errout_with_filelock;
|
||||
}
|
||||
|
||||
/* Check if the caller has sufficient privileges to open the file.
|
||||
* REVISIT: No file protection implemented
|
||||
*/
|
||||
/* Check if the caller has sufficient privileges to open the file. */
|
||||
|
||||
#ifdef CONFIG_FS_PERMISSION
|
||||
to = (FAR struct tmpfs_object_s *)tfo;
|
||||
ret = tmpfs_check_parentperm(fs, relpath, X_OK);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_filelock;
|
||||
}
|
||||
|
||||
ret = fs_checkopenperm(to->to_uid, to->to_gid,
|
||||
to->to_mode | S_IFREG, oflags);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_filelock;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If O_TRUNC is specified and the file is opened for writing,
|
||||
* then truncate the file. This operation requires that the file is
|
||||
|
|
@ -1467,7 +1648,15 @@ static int tmpfs_open(FAR struct file *filep, FAR const char *relpath,
|
|||
* on the new file object.
|
||||
*/
|
||||
|
||||
ret = tmpfs_create_file(fs, relpath, &tfo);
|
||||
#ifdef CONFIG_FS_PERMISSION
|
||||
ret = tmpfs_check_parentperm(fs, relpath, W_OK | X_OK);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_fslock;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = tmpfs_create_file(fs, relpath, mode, &tfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_fslock;
|
||||
|
|
@ -1936,6 +2125,36 @@ static int tmpfs_fstat(FAR const struct file *filep, FAR struct stat *buf)
|
|||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tmpfs_fchstat
|
||||
****************************************************************************/
|
||||
|
||||
static int tmpfs_fchstat(FAR const struct file *filep,
|
||||
FAR const struct stat *buf, int flags)
|
||||
{
|
||||
DEBUGASSERT(filep->f_priv != NULL && buf != NULL);
|
||||
|
||||
#ifdef CONFIG_FS_PERMISSION
|
||||
FAR struct tmpfs_file_s *tfo;
|
||||
int ret;
|
||||
|
||||
tfo = filep->f_priv;
|
||||
|
||||
ret = tmpfs_lock_file(tfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = tmpfs_chstat_object((FAR struct tmpfs_object_s *)tfo, buf, flags);
|
||||
tmpfs_unlock_file(tfo);
|
||||
return ret;
|
||||
#else
|
||||
UNUSED(flags);
|
||||
return -ENOSYS;
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tmpfs_truncate
|
||||
****************************************************************************/
|
||||
|
|
@ -2031,10 +2250,6 @@ static int tmpfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Skip over any leading directory separators (shouldn't be any) */
|
||||
|
||||
for (; *relpath == '/'; relpath++);
|
||||
|
||||
/* Find the directory object associated with this relative path.
|
||||
* If successful, this action will lock both the parent directory and
|
||||
* the file object, adding one to the reference count of both.
|
||||
|
|
@ -2045,10 +2260,21 @@ static int tmpfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
|||
ret = tmpfs_find_directory(fs, relpath, strlen(relpath), &tdo, NULL);
|
||||
if (ret >= 0)
|
||||
{
|
||||
tdir->tf_tdo = tdo;
|
||||
tdir->tf_index = tdo->tdo_nentries;
|
||||
*dir = &tdir->tf_base;
|
||||
tmpfs_unlock_directory(tdo);
|
||||
#ifdef CONFIG_FS_PERMISSION
|
||||
ret = tmpfs_check_pathperm(fs, relpath, strlen(relpath), R_OK | X_OK);
|
||||
if (ret < 0)
|
||||
{
|
||||
tdo->tdo_refs--;
|
||||
tmpfs_unlock_directory(tdo);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
tdir->tf_tdo = tdo;
|
||||
tdir->tf_index = tdo->tdo_nentries;
|
||||
*dir = &tdir->tf_base;
|
||||
tmpfs_unlock_directory(tdo);
|
||||
}
|
||||
}
|
||||
|
||||
/* Release the lock on the file system and return the result */
|
||||
|
|
@ -2212,7 +2438,7 @@ static int tmpfs_bind(FAR struct inode *blkdriver, FAR const void *data,
|
|||
* the file system structure.
|
||||
*/
|
||||
|
||||
tdo = tmpfs_alloc_directory(NULL);
|
||||
tdo = tmpfs_alloc_directory(NULL, 0777);
|
||||
if (tdo == NULL)
|
||||
{
|
||||
fs_heap_free(fs);
|
||||
|
|
@ -2481,7 +2707,7 @@ static int tmpfs_mkdir(FAR struct inode *mountpt, FAR const char *relpath,
|
|||
|
||||
/* Create the directory. */
|
||||
|
||||
ret = tmpfs_create_directory(fs, relpath, NULL);
|
||||
ret = tmpfs_create_directory(fs, relpath, mode, NULL);
|
||||
tmpfs_unlock(fs);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -2768,9 +2994,15 @@ static void tmpfs_stat_common(FAR struct tmpfs_object_s *to,
|
|||
FAR struct tmpfs_file_s *tfo =
|
||||
(FAR struct tmpfs_file_s *)to;
|
||||
|
||||
#ifdef CONFIG_FS_PERMISSION
|
||||
buf->st_mode = (to->to_mode & 07777) | S_IFREG;
|
||||
buf->st_uid = to->to_uid;
|
||||
buf->st_gid = to->to_gid;
|
||||
#else
|
||||
/* -rwxrwxrwx */
|
||||
|
||||
buf->st_mode = S_IRWXO | S_IRWXG | S_IRWXU | S_IFREG;
|
||||
#endif
|
||||
|
||||
/* Get the size of the object */
|
||||
|
||||
|
|
@ -2781,9 +3013,15 @@ static void tmpfs_stat_common(FAR struct tmpfs_object_s *to,
|
|||
FAR struct tmpfs_directory_s *tdo =
|
||||
(FAR struct tmpfs_directory_s *)to;
|
||||
|
||||
#ifdef CONFIG_FS_PERMISSION
|
||||
buf->st_mode = (to->to_mode & 07777) | S_IFDIR;
|
||||
buf->st_uid = to->to_uid;
|
||||
buf->st_gid = to->to_gid;
|
||||
#else
|
||||
/* drwxrwxrwx */
|
||||
|
||||
buf->st_mode = S_IRWXO | S_IRWXG | S_IRWXU | S_IFDIR;
|
||||
#endif
|
||||
|
||||
/* Get the size of the object */
|
||||
|
||||
|
|
@ -2853,6 +3091,47 @@ errout_with_fslock:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tmpfs_chstat
|
||||
****************************************************************************/
|
||||
|
||||
static int tmpfs_chstat(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
FAR const struct stat *buf, int flags)
|
||||
{
|
||||
DEBUGASSERT(mountpt != NULL && relpath != NULL && buf != NULL);
|
||||
|
||||
#ifdef CONFIG_FS_PERMISSION
|
||||
FAR struct tmpfs_s *fs;
|
||||
FAR struct tmpfs_object_s *to;
|
||||
int ret;
|
||||
|
||||
fs = mountpt->i_private;
|
||||
DEBUGASSERT(fs != NULL);
|
||||
|
||||
ret = tmpfs_lock(fs);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = tmpfs_find_object(fs, relpath, strlen(relpath), &to, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_fslock;
|
||||
}
|
||||
|
||||
ret = tmpfs_chstat_object(to, buf, flags);
|
||||
tmpfs_release_lockedobject(to);
|
||||
|
||||
errout_with_fslock:
|
||||
tmpfs_unlock(fs);
|
||||
return ret;
|
||||
#else
|
||||
UNUSED(flags);
|
||||
return -ENOSYS;
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@
|
|||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/mutex.h>
|
||||
|
|
@ -82,6 +84,11 @@ struct tmpfs_object_s
|
|||
uint8_t to_type; /* See enum tmpfs_objtype_e */
|
||||
uint8_t to_refs; /* Reference count */
|
||||
FAR struct tmpfs_directory_s *to_parent;
|
||||
#ifdef CONFIG_FS_PERMISSION
|
||||
mode_t to_mode; /* File mode (permission bits) */
|
||||
uid_t to_uid; /* Owner user ID */
|
||||
gid_t to_gid; /* Owner group ID */
|
||||
#endif
|
||||
};
|
||||
|
||||
/* The form of a directory memory object */
|
||||
|
|
@ -96,6 +103,11 @@ struct tmpfs_directory_s
|
|||
uint8_t tdo_type; /* See enum tmpfs_objtype_e */
|
||||
uint8_t tdo_refs; /* Reference count */
|
||||
FAR struct tmpfs_directory_s *tdo_parent;
|
||||
#ifdef CONFIG_FS_PERMISSION
|
||||
mode_t tdo_mode; /* Directory mode (permission bits) */
|
||||
uid_t tdo_uid; /* Owner user ID */
|
||||
gid_t tdo_gid; /* Owner group ID */
|
||||
#endif
|
||||
|
||||
/* Remaining fields are unique to a directory object */
|
||||
|
||||
|
|
@ -123,6 +135,11 @@ struct tmpfs_file_s
|
|||
uint8_t tfo_type; /* See enum tmpfs_objtype_e */
|
||||
uint8_t tfo_refs; /* Reference count */
|
||||
FAR struct tmpfs_directory_s *tfo_parent;
|
||||
#ifdef CONFIG_FS_PERMISSION
|
||||
mode_t tfo_mode; /* File mode (permission bits) */
|
||||
uid_t tfo_uid; /* Owner user ID */
|
||||
gid_t tfo_gid; /* Owner group ID */
|
||||
#endif
|
||||
|
||||
/* Remaining fields are unique to a directory object */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue