diff options
| author | [email protected] <[email protected]> | 2012-04-05 03:39:47 +0000 |
|---|---|---|
| committer | [email protected] <[email protected]> | 2012-04-05 03:39:47 +0000 |
| commit | f435f7116a5de30a2efad98b107ffb6b0e394c2b (patch) | |
| tree | 930c2c9c911289a35f2082f1850dd357ce457beb /components/dfs/filesystems | |
| parent | 3ab019bf860ca2e8e0e9ef887e663be7026bd42e (diff) | |
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
Diffstat (limited to 'components/dfs/filesystems')
12 files changed, 312 insertions, 116 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 36734e701c..248dea1710 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 fb598ebc18..a37409828d 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 aa9be92222..8e00e52592 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 5935287465..d96c4449a2 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 69df9420a2..9f79316f9f 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 121fe361a2..89f75da011 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 a4f33af285..d6a3e456fb 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 9450a1992b..d5aceed35e 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 0a91565452..1ef18b8219 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 5c630f5b92..1a7b3fac48 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 <string.h>
#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 377a300c0b..fd3f7f39aa 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;
- }
+ for (work = m_head; work; work = work->next) {
+ if (work == mtb)
+ return -1; // in the mounted list ? busy, return
+ }
+
+ 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;
- 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;
+ break;
}
+ }
- uffs_Perror(UFFS_MSG_NOISY, "mount partiton: %d,%d",
- work->dev->par.start, work->dev->par.end);
+ return work ? 0 : -1;
+}
- if (uffs_InitDevice(work->dev) != U_SUCC) {
- uffs_Perror(UFFS_MSG_SERIOUS, "init device fail !");
- return U_FAIL;
- }
- work->dev->dev_num = dev_num++;
+static uffs_MountTable * uffs_GetMountTableByMountPoint(const char *mount, uffs_MountTable *head)
+{
+ uffs_MountTable *work = NULL;
+
+ 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 ?
}
- if (uffs_InitObjectBuf() == U_SUCC) {
- if (uffs_DirEntryBufInit() == U_SUCC) {
- uffs_InitGlobalFsLock();
- return U_SUCC;
- }
+ 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;
}
- return U_FAIL;
+ 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;
}
-URET uffs_ReleaseMountTable(void)
+/**
+ * \brief unmount parttion
+ * \param[in] mount partition mount point
+ * \return 0 succ
+ * <0 fail
+ */
+int uffs_UnMount(const char *mount)
{
- struct uffs_MountTableEntrySt *tbl = uffs_GetMountTable();
- struct uffs_MountTableEntrySt *work;
+ uffs_MountTable *mtb = uffs_GetMountTableByMountPoint(mount, m_head);
- for (work = tbl; work; work = work->next) {
- uffs_ReleaseDevice(work->dev);
- work->dev->Release(work->dev);
+ if (mtb == NULL) {
+ uffs_Perror(UFFS_MSG_NOISY, "'%s' not mounted ?", mount);
+ return -1; // not mounted ?
}
- if (uffs_ReleaseObjectBuf() == U_SUCC) {
- if (uffs_DirEntryBufRelease() == U_SUCC) {
- uffs_ReleaseGlobalFsLock();
- return U_SUCC;
- }
+ if (uffs_GetMountTableByMountPoint(mount, m_free_head) != NULL) {
+ uffs_Perror(UFFS_MSG_NOISY, "'%s' already unmounted ?", mount);
+ return -1; // already unmounted ?
}
- return U_FAIL;
-}
+ 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 c0fc65e8f3..13103e9c1f 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);
}
|
