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

Linux 文件系统注册register_filesystem与注销unregister_filesystem源码详解

2017-06-08 16:21 525 查看
参考:  http://blog.csdn.net/gxfan/article/details/3079766

             http://bbs.chinaunix.net/thread-4103398-1-1.html  

在linux内核中,每一种注册了的文件系统都由一个类型为file_system_type的结构体来代表,该结构体中含有一个类型为file_system_type*的域next,linux正是通过这个next域把所有注册了的文件系统连接起来的,同时,linux内核还定义了一个指向链表中第一个元素的全局指针file_systems和一个用来用来防止并发访问该链表的读/写自旋锁file_systems_lock。

//查找file_systems中指定name的文件系统类型是否存在,若在,则返回指针,否则返回file_systems末尾的next指针

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;

}

/**

*        register_filesystem - register a new filesystem

*        @fs: the file system structure

*

*        Adds the file system passed to the list of file systems the kernel

*        is aware of for mount and other syscalls. Returns 0 on success,

*        or a negative errno code on an error.

*

*        The &struct file_system_type that is passed is linked into the kernel

*        structures and must not be freed until the file system has been

*        unregistered.

*/

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;                              //将filesystem静态变量指向fs

        write_unlock(&file_systems_lock); //解锁

        return res;

}

//------------------------------------------------------

static inline void INIT_LIST_HEAD(struct list_head *list)

{

        list->next = list;

        list->prev = list;

}

//------------------------------------------------------

EXPORT_SYMBOL(register_filesystem);

/**

*        unregister_filesystem - unregister a file system

*        @fs: filesystem to unregister

*

*        Remove a file system that was previously successfully registered

*        with the kernel. An error is returned if the file system is not found.

*        Zero is returned on a success.

*

*        Once this function has returned the &struct file_system_type structure

*        may be freed or reused.

*/

int unregister_filesystem(struct file_system_type * fs)

{

        struct file_system_type ** tmp;

        write_lock(&file_systems_lock);

        tmp = &file_systems;

        while (*tmp) {                                              //对比上面的代码,这里将注册了的文件系统类型从list中移除

                if (fs == *tmp) {

                        *tmp = fs->next;

                        fs->next = NULL;

                        write_unlock(&file_systems_lock);

                        return 0;

                }

                tmp = &(*tmp)->next;

        }

        write_unlock(&file_systems_lock);

        synchronize_rcu();

        return -EINVAL;

}

EXPORT_SYMBOL(unregister_filesystem)

    整个算法的关键部分就在于:申请的临时指针变量不是直接指向单链表中的结构体的,而是指向的“指向结构体的指针”,这些“指向结构体的指针”包括:指向单链表第一个元素的指针以及每一个结构体中的next变量。这里我们可以把指向单链表第一个元素的指针file_systems看成一个特殊的next元素来理解。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: