📄 xsfscore.c
字号:
// eXtendable Stream-based File System
// Kernel component
#include <string.h>
#include <memory.h>
#include <vfs.h>
#include <knllib.h>
#include <knlcon.h>
#include "vfsio.h"
#include "xsfs.h"
#include "xsfsbase.h"
#include "xsfsstream.h"
#include "xsfstree.h"
typedef struct _XSFSDEV
{
XSFS xsfs;
VFSIODEF io;
XSSTREAM root_stream;
XSFSROOT root;
} XSFSDEV;
typedef struct _XSFSMNODE
{
_u32 flags;
_u32 unit;
int index;
XSFSNODE node;
XSSTREAM stream;
} XSFSMNODE;
// XSFSMNODE flags
#define MNF_STREAM 0x00000001
static long on_create_dev(FSDEVICE *fsdev, _u32 param)
{
XSFSIMAGE image;
char *buf = NULL;
XSFSDEV* xsdev = (XSFSDEV*)fsnGetDevExtraMem(fsdev);
long ret = fsioOpenHandle(&xsdev->io, param);
if(!DEVICE_OK(ret)) return ret;
xsdev->xsfs.handle = &xsdev->io;
// now load file system information
// buf for one sector
if(!(buf = kmalloc(xsdev->io.sector_size, 0)))
{ ret = DEVICE_MAKEERR(DEVERR_MEMORY); goto L_create_exit; }
// the boot sector
if(fsioRead(&xsdev->io, 0, buf, 1)!=1)
{ ret = DEVICE_MAKEERR(DEVERR_INTERNAL); goto L_create_exit; }
// check signature
memcpy(&image, buf, sizeof(image));
if(strncmp(image.signature, "XSFS", 4)!=0)
{ ret = DEVICE_MAKEERR(DEVERR_INVALID); goto L_create_exit; }
// allocate buffer
memcpy(&xsdev->xsfs.desc, &image.descriptor, sizeof(XSFSDESC));
xsdev->xsfs.buffer = kmalloc(i_xsfs_unit_size(&xsdev->xsfs), 0);
if(!xsdev->xsfs.buffer)
{ ret = DEVICE_MAKEERR(DEVERR_MEMORY); goto L_create_exit; }
// load root stream
if(!xsfsLoadRoot(&xsdev->xsfs, &xsdev->root_stream, &xsdev->root))
{ ret = DEVICE_MAKEERR(DEVERR_NOTEXIST); goto L_create_exit; }
L_create_exit:
if(buf) kfree(buf);
if(!DEVICE_OK(ret))
{
if(fsioIsHandleValid(xsdev->xsfs.handle))
fsioClose(xsdev->xsfs.handle);
if(xsdev->xsfs.buffer)
{ kfree(xsdev->xsfs.buffer); xsdev->xsfs.buffer = NULL; }
}
return ret;
}
static long on_destroy_dev(FSDEVICE *fsdev)
{
XSFSDEV* xsdev = (XSFSDEV*)fsnGetDevExtraMem(fsdev);
if(xsdev->xsfs.buffer)
{ kfree(xsdev->xsfs.buffer); xsdev->xsfs.buffer = NULL; }
fsioClose(xsdev->xsfs.handle);
return 0;
}
static long on_new_node(FSDEVICE *fsdev, FSNODE *fsnode)
{
XSFSDEV *xsdev = (XSFSDEV*)fsnGetDevExtraMem(fsdev);
XSFSMNODE *mnode = (XSFSMNODE*)fsnGetExtraMem(fsnode);
_u32 start_unit;
if(!fsnode->parent || (fsnode->parent->flags&FSF_MOUNTED)
|| fsnode->parent->fsdev!=fsdev) // start from root
{
//KTRACE("XSFS: Get start_unit from root\n");
start_unit = xsdev->root.root.child_unit;
}
else start_unit = ((XSFSMNODE*)fsnGetExtraMem(fsnode->parent))->node.child_unit;
//KTRACE2("XSFS: on_new_node(\"%s\") start_unit = %u\n", fsnode->name, start_unit);
if(!start_unit) return DEVICE_MAKEERR(DEVERR_NOTEXIST);
//KTRACE1("XSFS: looking for node %s\n", fsnode->name);
mnode->unit = xsfsFindNode(&xsdev->xsfs, start_unit, fsnode->name, &mnode->node, &mnode->index);
//KTRACE2("XSFS: node %s %s\n", fsnode->name, mnode->unit?"found":"not found");
if(!mnode->unit) return DEVICE_MAKEERR(DEVERR_NOTEXIST);
//KTRACE1("XSFS: loading stream of node %s\n", fsnode->name);
if(!xsfsLoadDataStream(&xsdev->root_stream, &xsdev->root, mnode->node.data_entry, FSI_DEFAULT, &mnode->stream))
mnode->flags&=~MNF_STREAM;
else mnode->flags|=MNF_STREAM;
// file object should have a stream
if((mnode->node.flags&NF_TYPEMASK)==NF_TYPE_FILE && !(mnode->flags&MNF_STREAM))
return DEVICE_MAKEERR(DEVERR_NOTEXIST);
// check object type
switch(mnode->node.flags&NF_TYPEMASK)
{
case NF_TYPE_LABEL: fsnode->type = FST_LABEL; break;
case NF_TYPE_FILE: fsnode->type = FST_FILE; break;
case NF_TYPE_DIR: fsnode->type = FST_DIRECTORY; break;
case NF_TYPE_HARDLN: fsnode->type = FST_FILE; break;
case NF_TYPE_SYMLN: fsnode->type = FST_LINK; break;
default: fsnode->type = 0;
}
//KTRACE2("XSFS: on_new_node(\"%s\") fsnode->type = %x\n", fsnode->name, fsnode->type);
return 0;
}
static long __syscall fs_xsfs_dev_proc(_u32 cmd, FSDEVICE *fsdev, _u32 param)
{
switch(cmd)
{
case FSDEV_CREATE: return on_create_dev(fsdev, param);
case FSDEV_DESTROY: return on_destroy_dev(fsdev);
case FSDEV_NEWNODE: return on_new_node(fsdev, (FSNODE*)param);
case FSDEV_FREENODE: break;
case FSDEV_LOADNODE:
case FSDEV_UNLOADNODE:
case FSDEV_MOUNT:
case FSDEV_UNMOUNT: break;
default:
return DEVICE_MAKEERR(DEVERR_BADCMD);
}
return 0;
}
static void xsfs_dev_io(int rw, FSDEVICE *fsdev, FSNODE *fsnode, _u64 *cur_pos, void *buf, int len, int *trans_len)
{
XSFSMNODE *mnode = (XSFSMNODE*)fsnGetExtraMem(fsnode);
*trans_len = rw ? xsfsWriteStream(&mnode->stream, *cur_pos, buf, len)
: xsfsReadStream(&mnode->stream, *cur_pos, buf, len);
*cur_pos+=*trans_len;
}
static long __syscall fs_xsfs_dev_read(FSDEVICE *fsdev, FSNODE *fsnode, _u64 *cur_pos, void *buf, int len, int *trans_len)
{
xsfs_dev_io(0, fsdev, fsnode, cur_pos, buf, len, trans_len);
return 0;
}
static long __syscall fs_xsfs_dev_write(FSDEVICE *fsdev, FSNODE *fsnode, _u64 *cur_pos, void *buf, int len, int *trans_len)
{
xsfs_dev_io(1, fsdev, fsnode, cur_pos, buf, len, trans_len);
return 0;
}
static long __syscall fs_xsfs_dev_seek(FSDEVICE *fsdev, FSNODE *fsnode, _u64 *cur_pos, _s64 pos, int mode)
{
return 0;
}
static long __syscall fs_xsfs_dev_ioctrl(FSDEVICE *fsdev, FSNODE *fsnode, _u32 cmd, void *in_buf, _u32 in_len,
void *out_buf, _u32 out_len, _u32 *trans_len)
{
return DEVICE_MAKEERR(DEVERR_BADCMD);
}
static long __syscall fs_xsfs_drv_proc(_u32 cmd, _u32 param1, _u32 param2)
{
switch(cmd)
{
case FSDRV_LOAD:
((FSDRIVER*)param1)->extra = sizeof(XSFSDEV);
break;
case FSDRV_UNLOAD: break;
case FSDRV_NEWDEVICE:
((FSDEVICE*)param1)->proc = (VFSPROC)fs_xsfs_dev_proc;
((FSDEVICE*)param1)->ioctrl = fs_xsfs_dev_ioctrl;
((FSDEVICE*)param1)->read = fs_xsfs_dev_read;
((FSDEVICE*)param1)->write = fs_xsfs_dev_write;
((FSDEVICE*)param1)->seek = fs_xsfs_dev_seek;
((FSDEVICE*)param1)->node_extra = sizeof(XSFSMNODE);
break;
default:
return DEVICE_MAKEERR(DEVERR_BADCMD);
}
return 0;
}
HFSDRV fsInitXSFS(void)
{
return RegisterFileSystem("XSFS", fs_xsfs_drv_proc);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -