⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xsfscore.c

📁 一个操作系统,用C语言实现开发的,我在一个浙江大学的操作系统实验网站找到.大家学习以下
💻 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 + -