From 17bca89f078d38f2ee0c99f79cb150082371ddbc Mon Sep 17 00:00:00 2001 From: Saurav Pal Date: Mon, 28 Oct 2024 14:39:05 +0000 Subject: [PATCH] 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 --- fs/mnemofs/mnemofs.c | 196 +++++++++++++++++++++++-------------- fs/mnemofs/mnemofs.h | 25 ++++- fs/mnemofs/mnemofs_fsobj.c | 87 ++++++++++++++-- 3 files changed, 219 insertions(+), 89 deletions(-) diff --git a/fs/mnemofs/mnemofs.c b/fs/mnemofs/mnemofs.c index 060969cc506c9..219abdabcaecc 100644 --- a/fs/mnemofs/mnemofs.c +++ b/fs/mnemofs/mnemofs.c @@ -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; } diff --git a/fs/mnemofs/mnemofs.h b/fs/mnemofs/mnemofs.h index 0ab27bb800b5c..1c8faefb9549e 100644 --- a/fs/mnemofs/mnemofs.h +++ b/fs/mnemofs/mnemofs.h @@ -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 ****************************************************************************/ diff --git a/fs/mnemofs/mnemofs_fsobj.c b/fs/mnemofs/mnemofs_fsobj.c index 246c9852e93a0..a2009d7f4fe49 100644 --- a/fs/mnemofs/mnemofs_fsobj.c +++ b/fs/mnemofs/mnemofs_fsobj.c @@ -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 @@ static int search_ctz_by_name(FAR const struct mfs_sb_s * const sb, } 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 @@ int mfs_get_patharr(FAR const struct mfs_sb_s * const sb, */ 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; }