From: Tamir <carmeli.tamir@xxxxxxxxx> Changed file_system_type next field to list_head and refactored the code to use list.h functions. Signed-off-by: Carmeli Tamir <carmeli.tamir@xxxxxxxxx> --- fs/filesystems.c | 68 ++++++++++++++++++++++++---------------------- include/linux/fs.h | 2 +- 2 files changed, 36 insertions(+), 34 deletions(-) diff --git a/fs/filesystems.c b/fs/filesystems.c index 9135646e41ac..f12b98f2f079 100644 --- a/fs/filesystems.c +++ b/fs/filesystems.c @@ -31,7 +31,7 @@ * Once the reference is obtained we can drop the spinlock. */ -static struct file_system_type *file_systems; +static LIST_HEAD(file_systems); static DEFINE_RWLOCK(file_systems_lock); /* WARNING: This can be used only if we _already_ own a reference */ @@ -46,14 +46,16 @@ void put_filesystem(struct file_system_type *fs) module_put(fs->owner); } -static struct file_system_type **find_filesystem(const char *name, unsigned len) +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 (strncmp((*p)->name, name, len) == 0 && - !(*p)->name[len]) - break; - return p; + struct file_system_type *p; + + list_for_each_entry(p, &file_systems, fs_types) { + if (strncmp(p->name, name, len) == 0 && + !p->name[len]) + return p; + } + return NULL; } /** @@ -72,20 +74,21 @@ static struct file_system_type **find_filesystem(const char *name, unsigned len) int register_filesystem(struct file_system_type * fs) { int res = 0; - struct file_system_type ** p; + struct file_system_type *p; if (fs->parameters && !fs_validate_description(fs->parameters)) return -EINVAL; BUG_ON(strchr(fs->name, '.')); - if (fs->next) - return -EBUSY; + + INIT_LIST_HEAD(&fs->fs_types); + write_lock(&file_systems_lock); p = find_filesystem(fs->name, strlen(fs->name)); - if (*p) + if (p) res = -EBUSY; else - *p = fs; + list_add_tail(&fs->fs_types, &file_systems); write_unlock(&file_systems_lock); return res; } @@ -106,19 +109,16 @@ EXPORT_SYMBOL(register_filesystem); int unregister_filesystem(struct file_system_type * fs) { - struct file_system_type ** tmp; + struct file_system_type *tmp; write_lock(&file_systems_lock); - tmp = &file_systems; - while (*tmp) { - if (fs == *tmp) { - *tmp = fs->next; - fs->next = NULL; + list_for_each_entry(tmp, &file_systems, fs_types) { + if (fs == tmp) { + list_del(&tmp->fs_types); write_unlock(&file_systems_lock); synchronize_rcu(); return 0; } - tmp = &(*tmp)->next; } write_unlock(&file_systems_lock); @@ -141,7 +141,8 @@ static int fs_index(const char __user * __name) err = -EINVAL; read_lock(&file_systems_lock); - for (tmp=file_systems, index=0 ; tmp ; tmp=tmp->next, index++) { + list_for_each_entry(tmp, &file_systems, fs_types) { + index++; if (strcmp(tmp->name, name->name) == 0) { err = index; break; @@ -158,9 +159,11 @@ static int fs_name(unsigned int index, char __user * buf) int len, res; read_lock(&file_systems_lock); - for (tmp = file_systems; tmp; tmp = tmp->next, index--) + list_for_each_entry(tmp, &file_systems, fs_types) { + index--; if (index <= 0 && try_module_get(tmp->owner)) break; + } read_unlock(&file_systems_lock); if (!tmp) return -EINVAL; @@ -174,12 +177,13 @@ static int fs_name(unsigned int index, char __user * buf) static int fs_maxindex(void) { - struct file_system_type * tmp; - int index; + struct list_head *pos; + int index = 0; read_lock(&file_systems_lock); - for (tmp = file_systems, index = 0 ; tmp ; tmp = tmp->next, index++) - ; + list_for_each(pos, &file_systems) { + index++; + } read_unlock(&file_systems_lock); return index; } @@ -214,12 +218,12 @@ int __init get_filesystem_list(char *buf) struct file_system_type * tmp; read_lock(&file_systems_lock); - tmp = file_systems; - while (tmp && len < PAGE_SIZE - 80) { + list_for_each_entry(tmp, &file_systems, fs_types) { + if (len >= PAGE_SIZE - 80) + break; len += sprintf(buf+len, "%s\t%s\n", (tmp->fs_flags & FS_REQUIRES_DEV) ? "" : "nodev", tmp->name); - tmp = tmp->next; } read_unlock(&file_systems_lock); return len; @@ -231,12 +235,10 @@ static int filesystems_proc_show(struct seq_file *m, void *v) struct file_system_type * tmp; read_lock(&file_systems_lock); - tmp = file_systems; - while (tmp) { + list_for_each_entry(tmp, &file_systems, fs_types) { seq_printf(m, "%s\t%s\n", (tmp->fs_flags & FS_REQUIRES_DEV) ? "" : "nodev", tmp->name); - tmp = tmp->next; } read_unlock(&file_systems_lock); return 0; @@ -255,7 +257,7 @@ static struct file_system_type *__get_fs_type(const char *name, int len) struct file_system_type *fs; read_lock(&file_systems_lock); - fs = *(find_filesystem(name, len)); + fs = find_filesystem(name, len); if (fs && !try_module_get(fs->owner)) fs = NULL; read_unlock(&file_systems_lock); diff --git a/include/linux/fs.h b/include/linux/fs.h index dd28e7679089..833ada15bc8a 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2182,7 +2182,7 @@ struct file_system_type { const char *, void *); void (*kill_sb) (struct super_block *); struct module *owner; - struct file_system_type * next; + struct list_head fs_types; /* All registered file_system_type structs */ struct hlist_head fs_supers; struct lock_class_key s_lock_key; -- 2.19.1