Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15535035
  • 博文数量: 2005
  • 博客积分: 11986
  • 博客等级: 上将
  • 技术积分: 22535
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-17 13:56
文章分类

全部博文(2005)

文章存档

2014年(2)

2013年(2)

2012年(16)

2011年(66)

2010年(368)

2009年(743)

2008年(491)

2007年(317)

分类: LINUX

2008-10-19 03:02:06

浅析sysfs文件系统注册流程

start_kernel
=>vfs_caches_init
=>mnt_init
=>sysfs_init

int __init sysfs_init(void)
{
    int err = -ENOMEM;
//创建存放slab对象的cache管理单元
    sysfs_dir_cachep = kmem_cache_create("sysfs_dir_cache",
                     sizeof(struct sysfs_dirent),
                     0, 0, NULL);
    if (!sysfs_dir_cachep)
        goto out;

    err = sysfs_inode_init();
    if (err)
        goto out_err;

    err = register_filesystem(&sysfs_fs_type);//注册sysfs文件系统控制信息
    if (!err) {
//那么将sysfs文件系统mount上来

//sysfs文件系统是一个排它式的文件系统,不论被mount多少次都只产生一个sb超级块,
//如果尝试再次mount,即尝试再次调用sysfs_get_sb获取另一个sb超级块,那么将执行atomic_inc(old->s_active);增加
//已被mount的引用计数,然后如果s已经执行了alloc_super,那么调用destroy_super将其销毁,然后返回这个已被mount了的
//super_block超级块old,这样就实现了sysfs文件系统
不论被mount多少次都只产生一个sb超级块的效果,所以取名为get_sb_single[luther.gliethttp]        sysfs_mount = kern_mount(&sysfs_fs_type);

//http://blog.chinaunix.net/u1/38994/showart_1328541.html

//请参考:《浅析kern_mount加载sysfs的流程》
        if (IS_ERR(sysfs_mount)) {
            printk(KERN_ERR "sysfs: could not mount!\n");
            err = PTR_ERR(sysfs_mount);
            sysfs_mount = NULL;
            unregister_filesystem(&sysfs_fs_type);
            goto out_err;
        }
    } else
        goto out_err;
out:
    return err;
out_err:
    kmem_cache_destroy(sysfs_dir_cachep);
    sysfs_dir_cachep = NULL;
    goto out;
}

static struct file_system_type sysfs_fs_type = {
    .name        = "sysfs",
    .get_sb        = sysfs_get_sb,
    .kill_sb    = kill_anon_super,
};
//所有注册登记的文件系统结构体都链接到一个以file_systems开头的单向链表中[luther.gliethttp]
int register_filesystem(struct file_system_type * fs)
{
    int res = 0;
    struct file_system_type ** p;

    BUG_ON(strchr(fs->name, '.'));
    if (fs->next)
        return -EBUSY;
    INIT_LIST_HEAD(&fs->fs_supers);
    write_lock(&file_systems_lock);
    p = find_filesystem(fs->name, strlen(fs->name));
    if (*p)//该文件系统已经存在了
        res = -EBUSY;
    else
        *p = fs;//将fs挂到这个以file_systems开头的单向链表上[luther.gliethttp]
    write_unlock(&file_systems_lock);
    return res;
}
//顺序扫描file_systems这个单向链表,查找名为name的文件系统是否已经注册
static struct file_system_type **find_filesystem(const char *name, unsigned len)
{
    struct file_system_type **p;
    for (p=&file_systems; *p; p=&(*p)->next)
        if (strlen((*p)->name) == len &&
         strncmp((*p)->name, name, len) == 0)
            break;
    return p;
}

阅读(1883) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~