patch-2.1.23 linux/fs/open.c

Next file: linux/fs/pipe.c
Previous file: linux/fs/nfs/rpcsock.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.22/linux/fs/open.c linux/fs/open.c
@@ -18,6 +18,8 @@
 #include <linux/time.h>
 #include <linux/mm.h>
 #include <linux/file.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
 #include <asm/bitops.h>
@@ -27,19 +29,24 @@
 	struct inode * inode;
 	int error;
 
+	lock_kernel();
 	error = verify_area(VERIFY_WRITE, buf, sizeof(struct statfs));
 	if (error)
-		return error;
+		goto out;
 	error = namei(path,&inode);
 	if (error)
-		return error;
+		goto out;
+	error = -ENOSYS;
 	if (!inode->i_sb->s_op->statfs) {
 		iput(inode);
-		return -ENOSYS;
+		goto out;
 	}
 	inode->i_sb->s_op->statfs(inode->i_sb, buf, sizeof(struct statfs));
 	iput(inode);
-	return 0;
+	error = 0;
+out:
+	unlock_kernel();
+	return error;
 }
 
 asmlinkage int sys_fstatfs(unsigned int fd, struct statfs * buf)
@@ -48,19 +55,23 @@
 	struct file * file;
 	int error;
 
+	lock_kernel();
 	error = verify_area(VERIFY_WRITE, buf, sizeof(struct statfs));
 	if (error)
-		return error;
+		goto out;
 	if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
-		return -EBADF;
-	if (!(inode = file->f_inode))
-		return -ENOENT;
-	if (!inode->i_sb)
-	        return -ENODEV;
-	if (!inode->i_sb->s_op->statfs)
-		return -ENOSYS;
-	inode->i_sb->s_op->statfs(inode->i_sb, buf, sizeof(struct statfs));
-	return 0;
+		error = -EBADF;
+	else if (!(inode = file->f_inode))
+		error = -ENOENT;
+	else if (!inode->i_sb)
+		error = -ENODEV;
+	else if (!inode->i_sb->s_op->statfs)
+		error = -ENOSYS;
+	else
+		inode->i_sb->s_op->statfs(inode->i_sb, buf, sizeof(struct statfs));
+out:
+	unlock_kernel();
+	return error;
 }
 
 int do_truncate(struct inode *inode, unsigned long length)
@@ -87,29 +98,30 @@
 	struct inode * inode;
 	int error;
 
+	lock_kernel();
 	error = namei(path,&inode);
 	if (error)
-		return error;
+		goto out;
 
 	error = -EACCES;
 	if (S_ISDIR(inode->i_mode))
-		goto out;
+		goto iput_and_out;
 
 	error = permission(inode,MAY_WRITE);
 	if (error)
-		goto out;
+		goto iput_and_out;
 
 	error = -EROFS;
 	if (IS_RDONLY(inode))
-		goto out;
+		goto iput_and_out;
 
 	error = -EPERM;
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-		goto out;
+		goto iput_and_out;
 
 	error = get_write_access(inode);
 	if (error)
-		goto out;
+		goto iput_and_out;
 
 	error = locks_verify_area(FLOCK_VERIFY_WRITE, inode, NULL,
 				  length < inode->i_size ? length : inode->i_size,
@@ -120,8 +132,10 @@
 		error = do_truncate(inode, length);
 	}
 	put_write_access(inode);
-out:
+iput_and_out:
 	iput(inode);
+out:
+	unlock_kernel();
 	return error;
 }
 
@@ -131,19 +145,23 @@
 	struct file * file;
 	int error;
 
+	lock_kernel();
 	if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
