/* 文件系统学习笔记 */
注意 __s32 与 s32的区别和使用。
按照参考书的说法, 当kernel要把数据传递给user space的时候, 可以用__s32 ,而不要用s32,防止污染用户空间的名字空间。
而且在types.h 中, s32 是在定义了 __KERNEL__ 的情况下,才定义的,因此 s32才可以用在kernel和module中。
详细参考一下 semaphore.h (asm-i386)非常好, 好好研究一下:
再写一个module ,
关于什么时候,用信号量,什么时候, 用 lock ,
对具体操作独占的时候, 用信号量, 且实效性不是特别强,
对数据修改的时候, 很迫切, 用lock
对比下面两个例子:
/* We need to protect against concurrent writers.. */
down(&inode->i_sem); //不可中断, 相应还有可被信号中断的, down_interruptible()
ret = filemap_fdatasync(inode->i_mapping);
err = file->f_op->fsync(file, dentry, 0);
if (err && !ret)
ret = err;
err = filemap_fdatawait(inode->i_mapping);
if (err && !ret)
ret = err;
up(&inode->i_sem);
/*
* Check whether the specified fd has an open file.
*/
static inline struct file * fcheck(unsigned int fd)
{
struct file * file = NULL;
struct files_struct *files = current->files;
if (fd < files->max_fds) //max_fds 当前系统的文件描述符的最大数目
file = files->fd[fd];
return file;
}
struct file * fget(unsigned int fd)
{
struct file * file;
struct files_struct *files = current->files;
read_lock(&files->file_lock); //用读写锁的实例
file = fcheck(fd);
if (file)
get_file(file); // 文件对象引用计数增1
read_unlock(&files->file_lock);
return file;
}
×××: 当我们close一个文件的时候, 为什么会调用release()呢? 怎么实现的呢?
在这里:
void fput(struct file * file)
{
struct dentry * dentry = file->f_dentry;
struct vfsmount * mnt = file->f_vfsmnt;
struct inode * inode = dentry->d_inode;
if (atomic_dec_and_test(&file->f_count)) { //是不是应该加上 ==1 这项,否则,万一value=2呢澹恳惨猺elease吗澹烤筒欢粤税慑?
locks_remove_flock(file);
if (file->f_iobuf)
free_kiovec(1, &file->f_iobuf);
if (file->f_op && file->f_op->release) //这种顺序判断蛮好的,应该多用这种判断形式
file->f_op->release(inode, file);
fops_put(file->f_op);
if (file->f_mode & FMODE_WRITE)
put_write_access(inode);
file_list_lock();
file->f_dentry = NULL;
file->f_vfsmnt = NULL;
list_del(&file->f_list);
list_add(&file->f_list, &free_list);
files_stat.nr_free_files++;
file_list_unlock();
dput(dentry);
mntput(mnt);
}
}
无论在kernel中还是app中,这样的判断总是最好的:
if (file->f_op && file->f_op->release) //如果写后面,万一f_op是空的,就可能会有未知的问题发生了。
file->f_op->release(inode, file);
注意在文件系统数据结构方面 ,lock的重要性, 比如读写锁:
struct files_struct { //由系统的所有进程共享
//这样才能找到最到的那个已经分配的描述符
//接下来分配+1即可了
atomic_t count;
rwlock_t file_lock; /* Protects all the below members. Nests inside tsk->alloc_lock */
//rwlock_t permit multiple reader , but only one writer
int max_fds;
int max_fdset;
int next_fd;
struct file ** fd; /* current fd array */
fd_set *close_on_exec;
fd_set *open_fds;
fd_set close_on_exec_init;
fd_set open_fds_init;
struct file * fd_array[NR_OPEN_DEFAULT];
};
应用的时候, 如此:
read_lock(&files->file_lock);
/* 文件系统类型 */
/* file_system_type 类型的数据在kernel中组成了一个数组*/
struct file_system_type { //文件系统类型
const char *name;
int fs_flags;
struct super_block *(*read_super) (struct super_block *, void *, int); /* 负责填充内存中的超级块*/
struct module *owner;
struct file_system_type * next;
struct list_head fs_supers;
};
/* 定义文件系统操作函数 */ //gcc 扩展语法 , 可以这样给struct赋值
#define DECLARE_FSTYPE(var,type,read,flags)
struct file_system_type var = {
name: type,
read_super: read,
fs_flags: flags,
owner: THIS_MODULE,
}
super.c 含有大量的有用的跟文件系统有关的函数
kernel里面也用到zlib 函数(在cramfs中用到的)
/* mount 根文件系统 */
static void __init mount_root(void)
{
#ifdef CONFIG_ROOT_NFS
if (MAJOR(ROOT_DEV) == NFS_MAJOR
&& MINOR(ROOT_DEV) == NFS_MINOR) {
if (mount_nfs_root()) {
sys_chdir("/root");
ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
printk("VFS: Mounted root (nfs filesystem).
");
return;
}
printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.
");
ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
}
#endif
devfs_make_root(root_device_name);
create_dev("/dev/root", ROOT_DEV, root_device_name);
#ifdef CONFIG_BLK_DEV_FD
if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
/* rd_doload is 2 for a dual initrd/ramload setup */
if (rd_doload==2) {
if (rd_load_disk(1)) {
ROOT_DEV = MKDEV(RAMDISK_MAJOR, 1);
create_dev("/dev/root", ROOT_DEV, NULL);
}
} else
change_floppy("root floppy");
}
#endif
mount_block_root("/dev/root", root_mountflags);
}
/* 这里还就得用二重指针 */
static struct file_system_type **find_filesystem(const char *name)
{
struct file_system_type **p;
for (p=&file_systems; *p; p=&(*p)->next)
if (strcmp((*p)->name,name) == 0)
break;
return p;
}
static struct file_system_type *file_systems;
static rwlock_t file_systems_lock = RW_LOCK_UNLOCKED;
这里用到读写信号量:
在操纵链表的时候:加上信号量的保护:
write_lock(&file_systems_lock);
p = find_filesystem(fs->name); //
if (*p)
res = -EBUSY; //说明已经被注册了
else
*p = fs; //加在单链表的末尾
write_unlock(&file_systems_lock);
/* kernel经常使用的一种技巧:*/
static DECLARE_FSTYPE(ramfs_fs_type, "ramfs", ramfs_read_super, FS_LITTER);
static DECLARE_FSTYPE(rootfs_fs_type, "rootfs", ramfs_read_super, FS_NOMOUNT|FS_LITTER);
static int __init init_ramfs_fs(void)
{
return register_filesystem(&ramfs_fs_type);
}
在这种情况下, 在SourceInsight中, 无法找到ramfs_fs_type的定义, ^_^
/* 虚拟文件系统 安装点 的数据结构体 */
struct vfsmount
{
struct list_head mnt_hash;
struct vfsmount *mnt_parent; /* fs we are mounted on */
struct dentry *mnt_mountpoint; /* dentry of mountpoint */
struct dentry *mnt_root; /* root of the mounted tree */
struct super_block *mnt_sb; /* pointer to superblock */
struct list_head mnt_mou
阅读(1477) | 评论(0) | 转发(0) |