--- linux-2.5.52/include/linux/fs.h 2002-12-15 18:07:50.000000000 -0800 +++ linux/include/linux/fs.h 2002-12-23 07:00:02.000000000 -0800 @@ -19,6 +19,7 @@ #include #include #include +#include #include struct iovec; @@ -953,7 +954,8 @@ int fs_flags; struct super_block *(*get_sb) (struct file_system_type *, int, char *, void *); void (*kill_sb) (struct super_block *); - struct module *owner; + struct module *owner; /* Will be subsumed into mod_rwsem. */ + struct module_rwsem mod_rwsem; struct file_system_type * next; struct list_head fs_supers; }; --- linux-2.5.52/fs/filesystems.c 2002-12-15 18:08:14.000000000 -0800 +++ linux/fs/filesystems.c 2002-12-23 06:56:40.000000000 -0800 @@ -26,7 +26,7 @@ */ static struct file_system_type *file_systems; -static rwlock_t file_systems_lock = RW_LOCK_UNLOCKED; +static DECLARE_RWSEM(file_systems_rwsem); /* WARNING: This can be used only if we _already_ own a reference */ void get_filesystem(struct file_system_type *fs) @@ -81,13 +81,17 @@ if (fs->next) return -EBUSY; INIT_LIST_HEAD(&fs->fs_supers); - write_lock(&file_systems_lock); + down_write(&file_systems_rwsem); p = find_filesystem(fs->name); if (*p) res = -EBUSY; - else + else { *p = fs; - write_unlock(&file_systems_lock); + fs->mod_rwsem.module = fs->owner; + fs->mod_rwsem.rwsem = &file_systems_rwsem; + register_module_rwsem(&fs->mod_rwsem); + } + up_write(&file_systems_rwsem); return res; } @@ -107,18 +111,18 @@ { struct file_system_type ** tmp; - write_lock(&file_systems_lock); + /* sys_delete_module has already done a + down_write(&file_systems_rwsem) for us. */ tmp = &file_systems; while (*tmp) { if (fs == *tmp) { *tmp = fs->next; fs->next = NULL; - write_unlock(&file_systems_lock); + up_write(&file_systems_rwsem); return 0; } tmp = &(*tmp)->next; } - write_unlock(&file_systems_lock); return -EINVAL; } @@ -134,14 +138,14 @@ return err; err = -EINVAL; - read_lock(&file_systems_lock); + down_read(&file_systems_rwsem); for (tmp=file_systems, index=0 ; tmp ; tmp=tmp->next, index++) { if (strcmp(tmp->name,name) == 0) { err = index; break; } } - read_unlock(&file_systems_lock); + up_read(&file_systems_rwsem); putname(name); return err; } @@ -151,11 +155,11 @@ struct file_system_type * tmp; int len, res; - read_lock(&file_systems_lock); + down_read(&file_systems_rwsem); for (tmp = file_systems; tmp; tmp = tmp->next, index--) if (index <= 0 && try_inc_mod_count(tmp->owner)) break; - read_unlock(&file_systems_lock); + up_read(&file_systems_rwsem); if (!tmp) return -EINVAL; @@ -171,10 +175,10 @@ struct file_system_type * tmp; int index; - read_lock(&file_systems_lock); + down_read(&file_systems_rwsem); for (tmp = file_systems, index = 0 ; tmp ; tmp = tmp->next, index++) ; - read_unlock(&file_systems_lock); + up_read(&file_systems_rwsem); return index; } @@ -206,7 +210,7 @@ int len = 0; struct file_system_type * tmp; - read_lock(&file_systems_lock); + down_read(&file_systems_rwsem); tmp = file_systems; while (tmp && len < PAGE_SIZE - 80) { len += sprintf(buf+len, "%s\t%s\n", @@ -214,7 +218,7 @@ tmp->name); tmp = tmp->next; } - read_unlock(&file_systems_lock); + up_read(&file_systems_rwsem); return len; } @@ -222,17 +226,17 @@ { struct file_system_type *fs; - read_lock(&file_systems_lock); + down_read(&file_systems_rwsem); fs = *(find_filesystem(name)); if (fs && !try_inc_mod_count(fs->owner)) fs = NULL; - read_unlock(&file_systems_lock); + up_read(&file_systems_rwsem); if (!fs && (request_module(name) == 0)) { - read_lock(&file_systems_lock); + down_read(&file_systems_rwsem); fs = *(find_filesystem(name)); if (fs && !try_inc_mod_count(fs->owner)) fs = NULL; - read_unlock(&file_systems_lock); + up_read(&file_systems_rwsem); } return fs; }