patch-2.1.89 linux/fs/read_write.c

Next file: linux/fs/readdir.c
Previous file: linux/fs/proc/link.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.88/linux/fs/read_write.c linux/fs/read_write.c
@@ -62,14 +62,18 @@
 
 	lock_kernel();
 	retval = -EBADF;
-	if (fd >= NR_OPEN ||
-	    !(file = current->files->fd[fd]) ||
-	    !(dentry = file->f_dentry) ||
-	    !(inode = dentry->d_inode))
+	file = fget(fd);
+	if (!file)
 		goto bad;
+	/* N.B. Shouldn't this be ENOENT?? */
+	if (!(dentry = file->f_dentry) ||
+	    !(inode = dentry->d_inode))
+		goto out_putf;
 	retval = -EINVAL;
 	if (origin <= 2)
 		retval = llseek(file, offset, origin);
+out_putf:
+	fput(file);
 bad:
 	unlock_kernel();
 	return retval;
@@ -88,24 +92,28 @@
 
 	lock_kernel();
 	retval = -EBADF;
-	if (fd >= NR_OPEN ||
-	    !(file = current->files->fd[fd]) ||
-	    !(dentry = file->f_dentry) ||
-	    !(inode = dentry->d_inode))
+	file = fget(fd);
+	if (!file)
 		goto bad;
+	/* N.B. Shouldn't this be ENOENT?? */
+	if (!(dentry = file->f_dentry) ||
+	    !(inode = dentry->d_inode))
+		goto out_putf;
 	retval = -EINVAL;
 	if (origin > 2)
-		goto bad;
+		goto out_putf;
 
 	offset = llseek(file, ((loff_t) offset_high << 32) | offset_low,
 			origin);
 
 	retval = (int)offset & INT_MAX;
 	if (offset >= 0) {
-		retval = copy_to_user(result, &offset, sizeof(offset));
-		if (retval)
-			retval = -EFAULT;
+		retval = -EFAULT;
+		if (!copy_to_user(result, &offset, sizeof(offset)))
+			retval = 0;
 	}
+out_putf:
+	fput(file);
 bad:
 	unlock_kernel();
 	return retval;
@@ -201,9 +209,10 @@
 	if (count > UIO_MAXIOV)
 		goto out_nofree;
 	if (count > UIO_FASTIOV) {
-		iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
 		ret = -ENOMEM;
-		if (!iov) goto out_nofree;
+		iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
+		if (!iov)
+			goto out_nofree;
 	}
 	ret = -EFAULT;
 	if (copy_from_user(iov, vector, count*sizeof(*vector)))
@@ -280,11 +289,10 @@
 	file = fget(fd);
 	if (!file)
 		goto bad_file;
-	if (!(file->f_mode & FMODE_READ))
-		goto out;
-	ret = do_readv_writev(VERIFY_WRITE, file, vector, count);
-out:
+	if (file->f_mode & FMODE_READ)
+		ret = do_readv_writev(VERIFY_WRITE, file, vector, count);
 	fput(file);
+
 bad_file:
 	unlock_kernel();
 	return ret;
@@ -302,15 +310,13 @@
 	file = fget(fd);
 	if (!file)
 		goto bad_file;
-	if (!(file->f_mode & FMODE_WRITE))
-		goto out;
-
-	down(&file->f_dentry->d_inode->i_sem);
-	ret = do_readv_writev(VERIFY_READ, file, vector, count);
-	up(&file->f_dentry->d_inode->i_sem);
-
-out:
+	if (file->f_mode & FMODE_WRITE) {
+		down(&file->f_dentry->d_inode->i_sem);
+		ret = do_readv_writev(VERIFY_READ, file, vector, count);
+		up(&file->f_dentry->d_inode->i_sem);
+	}
 	fput(file);
+
 bad_file:
 	unlock_kernel();
 	return ret;

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