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; FAR struct mfs_sb_s *sb = NULL;
struct mtd_geometry_s geo; 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); 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)); sb = fs_heap_zalloc(sizeof(*sb));
if (!sb) if (!sb)
{ {
MFS_LOG("[mnemofs | BIND] SB in-memory allocation error."); MFS_LOG("BIND", "SB in-memory allocation error.");
ret = -ENOMEM; ret = -ENOMEM;
goto errout; goto errout;
} }
else 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). */ /* 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) if (!driver || !driver->u.i_mtd || !driver->u.i_mtd->ioctl)
{ {
MFS_LOG("[mnemofs | BIND] Unsupported device."); MFS_LOG("BIND", "Unsupported device.");
ret = -ENODEV; ret = -ENODEV;
goto errout_with_sb; goto errout_with_sb;
} }
else 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, ret = MTD_IOCTL(driver->u.i_mtd, MTDIOC_GEOMETRY,
(unsigned long) &geo); (unsigned long) &geo);
MFS_LOG("[mnemofs | BIND] MTD Driver Geometry read."); MFS_LOG("BIND", "MTD Driver Geometry read.");
MFS_EXTRA_LOG("[mnemofs | BIND] MTD Driver Geometry details." MFS_EXTRA_LOG("BIND", "MTD Driver Geometry details."
" Page size: %d, Block size: %d," " Page size: %d, Block size: %d,"
" Pages/Block: %d, Blocks: %d\n", " Pages/Block: %d, Blocks: %d\n",
geo.blocksize, geo.erasesize, geo.blocksize, geo.erasesize,
@ -1535,7 +1535,7 @@ static int mnemofs_bind(FAR struct inode *driver, FAR const void *data,
} }
else else
{ {
MFS_LOG("[mnemofs | BIND] Device is not an MTD device."); MFS_LOG("BIND", "Device is not an MTD device.");
ret = -ENODEV; ret = -ENODEV;
goto errout_with_sb; 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)); ret = nxmutex_init(&MFS_LOCK(sb));
if (predict_false(ret < 0)) 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; goto errout_with_sb;
} }
else else
{ {
MFS_EXTRA_LOG("[mnemofs | BIND] FS-wide Mutex Initialized."); MFS_EXTRA_LOG("BIND", "FS-wide Mutex Initialized.");
} }
ret = nxmutex_lock(&MFS_LOCK(sb)); ret = nxmutex_lock(&MFS_LOCK(sb));
if (ret < 0) 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; goto errout_with_lockinit;
} }
else else
{ {
MFS_EXTRA_LOG("[mnemofs | BIND] Mutex acquired."); MFS_EXTRA_LOG("BIND", "Mutex acquired.");
} }
sb->drv = driver; sb->drv = driver;
@ -1580,31 +1580,31 @@ static int mnemofs_bind(FAR struct inode *driver, FAR const void *data,
list_initialize(&MFS_OFILES(sb)); list_initialize(&MFS_OFILES(sb));
MFS_EXTRA_LOG("[mnemofs | BIND] SB initialized in-memory."); MFS_EXTRA_LOG("BIND", "SB initialized in-memory.");
MFS_EXTRA_LOG("[mnemofs | BIND] SB Details."); MFS_EXTRA_LOG("BIND", "SB Details.");
MFS_EXTRA_LOG("[mnemofs | BIND] \tDriver: %p", driver); MFS_EXTRA_LOG("BIND", "\tDriver: %p", driver);
MFS_EXTRA_LOG("[mnemofs | BIND] \tPage Size: %" PRIu32, sb->pg_sz); MFS_EXTRA_LOG("BIND", "\tPage Size: %" PRIu32, sb->pg_sz);
MFS_EXTRA_LOG("[mnemofs | BIND] \tLog Page Size: %" PRIu8, sb->log_pg_sz); MFS_EXTRA_LOG("BIND", "\tLog Page Size: %" PRIu8, sb->log_pg_sz);
MFS_EXTRA_LOG("[mnemofs | BIND] \tBlock Size: %" PRIu32, sb->blk_sz); MFS_EXTRA_LOG("BIND", "\tBlock Size: %" PRIu32, sb->blk_sz);
MFS_EXTRA_LOG("[mnemofs | BIND] \tLog Block Size: %" PRIu8, MFS_EXTRA_LOG("BIND", "\tLog Block Size: %" PRIu8,
sb->log_blk_sz); 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); sb->pg_in_blk);
MFS_EXTRA_LOG("[mnemofs | BIND] \tBlocks: %" PRIu32, sb->n_blks); MFS_EXTRA_LOG("BIND", "\tBlocks: %" PRIu32, sb->n_blks);
MFS_EXTRA_LOG("[mnemofs | BIND] \tLog Blocks: %" PRIu8, sb->log_n_blks); MFS_EXTRA_LOG("BIND", "\tLog Blocks: %" PRIu8, sb->log_n_blks);
MFS_EXTRA_LOG("[mnemofs | BIND] \tJournal Blocks: %" PRIu16, MFS_EXTRA_LOG("BIND", "\tJournal Blocks: %" PRIu16,
MFS_JRNL(sb).n_blks); 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)); sb->rw_buf = fs_heap_zalloc(MFS_PGSZ(sb));
if (predict_false(sb->rw_buf == NULL)) 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; goto errout_with_lock;
} }
else else
{ {
MFS_EXTRA_LOG("[mnemofs | BIND] RW Buffer allocated."); MFS_EXTRA_LOG("BIND", "RW Buffer allocated.");
} }
/* TODO: Format the superblock in Block 0. */ /* 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")) 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 /* Look for journal and maybe hopefully, the master node
* if it comes first. * 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++) 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); i + 1);
mfs_read_page(sb, buf, 8, MFS_BLK2PG(sb, i), 0); mfs_read_page(sb, buf, 8, MFS_BLK2PG(sb, i), 0);
for (j = 0; j < 8; j++) 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]); ", Offset %" PRIu32 ": %x", i, j, buf[j]);
} }
if (!MFS_STRLITCMP(buf, MFS_JRNL_MAGIC)) 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); i + 1);
ret = mfs_jrnl_init(sb, i); ret = mfs_jrnl_init(sb, i);
if (predict_false(ret < 0)) if (predict_false(ret < 0))
{ {
MFS_LOG("[mnemofs | BIND] Error initializing journal."); MFS_LOG("BIND", "Error initializing journal.");
goto errout_with_rwbuf; goto errout_with_rwbuf;
} }
else else
{ {
MFS_LOG("[mnemofs | BIND] Journal initialized."); MFS_LOG("BIND", "Journal initialized.");
} }
ret = mfs_mn_init(sb, i); ret = mfs_mn_init(sb, i);
if (predict_false(ret < 0)) if (predict_false(ret < 0))
{ {
MFS_LOG("[mnemofs | BIND] Error initializing masternode."); MFS_LOG("BIND", "Error initializing masternode.");
goto errout_with_rwbuf; goto errout_with_rwbuf;
} }
else else
{ {
MFS_LOG("[mnemofs | BIND] Master node initialized."); MFS_LOG("BIND", "Master node initialized.");
} }
break; break;
} }
MFS_EXTRA_LOG("[mnemofs | BIND] Resetting temporary buffer."); MFS_EXTRA_LOG("BIND", "Resetting temporary buffer.");
memset(buf, 0, 8); memset(buf, 0, 8);
} }
if (predict_false(sb->mn.pg == 0)) if (predict_false(sb->mn.pg == 0))
{ {
MFS_LOG("[mnemofs | BIND] Journal not found on device."); MFS_LOG("BIND", "Journal not found on device.");
MFS_LOG("[mnemofs | BIND] Device needs formatting."); MFS_LOG("BIND", "Device needs formatting.");
format = true; format = true;
memset(&MFS_JRNL(sb), 0, sizeof(struct mfs_jrnl_state_s)); 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 else
{ {
MFS_LOG("[mnemofs | BIND] Device already formatted."); MFS_LOG("BIND", "Device already formatted.");
mfs_lru_init(sb); mfs_lru_init(sb);
mfs_ba_init(sb); mfs_ba_init(sb);
@ -1691,11 +1691,11 @@ static int mnemofs_bind(FAR struct inode *driver, FAR const void *data,
if (format) if (format)
{ {
MFS_LOG("[mnemofs | BIND] Device format necessary."); MFS_LOG("BIND", "Device format necessary.");
} }
else else
{ {
MFS_EXTRA_LOG("[mnemofs | BIND] Device formatting configured."); MFS_EXTRA_LOG("BIND", "Device formatting configured.");
} }
mfs_ba_fmt(sb); 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); ret = mfs_jrnl_fmt(sb, &mnblk1, &mnblk2, &jrnl_blk);
if (predict_false(ret < 0)) if (predict_false(ret < 0))
{ {
MFS_LOG("[mnemofs | BIND] Error formatting Journal"); MFS_LOG("BIND", "Error formatting Journal");
goto errout_with_rwbuf; goto errout_with_rwbuf;
} }
else else
{ {
MFS_LOG("[mnemofs | BIND] Journal format completed."); MFS_LOG("BIND", "Journal format completed.");
} }
ret = mfs_mn_fmt(sb, mnblk1, mnblk2, jrnl_blk); ret = mfs_mn_fmt(sb, mnblk1, mnblk2, jrnl_blk);
if (predict_false(ret < 0)) if (predict_false(ret < 0))
{ {
MFS_LOG("[mnemofs | BIND] Error formatting Master Node"); MFS_LOG("BIND", "Error formatting Master Node");
goto errout_with_rwbuf; goto errout_with_rwbuf;
} }
else 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; *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)); 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; return ret;
errout_with_rwbuf: errout_with_rwbuf:
fs_heap_free(sb->rw_buf); fs_heap_free(sb->rw_buf);
MFS_LOG("[mnemofs | BIND] RW Buffer freed."); MFS_LOG("BIND", "RW Buffer freed.");
errout_with_lock: errout_with_lock:
nxmutex_unlock(&MFS_LOCK(sb)); nxmutex_unlock(&MFS_LOCK(sb));
MFS_EXTRA_LOG("[mnemofs | BIND] Mutex released."); MFS_EXTRA_LOG("BIND", "Mutex released.");
errout_with_sb: errout_with_sb:
fs_heap_free(sb); fs_heap_free(sb);
MFS_LOG("[mnemofs | BIND] Superblock freed."); MFS_LOG("BIND", "Superblock freed.");
errout_with_lockinit: errout_with_lockinit:
nxmutex_destroy(&MFS_LOCK(sb)); nxmutex_destroy(&MFS_LOCK(sb));
MFS_EXTRA_LOG("[mnemofs | BIND] Mutex destroyed."); MFS_EXTRA_LOG("BIND", "Mutex destroyed.");
errout: errout:
MFS_LOG("[mnemofs | BIND] Exit | Return: %d.", ret); MFS_LOG("BIND", "Exit | Return: %d.", ret);
return ret; return ret;
} }
@ -1782,28 +1782,28 @@ static int mnemofs_unbind(FAR void *handle, FAR struct inode **driver,
{ {
FAR struct mfs_sb_s *sb; FAR struct mfs_sb_s *sb;
MFS_LOG("[mnemofs | UNBIND] Entry."); MFS_LOG("UNBIND", "Entry.");
DEBUGASSERT(handle); DEBUGASSERT(handle);
sb = handle; sb = handle;
MFS_LOG("[mnemofs | UNBIND] Superblock %p.", sb); MFS_LOG("UNBIND", "Superblock %p.", sb);
*driver = sb->drv; *driver = sb->drv;
MFS_LOG("[mnemofs | UNBIND] Driver %p.", driver); MFS_LOG("UNBIND", "Driver %p.", driver);
mfs_jrnl_free(sb); mfs_jrnl_free(sb);
mfs_ba_free(sb); mfs_ba_free(sb);
nxmutex_destroy(&MFS_LOCK(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); fs_heap_free(sb->rw_buf);
MFS_LOG("[mnemofs | UNBIND] RW Buffer freed."); MFS_LOG("UNBIND", "RW Buffer freed.");
fs_heap_free(sb); 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; 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_sb_s *sb;
FAR struct mfs_path_s *path; 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; mode |= S_IFDIR;
MFS_LOG("MKDIR", "Mode is 0x%x.", mode);
DEBUGASSERT(mountpt != NULL); DEBUGASSERT(mountpt != NULL);
sb = mountpt->i_private; sb = mountpt->i_private;
MFS_EXTRA_LOG("MKDIR", "Superblock is %p.", sb);
DEBUGASSERT(sb != NULL); DEBUGASSERT(sb != NULL);
ret = nxmutex_lock(&MFS_LOCK(sb)); ret = nxmutex_lock(&MFS_LOCK(sb));
@ -1965,73 +1969,115 @@ static int mnemofs_mkdir(FAR struct inode *mountpt, FAR const char *relpath,
{ {
goto errout; goto errout;
} }
else
finfo("Lock acquired."); {
MFS_EXTRA_LOG("MKDIR", "Mutex lock acquired.");
}
flags = mfs_get_patharr(sb, relpath, &path, &depth); 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) if ((flags & MFS_EXIST) != 0)
{ {
finfo("File exists."); MFS_LOG("MKDIR", "The requested directory already exists.");
ret = -EEXIST; ret = -EEXIST;
goto errout_with_path; goto errout_with_path;
} }
else else
{ {
MFS_LOG("MKDIR", "The requested directory does not exist.");
if ((flags & MFS_P_EXIST) != 0) if ((flags & MFS_P_EXIST) != 0)
{ {
MFS_EXTRA_LOG("MKDIR", "Parent exists.");
if ((flags & MFS_P_ISDIR) != 0) if ((flags & MFS_P_ISDIR) != 0)
{ {
/* OK */ /* OK */
finfo("OK"); MFS_EXTRA_LOG("MKDIR", "Parent is all right.");
} }
else else
{ {
MFS_EXTRA_LOG("MKDIR", "Parent is not a directory.");
ret = -ENOTDIR; ret = -ENOTDIR;
goto errout_with_path; goto errout_with_path;
} }
} }
else else
{ {
MFS_EXTRA_LOG("MKDIR", "Parent not found.");
ret = -ENOENT; ret = -ENOENT;
goto errout_with_path; goto errout_with_path;
} }
} }
memset(&path[depth - 1], 0, sizeof(struct mfs_path_s)); 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_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. */ /* The last incomplete direntry will be added by mfs_pitr_appendnew. */
ret = mfs_pitr_appendnew(sb, path, depth, &pitr, relpath, mode); ret = mfs_pitr_appendnew(sb, path, depth, &pitr, relpath, mode);
if (predict_false(ret < 0)) if (predict_false(ret < 0))
{ {
MFS_LOG("MKDIR", "Could not append direntry. Return %d", ret);
goto errout_with_path; 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); mfs_pitr_free(&pitr);
MFS_EXTRA_LOG("MKDIR", "Parent iterator freed.");
finfo("Directory created at %s", relpath); MFS_LOG("MKDIR", "Directory created at \"%s\".", relpath);
mfs_free_patharr(path); mfs_free_patharr(path);
MFS_EXTRA_LOG("MKDIR", "Path array freed.");
nxmutex_unlock(&MFS_LOCK(sb)); 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; return ret;
errout_with_path: errout_with_path:
mfs_free_patharr(path); mfs_free_patharr(path);
MFS_EXTRA_LOG("MKDIR", "Path array freed.");
mfs_pitr_free(&pitr); mfs_pitr_free(&pitr);
nxmutex_unlock(&MFS_LOCK(sb)); 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: errout:
finfo("Mnemofs mkdir exited with ret %d.", ret); MFS_LOG("MKDIR", "Exit | Return: %d.", ret);
return ret; return ret;
} }