-		return -EBADF;
-	if (!(inode = file->f_inode))
-		return -ENOENT;
-	if (S_ISDIR(inode->i_mode) || !(file->f_mode & FMODE_WRITE))
-		return -EACCES;
-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-		return -EPERM;
-	error = locks_verify_area(FLOCK_VERIFY_WRITE, inode, file,
-				  length < inode->i_size ? length : inode->i_size,
-				  abs(inode->i_size - length));
-	if (!error)
-		error = do_truncate(inode, length);
+		error = -EBADF;
+	else if (!(inode = file->f_inode))
+		error = -ENOENT;
+	else if (S_ISDIR(inode->i_mode) || !(file->f_mode & FMODE_WRITE))
+		error = -EACCES;
+	else if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+		error = -EPERM;
+	else {
+		error = locks_verify_area(FLOCK_VERIFY_WRITE, inode, file,
+					  length<inode->i_size ? length : inode->i_size,
+					  abs(inode->i_size - length));
+		if (!error)
+			error = do_truncate(inode, length);
+	}
+	unlock_kernel();
 	return error;
 }
 
@@ -166,12 +184,14 @@
 	struct inode * inode;
 	struct iattr newattrs;
 
+	lock_kernel();
 	error = namei(filename,&inode);
 	if (error)
-		return error;
+		goto out;
+	error = -EROFS;
 	if (IS_RDONLY(inode)) {
 		iput(inode);
-		return -EROFS;
+		goto out;
 	}
 	/* Don't worry, the checks are done in inode_change_ok() */
 	newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
@@ -181,18 +201,20 @@
 			error = get_user(newattrs.ia_mtime, &times->modtime);
 		if (error) {
 			iput(inode);
-			return error;
+			goto out;
 		}
 		newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
 	} else {
 		if (current->fsuid != inode->i_uid &&
 		    (error = permission(inode,MAY_WRITE)) != 0) {
 			iput(inode);
-			return error;
+			goto out;
 		}
 	}
 	error = notify_change(inode, &newattrs);
 	iput(inode);
+out:
+	unlock_kernel();
 	return error;
 }
 
@@ -208,32 +230,32 @@
 	struct inode * inode;
 	struct iattr newattrs;
 
+	lock_kernel();
 	error = namei(filename,&inode);
 	if (error)
-		return error;
-	if (IS_RDONLY(inode)) {
-		iput(inode);
-		return -EROFS;
-	}
+		goto out;
+	error = -EROFS;
+	if (IS_RDONLY(inode))
+		goto iput_and_out;
 	/* Don't worry, the checks are done in inode_change_ok() */
 	newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
 	if (utimes) {
 		struct timeval times[2];
-		if (copy_from_user(&times, utimes, sizeof(times))) {
-			iput(inode);
-			return -EFAULT;
-		}		
+		error = -EFAULT;
+		if (copy_from_user(&times, utimes, sizeof(times)))
+			goto iput_and_out;
 		newattrs.ia_atime = times[0].tv_sec;
 		newattrs.ia_mtime = times[1].tv_sec;
 		newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
 	} else {
-		if ((error = permission(inode,MAY_WRITE)) != 0) {
-			iput(inode);
-			return error;
-		}
+		if ((error = permission(inode,MAY_WRITE)) != 0)
+			goto iput_and_out;
 	}
 	error = notify_change(inode, &newattrs);
+iput_and_out:
 	iput(inode);
+out:
+	unlock_kernel();
 	return error;
 }
 
@@ -245,10 +267,11 @@
 {
 	struct inode * inode;
 	int old_fsuid, old_fsgid;
-	int res;
+	int res = -EINVAL;
 
+	lock_kernel();
 	if (mode != (mode & S_IRWXO))	/* where's F_OK, X_OK, W_OK, R_OK? */
-		return -EINVAL;
+		goto out;
 	old_fsuid = current->fsuid;
 	old_fsgid = current->fsgid;
 	current->fsuid = current->uid;
@@ -260,6 +283,8 @@
 	}
 	current->fsuid = old_fsuid;
 	current->fsgid = old_fsgid;
+out:
+	unlock_kernel();
 	return res;
 }
 
@@ -268,40 +293,51 @@
 	struct inode * inode;
 	int error;
 
+	lock_kernel();
 	error = namei(filename,&inode);
 	if (error)
-		return error;
+		goto out;
+	error = -ENOTDIR;
 	if (!S_ISDIR(inode->i_mode)) {
 		iput(inode);
-		return -ENOTDIR;
+		goto out;
 	}
 	if ((error = permission(inode,MAY_EXEC)) != 0) {
 		iput(inode);
-		return error;
+		goto out;
 	}
 	iput(current->fs->pwd);
 	current->fs->pwd = inode;
