1
0
Fork 0
forked from nuttx/nuttx-update

fs/mnemofs: Fix mkdir for depth > 3 bug, better logs

- Fix bug which prevents mkdir for depth > 3.
- Better logs for mnemofs

Signed-off-by: Saurav Pal <resyfer.dev@gmail.com>
This commit is contained in:
Saurav Pal 2024-10-28 14:39:05 +00:00 committed by Xiang Xiao
parent 716d898dda
commit 17bca89f07
3 changed files with 219 additions and 89 deletions

View file

@ -1490,22 +1490,22 @@ static int mnemofs_bind(FAR struct inode *driver, FAR const void *data,
FAR struct mfs_sb_s *sb = NULL;
struct mtd_geometry_s geo;
MFS_LOG("[mnemofs | BIND] Entry.");
MFS_LOG("BIND", "Entry.");
MFS_EXTRA_LOG("[mnemofs | BIND] Resetting temporary buffer.");
MFS_EXTRA_LOG("BIND", "Resetting temporary buffer.");
memset(buf, 0, 8);
MFS_EXTRA_LOG("[mnemofs | BIND] Allocating superblock in memory.");
MFS_EXTRA_LOG("BIND", "Allocating superblock in memory.");
sb = fs_heap_zalloc(sizeof(*sb));
if (!sb)
{
MFS_LOG("[mnemofs | BIND] SB in-memory allocation error.");
MFS_LOG("BIND", "SB in-memory allocation error.");
ret = -ENOMEM;
goto errout;
}
else
{
MFS_EXTRA_LOG("[mnemofs | BIND] Superblock allocated at %p", sb);
MFS_EXTRA_LOG("BIND", "Superblock allocated at %p", sb);
}
/* Currently only supports NAND flashes (MTD devices). */
@ -1514,20 +1514,20 @@ static int mnemofs_bind(FAR struct inode *driver, FAR const void *data,
{
if (!driver || !driver->u.i_mtd || !driver->u.i_mtd->ioctl)
{
MFS_LOG("[mnemofs | BIND] Unsupported device.");
MFS_LOG("BIND", "Unsupported device.");
ret = -ENODEV;
goto errout_with_sb;
}
else
{
MFS_EXTRA_LOG("[mnemofs | BIND] Device is of MTD type.");
MFS_EXTRA_LOG("BIND", "Device is of MTD type.");
}
ret = MTD_IOCTL(driver->u.i_mtd, MTDIOC_GEOMETRY,
(unsigned long) &geo);
MFS_LOG("[mnemofs | BIND] MTD Driver Geometry read.");
MFS_EXTRA_LOG("[mnemofs | BIND] MTD Driver Geometry details."
MFS_LOG("BIND", "MTD Driver Geometry read.");
MFS_EXTRA_LOG("BIND", "MTD Driver Geometry details."
" Page size: %d, Block size: %d,"
" Pages/Block: %d, Blocks: %d\n",
geo.blocksize, geo.erasesize,
@ -1535,7 +1535,7 @@ static int mnemofs_bind(FAR struct inode *driver, FAR const void *data,
}
else
{
MFS_LOG("[mnemofs | BIND] Device is not an MTD device.");
MFS_LOG("BIND", "Device is not an MTD device.");
ret = -ENODEV;
goto errout_with_sb;
}
@ -1543,23 +1543,23 @@ static int mnemofs_bind(FAR struct inode *driver, FAR const void *data,
ret = nxmutex_init(&MFS_LOCK(sb));
if (predict_false(ret < 0))
{
MFS_LOG("[mnemofs | BIND] FS-wide Mutex failed to initialize.");
MFS_LOG("BIND", "FS-wide Mutex failed to initialize.");
goto errout_with_sb;
}
else
{
MFS_EXTRA_LOG("[mnemofs | BIND] FS-wide Mutex Initialized.");
MFS_EXTRA_LOG("BIND", "FS-wide Mutex Initialized.");
}
ret = nxmutex_lock(&MFS_LOCK(sb));
if (ret < 0)
{
MFS_LOG("[mnemofs | BIND] Mutex failed to lock. Return %d.", ret);
MFS_LOG("BIND", "Mutex failed to lock. Return %d.", ret);
goto errout_with_lockinit;
}
else
{
MFS_EXTRA_LOG("[mnemofs | BIND] Mutex acquired.");
MFS_EXTRA_LOG("BIND", "Mutex acquired.");
}
sb->drv = driver;
@ -1580,31 +1580,31 @@ static int mnemofs_bind(FAR struct inode *driver, FAR const void *data,
list_initialize(&MFS_OFILES(sb));
MFS_EXTRA_LOG("[mnemofs | BIND] SB initialized in-memory.");
MFS_EXTRA_LOG("[mnemofs | BIND] SB Details.");
MFS_EXTRA_LOG("[mnemofs | BIND] \tDriver: %p", driver);
MFS_EXTRA_LOG("[mnemofs | BIND] \tPage Size: %" PRIu32, sb->pg_sz);
MFS_EXTRA_LOG("[mnemofs | BIND] \tLog Page Size: %" PRIu8, sb->log_pg_sz);
MFS_EXTRA_LOG("[mnemofs | BIND] \tBlock Size: %" PRIu32, sb->blk_sz);
MFS_EXTRA_LOG("[mnemofs | BIND] \tLog Block Size: %" PRIu8,
MFS_EXTRA_LOG("BIND", "SB initialized in-memory.");
MFS_EXTRA_LOG("BIND", "SB Details.");
MFS_EXTRA_LOG("BIND", "\tDriver: %p", driver);
MFS_EXTRA_LOG("BIND", "\tPage Size: %" PRIu32, sb->pg_sz);
MFS_EXTRA_LOG("BIND", "\tLog Page Size: %" PRIu8, sb->log_pg_sz);
MFS_EXTRA_LOG("BIND", "\tBlock Size: %" PRIu32, sb->blk_sz);
MFS_EXTRA_LOG("BIND", "\tLog Block Size: %" PRIu8,
sb->log_blk_sz);
MFS_EXTRA_LOG("[mnemofs | BIND] \tPages Per Block: %" PRIu16,
MFS_EXTRA_LOG("BIND", "\tPages Per Block: %" PRIu16,
sb->pg_in_blk);
MFS_EXTRA_LOG("[mnemofs | BIND] \tBlocks: %" PRIu32, sb->n_blks);
MFS_EXTRA_LOG("[mnemofs | BIND] \tLog Blocks: %" PRIu8, sb->log_n_blks);
MFS_EXTRA_LOG("[mnemofs | BIND] \tJournal Blocks: %" PRIu16,
MFS_EXTRA_LOG("BIND", "\tBlocks: %" PRIu32, sb->n_blks);
MFS_EXTRA_LOG("BIND", "\tLog Blocks: %" PRIu8, sb->log_n_blks);
MFS_EXTRA_LOG("BIND", "\tJournal Blocks: %" PRIu16,
MFS_JRNL(sb).n_blks);
MFS_EXTRA_LOG("[mnemofs | BIND] \tFlush State: %" PRIu8, MFS_FLUSH(sb));
MFS_EXTRA_LOG("BIND", "\tFlush State: %" PRIu8, MFS_FLUSH(sb));
sb->rw_buf = fs_heap_zalloc(MFS_PGSZ(sb));
if (predict_false(sb->rw_buf == NULL))
{
MFS_LOG("[mnemofs | BIND] RW Buffer in-memory allocation error.");
MFS_LOG("BIND", "RW Buffer in-memory allocation error.");
goto errout_with_lock;
}
else
{
MFS_EXTRA_LOG("[mnemofs | BIND] RW Buffer allocated.");
MFS_EXTRA_LOG("BIND", "RW Buffer allocated.");
}
/* TODO: Format the superblock in Block 0. */
@ -1613,64 +1613,64 @@ static int mnemofs_bind(FAR struct inode *driver, FAR const void *data,
if (!MFS_STRLITCMP(data, "autoformat"))
{
MFS_LOG("[mnemofs | BIND] Autoformat is ON.");
MFS_LOG("BIND", "Autoformat is ON.");
/* Look for journal and maybe hopefully, the master node
* if it comes first.
*/
MFS_LOG("[mnemofs | BIND] Checking for valid mnemofs formatting.");
MFS_LOG("BIND", "Checking for valid mnemofs formatting.");
for (i = 0; i < MFS_NBLKS(sb); i++)
{
MFS_EXTRA_LOG("[mnemofs | BIND] Checking start of Block %" PRIu32,
MFS_EXTRA_LOG("BIND", "Checking start of Block %" PRIu32,
i + 1);
mfs_read_page(sb, buf, 8, MFS_BLK2PG(sb, i), 0);
for (j = 0; j < 8; j++)
{
MFS_EXTRA_LOG("[mnemofs | BIND] \tBlock %" PRIu32
MFS_EXTRA_LOG("BIND", "\tBlock %" PRIu32
", Offset %" PRIu32 ": %x", i, j, buf[j]);
}
if (!MFS_STRLITCMP(buf, MFS_JRNL_MAGIC))
{
MFS_LOG("[mnemofs | BIND] Found Journal at Block %" PRIu32,
MFS_LOG("BIND", "Found Journal at Block %" PRIu32,
i + 1);
ret = mfs_jrnl_init(sb, i);
if (predict_false(ret < 0))
{
MFS_LOG("[mnemofs | BIND] Error initializing journal.");
MFS_LOG("BIND", "Error initializing journal.");
goto errout_with_rwbuf;
}
else
{
MFS_LOG("[mnemofs | BIND] Journal initialized.");
MFS_LOG("BIND", "Journal initialized.");
}
ret = mfs_mn_init(sb, i);
if (predict_false(ret < 0))
{
MFS_LOG("[mnemofs | BIND] Error initializing masternode.");
MFS_LOG("BIND", "Error initializing masternode.");
goto errout_with_rwbuf;
}
else
{
MFS_LOG("[mnemofs | BIND] Master node initialized.");
MFS_LOG("BIND", "Master node initialized.");
}
break;
}
MFS_EXTRA_LOG("[mnemofs | BIND] Resetting temporary buffer.");
MFS_EXTRA_LOG("BIND", "Resetting temporary buffer.");
memset(buf, 0, 8);
}
if (predict_false(sb->mn.pg == 0))
{
MFS_LOG("[mnemofs | BIND] Journal not found on device.");
MFS_LOG("[mnemofs | BIND] Device needs formatting.");
MFS_LOG("BIND", "Journal not found on device.");
MFS_LOG("BIND", "Device needs formatting.");
format = true;
memset(&MFS_JRNL(sb), 0, sizeof(struct mfs_jrnl_state_s));
@ -1678,7 +1678,7 @@ static int mnemofs_bind(FAR struct inode *driver, FAR const void *data,
}
else
{
MFS_LOG("[mnemofs | BIND] Device already formatted.");
MFS_LOG("BIND", "Device already formatted.");
mfs_lru_init(sb);
mfs_ba_init(sb);
@ -1691,11 +1691,11 @@ static int mnemofs_bind(FAR struct inode *driver, FAR const void *data,
if (format)
{
MFS_LOG("[mnemofs | BIND] Device format necessary.");
MFS_LOG("BIND", "Device format necessary.");
}
else
{
MFS_EXTRA_LOG("[mnemofs | BIND] Device formatting configured.");
MFS_EXTRA_LOG("BIND", "Device formatting configured.");
}
mfs_ba_fmt(sb);
@ -1707,55 +1707,55 @@ static int mnemofs_bind(FAR struct inode *driver, FAR const void *data,
ret = mfs_jrnl_fmt(sb, &mnblk1, &mnblk2, &jrnl_blk);
if (predict_false(ret < 0))
{
MFS_LOG("[mnemofs | BIND] Error formatting Journal");
MFS_LOG("BIND", "Error formatting Journal");
goto errout_with_rwbuf;
}
else
{
MFS_LOG("[mnemofs | BIND] Journal format completed.");
MFS_LOG("BIND", "Journal format completed.");
}
ret = mfs_mn_fmt(sb, mnblk1, mnblk2, jrnl_blk);
if (predict_false(ret < 0))
{
MFS_LOG("[mnemofs | BIND] Error formatting Master Node");
MFS_LOG("BIND", "Error formatting Master Node");
goto errout_with_rwbuf;
}
else
{
MFS_LOG("[mnemofs | BIND] Master node format completed.");
MFS_LOG("BIND", "Master node format completed.");
}
MFS_LOG("[mnemofs | BIND] Device formatted.");
MFS_LOG("BIND", "Device formatted.");
}
*handle = (FAR void *)sb;
MFS_LOG("[mnemofs | BIND] Mount Successful. Super Block %p.", sb);
MFS_LOG("BIND", "Mount Successful. Super Block %p.", sb);
nxmutex_unlock(&MFS_LOCK(sb));
MFS_LOG("[mnemofs | BIND] Mutex released.");
MFS_LOG("BIND", "Mutex released.");
MFS_LOG("[mnemofs | BIND] Exit | Return: %d.", ret);
MFS_LOG("BIND", "Exit | Return: %d.", ret);
return ret;
errout_with_rwbuf:
fs_heap_free(sb->rw_buf);
MFS_LOG("[mnemofs | BIND] RW Buffer freed.");
MFS_LOG("BIND", "RW Buffer freed.");
errout_with_lock:
nxmutex_unlock(&MFS_LOCK(sb));
MFS_EXTRA_LOG("[mnemofs | BIND] Mutex released.");
MFS_EXTRA_LOG("BIND", "Mutex released.");
errout_with_sb:
fs_heap_free(sb);
MFS_LOG("[mnemofs | BIND] Superblock freed.");
MFS_LOG("BIND", "Superblock freed.");
errout_with_lockinit:
nxmutex_destroy(&MFS_LOCK(sb));
MFS_EXTRA_LOG("[mnemofs | BIND] Mutex destroyed.");
MFS_EXTRA_LOG("BIND", "Mutex destroyed.");
errout:
MFS_LOG("[mnemofs | BIND] Exit | Return: %d.", ret);
MFS_LOG("BIND", "Exit | Return: %d.", ret);
return ret;
}
@ -1782,28 +1782,28 @@ static int mnemofs_unbind(FAR void *handle, FAR struct inode **driver,
{
FAR struct mfs_sb_s *sb;
MFS_LOG("[mnemofs | UNBIND] Entry.");
MFS_LOG("UNBIND", "Entry.");
DEBUGASSERT(handle);
sb = handle;
MFS_LOG("[mnemofs | UNBIND] Superblock %p.", sb);
MFS_LOG("UNBIND", "Superblock %p.", sb);
*driver = sb->drv;
MFS_LOG("[mnemofs | UNBIND] Driver %p.", driver);
MFS_LOG("UNBIND", "Driver %p.", driver);
mfs_jrnl_free(sb);
mfs_ba_free(sb);
nxmutex_destroy(&MFS_LOCK(sb));
MFS_EXTRA_LOG("[mnemofs | UNBIND] Mutex destroyed.");
MFS_EXTRA_LOG("UNBIND", "Mutex destroyed.");
fs_heap_free(sb->rw_buf);
MFS_LOG("[mnemofs | UNBIND] RW Buffer freed.");
MFS_LOG("UNBIND", "RW Buffer freed.");
fs_heap_free(sb);
MFS_LOG("[mnemofs | UNBIND] Superblock freed.");
MFS_LOG("UNBIND", "Superblock freed.");
MFS_LOG("[mnemofs | UNBIND] Exit.");
MFS_LOG("UNBIND", "Exit.");
return OK;
}
@ -1952,12 +1952,16 @@ static int mnemofs_mkdir(FAR struct inode *mountpt, FAR const char *relpath,
FAR struct mfs_sb_s *sb;
FAR struct mfs_path_s *path;
finfo("Mnemofs mkdir at %s.", relpath);
MFS_LOG("MKDIR", "Entry.");
MFS_LOG("MKDIR", "New directory at \"%s\".", relpath);
mode |= S_IFDIR;
MFS_LOG("MKDIR", "Mode is 0x%x.", mode);
DEBUGASSERT(mountpt != NULL);
sb = mountpt->i_private;
MFS_EXTRA_LOG("MKDIR", "Superblock is %p.", sb);
DEBUGASSERT(sb != NULL);
ret = nxmutex_lock(&MFS_LOCK(sb));
@ -1965,73 +1969,115 @@ static int mnemofs_mkdir(FAR struct inode *mountpt, FAR const char *relpath,
{
goto errout;
}
finfo("Lock acquired.");
else
{
MFS_EXTRA_LOG("MKDIR", "Mutex lock acquired.");
}
flags = mfs_get_patharr(sb, relpath, &path, &depth);
MFS_EXTRA_LOG("MKDIR", "mnemofs flags retrieved is 0x%x.", flags);
MFS_EXTRA_LOG("MKDIR", "Path received is at %p.", path);
MFS_EXTRA_LOG("MKDIR", "Depth of path is %" PRIu32 ".", depth);
if ((flags & MFS_EXIST) != 0)
{
finfo("File exists.");
MFS_LOG("MKDIR", "The requested directory already exists.");
ret = -EEXIST;
goto errout_with_path;
}
else
{
MFS_LOG("MKDIR", "The requested directory does not exist.");
if ((flags & MFS_P_EXIST) != 0)
{
MFS_EXTRA_LOG("MKDIR", "Parent exists.");
if ((flags & MFS_P_ISDIR) != 0)
{
/* OK */
finfo("OK");
MFS_EXTRA_LOG("MKDIR", "Parent is all right.");
}
else
{
MFS_EXTRA_LOG("MKDIR", "Parent is not a directory.");
ret = -ENOTDIR;
goto errout_with_path;
}
}
else
{
MFS_EXTRA_LOG("MKDIR", "Parent not found.");
ret = -ENOENT;
goto errout_with_path;
}
}
memset(&path[depth - 1], 0, sizeof(struct mfs_path_s));
MFS_EXTRA_LOG("MKDIR", "Resetting, at index %u, path array %p.",
depth - 1, path);
mfs_pitr_init(sb, path, depth, &pitr, true);
MFS_EXTRA_LOG("MKDIR", "The path contains the child.");
MFS_EXTRA_LOG("MKDIR", "Parent iterator initialized.");
MFS_EXTRA_LOG("MKDIR", "\tDepth of parent %" PRIu32 ".",
pitr.depth);
MFS_EXTRA_LOG("MKDIR", "\tCurrent iteration offset %" PRIu32 ".",
pitr.c_off);
MFS_EXTRA_LOG("MKDIR", "\tParent's offset %" PRIu32 ".",
pitr.p.off);
MFS_EXTRA_LOG("MKDIR", "\tParent's size %" PRIu32 ".", pitr.p.sz);
MFS_EXTRA_LOG("MKDIR", "\tParent's CTZ (%" PRIu32 ", %" PRIu32 ")"
, pitr.p.ctz.idx_e, pitr.p.ctz.pg_e);
/* The last incomplete direntry will be added by mfs_pitr_appendnew. */
ret = mfs_pitr_appendnew(sb, path, depth, &pitr, relpath, mode);
if (predict_false(ret < 0))
{
MFS_LOG("MKDIR", "Could not append direntry. Return %d", ret);
goto errout_with_path;
}
else
{
MFS_EXTRA_LOG("MKDIR", "Direntry append successful.");
MFS_EXTRA_LOG("MKDIR", "\tDepth of parent %" PRIu32 ".", pitr.depth);
MFS_EXTRA_LOG("MKDIR", "\tCurrent iteration offset %" PRIu32 ".",
pitr.c_off);
MFS_EXTRA_LOG("MKDIR", "\tParent's offset %" PRIu32 ".", pitr.p.off);
MFS_EXTRA_LOG("MKDIR", "\tParent's size %" PRIu32 ".", pitr.p.sz);
MFS_EXTRA_LOG("MKDIR", "\tParent's CTZ (%" PRIu32 ", %" PRIu32 ")",
pitr.p.ctz.idx_e, pitr.p.ctz.pg_e);
}
mfs_pitr_free(&pitr);
finfo("Directory created at %s", relpath);
MFS_EXTRA_LOG("MKDIR", "Parent iterator freed.");
MFS_LOG("MKDIR", "Directory created at \"%s\".", relpath);
mfs_free_patharr(path);
MFS_EXTRA_LOG("MKDIR", "Path array freed.");
nxmutex_unlock(&MFS_LOCK(sb));
finfo("Lock released.");
MFS_EXTRA_LOG("MKDIR", "Mutex released.");
finfo("Mnemofs mkdir exited with ret %d.", ret);
MFS_LOG("MKDIR", "Exit | Return: %d.", ret);
return ret;
errout_with_path:
mfs_free_patharr(path);
MFS_EXTRA_LOG("MKDIR", "Path array freed.");
mfs_pitr_free(&pitr);
nxmutex_unlock(&MFS_LOCK(sb));
finfo("Lock released.");
MFS_EXTRA_LOG("MKDIR", "Mutex released.");
/* TODO: The flush operation does not work properly, and causes memory
* leaks by most likely not flushing out anything and keeping it in
* memory.
*/
errout:
finfo("Mnemofs mkdir exited with ret %d.", ret);
MFS_LOG("MKDIR", "Exit | Return: %d.", ret);
return ret;
}

View file

@ -98,9 +98,9 @@
#define MFS_JRNL_LIM(sb) (MFS_JRNL(sb).n_blks / 2)
#define MFS_TRAVERSE_INITSZ 8
#define MFS_LOG(fmt, ...) finfo(fmt, ##__VA_ARGS__)
#define MFS_LOG(fn, fmt, ...) finfo("[mnemofs | " fn "] " fmt, ##__VA_ARGS__)
#ifdef CONFIG_MNEMOFS_EXTRA_DEBUG
#define MFS_EXTRA_LOG(fmt, ...) MFS_LOG(fmt, ##__VA_ARGS__)
#define MFS_EXTRA_LOG(fn, fmt, ...) MFS_LOG(fn, fmt, ##__VA_ARGS__)
#else
#define MFS_EXTRA_LOG(fmt, ...) { }
#endif
@ -285,9 +285,9 @@ struct mfs_dirent_s
struct mfs_pitr_s
{
struct mfs_path_s p; /* Parent representation */
struct mfs_path_s p; /* Parent's path representation */
mfs_t depth;
mfs_t c_off; /* Current offset. */
mfs_t c_off; /* Current iteration offset. */
};
/* TODO: depth >= 1 */
@ -424,6 +424,23 @@ static inline mfs_t mfs_popcnt(mfs_t x)
#endif
}
static inline void MFS_EXTRA_LOG_DIRENT(FAR struct mfs_dirent_s *dirent)
{
MFS_EXTRA_LOG("EXTRA_LOG_DIRENT", "Direntry details.");
MFS_EXTRA_LOG("EXTRA_LOG_DIRENT", "\tDirent location %p", dirent);
MFS_EXTRA_LOG("EXTRA_LOG_DIRENT", "\tMode is %" PRIu16, dirent->mode);
MFS_EXTRA_LOG("EXTRA_LOG_DIRENT", "\tName is \"%.*s\"", dirent->namelen,
dirent->name);
MFS_EXTRA_LOG("EXTRA_LOG_DIRENT", "\tNamelen is %" PRIu32,
dirent->namelen);
MFS_EXTRA_LOG("EXTRA_LOG_DIRENT", "\tName Hash is %" PRIu16,
dirent->name_hash);
MFS_EXTRA_LOG("EXTRA_LOG_DIRENT", "\tSize is %" PRIu16,
dirent->sz);
/* TODO: Timespecs */
}
/****************************************************************************
* Public Function Prototypes
****************************************************************************/

View file

@ -175,19 +175,31 @@ static mfs_t nobjs_in_path(FAR const char *relpath)
*
****************************************************************************/
static const char *next_child(FAR const char *relpath)
static const char *next_child(FAR const char *path)
{
while (*relpath != 0)
mfs_t inc = 0;
FAR const char *tmp = path;
MFS_EXTRA_LOG("NEXT_CHILD", "Requested string is \"%s\" (%p),", path,
path);
while (*path != 0)
{
if (*relpath == '/')
if (*path == '/')
{
return relpath + 1;
MFS_EXTRA_LOG("NEXT_CHILD", "Length is %" PRIu32, inc);
DEBUGASSERT(inc == path - tmp);
return path + 1;
}
relpath++;
path++;
inc++;
}
return relpath;
MFS_EXTRA_LOG("NEXT_CHILD", "Length is %" PRIu32, inc);
DEBUGASSERT(inc == path - tmp);
MFS_EXTRA_LOG("NEXT_CHILD", "Last FS Object in string.");
return path;
}
/****************************************************************************
@ -793,7 +805,7 @@ errout:
}
int mfs_get_patharr(FAR const struct mfs_sb_s * const sb,
FAR const char * relpath, FAR struct mfs_path_s **path,
FAR const char *relpath, FAR struct mfs_path_s **path,
FAR mfs_t *depth)
{
int ret = OK;
@ -809,14 +821,29 @@ int mfs_get_patharr(FAR const struct mfs_sb_s * const sb,
FAR struct mfs_path_s *np = NULL;
FAR struct mfs_dirent_s *dirent = NULL;
MFS_LOG("MFS_GET_PATHARR", "Entry.");
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Relpath is \"%s\".", relpath);
*path = NULL;
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Path is %p.", path);
n_objs = nobjs_in_path(relpath);
MFS_EXTRA_LOG("MFS_GET_PATHARR", "There are %" PRIu32 " objects in path.",
n_objs);
np = fs_heap_zalloc(n_objs * sizeof(struct mfs_path_s));
if (predict_false(np == NULL))
{
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Could not allocate Path array.");
ret = -ENOMEM;
goto errout;
}
else
{
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Path array is allocated at %p.", np);
}
DEBUGASSERT(*cur != '/'); /* Relpath should not start with a '/' */
ctz = MFS_MN(sb).root_ctz;
sz = MFS_MN(sb).root_sz;
@ -825,16 +852,26 @@ int mfs_get_patharr(FAR const struct mfs_sb_s * const sb,
np[0].off = 0;
cur = relpath;
next = next_child(cur);
DEBUGASSERT(*next != 0 || n_objs == 2);
name_len = *next == 0 ? next - cur : next - cur - 1;
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Root Master Node.");
MFS_EXTRA_LOG("MFS_GET_PATHARR", "\tCTZ is (%" PRIu32 ", %" PRIu32 ")",
MFS_MN(sb).root_ctz.idx_e, MFS_MN(sb).root_ctz.pg_e);
MFS_EXTRA_LOG("MFS_GET_PATHARR", "\tSize is %" PRIu32, sz);
if (predict_false(n_objs == 1))
{
MFS_EXTRA_LOG("MFS_GET_PATHARR", "There is only one object (root).");
ret_flags |= MFS_ISDIR | MFS_EXIST;
/* This will not go into the loop. */
}
else if (predict_false(n_objs == 2))
{
MFS_EXTRA_LOG("MFS_GET_PATHARR", "There are only 2 objects.");
ret_flags |= MFS_P_EXIST | MFS_P_ISDIR;
}
@ -842,6 +879,8 @@ int mfs_get_patharr(FAR const struct mfs_sb_s * const sb,
for (i = 1; i < n_objs; i++)
{
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Looking at depth %" PRIu32, i);
/* np[i] is the fs object at depth i + 1. */
/* Need to update journal for every level in the path as, for eg., the
@ -849,42 +888,66 @@ int mfs_get_patharr(FAR const struct mfs_sb_s * const sb,
* by search_ctz_by_name function.
*/
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Current String is \"%.*s\" (%p)",
name_len, cur, cur);
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Name length is %" PRIu32, name_len);
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Next String is \"%s\"", next);
ret = search_ctz_by_name(sb, np, i, cur, name_len, &off, &dirent);
if (predict_false(ret < 0))
{
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Could not find CTZ.");
goto errout_with_ret_flags;
}
else
{
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Found CTZ.");
MFS_EXTRA_LOG("MFS_GET_PATHARR", "New Offset is %" PRIu32, off);
MFS_EXTRA_LOG_DIRENT(dirent);
}
if (i < n_objs - 2 && !S_ISDIR(dirent->mode))
{
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Depth %" PRIu32 " contains file",
i);
ret_flags |= MFS_FINPATH;
goto errout_with_ret_flags;
}
else if (i == n_objs - 2)
{
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Parent exists.");
ret_flags |= MFS_P_EXIST;
if (S_ISDIR(dirent->mode))
{
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Parent is a directory.");
ret_flags |= MFS_P_ISDIR;
}
else
{
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Parent is a file.");
ret_flags |= MFS_FINPATH;
goto errout_with_ret_flags;
}
}
else /* if (i == n_objs - 1) */
else if (i == n_objs - 1)
{
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Child exists.");
ret_flags |= MFS_EXIST;
if (S_ISDIR(dirent->mode))
{
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Child is a directory.");
ret_flags |= MFS_ISDIR;
}
else
{
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Child is a file.");
ret_flags |= MFS_ISFILE;
}
}
else
{
/* OK */
}
np[i].ctz = dirent->ctz;
np[i].off = off;
@ -897,13 +960,17 @@ int mfs_get_patharr(FAR const struct mfs_sb_s * const sb,
cur = next;
next = next_child(cur);
name_len = *next == 0 ? next - cur : next - cur - 1;
DEBUGASSERT(cur != next);
}
ret = ret_flags;
*depth = n_objs;
*path = np;
finfo("Got path array with flags %u, depth %u.", ret, n_objs);
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Child is a file.");
MFS_LOG("MKDIR", "Exit | Flags: %u, Depth %u.", ret, n_objs);
return ret;
errout_with_ret_flags:
@ -916,7 +983,7 @@ errout_with_ret_flags:
*/
errout:
finfo("Got path array with flags %u, depth %u.", ret, n_objs);
MFS_LOG("MKDIR", "Exit | Flags: %u, Depth %u.", ret, n_objs);
return ret;
}