View file

@ -98,9 +98,9 @@
#define MFS_JRNL_LIM(sb) (MFS_JRNL(sb).n_blks / 2) #define MFS_JRNL_LIM(sb) (MFS_JRNL(sb).n_blks / 2)
#define MFS_TRAVERSE_INITSZ 8 #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 #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 #else
#define MFS_EXTRA_LOG(fmt, ...) { } #define MFS_EXTRA_LOG(fmt, ...) { }
#endif #endif
@ -285,9 +285,9 @@ struct mfs_dirent_s
struct mfs_pitr_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 depth;
mfs_t c_off; /* Current offset. */ mfs_t c_off; /* Current iteration offset. */
}; };
/* TODO: depth >= 1 */ /* TODO: depth >= 1 */
@ -424,6 +424,23 @@ static inline mfs_t mfs_popcnt(mfs_t x)
#endif #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 * 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, 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) FAR mfs_t *depth)
{ {
int ret = OK; 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_path_s *np = NULL;
FAR struct mfs_dirent_s *dirent = 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; *path = NULL;
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Path is %p.", path);
n_objs = nobjs_in_path(relpath); 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)); np = fs_heap_zalloc(n_objs * sizeof(struct mfs_path_s));
if (predict_false(np == NULL)) if (predict_false(np == NULL))
{ {
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Could not allocate Path array.");
ret = -ENOMEM; ret = -ENOMEM;
goto errout; 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; ctz = MFS_MN(sb).root_ctz;
sz = MFS_MN(sb).root_sz; 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; np[0].off = 0;
cur = relpath; cur = relpath;
next = next_child(cur); next = next_child(cur);
DEBUGASSERT(*next != 0 || n_objs == 2);
name_len = *next == 0 ? next - cur : next - cur - 1; 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)) if (predict_false(n_objs == 1))
{ {
MFS_EXTRA_LOG("MFS_GET_PATHARR", "There is only one object (root).");
ret_flags |= MFS_ISDIR | MFS_EXIST; ret_flags |= MFS_ISDIR | MFS_EXIST;
/* This will not go into the loop. */ /* This will not go into the loop. */
} }
else if (predict_false(n_objs == 2)) 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; 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++) 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. */ /* np[i] is the fs object at depth i + 1. */
/* Need to update journal for every level in the path as, for eg., the /* 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. * 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); ret = search_ctz_by_name(sb, np, i, cur, name_len, &off, &dirent);
if (predict_false(ret < 0)) if (predict_false(ret < 0))
{ {
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Could not find CTZ.");
goto errout_with_ret_flags; 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)) if (i < n_objs - 2 && !S_ISDIR(dirent->mode))
{ {
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Depth %" PRIu32 " contains file",
i);
ret_flags |= MFS_FINPATH; ret_flags |= MFS_FINPATH;
goto errout_with_ret_flags; goto errout_with_ret_flags;
} }
else if (i == n_objs - 2) else if (i == n_objs - 2)
{ {
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Parent exists.");
ret_flags |= MFS_P_EXIST; ret_flags |= MFS_P_EXIST;
if (S_ISDIR(dirent->mode)) if (S_ISDIR(dirent->mode))
{ {
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Parent is a directory.");
ret_flags |= MFS_P_ISDIR; ret_flags |= MFS_P_ISDIR;
} }
else else
{ {
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Parent is a file.");
ret_flags |= MFS_FINPATH; ret_flags |= MFS_FINPATH;
goto errout_with_ret_flags; 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; ret_flags |= MFS_EXIST;
if (S_ISDIR(dirent->mode)) if (S_ISDIR(dirent->mode))
{ {
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Child is a directory.");
ret_flags |= MFS_ISDIR; ret_flags |= MFS_ISDIR;
} }
else else
{ {
MFS_EXTRA_LOG("MFS_GET_PATHARR", "Child is a file.");
ret_flags |= MFS_ISFILE; ret_flags |= MFS_ISFILE;
} }
} }
else
{
/* OK */
}
np[i].ctz = dirent->ctz; np[i].ctz = dirent->ctz;
np[i].off = off; np[i].off = off;
@ -897,13 +960,17 @@ int mfs_get_patharr(FAR const struct mfs_sb_s * const sb,
cur = next; cur = next;
next = next_child(cur); next = next_child(cur);
name_len = *next == 0 ? next - cur : next - cur - 1; name_len = *next == 0 ? next - cur : next - cur - 1;
DEBUGASSERT(cur != next);
} }
ret = ret_flags; ret = ret_flags;
*depth = n_objs; *depth = n_objs;
*path = np; *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; return ret;
errout_with_ret_flags: errout_with_ret_flags:
@ -916,7 +983,7 @@ errout_with_ret_flags:
*/ */
errout: 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; return ret;
} }