Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] Remove readv/writev methods and use aio_read/aio_write instead

This patch removes readv() and writev() methods and replaces them with
aio_read()/aio_write() methods.

Signed-off-by: Badari Pulavarty <pbadari@us.ibm.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Badari Pulavarty and committed by
Linus Torvalds
ee0b3e67 027445c3

+154 -388
-2
drivers/char/raw.c
··· 257 257 .open = raw_open, 258 258 .release= raw_release, 259 259 .ioctl = raw_ioctl, 260 - .readv = generic_file_readv, 261 - .writev = generic_file_writev, 262 260 .owner = THIS_MODULE, 263 261 }; 264 262
+10 -27
drivers/net/tun.c
··· 288 288 return len; 289 289 } 290 290 291 - /* Writev */ 292 - static ssize_t tun_chr_writev(struct file * file, const struct iovec *iv, 293 - unsigned long count, loff_t *pos) 291 + static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv, 292 + unsigned long count, loff_t pos) 294 293 { 295 - struct tun_struct *tun = file->private_data; 294 + struct tun_struct *tun = iocb->ki_filp->private_data; 296 295 297 296 if (!tun) 298 297 return -EBADFD; ··· 299 300 DBG(KERN_INFO "%s: tun_chr_write %ld\n", tun->dev->name, count); 300 301 301 302 return tun_get_user(tun, (struct iovec *) iv, iov_total(iv, count)); 302 - } 303 - 304 - /* Write */ 305 - static ssize_t tun_chr_write(struct file * file, const char __user * buf, 306 - size_t count, loff_t *pos) 307 - { 308 - struct iovec iv = { (void __user *) buf, count }; 309 - return tun_chr_writev(file, &iv, 1, pos); 310 303 } 311 304 312 305 /* Put packet to the user space buffer */ ··· 334 343 return total; 335 344 } 336 345 337 - /* Readv */ 338 - static ssize_t tun_chr_readv(struct file *file, const struct iovec *iv, 339 - unsigned long count, loff_t *pos) 346 + static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv, 347 + unsigned long count, loff_t pos) 340 348 { 349 + struct file *file = iocb->ki_filp; 341 350 struct tun_struct *tun = file->private_data; 342 351 DECLARE_WAITQUEUE(wait, current); 343 352 struct sk_buff *skb; ··· 415 424 remove_wait_queue(&tun->read_wait, &wait); 416 425 417 426 return ret; 418 - } 419 - 420 - /* Read */ 421 - static ssize_t tun_chr_read(struct file * file, char __user * buf, 422 - size_t count, loff_t *pos) 423 - { 424 - struct iovec iv = { buf, count }; 425 - return tun_chr_readv(file, &iv, 1, pos); 426 427 } 427 428 428 429 static void tun_setup(struct net_device *dev) ··· 747 764 static struct file_operations tun_fops = { 748 765 .owner = THIS_MODULE, 749 766 .llseek = no_llseek, 750 - .read = tun_chr_read, 751 - .readv = tun_chr_readv, 752 - .write = tun_chr_write, 753 - .writev = tun_chr_writev, 767 + .read = do_sync_read, 768 + .aio_read = tun_chr_aio_read, 769 + .write = do_sync_write, 770 + .aio_write = tun_chr_aio_write, 754 771 .poll = tun_chr_poll, 755 772 .ioctl = tun_chr_ioctl, 756 773 .open = tun_chr_open,
-2
fs/bad_inode.c
··· 40 40 .aio_fsync = EIO_ERROR, 41 41 .fasync = EIO_ERROR, 42 42 .lock = EIO_ERROR, 43 - .readv = EIO_ERROR, 44 - .writev = EIO_ERROR, 45 43 .sendfile = EIO_ERROR, 46 44 .sendpage = EIO_ERROR, 47 45 .get_unmapped_area = EIO_ERROR,
-2
fs/block_dev.c
··· 1191 1191 #ifdef CONFIG_COMPAT 1192 1192 .compat_ioctl = compat_blkdev_ioctl, 1193 1193 #endif 1194 - .readv = generic_file_readv, 1195 - .writev = generic_file_write_nolock, 1196 1194 .sendfile = generic_file_sendfile, 1197 1195 .splice_read = generic_file_splice_read, 1198 1196 .splice_write = generic_file_splice_write,
-16
fs/cifs/cifsfs.c
··· 480 480 return simple_set_mnt(mnt, sb); 481 481 } 482 482 483 - static ssize_t cifs_file_writev(struct file *file, const struct iovec *iov, 484 - unsigned long nr_segs, loff_t *ppos) 485 - { 486 - struct inode *inode = file->f_dentry->d_inode; 487 - ssize_t written; 488 - 489 - written = generic_file_writev(file, iov, nr_segs, ppos); 490 - if (!CIFS_I(inode)->clientCanCacheAll) 491 - filemap_fdatawrite(inode->i_mapping); 492 - return written; 493 - } 494 - 495 483 static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, 496 484 unsigned long nr_segs, loff_t pos) 497 485 { ··· 565 577 const struct file_operations cifs_file_ops = { 566 578 .read = do_sync_read, 567 579 .write = do_sync_write, 568 - .readv = generic_file_readv, 569 - .writev = cifs_file_writev, 570 580 .aio_read = generic_file_aio_read, 571 581 .aio_write = cifs_file_aio_write, 572 582 .open = cifs_open, ··· 606 620 const struct file_operations cifs_file_nobrl_ops = { 607 621 .read = do_sync_read, 608 622 .write = do_sync_write, 609 - .readv = generic_file_readv, 610 - .writev = cifs_file_writev, 611 623 .aio_read = generic_file_aio_read, 612 624 .aio_write = cifs_file_aio_write, 613 625 .open = cifs_open,
+11 -33
fs/compat.c
··· 70 70 return ret; 71 71 } 72 72 73 + #include "read_write.h" 74 + 73 75 /* 74 76 * Not all architectures have sys_utime, so implement this in terms 75 77 * of sys_utimes. ··· 1151 1149 const struct compat_iovec __user *uvector, 1152 1150 unsigned long nr_segs, loff_t *pos) 1153 1151 { 1154 - typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *); 1155 - typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *); 1156 - 1157 1152 compat_ssize_t tot_len; 1158 1153 struct iovec iovstack[UIO_FASTIOV]; 1159 1154 struct iovec *iov=iovstack, *vector; ··· 1233 1234 fnv = NULL; 1234 1235 if (type == READ) { 1235 1236 fn = file->f_op->read; 1236 - fnv = file->f_op->readv; 1237 + fnv = file->f_op->aio_read; 1237 1238 } else { 1238 1239 fn = (io_fn_t)file->f_op->write; 1239 - fnv = file->f_op->writev; 1240 - } 1241 - if (fnv) { 1242 - ret = fnv(file, iov, nr_segs, pos); 1243 - goto out; 1240 + fnv = file->f_op->aio_write; 1244 1241 } 1245 1242 1246 - /* Do it by hand, with file-ops */ 1247 - ret = 0; 1248 - vector = iov; 1249 - while (nr_segs > 0) { 1250 - void __user * base; 1251 - size_t len; 1252 - ssize_t nr; 1243 + if (fnv) 1244 + ret = do_sync_readv_writev(file, iov, nr_segs, tot_len, 1245 + pos, fnv); 1246 + else 1247 + ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn); 1253 1248 1254 - base = vector->iov_base; 1255 - len = vector->iov_len; 1256 - vector++; 1257 - nr_segs--; 1258 - 1259 - nr = fn(file, base, len, pos); 1260 - 1261 - if (nr < 0) { 1262 - if (!ret) ret = nr; 1263 - break; 1264 - } 1265 - ret += nr; 1266 - if (nr != len) 1267 - break; 1268 - } 1269 1249 out: 1270 1250 if (iov != iovstack) 1271 1251 kfree(iov); ··· 1272 1294 goto out; 1273 1295 1274 1296 ret = -EINVAL; 1275 - if (!file->f_op || (!file->f_op->readv && !file->f_op->read)) 1297 + if (!file->f_op || (!file->f_op->aio_read && !file->f_op->read)) 1276 1298 goto out; 1277 1299 1278 1300 ret = compat_do_readv_writev(READ, file, vec, vlen, &file->f_pos); ··· 1295 1317 goto out; 1296 1318 1297 1319 ret = -EINVAL; 1298 - if (!file->f_op || (!file->f_op->writev && !file->f_op->write)) 1320 + if (!file->f_op || (!file->f_op->aio_write && !file->f_op->write)) 1299 1321 goto out; 1300 1322 1301 1323 ret = compat_do_readv_writev(WRITE, file, vec, vlen, &file->f_pos);
-2
fs/ext2/file.c
··· 53 53 .open = generic_file_open, 54 54 .release = ext2_release_file, 55 55 .fsync = ext2_sync_file, 56 - .readv = generic_file_readv, 57 - .writev = generic_file_writev, 58 56 .sendfile = generic_file_sendfile, 59 57 .splice_read = generic_file_splice_read, 60 58 .splice_write = generic_file_splice_write,
-2
fs/ext3/file.c
··· 112 112 .write = do_sync_write, 113 113 .aio_read = generic_file_aio_read, 114 114 .aio_write = ext3_file_write, 115 - .readv = generic_file_readv, 116 - .writev = generic_file_writev, 117 115 .ioctl = ext3_ioctl, 118 116 #ifdef CONFIG_COMPAT 119 117 .compat_ioctl = ext3_compat_ioctl,
-2
fs/fat/file.c
··· 127 127 .llseek = generic_file_llseek, 128 128 .read = do_sync_read, 129 129 .write = do_sync_write, 130 - .readv = generic_file_readv, 131 - .writev = generic_file_writev, 132 130 .aio_read = generic_file_aio_read, 133 131 .aio_write = generic_file_aio_write, 134 132 .mmap = generic_file_mmap,
+10 -27
fs/fuse/dev.c
··· 680 680 * request_end(). Otherwise add it to the processing list, and set 681 681 * the 'sent' flag. 682 682 */ 683 - static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov, 684 - unsigned long nr_segs, loff_t *off) 683 + static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov, 684 + unsigned long nr_segs, loff_t pos) 685 685 { 686 686 int err; 687 687 struct fuse_req *req; 688 688 struct fuse_in *in; 689 689 struct fuse_copy_state cs; 690 690 unsigned reqsize; 691 + struct file *file = iocb->ki_filp; 691 692 struct fuse_conn *fc = fuse_get_conn(file); 692 693 if (!fc) 693 694 return -EPERM; ··· 762 761 return err; 763 762 } 764 763 765 - static ssize_t fuse_dev_read(struct file *file, char __user *buf, 766 - size_t nbytes, loff_t *off) 767 - { 768 - struct iovec iov; 769 - iov.iov_len = nbytes; 770 - iov.iov_base = buf; 771 - return fuse_dev_readv(file, &iov, 1, off); 772 - } 773 - 774 764 /* Look up request on processing list by unique ID */ 775 765 static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique) 776 766 { ··· 806 814 * it from the list and copy the rest of the buffer to the request. 807 815 * The request is finished by calling request_end() 808 816 */ 809 - static ssize_t fuse_dev_writev(struct file *file, const struct iovec *iov, 810 - unsigned long nr_segs, loff_t *off) 817 + static ssize_t fuse_dev_write(struct kiocb *iocb, const struct iovec *iov, 818 + unsigned long nr_segs, loff_t pos) 811 819 { 812 820 int err; 813 821 unsigned nbytes = iov_length(iov, nr_segs); 814 822 struct fuse_req *req; 815 823 struct fuse_out_header oh; 816 824 struct fuse_copy_state cs; 817 - struct fuse_conn *fc = fuse_get_conn(file); 825 + struct fuse_conn *fc = fuse_get_conn(iocb->ki_filp); 818 826 if (!fc) 819 827 return -EPERM; 820 828 ··· 888 896 err_finish: 889 897 fuse_copy_finish(&cs); 890 898 return err; 891 - } 892 - 893 - static ssize_t fuse_dev_write(struct file *file, const char __user *buf, 894 - size_t nbytes, loff_t *off) 895 - { 896 - struct iovec iov; 897 - iov.iov_len = nbytes; 898 - iov.iov_base = (char __user *) buf; 899 - return fuse_dev_writev(file, &iov, 1, off); 900 899 } 901 900 902 901 static unsigned fuse_dev_poll(struct file *file, poll_table *wait) ··· 1024 1041 const struct file_operations fuse_dev_operations = { 1025 1042 .owner = THIS_MODULE, 1026 1043 .llseek = no_llseek, 1027 - .read = fuse_dev_read, 1028 - .readv = fuse_dev_readv, 1029 - .write = fuse_dev_write, 1030 - .writev = fuse_dev_writev, 1044 + .read = do_sync_read, 1045 + .aio_read = fuse_dev_read, 1046 + .write = do_sync_write, 1047 + .aio_write = fuse_dev_write, 1031 1048 .poll = fuse_dev_poll, 1032 1049 .release = fuse_dev_release, 1033 1050 .fasync = fuse_dev_fasync,
-2
fs/hostfs/hostfs_kern.c
··· 389 389 .sendfile = generic_file_sendfile, 390 390 .aio_read = generic_file_aio_read, 391 391 .aio_write = generic_file_aio_write, 392 - .readv = generic_file_readv, 393 - .writev = generic_file_writev, 394 392 .write = generic_file_write, 395 393 .mmap = generic_file_mmap, 396 394 .open = hostfs_file_open,
-2
fs/jfs/file.c
··· 108 108 .aio_read = generic_file_aio_read, 109 109 .aio_write = generic_file_aio_write, 110 110 .mmap = generic_file_mmap, 111 - .readv = generic_file_readv, 112 - .writev = generic_file_writev, 113 111 .sendfile = generic_file_sendfile, 114 112 .fsync = jfs_fsync, 115 113 .release = jfs_release,
-2
fs/ntfs/file.c
··· 2298 2298 .llseek = generic_file_llseek, /* Seek inside file. */ 2299 2299 .read = generic_file_read, /* Read from file. */ 2300 2300 .aio_read = generic_file_aio_read, /* Async read from file. */ 2301 - .readv = generic_file_readv, /* Read from file. */ 2302 2301 #ifdef NTFS_RW 2303 2302 .write = ntfs_file_write, /* Write to file. */ 2304 2303 .aio_write = ntfs_file_aio_write, /* Async write to file. */ 2305 - .writev = ntfs_file_writev, /* Write to file. */ 2306 2304 /*.release = ,*/ /* Last file is closed. See 2307 2305 fs/ext2/file.c:: 2308 2306 ext2_release_file() for
+22 -37
fs/pipe.c
··· 218 218 }; 219 219 220 220 static ssize_t 221 - pipe_readv(struct file *filp, const struct iovec *_iov, 222 - unsigned long nr_segs, loff_t *ppos) 221 + pipe_read(struct kiocb *iocb, const struct iovec *_iov, 222 + unsigned long nr_segs, loff_t pos) 223 223 { 224 + struct file *filp = iocb->ki_filp; 224 225 struct inode *inode = filp->f_dentry->d_inode; 225 226 struct pipe_inode_info *pipe; 226 227 int do_wakeup; ··· 331 330 } 332 331 333 332 static ssize_t 334 - pipe_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) 333 + pipe_write(struct kiocb *iocb, const struct iovec *_iov, 334 + unsigned long nr_segs, loff_t ppos) 335 335 { 336 - struct iovec iov = { .iov_base = buf, .iov_len = count }; 337 - 338 - return pipe_readv(filp, &iov, 1, ppos); 339 - } 340 - 341 - static ssize_t 342 - pipe_writev(struct file *filp, const struct iovec *_iov, 343 - unsigned long nr_segs, loff_t *ppos) 344 - { 336 + struct file *filp = iocb->ki_filp; 345 337 struct inode *inode = filp->f_dentry->d_inode; 346 338 struct pipe_inode_info *pipe; 347 339 ssize_t ret; ··· 501 507 if (ret > 0) 502 508 file_update_time(filp); 503 509 return ret; 504 - } 505 - 506 - static ssize_t 507 - pipe_write(struct file *filp, const char __user *buf, 508 - size_t count, loff_t *ppos) 509 - { 510 - struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = count }; 511 - 512 - return pipe_writev(filp, &iov, 1, ppos); 513 510 } 514 511 515 512 static ssize_t ··· 721 736 */ 722 737 const struct file_operations read_fifo_fops = { 723 738 .llseek = no_llseek, 724 - .read = pipe_read, 725 - .readv = pipe_readv, 739 + .read = do_sync_read, 740 + .aio_read = pipe_read, 726 741 .write = bad_pipe_w, 727 742 .poll = pipe_poll, 728 743 .ioctl = pipe_ioctl, ··· 734 749 const struct file_operations write_fifo_fops = { 735 750 .llseek = no_llseek, 736 751 .read = bad_pipe_r, 737 - .write = pipe_write, 738 - .writev = pipe_writev, 752 + .write = do_sync_write, 753 + .aio_write = pipe_write, 739 754 .poll = pipe_poll, 740 755 .ioctl = pipe_ioctl, 741 756 .open = pipe_write_open, ··· 745 760 746 761 const struct file_operations rdwr_fifo_fops = { 747 762 .llseek = no_llseek, 748 - .read = pipe_read, 749 - .readv = pipe_readv, 750 - .write = pipe_write, 751 - .writev = pipe_writev, 763 + .read = do_sync_read, 764 + .aio_read = pipe_read, 765 + .write = do_sync_write, 766 + .aio_write = pipe_write, 752 767 .poll = pipe_poll, 753 768 .ioctl = pipe_ioctl, 754 769 .open = pipe_rdwr_open, ··· 758 773 759 774 static struct file_operations read_pipe_fops = { 760 775 .llseek = no_llseek, 761 - .read = pipe_read, 762 - .readv = pipe_readv, 776 + .read = do_sync_read, 777 + .aio_read = pipe_read, 763 778 .write = bad_pipe_w, 764 779 .poll = pipe_poll, 765 780 .ioctl = pipe_ioctl, ··· 771 786 static struct file_operations write_pipe_fops = { 772 787 .llseek = no_llseek, 773 788 .read = bad_pipe_r, 774 - .write = pipe_write, 775 - .writev = pipe_writev, 789 + .write = do_sync_write, 790 + .aio_write = pipe_write, 776 791 .poll = pipe_poll, 777 792 .ioctl = pipe_ioctl, 778 793 .open = pipe_write_open, ··· 782 797 783 798 static struct file_operations rdwr_pipe_fops = { 784 799 .llseek = no_llseek, 785 - .read = pipe_read, 786 - .readv = pipe_readv, 787 - .write = pipe_write, 788 - .writev = pipe_writev, 800 + .read = do_sync_read, 801 + .aio_read = pipe_read, 802 + .write = do_sync_write, 803 + .aio_write = pipe_write, 789 804 .poll = pipe_poll, 790 805 .ioctl = pipe_ioctl, 791 806 .open = pipe_rdwr_open,
+67 -34
fs/read_write.c
··· 15 15 #include <linux/module.h> 16 16 #include <linux/syscalls.h> 17 17 #include <linux/pagemap.h> 18 + #include "read_write.h" 18 19 19 20 #include <asm/uaccess.h> 20 21 #include <asm/unistd.h> ··· 451 450 452 451 EXPORT_UNUSED_SYMBOL(iov_shorten); /* June 2006 */ 453 452 453 + ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov, 454 + unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn) 455 + { 456 + struct kiocb kiocb; 457 + ssize_t ret; 458 + 459 + init_sync_kiocb(&kiocb, filp); 460 + kiocb.ki_pos = *ppos; 461 + kiocb.ki_left = len; 462 + kiocb.ki_nbytes = len; 463 + 464 + for (;;) { 465 + ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos); 466 + if (ret != -EIOCBRETRY) 467 + break; 468 + wait_on_retry_sync_kiocb(&kiocb); 469 + } 470 + 471 + if (ret == -EIOCBQUEUED) 472 + ret = wait_on_sync_kiocb(&kiocb); 473 + *ppos = kiocb.ki_pos; 474 + return ret; 475 + } 476 + 477 + /* Do it by hand, with file-ops */ 478 + ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov, 479 + unsigned long nr_segs, loff_t *ppos, io_fn_t fn) 480 + { 481 + struct iovec *vector = iov; 482 + ssize_t ret = 0; 483 + 484 + while (nr_segs > 0) { 485 + void __user *base; 486 + size_t len; 487 + ssize_t nr; 488 + 489 + base = vector->iov_base; 490 + len = vector->iov_len; 491 + vector++; 492 + nr_segs--; 493 + 494 + nr = fn(filp, base, len, ppos); 495 + 496 + if (nr < 0) { 497 + if (!ret) 498 + ret = nr; 499 + break; 500 + } 501 + ret += nr; 502 + if (nr != len) 503 + break; 504 + } 505 + 506 + return ret; 507 + } 508 + 454 509 /* A write operation does a read from user space and vice versa */ 455 510 #define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ) 456 511 ··· 514 457 const struct iovec __user * uvector, 515 458 unsigned long nr_segs, loff_t *pos) 516 459 { 517 - typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *); 518 - typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *); 519 - 520 460 size_t tot_len; 521 461 struct iovec iovstack[UIO_FASTIOV]; 522 - struct iovec *iov=iovstack, *vector; 462 + struct iovec *iov = iovstack; 523 463 ssize_t ret; 524 464 int seg; 525 465 io_fn_t fn; ··· 586 532 fnv = NULL; 587 533 if (type == READ) { 588 534 fn = file->f_op->read; 589 - fnv = file->f_op->readv; 535 + fnv = file->f_op->aio_read; 590 536 } else { 591 537 fn = (io_fn_t)file->f_op->write; 592 - fnv = file->f_op->writev; 593 - } 594 - if (fnv) { 595 - ret = fnv(file, iov, nr_segs, pos); 596 - goto out; 538 + fnv = file->f_op->aio_write; 597 539 } 598 540 599 - /* Do it by hand, with file-ops */ 600 - ret = 0; 601 - vector = iov; 602 - while (nr_segs > 0) { 603 - void __user * base; 604 - size_t len; 605 - ssize_t nr; 541 + if (fnv) 542 + ret = do_sync_readv_writev(file, iov, nr_segs, tot_len, 543 + pos, fnv); 544 + else 545 + ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn); 606 546 607 - base = vector->iov_base; 608 - len = vector->iov_len; 609 - vector++; 610 - nr_segs--; 611 - 612 - nr = fn(file, base, len, pos); 613 - 614 - if (nr < 0) { 615 - if (!ret) ret = nr; 616 - break; 617 - } 618 - ret += nr; 619 - if (nr != len) 620 - break; 621 - } 622 547 out: 623 548 if (iov != iovstack) 624 549 kfree(iov); ··· 618 585 { 619 586 if (!(file->f_mode & FMODE_READ)) 620 587 return -EBADF; 621 - if (!file->f_op || (!file->f_op->readv && !file->f_op->read)) 588 + if (!file->f_op || (!file->f_op->aio_read && !file->f_op->read)) 622 589 return -EINVAL; 623 590 624 591 return do_readv_writev(READ, file, vec, vlen, pos); ··· 631 598 { 632 599 if (!(file->f_mode & FMODE_WRITE)) 633 600 return -EBADF; 634 - if (!file->f_op || (!file->f_op->writev && !file->f_op->write)) 601 + if (!file->f_op || (!file->f_op->aio_write && !file->f_op->write)) 635 602 return -EINVAL; 636 603 637 604 return do_readv_writev(WRITE, file, vec, vlen, pos);
+14
fs/read_write.h
··· 1 + /* 2 + * This file is only for sharing some helpers from read_write.c with compat.c. 3 + * Don't use anywhere else. 4 + */ 5 + 6 + 7 + typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *); 8 + typedef ssize_t (*iov_fn_t)(struct kiocb *, const struct iovec *, 9 + unsigned long, loff_t); 10 + 11 + ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov, 12 + unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn); 13 + ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov, 14 + unsigned long nr_segs, loff_t *ppos, io_fn_t fn);
-94
fs/xfs/linux-2.6/xfs_file.c
··· 123 123 return __xfs_file_write(iocb, iov, nr_segs, IO_ISAIO|IO_INVIS, pos); 124 124 } 125 125 126 - STATIC inline ssize_t 127 - __xfs_file_readv( 128 - struct file *file, 129 - const struct iovec *iov, 130 - int ioflags, 131 - unsigned long nr_segs, 132 - loff_t *ppos) 133 - { 134 - struct inode *inode = file->f_mapping->host; 135 - bhv_vnode_t *vp = vn_from_inode(inode); 136 - struct kiocb kiocb; 137 - ssize_t rval; 138 - 139 - init_sync_kiocb(&kiocb, file); 140 - kiocb.ki_pos = *ppos; 141 - 142 - if (unlikely(file->f_flags & O_DIRECT)) 143 - ioflags |= IO_ISDIRECT; 144 - rval = bhv_vop_read(vp, &kiocb, iov, nr_segs, 145 - &kiocb.ki_pos, ioflags, NULL); 146 - 147 - *ppos = kiocb.ki_pos; 148 - return rval; 149 - } 150 - 151 - STATIC ssize_t 152 - xfs_file_readv( 153 - struct file *file, 154 - const struct iovec *iov, 155 - unsigned long nr_segs, 156 - loff_t *ppos) 157 - { 158 - return __xfs_file_readv(file, iov, 0, nr_segs, ppos); 159 - } 160 - 161 - STATIC ssize_t 162 - xfs_file_readv_invis( 163 - struct file *file, 164 - const struct iovec *iov, 165 - unsigned long nr_segs, 166 - loff_t *ppos) 167 - { 168 - return __xfs_file_readv(file, iov, IO_INVIS, nr_segs, ppos); 169 - } 170 - 171 - STATIC inline ssize_t 172 - __xfs_file_writev( 173 - struct file *file, 174 - const struct iovec *iov, 175 - int ioflags, 176 - unsigned long nr_segs, 177 - loff_t *ppos) 178 - { 179 - struct inode *inode = file->f_mapping->host; 180 - bhv_vnode_t *vp = vn_from_inode(inode); 181 - struct kiocb kiocb; 182 - ssize_t rval; 183 - 184 - init_sync_kiocb(&kiocb, file); 185 - kiocb.ki_pos = *ppos; 186 - if (unlikely(file->f_flags & O_DIRECT)) 187 - ioflags |= IO_ISDIRECT; 188 - 189 - rval = bhv_vop_write(vp, &kiocb, iov, nr_segs, 190 - &kiocb.ki_pos, ioflags, NULL); 191 - 192 - *ppos = kiocb.ki_pos; 193 - return rval; 194 - } 195 - 196 - STATIC ssize_t 197 - xfs_file_writev( 198 - struct file *file, 199 - const struct iovec *iov, 200 - unsigned long nr_segs, 201 - loff_t *ppos) 202 - { 203 - return __xfs_file_writev(file, iov, 0, nr_segs, ppos); 204 - } 205 - 206 - STATIC ssize_t 207 - xfs_file_writev_invis( 208 - struct file *file, 209 - const struct iovec *iov, 210 - unsigned long nr_segs, 211 - loff_t *ppos) 212 - { 213 - return __xfs_file_writev(file, iov, IO_INVIS, nr_segs, ppos); 214 - } 215 - 216 126 STATIC ssize_t 217 127 xfs_file_sendfile( 218 128 struct file *filp, ··· 450 540 .llseek = generic_file_llseek, 451 541 .read = do_sync_read, 452 542 .write = do_sync_write, 453 - .readv = xfs_file_readv, 454 - .writev = xfs_file_writev, 455 543 .aio_read = xfs_file_aio_read, 456 544 .aio_write = xfs_file_aio_write, 457 545 .sendfile = xfs_file_sendfile, ··· 473 565 .llseek = generic_file_llseek, 474 566 .read = do_sync_read, 475 567 .write = do_sync_write, 476 - .readv = xfs_file_readv_invis, 477 - .writev = xfs_file_writev_invis, 478 568 .aio_read = xfs_file_aio_read_invis, 479 569 .aio_write = xfs_file_aio_write_invis, 480 570 .sendfile = xfs_file_sendfile_invis,
-6
include/linux/fs.h
··· 1113 1113 int (*aio_fsync) (struct kiocb *, int datasync); 1114 1114 int (*fasync) (int, struct file *, int); 1115 1115 int (*lock) (struct file *, int, struct file_lock *); 1116 - ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t *); 1117 - ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *); 1118 1116 ssize_t (*sendfile) (struct file *, loff_t *, size_t, read_actor_t, void *); 1119 1117 ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); 1120 1118 unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); ··· 1732 1734 1733 1735 extern void 1734 1736 file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping); 1735 - extern ssize_t generic_file_readv(struct file *filp, const struct iovec *iov, 1736 - unsigned long nr_segs, loff_t *ppos); 1737 - ssize_t generic_file_writev(struct file *filp, const struct iovec *iov, 1738 - unsigned long nr_segs, loff_t *ppos); 1739 1737 extern loff_t no_llseek(struct file *file, loff_t offset, int origin); 1740 1738 extern loff_t generic_file_llseek(struct file *file, loff_t offset, int origin); 1741 1739 extern loff_t remote_llseek(struct file *file, loff_t offset, int origin);
-36
mm/filemap.c
··· 2421 2421 } 2422 2422 EXPORT_SYMBOL(generic_file_write); 2423 2423 2424 - ssize_t generic_file_readv(struct file *filp, const struct iovec *iov, 2425 - unsigned long nr_segs, loff_t *ppos) 2426 - { 2427 - struct kiocb kiocb; 2428 - ssize_t ret; 2429 - 2430 - init_sync_kiocb(&kiocb, filp); 2431 - ret = __generic_file_aio_read(&kiocb, iov, nr_segs, ppos); 2432 - if (-EIOCBQUEUED == ret) 2433 - ret = wait_on_sync_kiocb(&kiocb); 2434 - return ret; 2435 - } 2436 - EXPORT_SYMBOL(generic_file_readv); 2437 - 2438 - ssize_t generic_file_writev(struct file *file, const struct iovec *iov, 2439 - unsigned long nr_segs, loff_t *ppos) 2440 - { 2441 - struct address_space *mapping = file->f_mapping; 2442 - struct inode *inode = mapping->host; 2443 - ssize_t ret; 2444 - 2445 - mutex_lock(&inode->i_mutex); 2446 - ret = __generic_file_write_nolock(file, iov, nr_segs, ppos); 2447 - mutex_unlock(&inode->i_mutex); 2448 - 2449 - if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { 2450 - int err; 2451 - 2452 - err = sync_page_range(inode, mapping, *ppos - ret, ret); 2453 - if (err < 0) 2454 - ret = err; 2455 - } 2456 - return ret; 2457 - } 2458 - EXPORT_SYMBOL(generic_file_writev); 2459 - 2460 2424 /* 2461 2425 * Called under i_mutex for writes to S_ISREG files. Returns -EIO if something 2462 2426 * went wrong during pagecache shootdown.
-40
net/socket.c
··· 110 110 unsigned int cmd, unsigned long arg); 111 111 #endif 112 112 static int sock_fasync(int fd, struct file *filp, int on); 113 - static ssize_t sock_readv(struct file *file, const struct iovec *vector, 114 - unsigned long count, loff_t *ppos); 115 - static ssize_t sock_writev(struct file *file, const struct iovec *vector, 116 - unsigned long count, loff_t *ppos); 117 113 static ssize_t sock_sendpage(struct file *file, struct page *page, 118 114 int offset, size_t size, loff_t *ppos, int more); 119 115 ··· 132 136 .open = sock_no_open, /* special open code to disallow open via /proc */ 133 137 .release = sock_close, 134 138 .fasync = sock_fasync, 135 - .readv = sock_readv, 136 - .writev = sock_writev, 137 139 .sendpage = sock_sendpage, 138 140 .splice_write = generic_splice_sendpage, 139 141 }; ··· 694 700 return __sock_recvmsg(iocb, sock, msg, size, msg->msg_flags); 695 701 } 696 702 697 - static ssize_t sock_readv(struct file *file, const struct iovec *iov, 698 - unsigned long nr_segs, loff_t *ppos) 699 - { 700 - struct kiocb iocb; 701 - struct sock_iocb siocb; 702 - struct msghdr msg; 703 - int ret; 704 - 705 - init_sync_kiocb(&iocb, NULL); 706 - iocb.private = &siocb; 707 - 708 - ret = do_sock_read(&msg, &iocb, file, iov, nr_segs); 709 - if (-EIOCBQUEUED == ret) 710 - ret = wait_on_sync_kiocb(&iocb); 711 - return ret; 712 - } 713 - 714 703 static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, 715 704 unsigned long nr_segs, loff_t pos) 716 705 { ··· 734 757 msg->msg_flags |= MSG_EOR; 735 758 736 759 return __sock_sendmsg(iocb, sock, msg, size); 737 - } 738 - 739 - static ssize_t sock_writev(struct file *file, const struct iovec *iov, 740 - unsigned long nr_segs, loff_t *ppos) 741 - { 742 - struct msghdr msg; 743 - struct kiocb iocb; 744 - struct sock_iocb siocb; 745 - int ret; 746 - 747 - init_sync_kiocb(&iocb, NULL); 748 - iocb.private = &siocb; 749 - 750 - ret = do_sock_write(&msg, &iocb, file, iov, nr_segs); 751 - if (-EIOCBQUEUED == ret) 752 - ret = wait_on_sync_kiocb(&iocb); 753 - return ret; 754 760 } 755 761 756 762 static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov,
+20 -20
sound/core/pcm_native.c
··· 2852 2852 return result; 2853 2853 } 2854 2854 2855 - static ssize_t snd_pcm_readv(struct file *file, const struct iovec *_vector, 2856 - unsigned long count, loff_t * offset) 2855 + static ssize_t snd_pcm_aio_read(struct kiocb *iocb, const struct iovec *iov, 2856 + unsigned long nr_segs, loff_t pos) 2857 2857 2858 2858 { 2859 2859 struct snd_pcm_file *pcm_file; ··· 2864 2864 void __user **bufs; 2865 2865 snd_pcm_uframes_t frames; 2866 2866 2867 - pcm_file = file->private_data; 2867 + pcm_file = iocb->ki_filp->private_data; 2868 2868 substream = pcm_file->substream; 2869 2869 snd_assert(substream != NULL, return -ENXIO); 2870 2870 runtime = substream->runtime; 2871 2871 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 2872 2872 return -EBADFD; 2873 - if (count > 1024 || count != runtime->channels) 2873 + if (nr_segs > 1024 || nr_segs != runtime->channels) 2874 2874 return -EINVAL; 2875 - if (!frame_aligned(runtime, _vector->iov_len)) 2875 + if (!frame_aligned(runtime, iov->iov_len)) 2876 2876 return -EINVAL; 2877 - frames = bytes_to_samples(runtime, _vector->iov_len); 2878 - bufs = kmalloc(sizeof(void *) * count, GFP_KERNEL); 2877 + frames = bytes_to_samples(runtime, iov->iov_len); 2878 + bufs = kmalloc(sizeof(void *) * nr_segs, GFP_KERNEL); 2879 2879 if (bufs == NULL) 2880 2880 return -ENOMEM; 2881 - for (i = 0; i < count; ++i) 2882 - bufs[i] = _vector[i].iov_base; 2881 + for (i = 0; i < nr_segs; ++i) 2882 + bufs[i] = iov[i].iov_base; 2883 2883 result = snd_pcm_lib_readv(substream, bufs, frames); 2884 2884 if (result > 0) 2885 2885 result = frames_to_bytes(runtime, result); ··· 2887 2887 return result; 2888 2888 } 2889 2889 2890 - static ssize_t snd_pcm_writev(struct file *file, const struct iovec *_vector, 2891 - unsigned long count, loff_t * offset) 2890 + static ssize_t snd_pcm_aio_write(struct kiocb *iocb, const struct iovec *iov, 2891 + unsigned long nr_segs, loff_t pos) 2892 2892 { 2893 2893 struct snd_pcm_file *pcm_file; 2894 2894 struct snd_pcm_substream *substream; ··· 2898 2898 void __user **bufs; 2899 2899 snd_pcm_uframes_t frames; 2900 2900 2901 - pcm_file = file->private_data; 2901 + pcm_file = iocb->ki_filp->private_data; 2902 2902 substream = pcm_file->substream; 2903 2903 snd_assert(substream != NULL, result = -ENXIO; goto end); 2904 2904 runtime = substream->runtime; ··· 2906 2906 result = -EBADFD; 2907 2907 goto end; 2908 2908 } 2909 - if (count > 128 || count != runtime->channels || 2910 - !frame_aligned(runtime, _vector->iov_len)) { 2909 + if (nr_segs > 128 || nr_segs != runtime->channels || 2910 + !frame_aligned(runtime, iov->iov_len)) { 2911 2911 result = -EINVAL; 2912 2912 goto end; 2913 2913 } 2914 - frames = bytes_to_samples(runtime, _vector->iov_len); 2915 - bufs = kmalloc(sizeof(void *) * count, GFP_KERNEL); 2914 + frames = bytes_to_samples(runtime, iov->iov_len); 2915 + bufs = kmalloc(sizeof(void *) * nr_segs, GFP_KERNEL); 2916 2916 if (bufs == NULL) 2917 2917 return -ENOMEM; 2918 - for (i = 0; i < count; ++i) 2919 - bufs[i] = _vector[i].iov_base; 2918 + for (i = 0; i < nr_segs; ++i) 2919 + bufs[i] = iov[i].iov_base; 2920 2920 result = snd_pcm_lib_writev(substream, bufs, frames); 2921 2921 if (result > 0) 2922 2922 result = frames_to_bytes(runtime, result); ··· 3426 3426 { 3427 3427 .owner = THIS_MODULE, 3428 3428 .write = snd_pcm_write, 3429 - .writev = snd_pcm_writev, 3429 + .aio_write = snd_pcm_aio_write, 3430 3430 .open = snd_pcm_playback_open, 3431 3431 .release = snd_pcm_release, 3432 3432 .poll = snd_pcm_playback_poll, ··· 3438 3438 { 3439 3439 .owner = THIS_MODULE, 3440 3440 .read = snd_pcm_read, 3441 - .readv = snd_pcm_readv, 3441 + .aio_read = snd_pcm_aio_read, 3442 3442 .open = snd_pcm_capture_open, 3443 3443 .release = snd_pcm_release, 3444 3444 .poll = snd_pcm_capture_poll,