patch-2.3.10 linux/fs/open.c

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

diff -u --recursive --new-file v2.3.9/linux/fs/open.c linux/fs/open.c
@@ -37,29 +37,21 @@
 asmlinkage int sys_fstatfs(unsigned int fd, struct statfs * buf)
 {
 	struct file * file;
-	struct inode * inode;
-	struct dentry * dentry;
 	struct super_block * sb;
 	int error;
 
-	lock_kernel();
 	error = -EBADF;
 	file = fget(fd);
 	if (!file)
 		goto out;
-	error = -ENOENT;
-	if (!(dentry = file->f_dentry))
-		goto out_putf;
-	if (!(inode = dentry->d_inode))
-		goto out_putf;
 	error = -ENODEV;
-	sb = inode->i_sb;
+	sb = file->f_dentry->d_inode->i_sb;
+	lock_kernel();
 	if (sb && sb->s_op && sb->s_op->statfs)
 		error = sb->s_op->statfs(sb, buf, sizeof(struct statfs));
-out_putf:
+	unlock_kernel();
 	fput(file);
 out:
-	unlock_kernel();
 	return error;
 }
 
@@ -143,7 +135,6 @@
 	struct file * file;
 	int error;
 
-	lock_kernel();
 	error = -EBADF;
 	file = fget(fd);
 	if (!file)
@@ -162,12 +153,13 @@
 	error = locks_verify_area(FLOCK_VERIFY_WRITE, inode, file,
 				  length<inode->i_size ? length : inode->i_size,
 				  abs(inode->i_size - length));
+	lock_kernel();
 	if (!error)
 		error = do_truncate(dentry, length);
+	unlock_kernel();
 out_putf:
 	fput(file);
 out:
-	unlock_kernel();
 	return error;
 }
 
@@ -361,8 +353,6 @@
 	struct inode *inode;
 	int error;
 
-	lock_kernel();
-
 	error = -EBADF;
 	file = fget(fd);
 	if (!file)
@@ -378,16 +368,17 @@
 	if (!S_ISDIR(inode->i_mode))
 		goto out_putf;
 
+	lock_kernel();
 	error = permission(inode, MAY_EXEC);
 	if (!error) {
 		struct dentry *tmp = current->fs->pwd;
 		current->fs->pwd = dget(dentry);
 		dput(tmp);
 	}
+	unlock_kernel();
 out_putf:
 	fput(file);
 out:
-	unlock_kernel();
 	return error;
 }
 
@@ -439,7 +430,6 @@
 	int err = -EBADF;
 	struct iattr newattrs;
 
-	lock_kernel();
 	file = fget(fd);
 	if (!file)
 		goto out;
@@ -460,12 +450,13 @@
 		mode = inode->i_mode;
 	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
 	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
+	lock_kernel();
 	err = notify_change(dentry, &newattrs);
+	unlock_kernel();
 
 out_putf:
 	fput(file);
 out:
-	unlock_kernel();
 	return err;
 }
 
@@ -601,17 +592,17 @@
 	struct file * file;
 	int error = -EBADF;
 
-	lock_kernel();
 	file = fget(fd);
 	if (!file)
 		goto out;
 	error = -ENOENT;
+	lock_kernel();
 	if ((dentry = file->f_dentry) != NULL)
 		error = chown_common(dentry, user, group);
+	unlock_kernel();
 	fput(file);
 
 out:
-	unlock_kernel();
 	return error;
 }
 
@@ -663,6 +654,8 @@
 	f->f_op = NULL;
 	if (inode->i_op)
 		f->f_op = inode->i_op->default_file_ops;
+	if (inode->i_sb)
+		file_move(f, &inode->i_sb->s_files);
 	if (f->f_op && f->f_op->open) {
 		error = f->f_op->open(inode,f);
 		if (error)
@@ -693,6 +686,8 @@
 	int fd, error;
 
 	error = -EMFILE;
+
+	write_lock(&files->file_lock);
 	fd = find_first_zero_bit(&files->open_fds, NR_OPEN);
 	/*
 	 * N.B. For clone tasks sharing a files structure, this test
@@ -715,12 +710,15 @@
 	error = fd;
 
 out:
+	write_unlock(&files->file_lock);
 	return error;
 }
 
 inline void put_unused_fd(unsigned int fd)
 {
+	write_lock(&current->files->file_lock);
 	FD_CLR(fd, &current->files->open_fds);
+	write_unlock(&current->files->file_lock);
 }
 
 asmlinkage int sys_open(const char * filename, int flags, int mode)
@@ -731,17 +729,18 @@
 	tmp = getname(filename);
 	fd = PTR_ERR(tmp);
 	if (!IS_ERR(tmp)) {
-		lock_kernel();
 		fd = get_unused_fd();
 		if (fd >= 0) {
-			struct file * f = filp_open(tmp, flags, mode);
+			struct file * f;
+			lock_kernel();
+			f = filp_open(tmp, flags, mode);
+			unlock_kernel();
 			error = PTR_ERR(f);
 			if (IS_ERR(f))
 				goto out_error;
 			fd_install(fd, f);
 		}
 out:
-		unlock_kernel();
 		putname(tmp);
 	}
 	return fd;
@@ -790,7 +789,7 @@
 	int retval;
 	struct dentry *dentry = filp->f_dentry;
 
-	if (!atomic_read(&filp->f_count)) {
+	if (!file_count(filp)) {
 		printk("VFS: Close: file count is 0\n");
 		return 0;
 	}
@@ -812,19 +811,24 @@
 {
 	int error;
 	struct file * filp;
+	struct files_struct * files = current->files;
 
-	lock_kernel();
 	error = -EBADF;
-	filp = fcheck(fd);
-	if (filp) {
-		struct files_struct * files = current->files;
-		files->fd[fd] = NULL;
-		put_unused_fd(fd);
-		FD_CLR(fd, &files->close_on_exec);
-		error = filp_close(filp, files);
-	}
+	write_lock(&files->file_lock);
+	filp = frip(fd);
+	if (!filp)
+		goto out_unlock;
+	FD_CLR(fd, &files->close_on_exec);
+	write_unlock(&files->file_lock);
+	put_unused_fd(fd);
+	lock_kernel();
+	error = filp_close(filp, files);
 	unlock_kernel();
+out:
 	return error;
+out_unlock:
+	write_unlock(&files->file_lock);
+	goto out;
 }
 
 /*
@@ -835,14 +839,14 @@
 {
 	int ret = -EPERM;
 
-	lock_kernel();
 	if (!capable(CAP_SYS_TTY_CONFIG))
 		goto out;
 	/* If there is a controlling tty, hang it up */
+	lock_kernel();
 	if (current->tty)
 		tty_vhangup(current->tty);
+	unlock_kernel();
 	ret = 0;
 out:
-	unlock_kernel();
 	return ret;
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)