-	return (0);
+	error = 0;
+out:
+	unlock_kernel();
+	return error;
 }
 
 asmlinkage int sys_fchdir(unsigned int fd)
 {
 	struct inode * inode;
 	struct file * file;
-	int error;
+	int error = -EBADF;
 
+	lock_kernel();
 	if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
-		return -EBADF;
+		goto out;
+	error = -ENOENT;
 	if (!(inode = file->f_inode))
-		return -ENOENT;
+		goto out;
+	error = -ENOTDIR;
 	if (!S_ISDIR(inode->i_mode))
-		return -ENOTDIR;
+		goto out;
 	if ((error = permission(inode,MAY_EXEC)) != 0)
-		return error;
+		goto out;
 	iput(current->fs->pwd);
 	current->fs->pwd = inode;
 	inode->i_count++;
-	return (0);
+	error = 0;
+out:
+	unlock_kernel();
+	return error;
 }
 
 asmlinkage int sys_chroot(const char * filename)
@@ -309,20 +345,26 @@
 	struct inode * inode;
 	int error;
 
+	lock_kernel();
 	error = namei(filename,&inode);
 	if (error)
-		return error;
+		goto out;
+	error = -ENOTDIR;
 	if (!S_ISDIR(inode->i_mode)) {
 		iput(inode);
-		return -ENOTDIR;
+		goto out;
 	}
+	error = -EPERM;
 	if (!fsuser()) {
 		iput(inode);
-		return -EPERM;
+		goto out;
 	}
 	iput(current->fs->root);
 	current->fs->root = inode;
-	return (0);
+	error = 0;
+out:
+	unlock_kernel();
+	return error;
 }
 
 asmlinkage int sys_fchmod(unsigned int fd, mode_t mode)
@@ -330,21 +372,29 @@
 	struct inode * inode;
 	struct file * file;
 	struct iattr newattrs;
+	int err = -EBADF;
 
+	lock_kernel();
 	if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
-		return -EBADF;
+		goto out;
+	err = -ENOENT;
 	if (!(inode = file->f_inode))
-		return -ENOENT;
+		goto out;
+	err = -EROFS;
 	if (IS_RDONLY(inode))
-		return -EROFS;
+		goto out;
+	err = -EPERM;
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-		return -EPERM;
+		goto out;
 	if (mode == (mode_t) -1)
 		mode = inode->i_mode;
 	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
 	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
 	inode->i_dirt = 1;
-	return notify_change(inode, &newattrs);
+	err = notify_change(inode, &newattrs);
+out:
+	unlock_kernel();
+	return err;
 }
 
 asmlinkage int sys_chmod(const char * filename, mode_t mode)
@@ -353,24 +403,26 @@
 	int error;
 	struct iattr newattrs;
 
+	lock_kernel();
 	error = namei(filename,&inode);
 	if (error)
-		return error;
-	if (IS_RDONLY(inode)) {
-		iput(inode);
-		return -EROFS;
-	}
-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
-		iput(inode);
-		return -EPERM;
-	}
+		goto out;
+	error = -EROFS;
+	if (IS_RDONLY(inode))
+		goto iput_and_out;
+	error = -EPERM;
+	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+		goto iput_and_out;
 	if (mode == (mode_t) -1)
 		mode = inode->i_mode;
 	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
 	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
 	inode->i_dirt = 1;
 	error = notify_change(inode, &newattrs);
+iput_and_out:
 	iput(inode);
+out:
+	unlock_kernel();
 	return error;
 }
 
@@ -379,16 +431,20 @@
 	struct inode * inode;
 	struct file * file;
 	struct iattr newattrs;
-	int error;
+	int error = -EBADF;
 
+	lock_kernel();
 	if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
-		return -EBADF;
+		goto out;
+	error = -ENOENT;
 	if (!(inode = file->f_inode))
-		return -ENOENT;
+		goto out;
+	error = -EROFS;
 	if (IS_RDONLY(inode))
