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元素来理解。
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元素来理解。
相关文章推荐
- Linux 内核使用register_filesystem添加自定义文件系统deanfs
- 内核文件系统API之register_filesystem和unregister_filesystem
- Linux 创建文件系统及挂载文件系统流程详解
- Linux 创建文件系统及挂载文件系统流程详解
- Linux操作系统文件系统基础知识详解
- Linux创建文件系统及挂载文件系统流程详解
- Linux系统网络服务配置文件详解
- Filesystem之Linux系统文件命令精通指南(上)
- Linux操作系统文件系统基础知识详解
- Linux操作系统文件系统基础详解
- Linux 创建文件系统及挂载文件系统流程详解
- Linux 磁盘命令及挂载文件系统流程详解
- Linux操作系统文件系统基础知识详解
- Linux创建文件系统及挂载文件系统流程详解
- Linux 创建文件系统及挂载文件系统详解二
- 文件系统管理 之 Linux 创建文件系统及挂载文件系统流程详解
- Linux 创建文件系统及挂载文件系统流程详解
- Linux 创建文件系统及挂载文件系统流程详解
- Linux操作系统文件系统基础知识详解
- 构建arm linux 的根文件系统 root filesystem