提交 f435f711 编写于 作者: G goprife@gmail.com

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
上级 3ab019bf
...@@ -387,8 +387,30 @@ static int my_init_filesystem(void) ...@@ -387,8 +387,30 @@ static int my_init_filesystem(void)
uffs_RegisterMountTable(mtbl); uffs_RegisterMountTable(mtbl);
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 */ /* application entry */
...@@ -401,7 +423,7 @@ int main() ...@@ -401,7 +423,7 @@ int main()
// ... my application codes .... // ... my application codes ....
// read/write/create/delete files ... // read/write/create/delete files ...
uffs_ReleaseMountTable(); my_release_filesystem();
return 0; return 0;
} }
......
...@@ -124,12 +124,17 @@ static int init_uffs_fs(void) ...@@ -124,12 +124,17 @@ static int init_uffs_fs(void)
/* register mount table */ /* register mount table */
uffs_RegisterMountTable(mtbl); 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) static int release_uffs_fs(void)
{ {
return uffs_ReleaseMountTable(); uffs_UnMount("/");
return uffs_ReleaseFileSystemObjects();
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
......
...@@ -49,24 +49,31 @@ extern "C"{ ...@@ -49,24 +49,31 @@ extern "C"{
typedef struct uffs_MountTableEntrySt { typedef struct uffs_MountTableEntrySt {
uffs_Device *dev; uffs_Device *dev; // UFFS 'device' - core internal data structure for partition
int start_block; int start_block; // partition start block
int end_block; int end_block; // partition end block ( if < 0, reserve space form the end of storage)
const char *mount; const char *mount; // mount point
struct uffs_MountTableEntrySt *prev;
struct uffs_MountTableEntrySt *next; struct uffs_MountTableEntrySt *next;
} uffs_MountTable; } uffs_MountTable;
/** initialize registered mount table */ /** Register mount entry, will be put at 'unmounted' list */
URET uffs_InitMountTable(void); int uffs_RegisterMountTable(uffs_MountTable *mtb);
/** release registered mount table */ /** Remove mount entry from the list */
URET uffs_ReleaseMountTable(void); int uffs_UnRegisterMountTable(uffs_MountTable *mtb);
/** get registered mount table */ /** mount partition */
uffs_MountTable * uffs_GetMountTable(void); int uffs_Mount(const char *mount);
/** register mount table */ /** unmount parttion */
int uffs_RegisterMountTable(uffs_MountTable *mtab); 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 */ /** get matched mount point from absolute path */
int uffs_GetMatchedMountPointSize(const char *path); int uffs_GetMatchedMountPointSize(const char *path);
......
...@@ -325,9 +325,8 @@ int uffs_DirEntryBufPutAll(uffs_Device *dev); ...@@ -325,9 +325,8 @@ int uffs_DirEntryBufPutAll(uffs_Device *dev);
URET uffs_InitDevice(uffs_Device *dev); URET uffs_InitDevice(uffs_Device *dev);
URET uffs_ReleaseDevice(uffs_Device *dev); URET uffs_ReleaseDevice(uffs_Device *dev);
URET uffs_InitFileSystemObjects(void);
URET uffs_InitFlashClass(uffs_Device *dev); URET uffs_ReleaseFileSystemObjects(void);
#ifdef __cplusplus #ifdef __cplusplus
......
...@@ -68,7 +68,7 @@ struct BlockListSt { /* 12 bytes */ ...@@ -68,7 +68,7 @@ struct BlockListSt { /* 12 bytes */
union { union {
u16 serial; /* for suspended block list */ u16 serial; /* for suspended block list */
u8 need_check; /* for erased block list */ u8 need_check; /* for erased block list */
}u; } u;
}; };
struct DirhSt { /* 8 bytes */ struct DirhSt { /* 8 bytes */
......
...@@ -160,6 +160,7 @@ URET uffs_BlockInfoReleaseCache(uffs_Device *dev) ...@@ -160,6 +160,7 @@ URET uffs_BlockInfoReleaseCache(uffs_Device *dev)
} }
if (dev->mem.free) { if (dev->mem.free) {
dev->mem.free(dev, dev->bc.mem_pool); dev->mem.free(dev, dev->bc.mem_pool);
dev->mem.blockinfo_pool_size = 0;
} }
} }
......
...@@ -212,8 +212,10 @@ URET uffs_BufReleaseAll(uffs_Device *dev) ...@@ -212,8 +212,10 @@ URET uffs_BufReleaseAll(uffs_Device *dev)
return U_FAIL; return U_FAIL;
} }
if (dev->mem.free) if (dev->mem.free) {
dev->mem.free(dev, dev->buf.pool); dev->mem.free(dev, dev->buf.pool);
dev->mem.pagebuf_pool_size = 0;
}
dev->buf.pool = NULL; dev->buf.pool = NULL;
dev->buf.head = dev->buf.tail = NULL; dev->buf.head = dev->buf.tail = NULL;
......
...@@ -106,6 +106,7 @@ URET uffs_GetObjectInfo(uffs_Object *obj, uffs_ObjectInfo *info, int *err) ...@@ -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 ... // this is ROOT. UFFS does not physically has root, just fake it ...
memset(info, 0, sizeof(uffs_ObjectInfo)); memset(info, 0, sizeof(uffs_ObjectInfo));
info->serial = obj->serial; info->serial = obj->serial;
info->info.attr |= (FILE_ATTR_DIR | FILE_ATTR_WRITE);
if (err) if (err)
*err = UENOERR; *err = UENOERR;
ret = U_SUCC; ret = U_SUCC;
......
...@@ -966,8 +966,20 @@ static int do_WriteObject(uffs_Object *obj, const void *data, int len) ...@@ -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, size = do_WriteNewBlock(obj, data ? (u8 *)data + len - remain : NULL,
remain, fnode->u.file.serial, fdn); 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. // 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); uffs_BufFlushGroup(dev, fnode->u.file.serial, fdn);
if (size == 0) if (size == 0)
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include "uffs/uffs_tree.h" #include "uffs/uffs_tree.h"
#include "uffs/uffs_fs.h" #include "uffs/uffs_fs.h"
#include "uffs/uffs_badblock.h" #include "uffs/uffs_badblock.h"
#include "uffs/uffs_utils.h"
#include <string.h> #include <string.h>
#define PFX "init: " #define PFX "init: "
...@@ -178,3 +179,26 @@ ext: ...@@ -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;
}
...@@ -47,110 +47,222 @@ ...@@ -47,110 +47,222 @@
#define PFX "mtb : " #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; return -1;
if (work == NULL) { for (work = m_head; work; work = work->next) {
g_mtb_head = mtab; if (work == mtb)
return 0; return -1; // already mounted ?
} }
while (work) { for (work = m_free_head; work; work = work->next) {
if (mtab == work) { if (work == mtb)
/* already registered */ return 0; // already registered.
return 0; }
}
if (work->next == NULL) { /* replace the free head */
work->next = mtab; if (m_free_head)
mtab->next = NULL; m_free_head->prev = mtb;
return 0; mtb->prev = NULL;
mtb->next = m_free_head;
m_free_head = mtb;
mtb->dev->dev_num = ++dev_num;
return 0;
}
/**
* \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)
{
uffs_MountTable *work = NULL;
if (mtb == NULL)
return -1;
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;
break;
} }
work = work->next;
} }
return -1; return work ? 0 : -1;
} }
static uffs_MountTable * uffs_GetMountTableByMountPoint(const char *mount, uffs_MountTable *head)
{
uffs_MountTable *work = NULL;
URET uffs_InitMountTable(void) 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)
{ {
struct uffs_MountTableEntrySt *tbl = uffs_GetMountTable(); uffs_MountTable *mtb;
struct uffs_MountTableEntrySt *work;
int dev_num = 0;
for (work = tbl; work; work = work->next) {
uffs_Perror(UFFS_MSG_NOISY,
"init device for mount point %s ...",
work->mount);
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) { if (uffs_GetMountTableByMountPoint(mount, m_head) != NULL) {
uffs_Perror(UFFS_MSG_SERIOUS, uffs_Perror(UFFS_MSG_NOISY, "'%s' already mounted", mount);
"init device for mount point %s fail", return -1; // already mounted ?
work->mount); }
return U_FAIL;
} 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, "mount partiton: %d,%d", uffs_Perror(UFFS_MSG_NOISY,
work->dev->par.start, work->dev->par.end); "init device for mount point %s ...",
mtb->mount);
if (uffs_InitDevice(work->dev) != U_SUCC) { mtb->dev->par.start = mtb->start_block;
uffs_Perror(UFFS_MSG_SERIOUS, "init device fail !"); if (mtb->end_block < 0) {
return U_FAIL; mtb->dev->par.end =
} mtb->dev->attr->total_blocks + mtb->end_block;
work->dev->dev_num = dev_num++; }
else {
mtb->dev->par.end = mtb->end_block;
} }
if (uffs_InitObjectBuf() == U_SUCC) { if (mtb->dev->Init(mtb->dev) == U_FAIL) {
if (uffs_DirEntryBufInit() == U_SUCC) { uffs_Perror(UFFS_MSG_SERIOUS,
uffs_InitGlobalFsLock(); "init device for mount point %s fail",
return U_SUCC; 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;
} }
return U_FAIL; /* 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(); uffs_MountTable *mtb = uffs_GetMountTableByMountPoint(mount, m_head);
struct uffs_MountTableEntrySt *work;
for (work = tbl; work; work = work->next) { if (mtb == NULL) {
uffs_ReleaseDevice(work->dev); uffs_Perror(UFFS_MSG_NOISY, "'%s' not mounted ?", mount);
work->dev->Release(work->dev); return -1; // not mounted ?
} }
if (uffs_ReleaseObjectBuf() == U_SUCC) { if (uffs_GetMountTableByMountPoint(mount, m_free_head) != NULL) {
if (uffs_DirEntryBufRelease() == U_SUCC) { uffs_Perror(UFFS_MSG_NOISY, "'%s' already unmounted ?", mount);
uffs_ReleaseGlobalFsLock(); return -1; // already unmounted ?
return U_SUCC;
}
} }
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. * find the matched mount point from a given full absolute path.
...@@ -193,14 +305,11 @@ int uffs_GetMatchedMountPointSize(const char *path) ...@@ -193,14 +305,11 @@ int uffs_GetMatchedMountPointSize(const char *path)
*/ */
uffs_Device * uffs_GetDeviceFromMountPoint(const char *mount) uffs_Device * uffs_GetDeviceFromMountPoint(const char *mount)
{ {
struct uffs_MountTableEntrySt *devTab = uffs_GetMountTable(); uffs_MountTable *mtb = uffs_GetMountTableByMountPoint(mount, m_head);
while (devTab) { if (mtb) {
if (strcmp(mount, devTab->mount) == 0) { mtb->dev->ref_count++;
devTab->dev->ref_count++; return mtb->dev;
return devTab->dev;
}
devTab = devTab->next;
} }
return NULL; return NULL;
...@@ -215,15 +324,14 @@ uffs_Device * uffs_GetDeviceFromMountPoint(const char *mount) ...@@ -215,15 +324,14 @@ uffs_Device * uffs_GetDeviceFromMountPoint(const char *mount)
*/ */
uffs_Device * uffs_GetDeviceFromMountPointEx(const char *mount, int len) uffs_Device * uffs_GetDeviceFromMountPointEx(const char *mount, int len)
{ {
struct uffs_MountTableEntrySt *devTab = uffs_GetMountTable(); uffs_MountTable *work = NULL;
while (devTab) { for (work = m_head; work; work = work->next) {
if (strlen(devTab->mount) == len && if (strlen(work->mount) == len &&
strncmp(mount, devTab->mount, len) == 0) { strncmp(mount, work->mount, len) == 0) {
devTab->dev->ref_count++; work->dev->ref_count++;
return devTab->dev; return work->dev;
} }
devTab = devTab->next;
} }
return NULL; return NULL;
...@@ -239,13 +347,12 @@ uffs_Device * uffs_GetDeviceFromMountPointEx(const char *mount, int len) ...@@ -239,13 +347,12 @@ uffs_Device * uffs_GetDeviceFromMountPointEx(const char *mount, int len)
*/ */
const char * uffs_GetDeviceMountPoint(uffs_Device *dev) const char * uffs_GetDeviceMountPoint(uffs_Device *dev)
{ {
struct uffs_MountTableEntrySt * devTab = uffs_GetMountTable(); uffs_MountTable *work = NULL;
while (devTab) { for (work = m_head; work; work = work->next) {
if (devTab->dev == dev) { if (work->dev == dev) {
return devTab->mount; return work->mount;
} }
devTab = devTab->next;
} }
return NULL; return NULL;
......
...@@ -138,11 +138,13 @@ static int init_uffs_fs(void) ...@@ -138,11 +138,13 @@ static int init_uffs_fs(void)
0, // bc_caches - default 0, // bc_caches - default
0, // page_buffers - default 0, // page_buffers - default
0, // dirty_pages - default 0, // dirty_pages - default
0, // dirty_groups - force 1 0, // dirty_groups - default
0, // reserved_free_blocks - default 0, // reserved_free_blocks - default
}; };
if(bIsFileSystemInited) return -4; if (bIsFileSystemInited)
return -4;
bIsFileSystemInited = 1; bIsFileSystemInited = 1;
while (mtbl->dev) { while (mtbl->dev) {
...@@ -157,13 +159,26 @@ static int init_uffs_fs(void) ...@@ -157,13 +159,26 @@ static int init_uffs_fs(void)
mtbl++; 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) static int release_uffs_fs(void)
{ {
int ret; int ret = 0;
ret = uffs_ReleaseMountTable(); 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; return ret;
} }
...@@ -357,6 +372,7 @@ static int parse_options(int argc, char *argv[]) ...@@ -357,6 +372,7 @@ static int parse_options(int argc, char *argv[])
} }
if (m_idx == 0) { if (m_idx == 0) {
// if not given mount information, use default ('/' for whole partition)
parse_mount_point("/,0,-1", 0); parse_mount_point("/,0,-1", 0);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册