-		return -EROFS;
+		goto out;
+	error = -EPERM;
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-		return -EPERM;
+		goto out;
 	if (user == (uid_t) -1)
 		user = inode->i_uid;
 	if (group == (gid_t) -1)
@@ -417,13 +473,16 @@
 	inode->i_dirt = 1;
 	if (inode->i_sb && inode->i_sb->dq_op) {
 		inode->i_sb->dq_op->initialize(inode, -1);
+		error = -EDQUOT;
 		if (inode->i_sb->dq_op->transfer(inode, &newattrs, 0))
-			return -EDQUOT;
+			goto out;
 		error = notify_change(inode, &newattrs);
 		if (error)
 			inode->i_sb->dq_op->transfer(inode, &newattrs, 1);
 	} else
 		error = notify_change(inode, &newattrs);
+out:
+	unlock_kernel();
 	return error;
 }
 
@@ -433,17 +492,16 @@
 	int error;
 	struct iattr newattrs;
 
+	lock_kernel();
 	error = lnamei(filename,&inode);
 	if (error)
-		return error;
-	if (IS_RDONLY(inode)) {
-		iput(inode);
-		return -EROFS;
-	}
-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
-		iput(inode);
-		return -EPERM;
-	}
+		goto out;
+	error = -EROFS;
+	if (IS_RDONLY(inode))
+		goto iput_and_out;
+	error = -EPERM;
+	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+		goto iput_and_out;
 	if (user == (uid_t) -1)
 		user = inode->i_uid;
 	if (group == (gid_t) -1)
@@ -472,14 +530,18 @@
 	inode->i_dirt = 1;
 	if (inode->i_sb->dq_op) {
 		inode->i_sb->dq_op->initialize(inode, -1);
+		error = -EDQUOT;
 		if (inode->i_sb->dq_op->transfer(inode, &newattrs, 0))
-			return -EDQUOT;
+			goto out;
 		error = notify_change(inode, &newattrs);
 		if (error)
 			inode->i_sb->dq_op->transfer(inode, &newattrs, 1);
 	} else
 		error = notify_change(inode, &newattrs);
+iput_and_out:
 	iput(inode);
+out:
+	unlock_kernel();
 	return(error);
 }
 
@@ -574,17 +636,24 @@
 	char * tmp;
 	int fd, error;
 
+	lock_kernel();
 	fd = get_unused_fd();
-	if (fd < 0)
-		return fd;
+	if (fd < 0) {
+		error = fd;
+		goto out;
+	}
 	error = getname(filename, &tmp);
 	if (!error) {
 		error = do_open(tmp,flags,mode, fd);
 		putname(tmp);
-		if (!error)
-			return fd;
+		if (!error) {
+			error = fd;
+			goto out;
+		}
 	}
 	put_unused_fd(fd);
+out:
+	unlock_kernel();
 	return error;
 }
 
@@ -596,7 +665,12 @@
  */
 asmlinkage int sys_creat(const char * pathname, int mode)
 {
-	return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
+	int ret;
+
+	lock_kernel();
+	ret = sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
+	unlock_kernel();
+	return ret;
 }
 
 #endif
@@ -632,6 +706,7 @@
 	struct file * filp;
 	struct files_struct * files;
 
+	lock_kernel();
 	files = current->files;
 	error = -EBADF;
 	if (fd < NR_OPEN && (filp = files->fd[fd]) != NULL) {
@@ -640,6 +715,7 @@
 		files->fd[fd] = NULL;
 		error = close_fp(filp);
 	}
+	unlock_kernel();
 	return error;
 }
 
@@ -649,10 +725,16 @@
  */
 asmlinkage int sys_vhangup(void)
 {
+	int ret = -EPERM;
+
+	lock_kernel();
 	if (!suser())
-		return -EPERM;
+		goto out;
 	/* If there is a controlling tty, hang it up */
 	if (current->tty)
 		tty_vhangup(current->tty);
-	return 0;
+	ret = 0;
+out:
+	unlock_kernel();
+	return ret;
 }

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