[patch-2.3.99-pre7-1] file_systems_lock refinement

From: Tigran Aivazian (tigran@veritas.com)
Date: Mon May 01 2000 - 15:00:33 EST


Hi Linus,

A long time ago I wanted to protect file_systems via rw spinlock but
didn't know what to do in mount_root() which could block. Now I see the
elegant solution someone (Al Viro?) invented by means of the
try_inc_mod_count(). But he used plain spinlocks instead of rw spinlocks
so I would like to bring back to life my version - see patch below.

The ordinary spinlocks are too coarse for this purpose - there is no need
for mutual exclusion between, say, a process calling sysfs(2) and a
process reading /proc/filesystems or two processes reading from
/proc/filesystems..

Regards,
Tigran

--- 2399/fs/super.c Sat Apr 29 16:06:34 2000
+++ linux/fs/super.c Mon May 1 20:25:56 2000
@@ -74,7 +74,7 @@
  */
 
 static struct file_system_type *file_systems = NULL;
-static spinlock_t file_systems_lock = SPIN_LOCK_UNLOCKED;
+static rwlock_t file_systems_lock = RW_LOCK_UNLOCKED;
 
 /* WARNING: This can be used only if we _already_ own a reference */
 static void get_filesystem(struct file_system_type *fs)
@@ -120,13 +120,13 @@
                 return -EINVAL;
         if (fs->next)
                 return -EBUSY;
- spin_lock(&file_systems_lock);
+ write_lock(&file_systems_lock);
         p = find_filesystem(fs->name);
         if (*p)
                 res = -EBUSY;
         else
                 *p = fs;
- spin_unlock(&file_systems_lock);
+ write_unlock(&file_systems_lock);
         return res;
 }
 
@@ -146,18 +146,18 @@
 {
         struct file_system_type ** tmp;
 
- spin_lock(&file_systems_lock);
+ write_lock(&file_systems_lock);
         tmp = &file_systems;
         while (*tmp) {
                 if (fs == *tmp) {
                         *tmp = fs->next;
                         fs->next = NULL;
- spin_unlock(&file_systems_lock);
+ write_unlock(&file_systems_lock);
                         return 0;
                 }
                 tmp = &(*tmp)->next;
         }
- spin_unlock(&file_systems_lock);
+ write_unlock(&file_systems_lock);
         return -EINVAL;
 }
 
@@ -173,14 +173,14 @@
                 return err;
 
         err = -EINVAL;
- spin_lock(&file_systems_lock);
+ read_lock(&file_systems_lock);
         for (tmp=file_systems, index=0 ; tmp ; tmp=tmp->next, index++) {
                 if (strcmp(tmp->name,name) == 0) {
                         err = index;
                         break;
                 }
         }
- spin_unlock(&file_systems_lock);
+ read_unlock(&file_systems_lock);
         putname(name);
         return err;
 }
@@ -190,11 +190,11 @@
         struct file_system_type * tmp;
         int len, res;
 
- spin_lock(&file_systems_lock);
+ read_lock(&file_systems_lock);
         for (tmp = file_systems; tmp; tmp = tmp->next, index--)
                 if (index <= 0 && try_inc_mod_count(tmp->owner))
                                 break;
- spin_unlock(&file_systems_lock);
+ read_unlock(&file_systems_lock);
         if (!tmp)
                 return -EINVAL;
 
@@ -210,10 +210,10 @@
         struct file_system_type * tmp;
         int index;
 
- spin_lock(&file_systems_lock);
+ read_lock(&file_systems_lock);
         for (tmp = file_systems, index = 0 ; tmp ; tmp = tmp->next, index++)
                 ;
- spin_unlock(&file_systems_lock);
+ read_unlock(&file_systems_lock);
         return index;
 }
 
@@ -245,7 +245,7 @@
         int len = 0;
         struct file_system_type * tmp;
 
- spin_lock(&file_systems_lock);
+ read_lock(&file_systems_lock);
         tmp = file_systems;
         while (tmp && len < PAGE_SIZE - 80) {
                 len += sprintf(buf+len, "%s\t%s\n",
@@ -253,7 +253,7 @@
                         tmp->name);
                 tmp = tmp->next;
         }
- spin_unlock(&file_systems_lock);
+ read_unlock(&file_systems_lock);
         return len;
 }
 
@@ -261,17 +261,17 @@
 {
         struct file_system_type *fs;
         
- spin_lock(&file_systems_lock);
+ read_lock(&file_systems_lock);
         fs = *(find_filesystem(name));
         if (fs && !try_inc_mod_count(fs->owner))
                 fs = NULL;
- spin_unlock(&file_systems_lock);
+ read_unlock(&file_systems_lock);
         if (!fs && (request_module(name) == 0)) {
- spin_lock(&file_systems_lock);
+ read_lock(&file_systems_lock);
                 fs = *(find_filesystem(name));
                 if (fs && !try_inc_mod_count(fs->owner))
                         fs = NULL;
- spin_unlock(&file_systems_lock);
+ read_unlock(&file_systems_lock);
         }
         return fs;
 }
@@ -1369,22 +1369,21 @@
                 goto mount_it;
         }
 
- spin_lock(&file_systems_lock);
+ read_lock(&file_systems_lock);
         for (fs_type = file_systems ; fs_type ; fs_type = fs_type->next) {
                   if (!(fs_type->fs_flags & FS_REQUIRES_DEV))
                           continue;
                 if (!try_inc_mod_count(fs_type->owner))
                         continue;
- spin_unlock(&file_systems_lock);
+ read_unlock(&file_systems_lock);
                   sb = read_super(ROOT_DEV,bdev,fs_type,root_mountflags,NULL,1);
                 if (sb)
                         goto mount_it;
- spin_lock(&file_systems_lock);
+ read_lock(&file_systems_lock);
                 put_filesystem(fs_type);
         }
- spin_unlock(&file_systems_lock);
- panic("VFS: Unable to mount root fs on %s",
- kdevname(ROOT_DEV));
+ read_unlock(&file_systems_lock);
+ panic("VFS: Unable to mount root fs on %s", kdevname(ROOT_DEV));
 
 mount_it:
         printk ("VFS: Mounted root (%s filesystem)%s.\n",

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sun May 07 2000 - 21:00:09 EST