From: Linus Torvalds Date: Sat, 12 Apr 2014 21:49:50 +0000 (-0700) Subject: Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs X-Git-Tag: firefly_0821_release~176^2~4070 X-Git-Url: http://plrg.eecs.uci.edu/git/?p=firefly-linux-kernel-4.4.55.git;a=commitdiff_plain;h=5166701b368caea89d57b14bf41cf39e819dad51 Merge branch 'for-linus' of git://git./linux/kernel/git/viro/vfs Pull vfs updates from Al Viro: "The first vfs pile, with deep apologies for being very late in this window. Assorted cleanups and fixes, plus a large preparatory part of iov_iter work. There's a lot more of that, but it'll probably go into the next merge window - it *does* shape up nicely, removes a lot of boilerplate, gets rid of locking inconsistencie between aio_write and splice_write and I hope to get Kent's direct-io rewrite merged into the same queue, but some of the stuff after this point is having (mostly trivial) conflicts with the things already merged into mainline and with some I want more testing. This one passes LTP and xfstests without regressions, in addition to usual beating. BTW, readahead02 in ltp syscalls testsuite has started giving failures since "mm/readahead.c: fix readahead failure for memoryless NUMA nodes and limit readahead pages" - might be a false positive, might be a real regression..." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (63 commits) missing bits of "splice: fix racy pipe->buffers uses" cifs: fix the race in cifs_writev() ceph_sync_{,direct_}write: fix an oops on ceph_osdc_new_request() failure kill generic_file_buffered_write() ocfs2_file_aio_write(): switch to generic_perform_write() ceph_aio_write(): switch to generic_perform_write() xfs_file_buffered_aio_write(): switch to generic_perform_write() export generic_perform_write(), start getting rid of generic_file_buffer_write() generic_file_direct_write(): get rid of ppos argument btrfs_file_aio_write(): get rid of ppos kill the 5th argument of generic_file_buffered_write() kill the 4th argument of __generic_file_aio_write() lustre: don't open-code kernel_recvmsg() ocfs2: don't open-code kernel_recvmsg() drbd: don't open-code kernel_recvmsg() constify blk_rq_map_user_iov() and friends lustre: switch to kernel_sendmsg() ocfs2: don't open-code kernel_sendmsg() take iov_iter stuff to mm/iov_iter.c process_vm_access: tidy up a bit ... --- 5166701b368caea89d57b14bf41cf39e819dad51 diff --cc drivers/block/drbd/drbd_receiver.c index 18c76e84d540,1385714eccb7..68e3992e8838 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@@ -475,21 -473,12 +474,12 @@@ static int drbd_recv_short(struct socke .iov_len = size, }; struct msghdr msg = { - .msg_iovlen = 1, - .msg_iov = (struct iovec *)&iov, .msg_flags = (flags ? flags : MSG_WAITALL | MSG_NOSIGNAL) }; - int rv; - - oldfs = get_fs(); - set_fs(KERNEL_DS); - rv = sock_recvmsg(sock, &msg, size, msg.msg_flags); - set_fs(oldfs); - - return rv; + return kernel_recvmsg(sock, &msg, &iov, 1, size, msg.msg_flags); } -static int drbd_recv(struct drbd_tconn *tconn, void *buf, size_t size) +static int drbd_recv(struct drbd_connection *connection, void *buf, size_t size) { int rv; diff --cc drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c index a54b506ba7ca,733c79e1f12d..b87b246111c0 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c @@@ -373,10 -337,9 +337,10 @@@ ksocknal_lib_recv_kiov (ksock_conn_t *c /* NB we can't trust socket ops to either consume our iovs * or leave them alone. */ - if ((addr = ksocknal_lib_kiov_vmap(kiov, niov, scratchiov, pages)) != NULL) { + addr = ksocknal_lib_kiov_vmap(kiov, niov, scratchiov, pages); + if (addr != NULL) { nob = scratchiov[0].iov_len; - msg.msg_iovlen = 1; + n = 1; } else { for (nob = i = 0; i < niov; i++) { diff --cc drivers/staging/usbip/stub_dev.c index 773d8ca07a00,2e2ccefb9c2b..de692d7011a5 --- a/drivers/staging/usbip/stub_dev.c +++ b/drivers/staging/usbip/stub_dev.c @@@ -86,19 -86,16 +86,19 @@@ static ssize_t store_sockfd(struct devi struct stub_device *sdev = dev_get_drvdata(dev); int sockfd = 0; struct socket *socket; - ssize_t err = -EINVAL; + int rv; if (!sdev) { dev_err(dev, "sdev is null\n"); return -ENODEV; } - sscanf(buf, "%d", &sockfd); + rv = sscanf(buf, "%d", &sockfd); + if (rv != 1) + return -EINVAL; if (sockfd != -1) { + int err; dev_info(dev, "stub up\n"); spin_lock_irq(&sdev->ud.lock); diff --cc fs/btrfs/file.c index c5998477fe60,8ed4b165abbd..eb742c07e7a4 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@@ -1725,9 -1691,7 +1720,8 @@@ static ssize_t btrfs_file_aio_write(str struct file *file = iocb->ki_filp; struct inode *inode = file_inode(file); struct btrfs_root *root = BTRFS_I(inode)->root; - loff_t *ppos = &iocb->ki_pos; u64 start_pos; + u64 end_pos; ssize_t num_written = 0; ssize_t err = 0; size_t count, ocount; diff --cc fs/ceph/file.c index 66075a4ad979,359805b671b9..39da1c2efa50 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@@ -971,7 -970,7 +971,8 @@@ retry_snap goto retry_snap; } } else { + loff_t old_size = inode->i_size; + struct iov_iter from; /* * No need to acquire the i_truncate_mutex. Because * the MDS revokes Fwb caps before sending truncate @@@ -979,11 -978,10 +980,12 @@@ * are pending vmtruncate. So write and vmtruncate * can not run at the same time */ - written = generic_file_buffered_write(iocb, iov, nr_segs, - pos, &iocb->ki_pos, - count, 0); + iov_iter_init(&from, iov, nr_segs, count, 0); + written = generic_perform_write(file, &from, pos); + if (likely(written >= 0)) + iocb->ki_pos = pos + written; + if (inode->i_size > old_size) + ceph_fscache_update_objectsize(inode); mutex_unlock(&inode->i_mutex); } diff --cc fs/namei.c index 88339f59efb5,4fb52f0ca5cb..c6157c894fce --- a/fs/namei.c +++ b/fs/namei.c @@@ -4152,9 -4175,10 +4171,10 @@@ out return error; } + EXPORT_SYMBOL(vfs_rename); -SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname, - int, newdfd, const char __user *, newname) +SYSCALL_DEFINE5(renameat2, int, olddfd, const char __user *, oldname, + int, newdfd, const char __user *, newname, unsigned int, flags) { struct dentry *old_dir, *new_dir; struct dentry *old_dentry, *new_dentry; @@@ -4293,22 -4292,14 +4313,20 @@@ exit return error; } +SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname, + int, newdfd, const char __user *, newname) +{ + return sys_renameat2(olddfd, oldname, newdfd, newname, 0); +} + SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newname) { - return sys_renameat(AT_FDCWD, oldname, AT_FDCWD, newname); + return sys_renameat2(AT_FDCWD, oldname, AT_FDCWD, newname, 0); } - int vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen, const char *link) + int readlink_copy(char __user *buffer, int buflen, const char *link) { - int len; - - len = PTR_ERR(link); + int len = PTR_ERR(link); if (IS_ERR(link)) goto out; diff --cc mm/Makefile index 9e5aaf92197d,178a43406b0c..b484452dac57 --- a/mm/Makefile +++ b/mm/Makefile @@@ -16,8 -16,8 +16,9 @@@ obj-y := filemap.o mempool.o oom_kill readahead.o swap.o truncate.o vmscan.o shmem.o \ util.o mmzone.o vmstat.o backing-dev.o \ mm_init.o mmu_context.o percpu.o slab_common.o \ - compaction.o balloon_compaction.o \ - interval_tree.o list_lru.o iov_iter.o $(mmu-y) + compaction.o balloon_compaction.o vmacache.o \ - interval_tree.o list_lru.o workingset.o $(mmu-y) ++ interval_tree.o list_lru.o workingset.o \ ++ iov_iter.o $(mmu-y) obj-y += init-mm.o diff --cc mm/filemap.c index 27ebc0c9571b,1a455142784d..a82fbe4c9e8e --- a/mm/filemap.c +++ b/mm/filemap.c @@@ -2335,150 -1858,27 +2273,6 @@@ struct page *read_cache_page_gfp(struc } EXPORT_SYMBOL(read_cache_page_gfp); - static size_t __iovec_copy_from_user_inatomic(char *vaddr, - const struct iovec *iov, size_t base, size_t bytes) - { - size_t copied = 0, left = 0; - - while (bytes) { - char __user *buf = iov->iov_base + base; - int copy = min(bytes, iov->iov_len - base); - - base = 0; - left = __copy_from_user_inatomic(vaddr, buf, copy); - copied += copy; - bytes -= copy; - vaddr += copy; - iov++; - - if (unlikely(left)) - break; - } - return copied - left; - } - - /* - * Copy as much as we can into the page and return the number of bytes which - * were successfully copied. If a fault is encountered then return the number of - * bytes which were copied. - */ - size_t iov_iter_copy_from_user_atomic(struct page *page, - struct iov_iter *i, unsigned long offset, size_t bytes) - { - char *kaddr; - size_t copied; - - BUG_ON(!in_atomic()); - kaddr = kmap_atomic(page); - if (likely(i->nr_segs == 1)) { - int left; - char __user *buf = i->iov->iov_base + i->iov_offset; - left = __copy_from_user_inatomic(kaddr + offset, buf, bytes); - copied = bytes - left; - } else { - copied = __iovec_copy_from_user_inatomic(kaddr + offset, - i->iov, i->iov_offset, bytes); - } - kunmap_atomic(kaddr); - - return copied; - } - EXPORT_SYMBOL(iov_iter_copy_from_user_atomic); - - /* - * This has the same sideeffects and return value as - * iov_iter_copy_from_user_atomic(). - * The difference is that it attempts to resolve faults. - * Page must not be locked. - */ - size_t iov_iter_copy_from_user(struct page *page, - struct iov_iter *i, unsigned long offset, size_t bytes) - { - char *kaddr; - size_t copied; - - kaddr = kmap(page); - if (likely(i->nr_segs == 1)) { - int left; - char __user *buf = i->iov->iov_base + i->iov_offset; - left = __copy_from_user(kaddr + offset, buf, bytes); - copied = bytes - left; - } else { - copied = __iovec_copy_from_user_inatomic(kaddr + offset, - i->iov, i->iov_offset, bytes); - } - kunmap(page); - return copied; - } - EXPORT_SYMBOL(iov_iter_copy_from_user); - - void iov_iter_advance(struct iov_iter *i, size_t bytes) - { - BUG_ON(i->count < bytes); - - if (likely(i->nr_segs == 1)) { - i->iov_offset += bytes; - i->count -= bytes; - } else { - const struct iovec *iov = i->iov; - size_t base = i->iov_offset; - unsigned long nr_segs = i->nr_segs; - - /* - * The !iov->iov_len check ensures we skip over unlikely - * zero-length segments (without overruning the iovec). - */ - while (bytes || unlikely(i->count && !iov->iov_len)) { - int copy; - - copy = min(bytes, iov->iov_len - base); - BUG_ON(!i->count || i->count < copy); - i->count -= copy; - bytes -= copy; - base += copy; - if (iov->iov_len == base) { - iov++; - nr_segs--; - base = 0; - } - } - i->iov = iov; - i->iov_offset = base; - i->nr_segs = nr_segs; - } - } - EXPORT_SYMBOL(iov_iter_advance); - - /* - * Fault in the first iovec of the given iov_iter, to a maximum length - * of bytes. Returns 0 on success, or non-zero if the memory could not be - * accessed (ie. because it is an invalid address). -/** - * read_cache_page - read into page cache, fill it if needed - * @mapping: the page's address_space - * @index: the page index - * @filler: function to perform the read - * @data: first arg to filler(data, page) function, often left as NULL -- * - * writev-intensive code may want this to prefault several iovecs -- that - * would be possible (callers must not rely on the fact that _only_ the - * first iovec will be faulted with the current implementation). - */ - int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes) - { - char __user *buf = i->iov->iov_base + i->iov_offset; - bytes = min(bytes, i->iov->iov_len - i->iov_offset); - return fault_in_pages_readable(buf, bytes); - } - EXPORT_SYMBOL(iov_iter_fault_in_readable); - - /* - * Return the count of just the current iov_iter segment. - * Read into the page cache. If a page already exists, and PageUptodate() is - * not set, try to fill the page then wait for it to become unlocked. - * - * If the page does not get brought uptodate, return -EIO. -- */ - size_t iov_iter_single_seg_count(const struct iov_iter *i) -struct page *read_cache_page(struct address_space *mapping, - pgoff_t index, - int (*filler)(void *, struct page *), - void *data) --{ - const struct iovec *iov = i->iov; - if (i->nr_segs == 1) - return i->count; - else - return min(i->count, iov->iov_len - i->iov_offset); - return wait_on_page_read(read_cache_page_async(mapping, index, filler, data)); --} - EXPORT_SYMBOL(iov_iter_single_seg_count); -EXPORT_SYMBOL(read_cache_page); -- /* * Performs necessary checks before doing a write *