From 9cda2bc251849c6656f0fd68ecd14c26a99d52eb Mon Sep 17 00:00:00 2001 From: guohao15 Date: Thu, 4 Jan 2024 19:06:32 +0800 Subject: [PATCH 1/7] romfs:extend romfs to enable write part1 change romfs_cachenode to find all headers Signed-off-by: guohao15 --- fs/romfs/fs_romfs.h | 1 + fs/romfs/fs_romfsutil.c | 83 ++++++++++++++++++++--------------------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/fs/romfs/fs_romfs.h b/fs/romfs/fs_romfs.h index 71dd3f716601b..f0af14fcc50d9 100644 --- a/fs/romfs/fs_romfs.h +++ b/fs/romfs/fs_romfs.h @@ -164,6 +164,7 @@ struct romfs_nodeinfo_s uint32_t rn_next; /* Offset of the next file header+flags */ uint32_t rn_size; /* Size (if file) */ #ifdef CONFIG_FS_ROMFS_CACHE_NODE + uint32_t rn_origoffset; /* Offset of origin file header */ FAR struct romfs_nodeinfo_s **rn_child; /* The node array for link to lower level */ uint16_t rn_count; /* The count of node in rn_child level */ uint8_t rn_namesize; /* The length of name of the entry */ diff --git a/fs/romfs/fs_romfsutil.c b/fs/romfs/fs_romfsutil.c index e855b1bffecf8..b0f1cef05108a 100644 --- a/fs/romfs/fs_romfsutil.c +++ b/fs/romfs/fs_romfsutil.c @@ -405,16 +405,16 @@ static inline int romfs_searchdir(FAR struct romfs_mountpt_s *rm, #ifdef CONFIG_FS_ROMFS_CACHE_NODE static int romfs_cachenode(FAR struct romfs_mountpt_s *rm, - uint32_t offset, uint32_t next, - uint32_t size, FAR const char *name, + uint32_t origoffset, uint32_t offset, + uint32_t next, uint32_t size, + FAR const char *name, FAR struct romfs_nodeinfo_s **pnodeinfo) { FAR struct romfs_nodeinfo_s **child; FAR struct romfs_nodeinfo_s *nodeinfo; char childname[NAME_MAX + 1]; - uint32_t linkoffset; - uint32_t info; uint8_t num = 0; + uint32_t info; size_t nsize; int ret; @@ -427,71 +427,69 @@ static int romfs_cachenode(FAR struct romfs_mountpt_s *rm, *pnodeinfo = nodeinfo; nodeinfo->rn_offset = offset; + nodeinfo->rn_origoffset = origoffset; nodeinfo->rn_next = next; nodeinfo->rn_namesize = nsize; strlcpy(nodeinfo->rn_name, name, nsize + 1); - if (!IS_DIRECTORY(next)) + if (!IS_DIRECTORY(next) || (strcmp(name, ".") == 0) || + (strcmp(name, "..") == 0)) { nodeinfo->rn_size = size; return 0; } + origoffset = offset; child = nodeinfo->rn_child; do { - /* Parse the directory entry at this offset (which may be re-directed - * to some other entry if HARLINKED). - */ + /* Fetch the directory entry at this offset */ - ret = romfs_parsedirentry(rm, offset, &linkoffset, &next, &info, + ret = romfs_parsedirentry(rm, origoffset, &offset, &next, &info, &size); if (ret < 0) { return ret; } - ret = romfs_parsefilename(rm, offset, childname); + ret = romfs_parsefilename(rm, origoffset, childname); if (ret < 0) { return ret; } - if (strcmp(childname, ".") != 0 && strcmp(childname, "..") != 0) + if (child == NULL || nodeinfo->rn_count == num - 1) { - if (child == NULL || nodeinfo->rn_count == num - 1) - { - FAR void *tmp; - - tmp = kmm_realloc(nodeinfo->rn_child, (num + NODEINFO_NINCR) * - sizeof(*nodeinfo->rn_child)); - if (tmp == NULL) - { - return -ENOMEM; - } - - nodeinfo->rn_child = tmp; - memset(nodeinfo->rn_child + num, 0, NODEINFO_NINCR * - sizeof(*nodeinfo->rn_child)); - num += NODEINFO_NINCR; - } + FAR void *tmp; - child = &nodeinfo->rn_child[nodeinfo->rn_count++]; - if (IS_DIRECTORY(next)) + tmp = kmm_realloc(nodeinfo->rn_child, (num + NODEINFO_NINCR) * + sizeof(*nodeinfo->rn_child)); + if (tmp == NULL) { - linkoffset = info; + return -ENOMEM; } - ret = romfs_cachenode(rm, linkoffset, next, size, - childname, child); - if (ret < 0) - { - nodeinfo->rn_count--; - return ret; - } + nodeinfo->rn_child = tmp; + memset(nodeinfo->rn_child + num, 0, NODEINFO_NINCR * + sizeof(*nodeinfo->rn_child)); + num += NODEINFO_NINCR; + } + + child = &nodeinfo->rn_child[nodeinfo->rn_count++]; + if (IS_DIRECTORY(next)) + { + offset = info; + } + + ret = romfs_cachenode(rm, origoffset, offset, next, size, + childname, child); + if (ret < 0) + { + nodeinfo->rn_count--; + return ret; } next &= RFNEXT_OFFSETMASK; - offset = next; + origoffset = next; } while (next != 0); @@ -744,6 +742,7 @@ int romfs_fsconfigure(FAR struct romfs_mountpt_s *rm) { FAR const char *name; int16_t ndx; + uint32_t rootoffset; /* Then get information about the ROMFS filesystem on the devices managed * by this block driver. Read sector zero which contains the volume header. @@ -769,17 +768,17 @@ int romfs_fsconfigure(FAR struct romfs_mountpt_s *rm) /* The root directory entry begins right after the header */ name = (FAR const char *)&rm->rm_buffer[ROMFS_VHDR_VOLNAME]; + rootoffset = ROMFS_ALIGNUP(ROMFS_VHDR_VOLNAME + strlen(name) + 1); #ifdef CONFIG_FS_ROMFS_CACHE_NODE - ndx = romfs_cachenode(rm, ROMFS_ALIGNUP(ROMFS_VHDR_VOLNAME + - strlen(name) + 1), - RFNEXT_DIRECTORY, 0, "", &rm->rm_root); + ndx = romfs_cachenode(rm, 0, rootoffset, RFNEXT_DIRECTORY, + 0, "", &rm->rm_root); if (ndx < 0) { romfs_freenode(rm->rm_root); return ndx; } #else - rm->rm_rootoffset = ROMFS_ALIGNUP(ROMFS_VHDR_VOLNAME + strlen(name) + 1); + rm->rm_rootoffset = rootoffset; #endif /* and return success */ From 806af3ae17d166a991ceb3575603a3362b185660 Mon Sep 17 00:00:00 2001 From: guohao15 Date: Thu, 4 Jan 2024 20:52:51 +0800 Subject: [PATCH 2/7] romfs:extend romfs to enable write part2 add sparelist api Signed-off-by: guohao15 --- fs/romfs/Kconfig | 7 ++ fs/romfs/fs_romfs.c | 9 +- fs/romfs/fs_romfs.h | 23 ++++- fs/romfs/fs_romfsutil.c | 199 +++++++++++++++++++++++++++++++++++++--- 4 files changed, 221 insertions(+), 17 deletions(-) diff --git a/fs/romfs/Kconfig b/fs/romfs/Kconfig index 427cf3bf85301..ff0566ce820e9 100644 --- a/fs/romfs/Kconfig +++ b/fs/romfs/Kconfig @@ -27,4 +27,11 @@ config FS_ROMFS_CACHE_FILE_NSECTORS ---help--- The number of file cache sector +config FS_ROMFS_WRITEABLE + bool "Enable write extended feature in romfs" + default n + depends on FS_ROMFS_CACHE_NODE + ---help--- + Enable write extended feature in romfs + endif diff --git a/fs/romfs/fs_romfs.c b/fs/romfs/fs_romfs.c index e5af8c988b602..d95f7f20e4ac9 100644 --- a/fs/romfs/fs_romfs.c +++ b/fs/romfs/fs_romfs.c @@ -1112,7 +1112,7 @@ static int romfs_bind(FAR struct inode *blkdriver, FAR const void *data, * the ROMF header */ - ret = romfs_fsconfigure(rm); + ret = romfs_fsconfigure(rm, data); if (ret < 0) { ferr("ERROR: romfs_fsconfigure failed: %d\n", ret); @@ -1215,6 +1215,9 @@ static int romfs_unbind(FAR void *handle, FAR struct inode **blkdriver, #ifdef CONFIG_FS_ROMFS_CACHE_NODE romfs_freenode(rm->rm_root); +#endif +#ifdef CONFIG_FS_ROMFS_WRITEABLE + romfs_free_sparelist(&rm->rm_sparelist); #endif nxrmutex_destroy(&rm->rm_lock); kmm_free(rm); @@ -1273,8 +1276,8 @@ static int romfs_statfs(FAR struct inode *mountpt, FAR struct statfs *buf) /* Everything else follows in units of sectors */ buf->f_blocks = SEC_NSECTORS(rm, rm->rm_volsize + SEC_NDXMASK(rm)); - buf->f_bfree = 0; - buf->f_bavail = 0; + buf->f_bfree = rm->rm_hwnsectors - buf->f_blocks; + buf->f_bavail = buf->f_bfree; buf->f_namelen = NAME_MAX; errout_with_lock: diff --git a/fs/romfs/fs_romfs.h b/fs/romfs/fs_romfs.h index f0af14fcc50d9..b066d0adf2f93 100644 --- a/fs/romfs/fs_romfs.h +++ b/fs/romfs/fs_romfs.h @@ -26,6 +26,7 @@ ****************************************************************************/ #include +#include #include #include @@ -116,6 +117,20 @@ * Public Types ****************************************************************************/ +#ifdef CONFIG_FS_ROMFS_WRITEABLE +/* This structure represents the spare list. An instance of this + * structure is retained as file header and file data size on each mountpoint + * that is mounted with a romfs filesystem. + */ + +struct romfs_sparenode_s +{ + struct list_node node; + uint32_t start; + uint32_t end; +}; +#endif + /* This structure represents the overall mountpoint state. An instance of * this structure is retained as inode private data on each mountpoint that * is mounted with a romfs filesystem. @@ -139,6 +154,9 @@ struct romfs_mountpt_s uint32_t rm_cachesector; /* Current sector in the rm_buffer */ FAR uint8_t *rm_xipbase; /* Base address of directly accessible media */ FAR uint8_t *rm_buffer; /* Device sector buffer, allocated if rm_xipbase==0 */ +#ifdef CONFIG_FS_ROMFS_WRITEABLE + struct list_node rm_sparelist; /* The list of spare space */ +#endif }; /* This structure represents on open file under the mountpoint. An instance @@ -194,7 +212,7 @@ int romfs_hwread(FAR struct romfs_mountpt_s *rm, FAR uint8_t *buffer, int romfs_filecacheread(FAR struct romfs_mountpt_s *rm, FAR struct romfs_file_s *rf, uint32_t sector); int romfs_hwconfigure(FAR struct romfs_mountpt_s *rm); -int romfs_fsconfigure(FAR struct romfs_mountpt_s *rm); +int romfs_fsconfigure(FAR struct romfs_mountpt_s *rm, FAR const void *data); int romfs_fileconfigure(FAR struct romfs_mountpt_s *rm, FAR struct romfs_file_s *rf); int romfs_checkmount(FAR struct romfs_mountpt_s *rm); @@ -212,6 +230,9 @@ int romfs_datastart(FAR struct romfs_mountpt_s *rm, #ifdef CONFIG_FS_ROMFS_CACHE_NODE void romfs_freenode(FAR struct romfs_nodeinfo_s *node); #endif +#ifdef CONFIG_FS_ROMFS_WRITEABLE +void romfs_free_sparelist(FAR struct list_node *list); +#endif #undef EXTERN #if defined(__cplusplus) diff --git a/fs/romfs/fs_romfsutil.c b/fs/romfs/fs_romfsutil.c index b0f1cef05108a..6363d74803717 100644 --- a/fs/romfs/fs_romfsutil.c +++ b/fs/romfs/fs_romfsutil.c @@ -395,6 +395,127 @@ static inline int romfs_searchdir(FAR struct romfs_mountpt_s *rm, return -ENOENT; } +#ifdef CONFIG_FS_ROMFS_WRITEABLE +/**************************************************************************** + * Name: romfs_alloc_sparenode + * + * Description: + * Allocate the spare node + * + ****************************************************************************/ + +static FAR struct romfs_sparenode_s * +romfs_alloc_sparenode(uint32_t start, uint32_t end) +{ + FAR struct romfs_sparenode_s *node; + node = kmm_malloc(sizeof(struct romfs_sparenode_s)); + if (node == NULL) + { + ferr("romfs_alloc_sparenode: no memory\n"); + return NULL; + } + + node->start = start; + node->end = end; + return node; +} + +/**************************************************************************** + * Name: romfs_init_sparelist + * + * Description: + * Init the sparelist + * + ****************************************************************************/ + +static int romfs_init_sparelist(FAR struct romfs_mountpt_s *rm, bool rw) +{ + FAR struct romfs_sparenode_s *node; + + list_initialize(&rm->rm_sparelist); + if (!rw) + { + return 0; + } + + node = romfs_alloc_sparenode(0, rm->rm_hwsectorsize * + rm->rm_hwnsectors); + if (node == NULL) + { + return -ENOMEM; + } + + list_add_head(&rm->rm_sparelist, &node->node); + rm->rm_volsize = 0; + return 0; +} + +/**************************************************************************** + * Name: romfs_alloc_spareregion + * + * Description: + * Allocate the spare region + * + ****************************************************************************/ + +static int romfs_alloc_spareregion(FAR struct list_node *list, + uint32_t start, uint32_t end) +{ + FAR struct romfs_sparenode_s *node; + + list_for_every_entry(list, node, struct romfs_sparenode_s, node) + { + /* Find the node that start ~ end + * is in node->start ~ node->end + */ + + if (start == node->start && end == node->end) + { + /* Delete the node */ + + list_delete(&node->node); + kmm_free(node); + return 0; + } + else if (start == node->start) + { + /* Update the node */ + + node->start = end; + return 0; + } + else if (end == node->end) + { + /* Update the node */ + + node->end = start; + return 0; + } + else if (start > node->start && end < node->end) + { + /* Split the node */ + + FAR struct romfs_sparenode_s *new; + new = romfs_alloc_sparenode(end, node->end); + if (new == NULL) + { + return -ENOMEM; + } + + node->end = start; + list_add_after(&node->node, &new->node); + return 0; + } + } + + /* Not found */ + + ferr("No space for start %" PRIu32 ", end %" PRIu32 "\n", start, + end); + return -ENOENT; +} +#endif + /**************************************************************************** * Name: romfs_cachenode * @@ -431,6 +552,26 @@ static int romfs_cachenode(FAR struct romfs_mountpt_s *rm, nodeinfo->rn_next = next; nodeinfo->rn_namesize = nsize; strlcpy(nodeinfo->rn_name, name, nsize + 1); + +#ifdef CONFIG_FS_ROMFS_WRITEABLE + if (!list_is_empty(&rm->rm_sparelist)) + { + uint32_t totalsize = ROMFS_ALIGNUP(ROMFS_FHDR_NAME + nsize + 1); + if (offset == origoffset) + { + totalsize += size; + } + + rm->rm_volsize += totalsize; + ret = romfs_alloc_spareregion(&rm->rm_sparelist, offset, + offset + totalsize); + if (ret < 0) + { + return ret; + } + } +#endif + if (!IS_DIRECTORY(next) || (strcmp(name, ".") == 0) || (strcmp(name, "..") == 0)) { @@ -727,6 +868,27 @@ int romfs_hwconfigure(FAR struct romfs_mountpt_s *rm) return OK; } +/**************************************************************************** + * Name: romfs_free_sparelist + * + * Description: + * Free the sparelist + * + ****************************************************************************/ +#ifdef CONFIG_FS_ROMFS_WRITEABLE +void romfs_free_sparelist(FAR struct list_node *list) +{ + FAR struct romfs_sparenode_s *node; + FAR struct romfs_sparenode_s *tmp; + + list_for_every_entry_safe(list, node, tmp, struct romfs_sparenode_s, node) + { + list_delete(&node->node); + kmm_free(node); + } +} +#endif + /**************************************************************************** * Name: romfs_fsconfigure * @@ -738,20 +900,20 @@ int romfs_hwconfigure(FAR struct romfs_mountpt_s *rm) * ****************************************************************************/ -int romfs_fsconfigure(FAR struct romfs_mountpt_s *rm) +int romfs_fsconfigure(FAR struct romfs_mountpt_s *rm, FAR const void *data) { FAR const char *name; - int16_t ndx; + int ret; uint32_t rootoffset; /* Then get information about the ROMFS filesystem on the devices managed * by this block driver. Read sector zero which contains the volume header. */ - ndx = romfs_devcacheread(rm, 0); - if (ndx < 0) + ret = romfs_devcacheread(rm, 0); + if (ret < 0) { - return ndx; + return ret; } /* Verify the magic number at that identifies this as a ROMFS filesystem */ @@ -763,19 +925,30 @@ int romfs_fsconfigure(FAR struct romfs_mountpt_s *rm) /* Then extract the values we need from the header and return success */ - rm->rm_volsize = romfs_devread32(rm, ROMFS_VHDR_SIZE); + rm->rm_volsize = romfs_devread32(rm, ROMFS_VHDR_SIZE); /* The root directory entry begins right after the header */ - name = (FAR const char *)&rm->rm_buffer[ROMFS_VHDR_VOLNAME]; - rootoffset = ROMFS_ALIGNUP(ROMFS_VHDR_VOLNAME + strlen(name) + 1); + name = (FAR const char *)&rm->rm_buffer[ROMFS_VHDR_VOLNAME]; + rootoffset = ROMFS_ALIGNUP(ROMFS_VHDR_VOLNAME + strlen(name) + 1); +#ifdef CONFIG_FS_ROMFS_WRITEABLE + ret = romfs_init_sparelist(rm, data && strstr(data, "rw")); + if (ret < 0) + { + return ret; + } +#endif + #ifdef CONFIG_FS_ROMFS_CACHE_NODE - ndx = romfs_cachenode(rm, 0, rootoffset, RFNEXT_DIRECTORY, - 0, "", &rm->rm_root); - if (ndx < 0) + ret = romfs_cachenode(rm, 0, rootoffset, RFNEXT_DIRECTORY, + 0, "", &rm->rm_root); + if (ret < 0) { +# ifdef CONFIG_FS_ROMFS_WRITEABLE + romfs_free_sparelist(&rm->rm_sparelist); +# endif romfs_freenode(rm->rm_root); - return ndx; + return ret; } #else rm->rm_rootoffset = rootoffset; @@ -783,7 +956,7 @@ int romfs_fsconfigure(FAR struct romfs_mountpt_s *rm) /* and return success */ - rm->rm_mounted = true; + rm->rm_mounted = true; return OK; } From 3f783345fea425b9fc594a2ddd7a5ac265a6873e Mon Sep 17 00:00:00 2001 From: guohao15 Date: Fri, 26 Apr 2024 23:11:55 +0800 Subject: [PATCH 3/7] romfs:bugfix romfs_statfs fix for df cmd infomation of romfs Signed-off-by: guohao15 --- fs/romfs/fs_romfs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/romfs/fs_romfs.c b/fs/romfs/fs_romfs.c index d95f7f20e4ac9..7608008ac436b 100644 --- a/fs/romfs/fs_romfs.c +++ b/fs/romfs/fs_romfs.c @@ -1275,8 +1275,9 @@ static int romfs_statfs(FAR struct inode *mountpt, FAR struct statfs *buf) /* Everything else follows in units of sectors */ - buf->f_blocks = SEC_NSECTORS(rm, rm->rm_volsize + SEC_NDXMASK(rm)); - buf->f_bfree = rm->rm_hwnsectors - buf->f_blocks; + buf->f_blocks = rm->rm_hwnsectors; + buf->f_bfree = buf->f_blocks - + SEC_NSECTORS(rm, rm->rm_volsize + SEC_NDXMASK(rm)); buf->f_bavail = buf->f_bfree; buf->f_namelen = NAME_MAX; From d8bf43f98b5bdd89ca4d7815d35b072404938d95 Mon Sep 17 00:00:00 2001 From: guohao15 Date: Sat, 27 Apr 2024 20:01:26 +0800 Subject: [PATCH 4/7] romfs:bugfix use origoffset instead of offset origoffset represent the offset of current node offset represent the offset of the file when the current node is a soft or hard link Signed-off-by: guohao15 --- fs/romfs/fs_romfsutil.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/romfs/fs_romfsutil.c b/fs/romfs/fs_romfsutil.c index 6363d74803717..18961728465dd 100644 --- a/fs/romfs/fs_romfsutil.c +++ b/fs/romfs/fs_romfsutil.c @@ -563,8 +563,8 @@ static int romfs_cachenode(FAR struct romfs_mountpt_s *rm, } rm->rm_volsize += totalsize; - ret = romfs_alloc_spareregion(&rm->rm_sparelist, offset, - offset + totalsize); + ret = romfs_alloc_spareregion(&rm->rm_sparelist, origoffset, + origoffset + totalsize); if (ret < 0) { return ret; From c62bb8880b1a1f41a4ab32fc22c379c038de184b Mon Sep 17 00:00:00 2001 From: dongjiuzhu1 Date: Fri, 12 Jan 2024 17:18:45 +0800 Subject: [PATCH 5/7] Revert "fs/mount and fs/romfs: Add support to mount a ROMFS volume using an MTD driver interface using the standard mount() operation." This reverts commit 5708a1ac7375c491899be45aca2c85510a410d52. Signed-off-by: dongjiuzhu1 --- fs/mount/fs_mount.c | 3 -- fs/romfs/fs_romfsutil.c | 94 +++++++++++------------------------------ 2 files changed, 24 insertions(+), 73 deletions(-) diff --git a/fs/mount/fs_mount.c b/fs/mount/fs_mount.c index e6a2ce703ac2d..740facdfcbe83 100644 --- a/fs/mount/fs_mount.c +++ b/fs/mount/fs_mount.c @@ -125,9 +125,6 @@ static const struct fsmap_t g_bdfsmap[] = #ifdef MDFS_SUPPORT /* File systems that require MTD drivers */ -#ifdef CONFIG_FS_ROMFS -extern const struct mountpt_operations g_romfs_operations; -#endif #ifdef CONFIG_FS_SPIFFS extern const struct mountpt_operations g_spiffs_operations; #endif diff --git a/fs/romfs/fs_romfsutil.c b/fs/romfs/fs_romfsutil.c index 18961728465dd..b7dddbf670ed2 100644 --- a/fs/romfs/fs_romfsutil.c +++ b/fs/romfs/fs_romfsutil.c @@ -37,7 +37,6 @@ #include #include -#include #include "fs_romfs.h" @@ -677,16 +676,8 @@ int romfs_hwread(FAR struct romfs_mountpt_s *rm, FAR uint8_t *buffer, FAR struct inode *inode = rm->rm_blkdriver; ssize_t nsectorsread = -ENODEV; - if (INODE_IS_MTD(inode)) - { - nsectorsread = - MTD_BREAD(inode->u.i_mtd, sector, nsectors, buffer); - } - else if (inode->u.i_bops->read) - { - nsectorsread = - inode->u.i_bops->read(inode, buffer, sector, nsectors); - } + nsectorsread = + inode->u.i_bops->read(inode, buffer, sector, nsectors); if (nsectorsread == (ssize_t)nsectors) { @@ -778,6 +769,7 @@ int romfs_filecacheread(FAR struct romfs_mountpt_s *rm, int romfs_hwconfigure(FAR struct romfs_mountpt_s *rm) { FAR struct inode *inode = rm->rm_blkdriver; + struct geometry geo; int ret; /* Get the underlying device geometry */ @@ -789,72 +781,40 @@ int romfs_hwconfigure(FAR struct romfs_mountpt_s *rm) } #endif - if (INODE_IS_MTD(inode)) + ret = inode->u.i_bops->geometry(inode, &geo); + if (ret != OK) { - struct mtd_geometry_s mgeo; - - ret = MTD_IOCTL(inode->u.i_mtd, MTDIOC_GEOMETRY, - (unsigned long)&mgeo); - if (ret != OK) - { - return ret; - } - - /* Save that information in the mount structure */ - - rm->rm_hwsectorsize = mgeo.blocksize; - rm->rm_hwnsectors = mgeo.neraseblocks * - (mgeo.erasesize / mgeo.blocksize); + return ret; } - else - { - struct geometry geo; - - ret = inode->u.i_bops->geometry(inode, &geo); - if (ret != OK) - { - return ret; - } - if (!geo.geo_available) - { - return -EBUSY; - } + if (!geo.geo_available) + { + return -EBUSY; + } - /* Save that information in the mount structure */ + /* Save that information in the mount structure */ - rm->rm_hwsectorsize = geo.geo_sectorsize; - rm->rm_hwnsectors = geo.geo_nsectors; - } + rm->rm_hwsectorsize = geo.geo_sectorsize; + rm->rm_hwnsectors = geo.geo_nsectors; /* Determine if block driver supports the XIP mode of operation */ rm->rm_cachesector = (uint32_t)-1; - if (INODE_IS_MTD(inode)) - { - ret = MTD_IOCTL(inode->u.i_mtd, BIOC_XIPBASE, - (unsigned long)&rm->rm_xipbase); - } - else if (inode->u.i_bops->ioctl != NULL) + if (inode->u.i_bops->ioctl) { ret = inode->u.i_bops->ioctl(inode, BIOC_XIPBASE, (unsigned long)&rm->rm_xipbase); - } - else - { - ret = -ENOTSUP; - } - - if (ret == OK && rm->rm_xipbase) - { - /* Yes.. Then we will directly access the media (vs. - * copying into an allocated sector buffer. - */ + if (ret == OK && rm->rm_xipbase) + { + /* Yes.. Then we will directly access the media (vs. + * copying into an allocated sector buffer. + */ - rm->rm_buffer = rm->rm_xipbase; - rm->rm_cachesector = 0; - return OK; + rm->rm_buffer = rm->rm_xipbase; + rm->rm_cachesector = 0; + return OK; + } } /* Allocate the device cache buffer for normal sector accesses */ @@ -1040,13 +1000,7 @@ int romfs_checkmount(FAR struct romfs_mountpt_s *rm) */ inode = rm->rm_blkdriver; - if (INODE_IS_MTD(inode)) - { - /* It is impossible to remove MTD device */ - - return OK; - } - else if (inode->u.i_bops->geometry) + if (inode->u.i_bops->geometry) { ret = inode->u.i_bops->geometry(inode, &geo); if (ret == OK && geo.geo_available && !geo.geo_mediachanged) From 1ae1500aaad98000c79dd901924be44b719dce32 Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Sun, 4 Feb 2024 06:22:20 +0800 Subject: [PATCH 6/7] fs/romfs: Call block_operations::close when romfs_bind fail Signed-off-by: Xiang Xiao --- fs/romfs/fs_romfs.c | 25 ++++++++++++++++--------- fs/romfs/fs_romfsutil.c | 4 +--- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/fs/romfs/fs_romfs.c b/fs/romfs/fs_romfs.c index 7608008ac436b..b16ed77e82374 100644 --- a/fs/romfs/fs_romfs.c +++ b/fs/romfs/fs_romfs.c @@ -1074,12 +1074,11 @@ static int romfs_bind(FAR struct inode *blkdriver, FAR const void *data, return -ENODEV; } - if (INODE_IS_BLOCK(blkdriver) && - blkdriver->u.i_bops->open != NULL && - blkdriver->u.i_bops->open(blkdriver) != OK) + if (blkdriver->u.i_bops->open != NULL && + (ret = blkdriver->u.i_bops->open(blkdriver)) != OK) { ferr("ERROR: No open method\n"); - return -ENODEV; + return ret; } /* Create an instance of the mountpt state structure */ @@ -1088,7 +1087,8 @@ static int romfs_bind(FAR struct inode *blkdriver, FAR const void *data, if (!rm) { ferr("ERROR: Failed to allocate mountpoint structure\n"); - return -ENOMEM; + ret = -ENOMEM; + goto errout; } /* Initialize the allocated mountpt state structure. The filesystem is @@ -1105,7 +1105,7 @@ static int romfs_bind(FAR struct inode *blkdriver, FAR const void *data, if (ret < 0) { ferr("ERROR: romfs_hwconfigure failed: %d\n", ret); - goto errout; + goto errout_with_mount; } /* Then complete the mount by getting the ROMFS configuratrion from @@ -1130,9 +1130,16 @@ static int romfs_bind(FAR struct inode *blkdriver, FAR const void *data, kmm_free(rm->rm_buffer); } -errout: +errout_with_mount: nxrmutex_destroy(&rm->rm_lock); kmm_free(rm); + +errout: + if (blkdriver->u.i_bops->close != NULL) + { + blkdriver->u.i_bops->close(blkdriver); + } + return ret; } @@ -1177,7 +1184,7 @@ static int romfs_unbind(FAR void *handle, FAR struct inode **blkdriver, * no open file references. */ - ret = (flags != 0) ? -ENOSYS : -EBUSY; + ret = flags ? -ENOSYS : -EBUSY; } else { @@ -1208,7 +1215,7 @@ static int romfs_unbind(FAR void *handle, FAR struct inode **blkdriver, /* Release the mountpoint private data */ - if (!rm->rm_xipbase && rm->rm_buffer) + if (!rm->rm_xipbase) { kmm_free(rm->rm_buffer); } diff --git a/fs/romfs/fs_romfsutil.c b/fs/romfs/fs_romfsutil.c index b7dddbf670ed2..df361687be56d 100644 --- a/fs/romfs/fs_romfsutil.c +++ b/fs/romfs/fs_romfsutil.c @@ -674,9 +674,7 @@ int romfs_hwread(FAR struct romfs_mountpt_s *rm, FAR uint8_t *buffer, /* In non-XIP mode, we have to read the data from the device */ FAR struct inode *inode = rm->rm_blkdriver; - ssize_t nsectorsread = -ENODEV; - - nsectorsread = + ssize_t nsectorsread = inode->u.i_bops->read(inode, buffer, sector, nsectors); if (nsectorsread == (ssize_t)nsectors) From 617530b93ee5209a44f19048c023e72f17f5e0b8 Mon Sep 17 00:00:00 2001 From: guohao15 Date: Thu, 25 Apr 2024 18:37:56 +0800 Subject: [PATCH 7/7] romfs:extend romfs to enable write part3 add romfs_mkfs to support autoformat && forceformat Signed-off-by: guohao15 --- fs/romfs/fs_romfs.c | 48 ++++++++++---- fs/romfs/fs_romfs.h | 2 + fs/romfs/fs_romfsutil.c | 136 +++++++++++++++++++++++++++++++++++++--- 3 files changed, 168 insertions(+), 18 deletions(-) diff --git a/fs/romfs/fs_romfs.c b/fs/romfs/fs_romfs.c index b16ed77e82374..9d6b05bcd130b 100644 --- a/fs/romfs/fs_romfs.c +++ b/fs/romfs/fs_romfs.c @@ -1108,6 +1108,18 @@ static int romfs_bind(FAR struct inode *blkdriver, FAR const void *data, goto errout_with_mount; } +#ifdef CONFIG_FS_ROMFS_WRITEABLE + if (data && strstr(data, "rw") && strstr(data, "forceformat")) + { + ret = romfs_mkfs(rm); + if (ret < 0) + { + ferr("ERROR: romfs_mkfs failed: %d\n", ret); + goto errout_with_buffer; + } + } +#endif + /* Then complete the mount by getting the ROMFS configuratrion from * the ROMF header */ @@ -1115,8 +1127,29 @@ static int romfs_bind(FAR struct inode *blkdriver, FAR const void *data, ret = romfs_fsconfigure(rm, data); if (ret < 0) { - ferr("ERROR: romfs_fsconfigure failed: %d\n", ret); - goto errout_with_buffer; +#ifdef CONFIG_FS_ROMFS_WRITEABLE + if (data && strstr(data, "rw") && strstr(data, "autoformat")) + { + ret = romfs_mkfs(rm); + if (ret < 0) + { + ferr("ERROR: romfs_format failed: %d\n", ret); + goto errout_with_buffer; + } + + ret = romfs_fsconfigure(rm, data); + if (ret < 0) + { + ferr("ERROR: romfs_fsconfigure failed: %d\n", ret); + goto errout_with_buffer; + } + } + else +#endif + { + ferr("ERROR: romfs_fsconfigure failed: %d\n", ret); + goto errout_with_buffer; + } } /* Mounted! */ @@ -1125,10 +1158,7 @@ static int romfs_bind(FAR struct inode *blkdriver, FAR const void *data, return OK; errout_with_buffer: - if (!rm->rm_xipbase) - { - kmm_free(rm->rm_buffer); - } + kmm_free(rm->rm_devbuffer); errout_with_mount: nxrmutex_destroy(&rm->rm_lock); @@ -1215,11 +1245,7 @@ static int romfs_unbind(FAR void *handle, FAR struct inode **blkdriver, /* Release the mountpoint private data */ - if (!rm->rm_xipbase) - { - kmm_free(rm->rm_buffer); - } - + kmm_free(rm->rm_devbuffer); #ifdef CONFIG_FS_ROMFS_CACHE_NODE romfs_freenode(rm->rm_root); #endif diff --git a/fs/romfs/fs_romfs.h b/fs/romfs/fs_romfs.h index b066d0adf2f93..5906f68e837b8 100644 --- a/fs/romfs/fs_romfs.h +++ b/fs/romfs/fs_romfs.h @@ -154,6 +154,7 @@ struct romfs_mountpt_s uint32_t rm_cachesector; /* Current sector in the rm_buffer */ FAR uint8_t *rm_xipbase; /* Base address of directly accessible media */ FAR uint8_t *rm_buffer; /* Device sector buffer, allocated if rm_xipbase==0 */ + FAR uint8_t *rm_devbuffer; /* Device sector buffer, allocated for write if rm_xipbase != 0 */ #ifdef CONFIG_FS_ROMFS_WRITEABLE struct list_node rm_sparelist; /* The list of spare space */ #endif @@ -231,6 +232,7 @@ int romfs_datastart(FAR struct romfs_mountpt_s *rm, void romfs_freenode(FAR struct romfs_nodeinfo_s *node); #endif #ifdef CONFIG_FS_ROMFS_WRITEABLE +int romfs_mkfs(FAR struct romfs_mountpt_s *rm); void romfs_free_sparelist(FAR struct list_node *list); #endif diff --git a/fs/romfs/fs_romfsutil.c b/fs/romfs/fs_romfsutil.c index df361687be56d..021a9753e6fd6 100644 --- a/fs/romfs/fs_romfsutil.c +++ b/fs/romfs/fs_romfsutil.c @@ -513,6 +513,78 @@ static int romfs_alloc_spareregion(FAR struct list_node *list, end); return -ENOENT; } + +/**************************************************************************** + * Name: romfs_devwrite32 + * + * Description: + * Write the big-endian 32-bit value to the mount device buffer + * + ****************************************************************************/ + +static void romfs_devwrite32(FAR struct romfs_mountpt_s *rm, + int ndx, uint32_t value) +{ + /* Write the 32-bit value to the specified index in the buffer */ + + rm->rm_devbuffer[ndx] = (uint8_t)(value >> 24) & 0xff; + rm->rm_devbuffer[ndx + 1] = (uint8_t)(value >> 16) & 0xff; + rm->rm_devbuffer[ndx + 2] = (uint8_t)(value >> 8) & 0xff; + rm->rm_devbuffer[ndx + 3] = (uint8_t)(value & 0xff); +} + +/**************************************************************************** + * Name: romfs_hwwrite + * + * Description: + * Write the specified number of sectors to the block device + * + ****************************************************************************/ + +static int romfs_hwwrite(FAR struct romfs_mountpt_s *rm, FAR uint8_t *buffer, + uint32_t sector, unsigned int nsectors) +{ + FAR struct inode *inode = rm->rm_blkdriver; + ssize_t ret = -ENODEV; + + if (inode->u.i_bops->write) + { + ret = inode->u.i_bops->write(inode, buffer, sector, nsectors); + } + + if (ret == (ssize_t)nsectors) + { + ret = OK; + } + + return ret; +} + +/**************************************************************************** + * Name: romfs_devcachewrite + * + * Description: + * Write the specified sector for specified offset into the sector cache. + * + ****************************************************************************/ + +static int romfs_devcachewrite(FAR struct romfs_mountpt_s *rm, + uint32_t sector) +{ + int ret; + + ret = romfs_hwwrite(rm, rm->rm_devbuffer, sector, 1); + if (ret == OK) + { + rm->rm_cachesector = sector; + } + else + { + rm->rm_cachesector = (uint32_t)-1; + } + + return ret; +} #endif /**************************************************************************** @@ -799,6 +871,14 @@ int romfs_hwconfigure(FAR struct romfs_mountpt_s *rm) rm->rm_cachesector = (uint32_t)-1; + /* Allocate the device cache buffer for normal sector accesses */ + + rm->rm_devbuffer = kmm_malloc(rm->rm_hwsectorsize); + if (!rm->rm_devbuffer) + { + return -ENOMEM; + } + if (inode->u.i_bops->ioctl) { ret = inode->u.i_bops->ioctl(inode, BIOC_XIPBASE, @@ -815,14 +895,9 @@ int romfs_hwconfigure(FAR struct romfs_mountpt_s *rm) } } - /* Allocate the device cache buffer for normal sector accesses */ - - rm->rm_buffer = kmm_malloc(rm->rm_hwsectorsize); - if (!rm->rm_buffer) - { - return -ENOMEM; - } + /* The device cache buffer for normal sector accesses */ + rm->rm_buffer = rm->rm_devbuffer; return OK; } @@ -1341,3 +1416,50 @@ int romfs_datastart(FAR struct romfs_mountpt_s *rm, return -EINVAL; /* Won't get here */ #endif } + +#ifdef CONFIG_FS_ROMFS_WRITEABLE + +/**************************************************************************** + * Name: romfs_mkfs + * + * Description: + * Format the romfs filesystem + * + ****************************************************************************/ + +int romfs_mkfs(FAR struct romfs_mountpt_s *rm) +{ + /* Write the magic number at that identifies this as a ROMFS filesystem */ + + memcpy(rm->rm_devbuffer + ROMFS_VHDR_ROM1FS, ROMFS_VHDR_MAGIC, + ROMFS_VHDR_SIZE); + + /* Init the ROMFS volume to zero */ + + romfs_devwrite32(rm, ROMFS_VHDR_SIZE, 0); + + /* Write the volume name */ + + memcpy(rm->rm_devbuffer + ROMFS_VHDR_VOLNAME, "romfs", 6); + + /* Write the root node . */ + + romfs_devwrite32(rm, 0x20 + ROMFS_FHDR_NEXT, 0x40 | RFNEXT_DIRECTORY); + romfs_devwrite32(rm, 0x20 + ROMFS_FHDR_INFO, 0x20); + romfs_devwrite32(rm, 0x20 + ROMFS_FHDR_SIZE, 0); + romfs_devwrite32(rm, 0x20 + ROMFS_FHDR_CHKSUM, 0); + memcpy(rm->rm_devbuffer + 0x20 + ROMFS_FHDR_NAME, ".", 2); + + /* Write the root node .. */ + + romfs_devwrite32(rm, 0x40 + ROMFS_FHDR_NEXT, RFNEXT_HARDLINK); + romfs_devwrite32(rm, 0x40 + ROMFS_FHDR_INFO, 0x20); + romfs_devwrite32(rm, 0x40 + ROMFS_FHDR_SIZE, 0); + romfs_devwrite32(rm, 0x40 + ROMFS_FHDR_CHKSUM, 0); + memcpy(rm->rm_devbuffer + 0x40 + ROMFS_FHDR_NAME, "..", 3); + + /* Write the buffer to sector zero */ + + return romfs_devcachewrite(rm, 0); +} +#endif