patch-2.3.44 linux/fs/read_write.c

Next file: linux/include/asm-alpha/pgtable.h
Previous file: linux/fs/qnx4/namei.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.43/linux/fs/read_write.c linux/fs/read_write.c
@@ -170,12 +170,14 @@
 			       unsigned long count)
 {
 	typedef ssize_t (*io_fn_t)(struct file *, char *, size_t, loff_t *);
+	typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *);
 
 	size_t tot_len;
 	struct iovec iovstack[UIO_FASTIOV];
 	struct iovec *iov=iovstack;
 	ssize_t ret, i;
 	io_fn_t fn;
+	iov_fn_t fnv;
 	struct inode *inode;
 
 	/*
@@ -188,6 +190,8 @@
 	ret = -EINVAL;
 	if (count > UIO_MAXIOV)
 		goto out_nofree;
+	if (!file->f_op)
+		goto out_nofree;
 	if (count > UIO_FASTIOV) {
 		ret = -ENOMEM;
 		iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
@@ -209,24 +213,15 @@
 				inode, file, file->f_pos, tot_len);
 	if (ret) goto out;
 
-	/*
-	 * Then do the actual IO.  Note that sockets need to be handled
-	 * specially as they have atomicity guarantees and can handle
-	 * iovec's natively
-	 */
-	if (inode->i_sock) {
-		ret = sock_readv_writev(type,inode,file,iov,count,tot_len);
+	fnv = (type == VERIFY_WRITE ? file->f_op->readv : file->f_op->writev);
+	if (fnv) {
+		ret = fnv(file, iov, count, &file->f_pos);
 		goto out;
 	}
 
-	ret = -EINVAL;
-	if (!file->f_op)
-		goto out;
-
 	/* VERIFY_WRITE actually means a read, as we write to user space */
-	fn = file->f_op->read;
-	if (type == VERIFY_READ)
-		fn = (io_fn_t) file->f_op->write;		
+	fn = (type == VERIFY_WRITE ? file->f_op->read :
+	      (io_fn_t) file->f_op->write);
 
 	ret = 0;
 	vector = iov;
@@ -269,7 +264,8 @@
 	file = fget(fd);
 	if (!file)
 		goto bad_file;
-	if (file->f_op && file->f_op->read && (file->f_mode & FMODE_READ))
+	if (file->f_op && (file->f_mode & FMODE_READ) &&
+	    (file->f_op->readv || file->f_op->read))
 		ret = do_readv_writev(VERIFY_WRITE, file, vector, count);
 	fput(file);
 
@@ -288,7 +284,8 @@
 	file = fget(fd);
 	if (!file)
 		goto bad_file;
-	if (file->f_op && file->f_op->write && (file->f_mode & FMODE_WRITE))
+	if (file->f_op && (file->f_mode & FMODE_WRITE) &&
+	    (file->f_op->writev || file->f_op->write))
 		ret = do_readv_writev(VERIFY_READ, file, vector, count);
 	fput(file);
 

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