fs/tmpfs: Fix the memory corruption when reallocate tmpfs_directory_s

since it's hard to adjust all childern to point back the new parent
location. Let's allocate the dynamical part(e.g. tdo_entry) separately
and remove the back pointer.

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Change-Id: I53afb8336360b7845bd8ecb5aa908acea20e7797
This commit is contained in:
Xiang Xiao 2021-06-24 22:55:08 +08:00 committed by Alan Carvalho de Assis
parent ce20211357
commit c406e03cfe
2 changed files with 61 additions and 119 deletions

View File

@ -76,9 +76,9 @@ static void tmpfs_unlock_reentrant(FAR struct tmpfs_sem_s *sem);
static void tmpfs_unlock(FAR struct tmpfs_s *fs); static void tmpfs_unlock(FAR struct tmpfs_s *fs);
static int tmpfs_lock_object(FAR struct tmpfs_object_s *to); static int tmpfs_lock_object(FAR struct tmpfs_object_s *to);
static void tmpfs_unlock_object(FAR struct tmpfs_object_s *to); static void tmpfs_unlock_object(FAR struct tmpfs_object_s *to);
static int tmpfs_realloc_directory(FAR struct tmpfs_directory_s **tdo, static int tmpfs_realloc_directory(FAR struct tmpfs_directory_s *tdo,
unsigned int nentries); unsigned int nentries);
static int tmpfs_realloc_file(FAR struct tmpfs_file_s **tfo, static int tmpfs_realloc_file(FAR struct tmpfs_file_s *tfo,
size_t newsize); size_t newsize);
static void tmpfs_release_lockedobject(FAR struct tmpfs_object_s *to); static void tmpfs_release_lockedobject(FAR struct tmpfs_object_s *to);
static void tmpfs_release_lockedfile(FAR struct tmpfs_file_s *tfo); static void tmpfs_release_lockedfile(FAR struct tmpfs_file_s *tfo);
@ -86,7 +86,7 @@ static int tmpfs_find_dirent(FAR struct tmpfs_directory_s *tdo,
FAR const char *name); FAR const char *name);
static int tmpfs_remove_dirent(FAR struct tmpfs_directory_s *tdo, static int tmpfs_remove_dirent(FAR struct tmpfs_directory_s *tdo,
FAR const char *name); FAR const char *name);
static int tmpfs_add_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); FAR struct tmpfs_object_s *to, FAR const char *name);
static FAR struct tmpfs_file_s *tmpfs_alloc_file(void); static FAR struct tmpfs_file_s *tmpfs_alloc_file(void);
static int tmpfs_create_file(FAR struct tmpfs_s *fs, static int tmpfs_create_file(FAR struct tmpfs_s *fs,
@ -293,24 +293,23 @@ static void tmpfs_unlock_object(FAR struct tmpfs_object_s *to)
* Name: tmpfs_realloc_directory * Name: tmpfs_realloc_directory
****************************************************************************/ ****************************************************************************/
static int tmpfs_realloc_directory(FAR struct tmpfs_directory_s **tdo, static int tmpfs_realloc_directory(FAR struct tmpfs_directory_s *tdo,
unsigned int nentries) unsigned int nentries)
{ {
FAR struct tmpfs_directory_s *oldtdo = *tdo; FAR struct tmpfs_dirent_s *newentry;
FAR struct tmpfs_directory_s *newtdo;
size_t objsize; size_t objsize;
int ret = oldtdo->tdo_nentries; int ret = tdo->tdo_nentries;
/* Get the new object size */ /* Get the new object size */
objsize = SIZEOF_TMPFS_DIRECTORY(nentries); objsize = SIZEOF_TMPFS_DIRECTORY(nentries);
if (objsize <= oldtdo->tdo_alloc) if (objsize <= tdo->tdo_alloc)
{ {
/* Already big enough. /* Already big enough.
* REVISIT: Missing logic to shrink directory objects. * REVISIT: Missing logic to shrink directory objects.
*/ */
oldtdo->tdo_nentries = nentries; tdo->tdo_nentries = nentries;
return ret; return ret;
} }
@ -322,22 +321,17 @@ static int tmpfs_realloc_directory(FAR struct tmpfs_directory_s **tdo,
/* Realloc the directory object */ /* Realloc the directory object */
newtdo = (FAR struct tmpfs_directory_s *)kmm_realloc(oldtdo, objsize); newentry = kmm_realloc(tdo->tdo_entry, objsize);
if (newtdo == NULL) if (newentry == NULL)
{ {
return -ENOMEM; return -ENOMEM;
} }
/* Adjust the reference in the parent directory entry */
DEBUGASSERT(newtdo->tdo_dirent);
newtdo->tdo_dirent->tde_object = (FAR struct tmpfs_object_s *)newtdo;
/* Return the new address of the reallocated directory object */ /* Return the new address of the reallocated directory object */
newtdo->tdo_alloc = objsize; tdo->tdo_alloc = objsize;
newtdo->tdo_nentries = nentries; tdo->tdo_nentries = nentries;
*tdo = newtdo; tdo->tdo_entry = newentry;
/* Return the index to the first, newly allocated directory entry */ /* Return the index to the first, newly allocated directory entry */
@ -348,22 +342,16 @@ static int tmpfs_realloc_directory(FAR struct tmpfs_directory_s **tdo,
* Name: tmpfs_realloc_file * Name: tmpfs_realloc_file
****************************************************************************/ ****************************************************************************/
static int tmpfs_realloc_file(FAR struct tmpfs_file_s **tfo, static int tmpfs_realloc_file(FAR struct tmpfs_file_s *tfo,
size_t newsize) size_t newsize)
{ {
FAR struct tmpfs_file_s *oldtfo = *tfo; FAR uint8_t *newdata;
FAR struct tmpfs_file_s *newtfo;
size_t objsize;
size_t allocsize; size_t allocsize;
size_t delta; size_t delta;
/* Check if the current allocation is sufficient */
objsize = SIZEOF_TMPFS_FILE(newsize);
/* Are we growing or shrinking the object? */ /* Are we growing or shrinking the object? */
if (objsize <= oldtfo->tfo_alloc) if (newsize <= tfo->tfo_alloc)
{ {
/* Shrinking ... Shrink unconditionally if the size is shrinking to /* Shrinking ... Shrink unconditionally if the size is shrinking to
* zero. * zero.
@ -375,12 +363,12 @@ static int tmpfs_realloc_file(FAR struct tmpfs_file_s **tfo,
* lot. * lot.
*/ */
delta = oldtfo->tfo_alloc - objsize; delta = tfo->tfo_alloc - newsize;
if (delta <= CONFIG_FS_TMPFS_FILE_FREEGUARD) if (delta <= CONFIG_FS_TMPFS_FILE_FREEGUARD)
{ {
/* Hasn't shrunk enough.. Return doing nothing for now */ /* Hasn't shrunk enough.. Return doing nothing for now */
oldtfo->tfo_size = newsize; tfo->tfo_size = newsize;
return OK; return OK;
} }
} }
@ -390,26 +378,21 @@ static int tmpfs_realloc_file(FAR struct tmpfs_file_s **tfo,
* reallocations. * reallocations.
*/ */
allocsize = objsize + CONFIG_FS_TMPFS_FILE_ALLOCGUARD; allocsize = newsize + CONFIG_FS_TMPFS_FILE_ALLOCGUARD;
/* Realloc the file object */ /* Realloc the file object */
newtfo = (FAR struct tmpfs_file_s *)kmm_realloc(oldtfo, allocsize); newdata = kmm_realloc(tfo->tfo_data, allocsize);
if (newtfo == NULL) if (newdata == NULL)
{ {
return -ENOMEM; return -ENOMEM;
} }
/* Adjust the reference in the parent directory entry */
DEBUGASSERT(newtfo->tfo_dirent);
newtfo->tfo_dirent->tde_object = (FAR struct tmpfs_object_s *)newtfo;
/* Return the new address of the reallocated file object */ /* Return the new address of the reallocated file object */
newtfo->tfo_alloc = allocsize; tfo->tfo_alloc = allocsize;
newtfo->tfo_size = newsize; tfo->tfo_size = newsize;
*tfo = newtfo; tfo->tfo_data = newdata;
return OK; return OK;
} }
@ -449,6 +432,7 @@ static void tmpfs_release_lockedfile(FAR struct tmpfs_file_s *tfo)
if (tfo->tfo_refs == 1 && (tfo->tfo_flags & TFO_FLAG_UNLINKED) != 0) if (tfo->tfo_refs == 1 && (tfo->tfo_flags & TFO_FLAG_UNLINKED) != 0)
{ {
nxsem_destroy(&tfo->tfo_exclsem.ts_sem); nxsem_destroy(&tfo->tfo_exclsem.ts_sem);
kmm_free(tfo->tfo_data);
kmm_free(tfo); kmm_free(tfo);
} }
@ -512,22 +496,7 @@ static int tmpfs_remove_dirent(FAR struct tmpfs_directory_s *tdo,
last = tdo->tdo_nentries - 1; last = tdo->tdo_nentries - 1;
if (index != last) if (index != last)
{ {
FAR struct tmpfs_dirent_s *newtde; tdo->tdo_entry[index] = tdo->tdo_entry[last];
FAR struct tmpfs_dirent_s *oldtde;
FAR struct tmpfs_object_s *to;
/* Move the directory entry */
newtde = &tdo->tdo_entry[index];
oldtde = &tdo->tdo_entry[last];
to = oldtde->tde_object;
newtde->tde_object = to;
newtde->tde_name = oldtde->tde_name;
/* Reset the backward link to the directory entry */
to->to_dirent = newtde;
} }
/* And decrement the count of directory entries */ /* And decrement the count of directory entries */
@ -540,12 +509,10 @@ static int tmpfs_remove_dirent(FAR struct tmpfs_directory_s *tdo,
* Name: tmpfs_add_dirent * Name: tmpfs_add_dirent
****************************************************************************/ ****************************************************************************/
static int tmpfs_add_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 struct tmpfs_object_s *to,
FAR const char *name) FAR const char *name)
{ {
FAR struct tmpfs_directory_s *oldtdo;
FAR struct tmpfs_directory_s *newtdo;
FAR struct tmpfs_dirent_s *tde; FAR struct tmpfs_dirent_s *tde;
FAR char *newname; FAR char *newname;
unsigned int nentries; unsigned int nentries;
@ -563,8 +530,7 @@ static int tmpfs_add_dirent(FAR struct tmpfs_directory_s **tdo,
/* Get the new number of entries */ /* Get the new number of entries */
oldtdo = *tdo; nentries = tdo->tdo_nentries + 1;
nentries = oldtdo->tdo_nentries + 1;
/* Reallocate the directory object (if necessary) */ /* Reallocate the directory object (if necessary) */
@ -577,14 +543,10 @@ static int tmpfs_add_dirent(FAR struct tmpfs_directory_s **tdo,
/* Save the new object info in the new directory entry */ /* Save the new object info in the new directory entry */
newtdo = *tdo; tde = &tdo->tdo_entry[index];
tde = &newtdo->tdo_entry[index];
tde->tde_object = to; tde->tde_object = to;
tde->tde_name = newname; tde->tde_name = newname;
/* Add backward link to the directory entry to the object */
to->to_dirent = tde;
return OK; return OK;
} }
@ -595,12 +557,10 @@ static int tmpfs_add_dirent(FAR struct tmpfs_directory_s **tdo,
static FAR struct tmpfs_file_s *tmpfs_alloc_file(void) static FAR struct tmpfs_file_s *tmpfs_alloc_file(void)
{ {
FAR struct tmpfs_file_s *tfo; FAR struct tmpfs_file_s *tfo;
size_t allocsize;
/* Create a new zero length file object */ /* Create a new zero length file object */
allocsize = SIZEOF_TMPFS_FILE(CONFIG_FS_TMPFS_FILE_ALLOCGUARD); tfo = (FAR struct tmpfs_file_s *)kmm_malloc(sizeof(*tfo));
tfo = (FAR struct tmpfs_file_s *)kmm_malloc(allocsize);
if (tfo == NULL) if (tfo == NULL)
{ {
return NULL; return NULL;
@ -610,11 +570,12 @@ static FAR struct tmpfs_file_s *tmpfs_alloc_file(void)
* locked with one reference count. * locked with one reference count.
*/ */
tfo->tfo_alloc = allocsize; tfo->tfo_alloc = 0;
tfo->tfo_type = TMPFS_REGULAR; tfo->tfo_type = TMPFS_REGULAR;
tfo->tfo_refs = 1; tfo->tfo_refs = 1;
tfo->tfo_flags = 0; tfo->tfo_flags = 0;
tfo->tfo_size = 0; tfo->tfo_size = 0;
tfo->tfo_data = NULL;
tfo->tfo_exclsem.ts_holder = getpid(); tfo->tfo_exclsem.ts_holder = getpid();
tfo->tfo_exclsem.ts_count = 1; tfo->tfo_exclsem.ts_count = 1;
@ -718,7 +679,7 @@ static int tmpfs_create_file(FAR struct tmpfs_s *fs,
/* Then add the new, empty file to the directory */ /* Then add the new, empty file to the directory */
ret = tmpfs_add_dirent(&parent, (FAR struct tmpfs_object_s *)newtfo, name); ret = tmpfs_add_dirent(parent, (FAR struct tmpfs_object_s *)newtfo, name);
if (ret < 0) if (ret < 0)
{ {
goto errout_with_file; goto errout_with_file;
@ -757,19 +718,10 @@ errout_with_copy:
static FAR struct tmpfs_directory_s *tmpfs_alloc_directory(void) static FAR struct tmpfs_directory_s *tmpfs_alloc_directory(void)
{ {
FAR struct tmpfs_directory_s *tdo; FAR struct tmpfs_directory_s *tdo;
size_t allocsize;
unsigned int nentries;
/* Convert the pre-allocated memory to a number of directory entries */
nentries = (CONFIG_FS_TMPFS_DIRECTORY_ALLOCGUARD +
sizeof(struct tmpfs_dirent_s) - 1) /
sizeof(struct tmpfs_dirent_s);
/* Create a new zero length directory object */ /* Create a new zero length directory object */
allocsize = SIZEOF_TMPFS_DIRECTORY(nentries); tdo = (FAR struct tmpfs_directory_s *)kmm_malloc(sizeof(*tdo));
tdo = (FAR struct tmpfs_directory_s *)kmm_malloc(allocsize);
if (tdo == NULL) if (tdo == NULL)
{ {
return NULL; return NULL;
@ -777,10 +729,11 @@ static FAR struct tmpfs_directory_s *tmpfs_alloc_directory(void)
/* Initialize the new directory object */ /* Initialize the new directory object */
tdo->tdo_alloc = allocsize; tdo->tdo_alloc = 0;
tdo->tdo_type = TMPFS_DIRECTORY; tdo->tdo_type = TMPFS_DIRECTORY;
tdo->tdo_refs = 0; tdo->tdo_refs = 0;
tdo->tdo_nentries = 0; tdo->tdo_nentries = 0;
tdo->tdo_entry = NULL;
tdo->tdo_exclsem.ts_holder = TMPFS_NO_HOLDER; tdo->tdo_exclsem.ts_holder = TMPFS_NO_HOLDER;
tdo->tdo_exclsem.ts_count = 0; tdo->tdo_exclsem.ts_count = 0;
@ -880,7 +833,7 @@ static int tmpfs_create_directory(FAR struct tmpfs_s *fs,
/* Then add the new, empty file to the directory */ /* Then add the new, empty file to the directory */
ret = tmpfs_add_dirent(&parent, (FAR struct tmpfs_object_s *)newtdo, name); ret = tmpfs_add_dirent(parent, (FAR struct tmpfs_object_s *)newtdo, name);
if (ret < 0) if (ret < 0)
{ {
goto errout_with_directory; goto errout_with_directory;
@ -1189,6 +1142,7 @@ static int tmpfs_statfs_callout(FAR struct tmpfs_directory_s *tdo,
*/ */
tmptfo = (FAR struct tmpfs_file_s *)to; tmptfo = (FAR struct tmpfs_file_s *)to;
tmpbuf->tsf_alloc += sizeof(struct tmpfs_file_s);
tmpbuf->tsf_inuse += tmptfo->tfo_size; tmpbuf->tsf_inuse += tmptfo->tfo_size;
tmpbuf->tsf_files++; tmpbuf->tsf_files++;
} }
@ -1206,6 +1160,7 @@ static int tmpfs_statfs_callout(FAR struct tmpfs_directory_s *tdo,
inuse = SIZEOF_TMPFS_DIRECTORY(tmptdo->tdo_nentries); inuse = SIZEOF_TMPFS_DIRECTORY(tmptdo->tdo_nentries);
avail = tmptdo->tdo_alloc - inuse; avail = tmptdo->tdo_alloc - inuse;
tmpbuf->tsf_alloc += sizeof(struct tmpfs_directory_s);
tmpbuf->tsf_inuse += inuse; tmpbuf->tsf_inuse += inuse;
tmpbuf->tsf_ffree += avail / sizeof(struct tmpfs_dirent_s); tmpbuf->tsf_ffree += avail / sizeof(struct tmpfs_dirent_s);
} }
@ -1240,20 +1195,9 @@ static int tmpfs_free_callout(FAR struct tmpfs_directory_s *tdo,
if (index != last) if (index != last)
{ {
FAR struct tmpfs_dirent_s *oldtde;
FAR struct tmpfs_object_s *oldto;
/* Move the directory entry */ /* Move the directory entry */
oldtde = &tdo->tdo_entry[last]; *tde = tdo->tdo_entry[last];
oldto = oldtde->tde_object;
tde->tde_object = oldto;
tde->tde_name = oldtde->tde_name;
/* Reset the backward link to the directory entry */
oldto->to_dirent = tde;
} }
/* And decrement the count of directory entries */ /* And decrement the count of directory entries */
@ -1275,6 +1219,14 @@ static int tmpfs_free_callout(FAR struct tmpfs_directory_s *tdo,
tfo->tfo_flags |= TFO_FLAG_UNLINKED; tfo->tfo_flags |= TFO_FLAG_UNLINKED;
return TMPFS_UNLINKED; return TMPFS_UNLINKED;
} }
kmm_free(tfo->tfo_data);
}
else /* if (to->to_type == TMPFS_DIRECTORY) */
{
tdo = (FAR struct tmpfs_directory_s *)to;
kmm_free(tdo->tdo_entry);
} }
/* Free the object now */ /* Free the object now */
@ -1441,7 +1393,7 @@ static int tmpfs_open(FAR struct file *filep, FAR const char *relpath,
if (tfo->tfo_size > 0) if (tfo->tfo_size > 0)
{ {
ret = tmpfs_realloc_file(&tfo, 0); ret = tmpfs_realloc_file(tfo, 0);
if (ret < 0) if (ret < 0)
{ {
goto errout_with_filelock; goto errout_with_filelock;
@ -1561,6 +1513,7 @@ static int tmpfs_close(FAR struct file *filep)
* have any other references. * have any other references.
*/ */
kmm_free(tfo->tfo_data);
kmm_free(tfo); kmm_free(tfo);
return OK; return OK;
} }
@ -1662,13 +1615,11 @@ static ssize_t tmpfs_write(FAR struct file *filep, FAR const char *buffer,
{ {
/* Reallocate the file to handle the write past the end of the file. */ /* Reallocate the file to handle the write past the end of the file. */
ret = tmpfs_realloc_file(&tfo, (size_t)endpos); ret = tmpfs_realloc_file(tfo, (size_t)endpos);
if (ret < 0) if (ret < 0)
{ {
goto errout_with_lock; goto errout_with_lock;
} }
filep->f_priv = tfo;
} }
/* Copy data from the memory object to the user buffer */ /* Copy data from the memory object to the user buffer */
@ -1892,14 +1843,12 @@ static int tmpfs_truncate(FAR struct file *filep, off_t length)
{ {
/* The size is changing.. up or down. Reallocate the file memory. */ /* The size is changing.. up or down. Reallocate the file memory. */
ret = tmpfs_realloc_file(&tfo, (size_t)length); ret = tmpfs_realloc_file(tfo, (size_t)length);
if (ret < 0) if (ret < 0)
{ {
goto errout_with_lock; goto errout_with_lock;
} }
filep->f_priv = tfo;
/* If the size has increased, then we need to zero the newly added /* If the size has increased, then we need to zero the newly added
* memory. * memory.
*/ */
@ -2127,10 +2076,6 @@ static int tmpfs_bind(FAR struct inode *blkdriver, FAR const void *data,
fs->tfs_root.tde_object = (FAR struct tmpfs_object_s *)tdo; fs->tfs_root.tde_object = (FAR struct tmpfs_object_s *)tdo;
fs->tfs_root.tde_name = ""; fs->tfs_root.tde_name = "";
/* Set up the backward link (to support reallocation) */
tdo->tdo_dirent = &fs->tfs_root;
/* Initialize the file system state */ /* Initialize the file system state */
fs->tfs_exclsem.ts_holder = TMPFS_NO_HOLDER; fs->tfs_exclsem.ts_holder = TMPFS_NO_HOLDER;
@ -2174,6 +2119,7 @@ static int tmpfs_unbind(FAR void *handle, FAR struct inode **blkdriver,
/* Now we can destroy the root file system and the file system itself. */ /* Now we can destroy the root file system and the file system itself. */
nxsem_destroy(&tdo->tdo_exclsem.ts_sem); nxsem_destroy(&tdo->tdo_exclsem.ts_sem);
kmm_free(tdo->tdo_entry);
kmm_free(tdo); kmm_free(tdo);
nxsem_destroy(&fs->tfs_exclsem.ts_sem); nxsem_destroy(&fs->tfs_exclsem.ts_sem);
@ -2341,6 +2287,7 @@ static int tmpfs_unlink(FAR struct inode *mountpt, FAR const char *relpath)
else else
{ {
nxsem_destroy(&tfo->tfo_exclsem.ts_sem); nxsem_destroy(&tfo->tfo_exclsem.ts_sem);
kmm_free(tfo->tfo_data);
kmm_free(tfo); kmm_free(tfo);
} }
@ -2475,6 +2422,7 @@ static int tmpfs_rmdir(FAR struct inode *mountpt, FAR const char *relpath)
/* Free the directory object */ /* Free the directory object */
nxsem_destroy(&tdo->tdo_exclsem.ts_sem); nxsem_destroy(&tdo->tdo_exclsem.ts_sem);
kmm_free(tdo->tdo_entry);
kmm_free(tdo); kmm_free(tdo);
/* Release the reference and lock on the parent directory */ /* Release the reference and lock on the parent directory */
@ -2629,7 +2577,7 @@ static int tmpfs_rename(FAR struct inode *mountpt,
/* Add an entry to the new parent directory. */ /* Add an entry to the new parent directory. */
ret = tmpfs_add_dirent(&newparent, to, newname); ret = tmpfs_add_dirent(newparent, to, newname);
errout_with_oldparent: errout_with_oldparent:
oldparent->tdo_refs--; oldparent->tdo_refs--;

View File

@ -87,7 +87,6 @@ struct tmpfs_dirent_s
struct tmpfs_object_s struct tmpfs_object_s
{ {
FAR struct tmpfs_dirent_s *to_dirent;
struct tmpfs_sem_s to_exclsem; struct tmpfs_sem_s to_exclsem;
size_t to_alloc; /* Allocated size of the memory object */ size_t to_alloc; /* Allocated size of the memory object */
@ -101,7 +100,6 @@ struct tmpfs_directory_s
{ {
/* First fields must match common TMPFS object layout */ /* First fields must match common TMPFS object layout */
FAR struct tmpfs_dirent_s *tdo_dirent;
struct tmpfs_sem_s tdo_exclsem; struct tmpfs_sem_s tdo_exclsem;
size_t tdo_alloc; /* Allocated size of the directory object */ size_t tdo_alloc; /* Allocated size of the directory object */
@ -111,11 +109,10 @@ struct tmpfs_directory_s
/* Remaining fields are unique to a directory object */ /* Remaining fields are unique to a directory object */
uint16_t tdo_nentries; /* Number of directory entries */ uint16_t tdo_nentries; /* Number of directory entries */
struct tmpfs_dirent_s tdo_entry[1]; FAR struct tmpfs_dirent_s *tdo_entry;
}; };
#define SIZEOF_TMPFS_DIRECTORY(n) \ #define SIZEOF_TMPFS_DIRECTORY(n) ((n) * sizeof(struct tmpfs_dirent_s))
(sizeof(struct tmpfs_directory_s) + ((n) - 1) * sizeof(struct tmpfs_dirent_s))
/* The form of a regular file memory object /* The form of a regular file memory object
* *
@ -129,7 +126,6 @@ struct tmpfs_file_s
{ {
/* First fields must match common TMPFS object layout */ /* First fields must match common TMPFS object layout */
FAR struct tmpfs_dirent_s *tfo_dirent;
struct tmpfs_sem_s tfo_exclsem; struct tmpfs_sem_s tfo_exclsem;
size_t tfo_alloc; /* Allocated size of the file object */ size_t tfo_alloc; /* Allocated size of the file object */
@ -140,11 +136,9 @@ struct tmpfs_file_s
uint8_t tfo_flags; /* See TFO_FLAG_* definitions */ uint8_t tfo_flags; /* See TFO_FLAG_* definitions */
size_t tfo_size; /* Valid file size */ size_t tfo_size; /* Valid file size */
uint8_t tfo_data[1]; /* File data starts here */ FAR uint8_t *tfo_data; /* File data starts here */
}; };
#define SIZEOF_TMPFS_FILE(n) (sizeof(struct tmpfs_file_s) + (n) - 1)
/* This structure represents one instance of a TMPFS file system */ /* This structure represents one instance of a TMPFS file system */
struct tmpfs_s struct tmpfs_s