patch-2.1.23 linux/fs/super.c

Next file: linux/fs/sysv/dir.c
Previous file: linux/fs/stat.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.22/linux/fs/super.c linux/fs/super.c
@@ -30,6 +30,8 @@
 #include <linux/string.h>
 #include <linux/locks.h>
 #include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
 #include <linux/fd.h>
 
 #include <asm/system.h>
@@ -246,6 +248,7 @@
 	int retval = -EINVAL;
 	unsigned int index;
 
+	lock_kernel();
 	va_start(args, option);
 	switch (option) {
 		case 1:
@@ -262,6 +265,7 @@
 			break;
 	}
 	va_end(args);
+	unlock_kernel();
 	return retval;
 }
 
@@ -473,13 +477,15 @@
         struct ustat tmp;
         struct statfs sbuf;
         unsigned long old_fs;
+	int err = -EINVAL;
 
+	lock_kernel();
         s = get_super(to_kdev_t(dev));
         if (s == NULL)
-                return -EINVAL;
-
+                goto out;
+	err = -ENOSYS;
         if (!(s->s_op->statfs))
-                return -ENOSYS;
+                goto out;
 
         old_fs = get_fs();
         set_fs(get_ds());
@@ -490,7 +496,10 @@
         tmp.f_tfree = sbuf.f_bfree;
         tmp.f_tinode = sbuf.f_ffree;
 
-        return copy_to_user(ubuf,&tmp,sizeof(struct ustat)) ? -EFAULT : 0;
+        err = copy_to_user(ubuf,&tmp,sizeof(struct ustat)) ? -EFAULT : 0;
+out:
+	unlock_kernel();
+	return err;
 }
 
 static struct super_block * read_super(kdev_t dev,const char *name,int flags,
@@ -625,27 +634,30 @@
 {
 	struct inode * inode;
 	kdev_t dev;
-	int retval;
+	int retval = -EPERM;
 	struct inode dummy_inode;
 
+	lock_kernel();
 	if (!suser())
-		return -EPERM;
+		goto out;
 	retval = namei(name, &inode);
 	if (retval) {
 		retval = lnamei(name, &inode);
 		if (retval)
-			return retval;
+			goto out;
 	}
 	if (S_ISBLK(inode->i_mode)) {
 		dev = inode->i_rdev;
+		retval = -EACCES;
 		if (IS_NODEV(inode)) {
 			iput(inode);
-			return -EACCES;
+			goto out;
 		}
 	} else {
+		retval = -EINVAL;
 		if (!inode->i_sb || inode != inode->i_sb->s_mounted) {
 			iput(inode);
-			return -EINVAL;
+			goto out;
 		}
 		dev = inode->i_sb->s_dev;
 		iput(inode);
@@ -653,9 +665,10 @@
 		dummy_inode.i_rdev = dev;
 		inode = &dummy_inode;
 	}
+	retval = -ENXIO;
 	if (MAJOR(dev) >= MAX_BLKDEV) {
 		iput(inode);
-		return -ENXIO;
+		goto out;
 	}
 	retval = do_umount(dev,0);
 	if (!retval) {
@@ -667,10 +680,11 @@
 	}
 	if (inode != &dummy_inode)
 		iput(inode);
-	if (retval)
-		return retval;
-	fsync_dev(dev);
-	return 0;
+	if (!retval)
+		fsync_dev(dev);
+out:
+	unlock_kernel();
+	return retval;
 }
 
 /*
@@ -814,9 +828,9 @@
  * information (or be NULL).
  *
  * NOTE! As old versions of mount() didn't use this setup, the flags
- * has to have a special 16-bit magic number in the hight word:
+ * have to have a special 16-bit magic number in the high word:
  * 0xC0ED. If this magic word isn't present, the flags and data info
- * isn't used, as the syscall assumes we are talking to an older
+ * aren't used, as the syscall assumes we are talking to an older
  * version that didn't understand them.
  */
 asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
@@ -826,54 +840,60 @@
 	struct inode * inode;
 	struct file_operations * fops;
 	kdev_t dev;
-	int retval;
+	int retval = -EPERM;
 	const char * t;
 	unsigned long flags = 0;
 	unsigned long page = 0;
 
+	lock_kernel();
 	if (!suser())
-		return -EPERM;
+		goto out;
 	if ((new_flags &
 	     (MS_MGC_MSK | MS_REMOUNT)) == (MS_MGC_VAL | MS_REMOUNT)) {
 		retval = copy_mount_options (data, &page);
 		if (retval < 0)
-			return retval;
+			goto out;
 		retval = do_remount(dir_name,
 				    new_flags & ~MS_MGC_MSK & ~MS_REMOUNT,
 				    (char *) page);
 		free_page(page);
-		return retval;
+		goto out;
 	}
 	retval = copy_mount_options (type, &page);
 	if (retval < 0)
-		return retval;
+		goto out;
 	fstype = get_fs_type((char *) page);
 	free_page(page);
+	retval = -ENODEV;
 	if (!fstype)		
-		return -ENODEV;
+		goto out;
 	t = fstype->name;
 	fops = NULL;
 	if (fstype->requires_dev) {
 		retval = namei(dev_name, &inode);
 		if (retval)
-			return retval;
+			goto out;
+		retval = -ENOTBLK;
 		if (!S_ISBLK(inode->i_mode)) {
 			iput(inode);
-			return -ENOTBLK;
+			goto out;
 		}
+		retval = -EACCES;
 		if (IS_NODEV(inode)) {
 			iput(inode);
-			return -EACCES;
+			goto out;
 		}
 		dev = inode->i_rdev;
+		retval = -ENXIO;
 		if (MAJOR(dev) >= MAX_BLKDEV) {
 			iput(inode);
-			return -ENXIO;
+			goto out;
 		}
 		fops = get_blkfops(MAJOR(dev));
+		retval = -ENOTBLK;
 		if (!fops) {
 			iput(inode);
-			return -ENOTBLK;
+			goto out;
 		}
 		if (fops->open) {
 			struct file dummy;	/* allows read-write or read-only flag */
@@ -883,13 +903,14 @@
 			retval = fops->open(inode, &dummy);
 			if (retval) {
 				iput(inode);
-				return retval;
+				goto out;
 			}
 		}
 
 	} else {
+		retval = -EMFILE;
 		if (!(dev = get_unnamed_dev()))
-			return -EMFILE;
+			goto out;
 		inode = NULL;
 	}
 	page = 0;
@@ -899,7 +920,7 @@
 		if (retval < 0) {
 			put_unnamed_dev(dev);
 			iput(inode);
-			return retval;
+			goto out;
 		}
 	}
 	retval = do_mount(dev,dev_name,dir_name,t,flags,(void *) page);
@@ -909,6 +930,8 @@
 		put_unnamed_dev(dev);
 	}
 	iput(inode);
+out:
+	unlock_kernel();
 	return retval;
 }
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov