您的位置:首页 > 运维架构 > Linux

linux下的简单文件系统(file system)

2013-12-17 00:37 357 查看
貌似这东西英文的网上一抓一大把,不过绝大部分都是基于2.4.x的内核的,而那么早的操作系统我没下载到。

于是就用手里3.11的ubuntu开始了写文件系统。

过程真是痛苦。。。。

为了不然后人继续为这个题目痛苦,所以有了这篇博客。

作为一个初学者,我的一些理解估计是有问题的,欢迎批评指正。

首先推荐几个地方:

http://lxr.free-electrons.com/source linux的源码,提供了查找变量函数的定义使用,以及不同版本之间的对比。
https://github.com/mkatiyar/testfs 一哥们写的vfs的源码,估计版本是2.4.x
http://www.geocities.ws/ravikiran_uvs/articles/rkfs-old.html 一个非常简单的vfs源码,也是2.4.x的源码

http://lxr.free-electrons.com/source/Documentation/filesystems/vfs.txt 官方文档

还有我在写vfs时参考的一本书《linux操作系统实验教程》罗 宇,等.电子工业出版社

我的环境:

Oracle VM VirtureBox---Linux 3.11(ubuntu)

准备工作:

了解super_block, super_operations, inode, inode_operations,file_operations,dentry_operations

详见推荐[4],以及可参考的中文版/article/2554169.html
注意磁盘上结构的组织

程序的组织流程:
//super.c
static int testfs_fill_super(struct super_block*sb, void *data, int silent)
{
...
extern int register_filesystem(struct file_system_type * testfs_type);
...
}


//super.c
static struct file_system_type testfs_type = {
.owner = THIS_MODULE,
.name  = "testfs",
.mount = testfs_mount,
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};


//super.c
struct dentry *testfs_mount(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data)
{
return mount_bdev(fs_type, flags, dev_name, data, testfs_fill_super);
}


//super.c
static int testfs_fill_super(struct super_block*sb, void *data, int silent)
{
...
sb->s_op= &testfs_sops;
root = testfs_iget(sb,TESTFS_ROOT_INODE(ts));
...
}


//super.c
static const struct super_operations testfs_sops = {
.alloc_inode   = testfs_alloc_inode,
.write_inode   = testfs_write_inode,
.destroy_inode = testfs_destroy_inode,
.put_super     = testfs_put_super,
};


//inode.c
struct inode *testfs_iget(struct super_block *sb, unsigned int ino){
...
if (S_ISREG(inode->i_mode)) {
inode->i_op = &testfs_file_inode_operations;
inode->i_fop = &testfs_file_operations;
} else if (S_ISDIR(inode->i_mode)) {
inode->i_op = &testfs_dir_inode_operations;
inode->i_fop = &testfs_dir_operations;
} else if (S_ISLNK(inode->i_mode)) {
inode->i_op = &testfs_symlink_inode_operations;
}
...
}


//dir.c
const struct file_operations testfs_dir_operations = {
.llseek = generic_file_llseek,
.read = generic_read_dir,
.iterate = testfs_iterate,
};


//namei.c
const struct inode_operations testfs_dir_inode_operations = {
.create = testfs_create,
.lookup = testfs_lookup,
.unlink = testfs_unlink,
.mkdir = testfs_mkdir,
.rmdir = testfs_rmdir,
.symlink = testfs_symlink,
.setattr = testfs_setattr,
.permission = testfs_permission,
};


//file.c
const struct inode_operations testfs_file_inode_operations = {
.setattr  = testfs_setattr,
.permission = testfs_permission,
};

const struct file_operations testfs_file_operations = {
.read = do_sync_read,
.write = do_sync_write,
.aio_read = generic_file_aio_read,
.aio_write = generic_file_aio_write,
.open = generic_file_open,
};


设备创建与删除

文件的挂载(当作设备)

#dd if=/dev/zero of=/tmpfile bs=1k count=200
#losetup /dev/loop0 /tmpfile
#losetup –d /dev/loop0


格式化设备(C实现)

1. 取得分区大小并打,开设备

2. 为各种数据开辟缓冲区

3. 处理超级块与根节点

a) 分配空闲索引节点;

b) 写入.与..两个目录项

4. 将缓冲内容写入文件

附效果图纪念~

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: