fs/mnemofs: Refactor path logic, direntry size bug fix, open free bug fix

Refactoring path logic to prevent logic flaws, direntry size bug fix to allow proper direntry traversal, open free bug fix to prevent memory leak after close.

Signed-off-by: Saurav Pal <resyfer.dev@gmail.com>
This commit is contained in:
Saurav Pal
2024-08-08 16:38:56 +00:00
committed by Alin Jerpelea
parent 01bac59cb7
commit 0be6dfb552
14 changed files with 2208 additions and 1635 deletions
+1 -1
View File
@@ -66,4 +66,4 @@ tools/gdb/__pycache__
/build
.ccls-cache
compile_commands.json
imx9-sdimage.img
imx9-sdimage.img
+15 -4
View File
@@ -25,6 +25,7 @@
* Included Files
****************************************************************************/
#include <debug.h>
#include <stddef.h>
#include <nuttx/compiler.h>
@@ -89,8 +90,8 @@
#else
#define NAND_RAM_LOG
#define NAND_RAM_STATUS_LOG
#define NAND_RAM_LOG(str, ...)
#define NAND_RAM_STATUS_LOG(str, ...)
#endif /* CONFIG_MTD_NAND_RAM_DEBUG */
@@ -197,10 +198,12 @@ static void nand_ram_storage_status(void)
static inline void nand_ram_status(void)
{
#ifdef CONFIG_MTD_NAND_RAM_DEBUG
if (nand_ram_ins_i % NAND_RAM_STATUS_LEVEL == 0)
{
nand_ram_storage_status();
}
#endif
}
/****************************************************************************
@@ -353,12 +356,19 @@ int nand_ram_rawread(FAR struct nand_raw_s *raw, off_t block,
if (data != NULL)
{
memcpy(data, (const void *)read_page_data, NAND_RAM_PAGE_SIZE);
if (nand_ram_flash_spare[read_page].free == NAND_RAM_PAGE_FREE)
{
memset(data, 0, NAND_RAM_PAGE_SIZE);
}
else
{
memcpy(data, (const void *)read_page_data, NAND_RAM_PAGE_SIZE);
}
}
if (spare != NULL)
{
memcpy(spare, (const void *)read_page_spare, NAND_RAM_PAGE_SIZE);
memcpy(spare, (const void *)read_page_spare, NAND_RAM_SPARE_SIZE);
}
NAND_RAM_LOG("[LOWER %lu | %s] Done\n", nand_ram_ins_i, "rawread");
@@ -420,6 +430,7 @@ int nand_ram_rawwrite(FAR struct nand_raw_s *raw, off_t block,
nand_ram_flash_spare[write_page].n_write++;
memset((void *)write_page_data, 0, NAND_RAM_PAGE_SIZE);
if (data != NULL)
{
memcpy((void *)write_page_data, data, NAND_RAM_PAGE_SIZE);
+3 -3
View File
@@ -328,7 +328,7 @@ int nand_wrapper_isbad(FAR struct mtd_dev_s *dev, off_t block)
nxmutex_lock(&nand_wrapper_dev_mut);
nand_wrapper_ins_i++;
NAND_WRAPPER_LOG("[UPPER %lu | %s] Blocks: %d\n",
NAND_WRAPPER_LOG("[UPPER %lu | %s] Block: %d\n",
nand_wrapper_ins_i, "isbad", block);
DEBUGASSERT(nand_dev && nand_dev->under.mtd.isbad);
@@ -336,8 +336,8 @@ int nand_wrapper_isbad(FAR struct mtd_dev_s *dev, off_t block)
if (ret >= 0)
{
NAND_WRAPPER_LOG("[UPPER %lu | %s] Done\n",
nand_wrapper_ins_i, "isbad");
NAND_WRAPPER_LOG("[UPPER %lu | %s] Done %d\n",
nand_wrapper_ins_i, "isbad", ret);
}
else
{
+147 -106
View File
File diff suppressed because it is too large Load Diff
+247 -241
View File
File diff suppressed because it is too large Load Diff
+24 -14
View File
@@ -91,7 +91,7 @@
* Pre-processor Definitions
****************************************************************************/
#define BMAP_GET(bmap, idx, off) ((bmap)[(idx)] & (1 << (off)))
#define BMAP_GET(bmap, idx, off) (((bmap)[(idx)] & (1 << (off))) != 0)
#define BMAP_SET(bmap, idx, off) ((bmap)[(idx)] |= (1 << (off)))
#define DEL_ARR_BLK(sb, blk) (MFS_BA((sb)).k_del[(blk) * sizeof(size_t)])
#define DEL_ARR_PG(sb, pg) (DEL_ARR_BLK(sb, MFS_PG2BLK((sb), (pg))))
@@ -134,14 +134,8 @@ static int is_blk_writeable(FAR struct mfs_sb_s * const sb,
* idx - Populated later with the index of page in MFS_BA(sb).bmap_upgs
* off - Populated later with the offset of page in MFS_BA(sb).bmap_upgs
*
* Returned Value:
* MFS_BLK_BAD - If the block of the page is a bad block.
* MFS_PG_USED - If the page is being used.
* MFS_BLK_ERASABLE - If page can be allocated, but block needs erase.
* MFS_PG_FREE - If the page is free.
*
* Assumptions/Limitations:
* Does not check validity of the page number.
* Does not check validity of the index.
*
****************************************************************************/
@@ -503,13 +497,28 @@ void mfs_ba_pgmarkdel(FAR struct mfs_sb_s * const sb, mfs_t pg)
void mfs_ba_blkmarkdel(FAR struct mfs_sb_s * const sb, mfs_t blk)
{
mfs_erase_blk(sb, blk);
DEL_ARR_BLK(sb, blk) = 0;
DEL_ARR_BLK(sb, blk) = MFS_PGINBLK(sb);
}
void mfs_ba_delmarked(FAR struct mfs_sb_s * const sb)
int mfs_ba_delmarked(FAR struct mfs_sb_s * const sb)
{
/* TODO */
int ret = OK;
mfs_t i;
for (i = 1; i < MFS_NBLKS(sb); i++)
{
if (DEL_ARR_BLK(sb, i) == MFS_PGINBLK(sb))
{
ret = mfs_erase_blk(sb, i);
if (ret != OK)
{
return ret;
}
}
}
return ret;
}
/* Mark a page as being used. Used by master node during initial format and
@@ -517,15 +526,16 @@ void mfs_ba_delmarked(FAR struct mfs_sb_s * const sb)
void mfs_ba_markusedpg(FAR struct mfs_sb_s * const sb, mfs_t pg)
{
mfs_t idx;
mfs_t idx;
uint8_t off;
pg2bmap(pg, &idx, &off);
BMAP_SET(MFS_BA(sb).bmap_upgs, idx, off); /* Set as used */
}
void mfs_ba_markusedblk(FAR struct mfs_sb_s * const sb, mfs_t blk)
{
mfs_t i = 0;
mfs_t i = 0;
mfs_t pg = MFS_BLK2PG(sb, blk);
for (i = 0; i < MFS_PGINBLK(sb); i++)
+253 -363
View File
File diff suppressed because it is too large Load Diff
+600 -444
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+401 -185
View File
File diff suppressed because it is too large Load Diff
+7 -7
View File
@@ -186,15 +186,15 @@ static FAR const char *deser_mn(FAR const char * const in,
int mfs_mn_init(FAR struct mfs_sb_s * const sb, const mfs_t jrnl_blk)
{
int ret = OK;
mfs_t i = 0;
int ret = OK;
mfs_t i = 0;
mfs_t mblk1;
mfs_t mblk2;
mfs_t jrnl_blk_tmp;
bool found = false;
bool found = false;
uint8_t hash;
struct mfs_mn_s mn;
const mfs_t sz = sizeof(struct mfs_mn_s) - sizeof(mn.pg);
const mfs_t sz = sizeof(struct mfs_mn_s) - sizeof(mn.pg);
char buftmp[4];
char buf[sz + 1];
@@ -265,14 +265,14 @@ errout:
int mfs_mn_fmt(FAR struct mfs_sb_s * const sb, const mfs_t jrnl_blk)
{
int ret = OK;
int ret = OK;
mfs_t pg;
mfs_t mblk1;
mfs_t mblk2;
struct mfs_mn_s mn;
const mfs_t sz = sizeof(struct mfs_mn_s) - sizeof(mn.pg);
char buf[sz + 1];
struct timespec ts;
const mfs_t sz = sizeof(struct mfs_mn_s) - sizeof(mn.pg);
char buf[sz + 1];
clock_gettime(CLOCK_REALTIME, &ts);
+31 -1
View File
@@ -85,12 +85,22 @@
int mfs_isbadblk(FAR const struct mfs_sb_s * const sb, mfs_t blk)
{
if (predict_false(blk > MFS_NBLKS(sb)))
{
return -EINVAL;
}
return MTD_ISBAD(MFS_MTD(sb), blk);
}
int mfs_markbadblk(FAR const struct mfs_sb_s * const sb, mfs_t blk)
{
return MTD_ISBAD(MFS_MTD(sb), blk);
if (predict_false(blk > MFS_NBLKS(sb)))
{
return -EINVAL;
}
return MTD_MARKBAD(MFS_MTD(sb), blk);
}
/* NOTE: These functions do not update the block allocator's state nor do
@@ -103,6 +113,11 @@ ssize_t mfs_write_page(FAR const struct mfs_sb_s * const sb,
{
int ret = OK;
if (predict_false(page > MFS_NPGS(sb) || pgoff >= MFS_PGSZ(sb)))
{
return -EINVAL;
}
mempcpy(MFS_RWBUF(sb) + pgoff, data, datalen);
ret = MTD_BWRITE(MFS_MTD(sb), page, 1, MFS_RWBUF(sb));
@@ -123,6 +138,11 @@ ssize_t mfs_read_page(FAR const struct mfs_sb_s * const sb,
{
int ret = OK;
if (predict_false(page > MFS_NPGS(sb) || pgoff >= MFS_PGSZ(sb)))
{
return -EINVAL;
}
ret = MTD_BREAD(MFS_MTD(sb), page, 1, MFS_RWBUF(sb));
if (ret < 0)
{
@@ -139,11 +159,21 @@ errout_with_reset:
int mfs_erase_blk(FAR const struct mfs_sb_s * const sb, const off_t blk)
{
if (predict_false(blk > MFS_NBLKS(sb)))
{
return -EINVAL;
}
return MTD_ERASE(MFS_MTD(sb), blk, 1);
}
int mfs_erase_nblks(FAR const struct mfs_sb_s * const sb, const off_t blk,
const size_t n)
{
if (predict_false(blk + n > MFS_NBLKS(sb)))
{
return -EINVAL;
}
return MTD_ERASE(MFS_MTD(sb), blk, n);
}
+58
View File
@@ -92,6 +92,8 @@ uint8_t mfs_arrhash(FAR const char *arr, ssize_t len)
ssize_t r = len - 1;
uint16_t hash = 0;
/* TODO: Change the array checksum to be 16 bit long. */
while (l <= r)
{
hash += arr[l] * arr[r] * (l + 1) * (r + 1);
@@ -105,6 +107,27 @@ uint8_t mfs_arrhash(FAR const char *arr, ssize_t len)
return hash % (1 << 8);
}
uint16_t mfs_hash(FAR const char *arr, ssize_t len)
{
ssize_t l = 0;
ssize_t r = len - 1;
uint32_t hash = 0;
/* TODO: Change the array checksum to be 16 bit long. */
while (l <= r)
{
hash += arr[l] * arr[r] * (l + 1) * (r + 1);
l++;
r--;
hash %= (1 << MFS_HASHSZ);
}
finfo("Hash calculated for size %ld to be %u.", len, hash);
return hash;
}
FAR char *mfs_ser_8(const uint8_t n, FAR char * const out)
{
*out = n;
@@ -189,6 +212,28 @@ FAR const char *mfs_deser_ctz(FAR const char * const in,
return i;
}
FAR char *mfs_ser_path(FAR const struct mfs_path_s * const x,
FAR char * const out)
{
char *o = out;
o = mfs_ser_ctz(&x->ctz, o);
o = mfs_ser_mfs(x->off, o);
o = mfs_ser_mfs(x->sz, o);
return o;
}
FAR const char *mfs_deser_path(FAR const char * const in,
FAR struct mfs_path_s * const x)
{
const char *i = in;
i = mfs_deser_ctz(i, &x->ctz);
i = mfs_deser_mfs(i, &x->off);
i = mfs_deser_mfs(i, &x->sz);
return i;
}
FAR char *mfs_ser_timespec(FAR const struct timespec * const x,
FAR char * const out)
{
@@ -225,3 +270,16 @@ mfs_t mfs_set_msb(mfs_t n)
{
return 31 - mfs_clz(n);
}
bool mfs_ctz_eq(FAR const struct mfs_ctz_s * const a,
FAR const struct mfs_ctz_s * const b)
{
return a->idx_e == b->idx_e && a->pg_e == b->pg_e;
}
bool mfs_path_eq(FAR const struct mfs_path_s * const a,
FAR const struct mfs_path_s * const b)
{
return mfs_ctz_eq(&a->ctz, &b->ctz) && (a->off == b->off)
&& (a->sz == b->sz);
}
+6 -6
View File
@@ -43,14 +43,14 @@
#define NAND_RAM_SIZE NAND_RAM_MB(CONFIG_MTD_NAND_RAM_SIZE)
#define NAND_RAM_LOG_PAGES_PER_BLOCK ((uint32_t) 7)
#define NAND_RAM_PAGE_SIZE ((uint32_t) (1 << 9)) /* 512 B */
#define NAND_RAM_SPARE_SIZE ((uint32_t) (1 << 4)) /* 16 B */
#define NAND_RAM_LOG_PAGES_PER_BLOCK ((uint32_t) 4)
#define NAND_RAM_PAGE_SIZE ((uint32_t) (1 << 7))
#define NAND_RAM_SPARE_SIZE ((uint32_t) (1 << 3))
#define NAND_RAM_BLOCK_SIZE ((uint32_t) ((1 << NAND_RAM_LOG_PAGES_PER_BLOCK) * NAND_RAM_PAGE_SIZE))
#define NAND_RAM_N_PAGES ((uint32_t) NAND_RAM_SIZE / NAND_RAM_PAGE_SIZE)
#define NAND_RAM_TOTAL_PAGE_SIZE ((uint32_t) (NAND_RAM_PAGE_SIZE + NAND_RAM_SPARE_SIZE))
#define NAND_RAM_PAGES_PER_BLOCK ((uint32_t) (NAND_RAM_BLOCK_SIZE / NAND_RAM_PAGE_SIZE))
#define NAND_RAM_N_BLOCKS ((uint32_t) (NAND_RAM_N_PAGES / NAND_RAM_PAGES_PER_BLOCK))
#define NAND_RAM_BLOCK_SIZE ((uint32_t) ((1 << NAND_RAM_LOG_PAGES_PER_BLOCK) * NAND_RAM_PAGE_SIZE))
#define NAND_RAM_PAGES_PER_BLOCK ((uint32_t) (1 << (NAND_RAM_LOG_PAGES_PER_BLOCK)))
#define NAND_RAM_N_BLOCKS ((uint32_t) (NAND_RAM_SIZE / (NAND_RAM_PAGES_PER_BLOCK * NAND_RAM_PAGE_SIZE)))
#define NAND_RAM_PAGE_WRITTEN 0
#define NAND_RAM_PAGE_FREE 1