提交 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)
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;
}
......
......@@ -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[])
......
......@@ -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);
......
......@@ -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
......
......@@ -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 */
......
......@@ -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;
}
}
......
......@@ -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;
......
......@@ -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;
......
......@@ -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)
......
......@@ -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;
}
......@@ -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;
for (work = m_free_head; work; work = work->next) {
if (work == mtb)
return 0; // already registered.
}
/* 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;
}
/**
* \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();
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;
}
uffs_MountTable *mtb;
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;
}
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, "mount partiton: %d,%d",
work->dev->par.start, work->dev->par.end);
uffs_Perror(UFFS_MSG_NOISY,
"init device for mount point %s ...",
mtb->mount);
if (uffs_InitDevice(work->dev) != U_SUCC) {
uffs_Perror(UFFS_MSG_SERIOUS, "init device fail !");
return U_FAIL;
}
work->dev->dev_num = dev_num++;
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 (uffs_InitObjectBuf() == U_SUCC) {
if (uffs_DirEntryBufInit() == U_SUCC) {
uffs_InitGlobalFsLock();
return U_SUCC;
}
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;
}
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();
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;
......
......@@ -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);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册