From f435f7116a5de30a2efad98b107ffb6b0e394c2b Mon Sep 17 00:00:00 2001 From: "goprife@gmail.com" Date: Thu, 5 Apr 2012 03:39:47 +0000 Subject: [PATCH] update uffs from official repo(fixed bugs and support mount/unmount one partition" git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2018 bbd45198-f89e-11dd-88c7-29a3b14d5316 --- .../src/example/flash-interface-example.c | 28 +- .../uffs/src/example/static-mem-allocate.c | 9 +- .../filesystems/uffs/src/inc/uffs/uffs_mtb.h | 31 +- .../uffs/src/inc/uffs/uffs_public.h | 5 +- .../filesystems/uffs/src/inc/uffs/uffs_tree.h | 2 +- .../uffs/src/uffs/uffs_blockinfo.c | 1 + .../dfs/filesystems/uffs/src/uffs/uffs_buf.c | 4 +- .../dfs/filesystems/uffs/src/uffs/uffs_find.c | 1 + .../dfs/filesystems/uffs/src/uffs/uffs_fs.c | 14 +- .../dfs/filesystems/uffs/src/uffs/uffs_init.c | 24 ++ .../dfs/filesystems/uffs/src/uffs/uffs_mtb.c | 295 ++++++++++++------ .../dfs/filesystems/uffs/src/utils/mkuffs.c | 26 +- 12 files changed, 318 insertions(+), 122 deletions(-) diff --git a/components/dfs/filesystems/uffs/src/example/flash-interface-example.c b/components/dfs/filesystems/uffs/src/example/flash-interface-example.c index 36734e701..248dea171 100644 --- a/components/dfs/filesystems/uffs/src/example/flash-interface-example.c +++ b/components/dfs/filesystems/uffs/src/example/flash-interface-example.c @@ -387,8 +387,30 @@ static int my_init_filesystem(void) uffs_RegisterMountTable(mtbl); mtbl++; } - - return uffs_InitMountTable() == U_SUCC ? 0 : -1; + + // mount partitions + for (mtbl = &(demo_mount_table[0]); mtbl->mount != NULL; mtbl++) { + uffs_Mount(mtbl->mount); + } + + return uffs_InitFileSystemObjects() == U_SUCC ? 0 : -1; +} + +static int my_release_filesystem(void) +{ + uffs_MountTable *mtb; + int ret = 0; + + // unmount parttions + for (mtb = &(demo_mount_table[0]); ret == 0 && mtb->mount != NULL; mtb++) { + ret = uffs_UnMount(mtb->mount); + } + + // release objects + if (ret == 0) + ret = (uffs_ReleaseFileSystemObjects() == U_SUCC ? 0 : -1); + + return ret; } /* application entry */ @@ -401,7 +423,7 @@ int main() // ... my application codes .... // read/write/create/delete files ... - uffs_ReleaseMountTable(); + my_release_filesystem(); return 0; } diff --git a/components/dfs/filesystems/uffs/src/example/static-mem-allocate.c b/components/dfs/filesystems/uffs/src/example/static-mem-allocate.c index fb598ebc1..a37409828 100644 --- a/components/dfs/filesystems/uffs/src/example/static-mem-allocate.c +++ b/components/dfs/filesystems/uffs/src/example/static-mem-allocate.c @@ -124,12 +124,17 @@ static int init_uffs_fs(void) /* register mount table */ uffs_RegisterMountTable(mtbl); - return uffs_InitMountTable() == U_SUCC ? 0 : -1; + /* mount it */ + uffs_Mount("/"); + + return uffs_InitFileSystemObjects() == U_SUCC ? 0 : -1; } static int release_uffs_fs(void) { - return uffs_ReleaseMountTable(); + uffs_UnMount("/"); + + return uffs_ReleaseFileSystemObjects(); } int main(int argc, char *argv[]) diff --git a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_mtb.h b/components/dfs/filesystems/uffs/src/inc/uffs/uffs_mtb.h index aa9be9222..8e00e5259 100644 --- a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_mtb.h +++ b/components/dfs/filesystems/uffs/src/inc/uffs/uffs_mtb.h @@ -49,24 +49,31 @@ extern "C"{ typedef struct uffs_MountTableEntrySt { - uffs_Device *dev; - int start_block; - int end_block; - const char *mount; + uffs_Device *dev; // UFFS 'device' - core internal data structure for partition + int start_block; // partition start block + int end_block; // partition end block ( if < 0, reserve space form the end of storage) + const char *mount; // mount point + struct uffs_MountTableEntrySt *prev; struct uffs_MountTableEntrySt *next; } uffs_MountTable; -/** initialize registered mount table */ -URET uffs_InitMountTable(void); +/** Register mount entry, will be put at 'unmounted' list */ +int uffs_RegisterMountTable(uffs_MountTable *mtb); -/** release registered mount table */ -URET uffs_ReleaseMountTable(void); +/** Remove mount entry from the list */ +int uffs_UnRegisterMountTable(uffs_MountTable *mtb); -/** get registered mount table */ -uffs_MountTable * uffs_GetMountTable(void); +/** mount partition */ +int uffs_Mount(const char *mount); -/** register mount table */ -int uffs_RegisterMountTable(uffs_MountTable *mtab); +/** unmount parttion */ +int uffs_UnMount(const char *mount); + +/** get mounted entry list */ +uffs_MountTable * uffs_MtbGetMounted(void); + +/** get unmounted entry list */ +uffs_MountTable * uffs_MtbGetUnMounted(void); /** get matched mount point from absolute path */ int uffs_GetMatchedMountPointSize(const char *path); diff --git a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_public.h b/components/dfs/filesystems/uffs/src/inc/uffs/uffs_public.h index 593528746..d96c4449a 100644 --- a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_public.h +++ b/components/dfs/filesystems/uffs/src/inc/uffs/uffs_public.h @@ -325,9 +325,8 @@ int uffs_DirEntryBufPutAll(uffs_Device *dev); URET uffs_InitDevice(uffs_Device *dev); URET uffs_ReleaseDevice(uffs_Device *dev); - -URET uffs_InitFlashClass(uffs_Device *dev); - +URET uffs_InitFileSystemObjects(void); +URET uffs_ReleaseFileSystemObjects(void); #ifdef __cplusplus diff --git a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_tree.h b/components/dfs/filesystems/uffs/src/inc/uffs/uffs_tree.h index 69df9420a..9f79316f9 100644 --- a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_tree.h +++ b/components/dfs/filesystems/uffs/src/inc/uffs/uffs_tree.h @@ -68,7 +68,7 @@ struct BlockListSt { /* 12 bytes */ union { u16 serial; /* for suspended block list */ u8 need_check; /* for erased block list */ - }u; + } u; }; struct DirhSt { /* 8 bytes */ diff --git a/components/dfs/filesystems/uffs/src/uffs/uffs_blockinfo.c b/components/dfs/filesystems/uffs/src/uffs/uffs_blockinfo.c index 121fe361a..89f75da01 100644 --- a/components/dfs/filesystems/uffs/src/uffs/uffs_blockinfo.c +++ b/components/dfs/filesystems/uffs/src/uffs/uffs_blockinfo.c @@ -160,6 +160,7 @@ URET uffs_BlockInfoReleaseCache(uffs_Device *dev) } if (dev->mem.free) { dev->mem.free(dev, dev->bc.mem_pool); + dev->mem.blockinfo_pool_size = 0; } } diff --git a/components/dfs/filesystems/uffs/src/uffs/uffs_buf.c b/components/dfs/filesystems/uffs/src/uffs/uffs_buf.c index a4f33af28..d6a3e456f 100644 --- a/components/dfs/filesystems/uffs/src/uffs/uffs_buf.c +++ b/components/dfs/filesystems/uffs/src/uffs/uffs_buf.c @@ -212,8 +212,10 @@ URET uffs_BufReleaseAll(uffs_Device *dev) return U_FAIL; } - if (dev->mem.free) + if (dev->mem.free) { dev->mem.free(dev, dev->buf.pool); + dev->mem.pagebuf_pool_size = 0; + } dev->buf.pool = NULL; dev->buf.head = dev->buf.tail = NULL; diff --git a/components/dfs/filesystems/uffs/src/uffs/uffs_find.c b/components/dfs/filesystems/uffs/src/uffs/uffs_find.c index 9450a1992..d5aceed35 100644 --- a/components/dfs/filesystems/uffs/src/uffs/uffs_find.c +++ b/components/dfs/filesystems/uffs/src/uffs/uffs_find.c @@ -106,6 +106,7 @@ URET uffs_GetObjectInfo(uffs_Object *obj, uffs_ObjectInfo *info, int *err) // this is ROOT. UFFS does not physically has root, just fake it ... memset(info, 0, sizeof(uffs_ObjectInfo)); info->serial = obj->serial; + info->info.attr |= (FILE_ATTR_DIR | FILE_ATTR_WRITE); if (err) *err = UENOERR; ret = U_SUCC; diff --git a/components/dfs/filesystems/uffs/src/uffs/uffs_fs.c b/components/dfs/filesystems/uffs/src/uffs/uffs_fs.c index 0a9156545..1ef18b821 100644 --- a/components/dfs/filesystems/uffs/src/uffs/uffs_fs.c +++ b/components/dfs/filesystems/uffs/src/uffs/uffs_fs.c @@ -966,8 +966,20 @@ static int do_WriteObject(uffs_Object *obj, const void *data, int len) size = do_WriteNewBlock(obj, data ? (u8 *)data + len - remain : NULL, remain, fnode->u.file.serial, fdn); - // Flush immediately, so that the new data node will be + // + // Flush the new block buffers immediately, so that the new data node will be // created and put in the tree. + // + // But before do that, we need to make sure the previous + // data block (if exist) been flushed first. + // + if (fdn > 1) { + uffs_BufFlushGroup(dev, fnode->u.file.serial, fdn - 1); + } + else { + uffs_BufFlushGroup(dev, fnode->u.file.parent, fnode->u.file.serial); + } + // Now flush the new block. uffs_BufFlushGroup(dev, fnode->u.file.serial, fdn); if (size == 0) diff --git a/components/dfs/filesystems/uffs/src/uffs/uffs_init.c b/components/dfs/filesystems/uffs/src/uffs/uffs_init.c index 5c630f5b9..1a7b3fac4 100644 --- a/components/dfs/filesystems/uffs/src/uffs/uffs_init.c +++ b/components/dfs/filesystems/uffs/src/uffs/uffs_init.c @@ -42,6 +42,7 @@ #include "uffs/uffs_tree.h" #include "uffs/uffs_fs.h" #include "uffs/uffs_badblock.h" +#include "uffs/uffs_utils.h" #include #define PFX "init: " @@ -178,3 +179,26 @@ ext: } +URET uffs_InitFileSystemObjects(void) +{ + if (uffs_InitObjectBuf() == U_SUCC) { + if (uffs_DirEntryBufInit() == U_SUCC) { + uffs_InitGlobalFsLock(); + return U_SUCC; + } + } + + return U_FAIL; +} + +URET uffs_ReleaseFileSystemObjects(void) +{ + if (uffs_ReleaseObjectBuf() == U_SUCC) { + if (uffs_DirEntryBufRelease() == U_SUCC) { + uffs_ReleaseGlobalFsLock(); + return U_SUCC; + } + } + + return U_FAIL; +} diff --git a/components/dfs/filesystems/uffs/src/uffs/uffs_mtb.c b/components/dfs/filesystems/uffs/src/uffs/uffs_mtb.c index 377a300c0..fd3f7f39a 100644 --- a/components/dfs/filesystems/uffs/src/uffs/uffs_mtb.c +++ b/components/dfs/filesystems/uffs/src/uffs/uffs_mtb.c @@ -47,110 +47,222 @@ #define PFX "mtb : " -static struct uffs_MountTableEntrySt *g_mtb_head = NULL; +static struct uffs_MountTableEntrySt *m_head = NULL; // list of mounted entries +static struct uffs_MountTableEntrySt *m_free_head = NULL; // list of unmounted entries -uffs_MountTable * uffs_GetMountTable(void) +/** Return mounted entries header */ +uffs_MountTable * uffs_MtbGetMounted(void) { - return g_mtb_head; + return m_head; } -int uffs_RegisterMountTable(uffs_MountTable *mtab) +/** Return unmounted entries header */ +uffs_MountTable * uffs_MtbGetUnMounted(void) { - uffs_MountTable *work = g_mtb_head; + return m_free_head; +} - if (mtab == NULL) +/** + * \brief Register mount table + * \param mtb mount table entry + * \return 0 succ + * -1 failed (e.g. already registered and mounted) + */ +int uffs_RegisterMountTable(uffs_MountTable *mtb) +{ + uffs_MountTable *work = NULL; + static int dev_num = 0; + + if (mtb == NULL) return -1; - if (work == NULL) { - g_mtb_head = mtab; - return 0; + for (work = m_head; work; work = work->next) { + if (work == mtb) + return -1; // already mounted ? } - while (work) { - if (mtab == work) { - /* already registered */ - return 0; - } - if (work->next == NULL) { - work->next = mtab; - mtab->next = NULL; - return 0; - } - work = work->next; + for (work = m_free_head; work; work = work->next) { + if (work == mtb) + return 0; // already registered. } - return -1; + /* replace the free head */ + if (m_free_head) + m_free_head->prev = mtb; + mtb->prev = NULL; + mtb->next = m_free_head; + m_free_head = mtb; + + mtb->dev->dev_num = ++dev_num; + + return 0; } - -URET uffs_InitMountTable(void) +/** + * \brief Remove mount entry from the table + * \param mtb mount table entry + * \return 0 removed succ + * -1 entry in used or not in the 'unmounted' list + */ +int uffs_UnRegisterMountTable(uffs_MountTable *mtb) { - struct uffs_MountTableEntrySt *tbl = uffs_GetMountTable(); - struct uffs_MountTableEntrySt *work; - int dev_num = 0; + uffs_MountTable *work = NULL; - for (work = tbl; work; work = work->next) { - uffs_Perror(UFFS_MSG_NOISY, - "init device for mount point %s ...", - work->mount); + if (mtb == NULL) + return -1; - work->dev->par.start = work->start_block; - if (work->end_block < 0) { - work->dev->par.end = - work->dev->attr->total_blocks + work->end_block; - } - else { - work->dev->par.end = work->end_block; - } - - if (work->dev->Init(work->dev) == U_FAIL) { - uffs_Perror(UFFS_MSG_SERIOUS, - "init device for mount point %s fail", - work->mount); - return U_FAIL; - } - - uffs_Perror(UFFS_MSG_NOISY, "mount partiton: %d,%d", - work->dev->par.start, work->dev->par.end); - - if (uffs_InitDevice(work->dev) != U_SUCC) { - uffs_Perror(UFFS_MSG_SERIOUS, "init device fail !"); - return U_FAIL; - } - work->dev->dev_num = dev_num++; + for (work = m_head; work; work = work->next) { + if (work == mtb) + return -1; // in the mounted list ? busy, return } - if (uffs_InitObjectBuf() == U_SUCC) { - if (uffs_DirEntryBufInit() == U_SUCC) { - uffs_InitGlobalFsLock(); - return U_SUCC; + for (work = m_free_head; work; work = work->next) { + if (work == mtb) { + // found, remove it from the list + if (work->next) + work->next->prev = work->prev; + if (work->prev) + work->prev->next = work->next; + if (work == m_free_head) + m_free_head = work->next; + + break; } } - return U_FAIL; + return work ? 0 : -1; } -URET uffs_ReleaseMountTable(void) +static uffs_MountTable * uffs_GetMountTableByMountPoint(const char *mount, uffs_MountTable *head) { - struct uffs_MountTableEntrySt *tbl = uffs_GetMountTable(); - struct uffs_MountTableEntrySt *work; + uffs_MountTable *work = NULL; - for (work = tbl; work; work = work->next) { - uffs_ReleaseDevice(work->dev); - work->dev->Release(work->dev); - } - - if (uffs_ReleaseObjectBuf() == U_SUCC) { - if (uffs_DirEntryBufRelease() == U_SUCC) { - uffs_ReleaseGlobalFsLock(); - return U_SUCC; - } - } - - return U_FAIL; + for (work = head; work; work = work->next) { + if (strcmp(work->mount, mount) == 0) + break; + } + return work; } +/** + * \brief mount partition + * \param[in] mount partition mount point + * \return 0 succ + * <0 fail + * + * \note use uffs_RegisterMountTable() register mount entry before you can mount it. + * mount point should ended with '/', e.g. '/sys/' + */ +int uffs_Mount(const char *mount) +{ + uffs_MountTable *mtb; + if (uffs_GetMountTableByMountPoint(mount, m_head) != NULL) { + uffs_Perror(UFFS_MSG_NOISY, "'%s' already mounted", mount); + return -1; // already mounted ? + } + + mtb = uffs_GetMountTableByMountPoint(mount, m_free_head); + if (mtb == NULL) { + uffs_Perror(UFFS_MSG_NOISY, "'%s' not registered", mount); + return -1; // not registered ? + } + + uffs_Perror(UFFS_MSG_NOISY, + "init device for mount point %s ...", + mtb->mount); + + mtb->dev->par.start = mtb->start_block; + if (mtb->end_block < 0) { + mtb->dev->par.end = + mtb->dev->attr->total_blocks + mtb->end_block; + } + else { + mtb->dev->par.end = mtb->end_block; + } + + if (mtb->dev->Init(mtb->dev) == U_FAIL) { + uffs_Perror(UFFS_MSG_SERIOUS, + "init device for mount point %s fail", + mtb->mount); + return -1; + } + + uffs_Perror(UFFS_MSG_NOISY, "mount partiton: %d,%d", + mtb->dev->par.start, mtb->dev->par.end); + + if (uffs_InitDevice(mtb->dev) != U_SUCC) { + uffs_Perror(UFFS_MSG_SERIOUS, "init device fail !"); + return -1; + } + + /* now break it from unmounted list */ + if (mtb->prev) + mtb->prev->next = mtb->next; + if (mtb->next) + mtb->next->prev = mtb->prev; + if (m_free_head == mtb) + m_free_head = mtb->next; + + /* link to mounted list */ + mtb->prev = NULL; + mtb->next = m_head; + if (m_head) + m_head->prev = mtb; + m_head = mtb; + + return 0; +} + +/** + * \brief unmount parttion + * \param[in] mount partition mount point + * \return 0 succ + * <0 fail + */ +int uffs_UnMount(const char *mount) +{ + uffs_MountTable *mtb = uffs_GetMountTableByMountPoint(mount, m_head); + + if (mtb == NULL) { + uffs_Perror(UFFS_MSG_NOISY, "'%s' not mounted ?", mount); + return -1; // not mounted ? + } + + if (uffs_GetMountTableByMountPoint(mount, m_free_head) != NULL) { + uffs_Perror(UFFS_MSG_NOISY, "'%s' already unmounted ?", mount); + return -1; // already unmounted ? + } + + if (mtb->dev->ref_count != 0) { + uffs_Perror(UFFS_MSG_NORMAL, "Can't unmount '%s' - busy", mount); + return -1; + } + + if (uffs_ReleaseDevice(mtb->dev) == U_FAIL) { + uffs_Perror(UFFS_MSG_NORMAL, "Can't release device for mount point '%s'", mount); + return -1; + } + + mtb->dev->Release(mtb->dev); + + // break from mounted list + if (mtb->prev) + mtb->prev->next = mtb->next; + if (mtb->next) + mtb->next->prev = mtb->prev; + if (mtb == m_head) + m_head = mtb->next; + + // put to unmounted list + mtb->prev = NULL; + mtb->next = m_free_head; + if (m_free_head) + m_free_head->prev = mtb; + m_free_head = mtb; + + return 0; +} /** * find the matched mount point from a given full absolute path. @@ -193,14 +305,11 @@ int uffs_GetMatchedMountPointSize(const char *path) */ uffs_Device * uffs_GetDeviceFromMountPoint(const char *mount) { - struct uffs_MountTableEntrySt *devTab = uffs_GetMountTable(); + uffs_MountTable *mtb = uffs_GetMountTableByMountPoint(mount, m_head); - while (devTab) { - if (strcmp(mount, devTab->mount) == 0) { - devTab->dev->ref_count++; - return devTab->dev; - } - devTab = devTab->next; + if (mtb) { + mtb->dev->ref_count++; + return mtb->dev; } return NULL; @@ -215,15 +324,14 @@ uffs_Device * uffs_GetDeviceFromMountPoint(const char *mount) */ uffs_Device * uffs_GetDeviceFromMountPointEx(const char *mount, int len) { - struct uffs_MountTableEntrySt *devTab = uffs_GetMountTable(); + uffs_MountTable *work = NULL; - while (devTab) { - if (strlen(devTab->mount) == len && - strncmp(mount, devTab->mount, len) == 0) { - devTab->dev->ref_count++; - return devTab->dev; + for (work = m_head; work; work = work->next) { + if (strlen(work->mount) == len && + strncmp(mount, work->mount, len) == 0) { + work->dev->ref_count++; + return work->dev; } - devTab = devTab->next; } return NULL; @@ -239,13 +347,12 @@ uffs_Device * uffs_GetDeviceFromMountPointEx(const char *mount, int len) */ const char * uffs_GetDeviceMountPoint(uffs_Device *dev) { - struct uffs_MountTableEntrySt * devTab = uffs_GetMountTable(); + uffs_MountTable *work = NULL; - while (devTab) { - if (devTab->dev == dev) { - return devTab->mount; + for (work = m_head; work; work = work->next) { + if (work->dev == dev) { + return work->mount; } - devTab = devTab->next; } return NULL; diff --git a/components/dfs/filesystems/uffs/src/utils/mkuffs.c b/components/dfs/filesystems/uffs/src/utils/mkuffs.c index c0fc65e8f..13103e9c1 100644 --- a/components/dfs/filesystems/uffs/src/utils/mkuffs.c +++ b/components/dfs/filesystems/uffs/src/utils/mkuffs.c @@ -138,11 +138,13 @@ static int init_uffs_fs(void) 0, // bc_caches - default 0, // page_buffers - default 0, // dirty_pages - default - 0, // dirty_groups - force 1 + 0, // dirty_groups - default 0, // reserved_free_blocks - default }; - if(bIsFileSystemInited) return -4; + if (bIsFileSystemInited) + return -4; + bIsFileSystemInited = 1; while (mtbl->dev) { @@ -157,13 +159,26 @@ static int init_uffs_fs(void) mtbl++; } - return uffs_InitMountTable() == U_SUCC ? 0 : -1; + // mount partitions + for (mtbl = &(conf_mounts[0]); mtbl->mount != NULL; mtbl++) { + uffs_Mount(mtbl->mount); + } + + return uffs_InitFileSystemObjects() == U_SUCC ? 0 : -1; } static int release_uffs_fs(void) { - int ret; - ret = uffs_ReleaseMountTable(); + int ret = 0; + uffs_MountTable *mtb; + + for (mtb = &(conf_mounts[0]); ret == 0 && mtb->mount != NULL; mtb++) { + uffs_UnMount(mtb->mount); + } + + if (ret == 0) + ret = (uffs_ReleaseFileSystemObjects() == U_SUCC ? 0 : -1); + return ret; } @@ -357,6 +372,7 @@ static int parse_options(int argc, char *argv[]) } if (m_idx == 0) { + // if not given mount information, use default ('/' for whole partition) parse_mount_point("/,0,-1", 0); }