aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-12 17:49:50 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-12 17:49:50 -0400
commit5166701b368caea89d57b14bf41cf39e819dad51 (patch)
treec73b9d4860809e3afa9359be9d03ba2d8d98a18e /fs/cifs
parent0a7418f5f569512e98789c439198eed4b507cce3 (diff)
parenta786c06d9f2719203c00b3d97b21f9a96980d0b5 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/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 ...
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cifsfs.c1
-rw-r--r--fs/cifs/file.c128
2 files changed, 52 insertions, 77 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 2c70cbe35d39..df9c9141c099 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -850,7 +850,6 @@ const struct inode_operations cifs_file_inode_ops = {
850/* revalidate:cifs_revalidate, */ 850/* revalidate:cifs_revalidate, */
851 .setattr = cifs_setattr, 851 .setattr = cifs_setattr,
852 .getattr = cifs_getattr, /* do we need this anymore? */ 852 .getattr = cifs_getattr, /* do we need this anymore? */
853 .rename = cifs_rename,
854 .permission = cifs_permission, 853 .permission = cifs_permission,
855#ifdef CONFIG_CIFS_XATTR 854#ifdef CONFIG_CIFS_XATTR
856 .setxattr = cifs_setxattr, 855 .setxattr = cifs_setxattr,
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 216d7e99f921..8807442c94dd 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2579,19 +2579,32 @@ cifs_writev(struct kiocb *iocb, const struct iovec *iov,
2579 struct cifsInodeInfo *cinode = CIFS_I(inode); 2579 struct cifsInodeInfo *cinode = CIFS_I(inode);
2580 struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server; 2580 struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server;
2581 ssize_t rc = -EACCES; 2581 ssize_t rc = -EACCES;
2582 loff_t lock_pos = pos; 2582 loff_t lock_pos = iocb->ki_pos;
2583 2583
2584 if (file->f_flags & O_APPEND)
2585 lock_pos = i_size_read(inode);
2586 /* 2584 /*
2587 * We need to hold the sem to be sure nobody modifies lock list 2585 * We need to hold the sem to be sure nobody modifies lock list
2588 * with a brlock that prevents writing. 2586 * with a brlock that prevents writing.
2589 */ 2587 */
2590 down_read(&cinode->lock_sem); 2588 down_read(&cinode->lock_sem);
2589 mutex_lock(&inode->i_mutex);
2590 if (file->f_flags & O_APPEND)
2591 lock_pos = i_size_read(inode);
2591 if (!cifs_find_lock_conflict(cfile, lock_pos, iov_length(iov, nr_segs), 2592 if (!cifs_find_lock_conflict(cfile, lock_pos, iov_length(iov, nr_segs),
2592 server->vals->exclusive_lock_type, NULL, 2593 server->vals->exclusive_lock_type, NULL,
2593 CIFS_WRITE_OP)) 2594 CIFS_WRITE_OP)) {
2594 rc = generic_file_aio_write(iocb, iov, nr_segs, pos); 2595 rc = __generic_file_aio_write(iocb, iov, nr_segs);
2596 mutex_unlock(&inode->i_mutex);
2597
2598 if (rc > 0) {
2599 ssize_t err;
2600
2601 err = generic_write_sync(file, iocb->ki_pos - rc, rc);
2602 if (rc < 0)
2603 rc = err;
2604 }
2605 } else {
2606 mutex_unlock(&inode->i_mutex);
2607 }
2595 up_read(&cinode->lock_sem); 2608 up_read(&cinode->lock_sem);
2596 return rc; 2609 return rc;
2597} 2610}
@@ -2727,56 +2740,27 @@ cifs_retry_async_readv(struct cifs_readdata *rdata)
2727/** 2740/**
2728 * cifs_readdata_to_iov - copy data from pages in response to an iovec 2741 * cifs_readdata_to_iov - copy data from pages in response to an iovec
2729 * @rdata: the readdata response with list of pages holding data 2742 * @rdata: the readdata response with list of pages holding data
2730 * @iov: vector in which we should copy the data 2743 * @iter: destination for our data
2731 * @nr_segs: number of segments in vector
2732 * @offset: offset into file of the first iovec
2733 * @copied: used to return the amount of data copied to the iov
2734 * 2744 *
2735 * This function copies data from a list of pages in a readdata response into 2745 * This function copies data from a list of pages in a readdata response into
2736 * an array of iovecs. It will first calculate where the data should go 2746 * an array of iovecs. It will first calculate where the data should go
2737 * based on the info in the readdata and then copy the data into that spot. 2747 * based on the info in the readdata and then copy the data into that spot.
2738 */ 2748 */
2739static ssize_t 2749static int
2740cifs_readdata_to_iov(struct cifs_readdata *rdata, const struct iovec *iov, 2750cifs_readdata_to_iov(struct cifs_readdata *rdata, struct iov_iter *iter)
2741 unsigned long nr_segs, loff_t offset, ssize_t *copied)
2742{ 2751{
2743 int rc = 0; 2752 size_t remaining = rdata->bytes;
2744 struct iov_iter ii;
2745 size_t pos = rdata->offset - offset;
2746 ssize_t remaining = rdata->bytes;
2747 unsigned char *pdata;
2748 unsigned int i; 2753 unsigned int i;
2749 2754
2750 /* set up iov_iter and advance to the correct offset */
2751 iov_iter_init(&ii, iov, nr_segs, iov_length(iov, nr_segs), 0);
2752 iov_iter_advance(&ii, pos);
2753
2754 *copied = 0;
2755 for (i = 0; i < rdata->nr_pages; i++) { 2755 for (i = 0; i < rdata->nr_pages; i++) {
2756 ssize_t copy;
2757 struct page *page = rdata->pages[i]; 2756 struct page *page = rdata->pages[i];
2758 2757 size_t copy = min(remaining, PAGE_SIZE);
2759 /* copy a whole page or whatever's left */ 2758 size_t written = copy_page_to_iter(page, 0, copy, iter);
2760 copy = min_t(ssize_t, remaining, PAGE_SIZE); 2759 remaining -= written;
2761 2760 if (written < copy && iov_iter_count(iter) > 0)
2762 /* ...but limit it to whatever space is left in the iov */ 2761 break;
2763 copy = min_t(ssize_t, copy, iov_iter_count(&ii));
2764
2765 /* go while there's data to be copied and no errors */
2766 if (copy && !rc) {
2767 pdata = kmap(page);
2768 rc = memcpy_toiovecend(ii.iov, pdata, ii.iov_offset,
2769 (int)copy);
2770 kunmap(page);
2771 if (!rc) {
2772 *copied += copy;
2773 remaining -= copy;
2774 iov_iter_advance(&ii, copy);
2775 }
2776 }
2777 } 2762 }
2778 2763 return remaining ? -EFAULT : 0;
2779 return rc;
2780} 2764}
2781 2765
2782static void 2766static void
@@ -2837,20 +2821,21 @@ cifs_uncached_read_into_pages(struct TCP_Server_Info *server,
2837 return total_read > 0 ? total_read : result; 2821 return total_read > 0 ? total_read : result;
2838} 2822}
2839 2823
2840static ssize_t 2824ssize_t cifs_user_readv(struct kiocb *iocb, const struct iovec *iov,
2841cifs_iovec_read(struct file *file, const struct iovec *iov, 2825 unsigned long nr_segs, loff_t pos)
2842 unsigned long nr_segs, loff_t *poffset)
2843{ 2826{
2827 struct file *file = iocb->ki_filp;
2844 ssize_t rc; 2828 ssize_t rc;
2845 size_t len, cur_len; 2829 size_t len, cur_len;
2846 ssize_t total_read = 0; 2830 ssize_t total_read = 0;
2847 loff_t offset = *poffset; 2831 loff_t offset = pos;
2848 unsigned int npages; 2832 unsigned int npages;
2849 struct cifs_sb_info *cifs_sb; 2833 struct cifs_sb_info *cifs_sb;
2850 struct cifs_tcon *tcon; 2834 struct cifs_tcon *tcon;
2851 struct cifsFileInfo *open_file; 2835 struct cifsFileInfo *open_file;
2852 struct cifs_readdata *rdata, *tmp; 2836 struct cifs_readdata *rdata, *tmp;
2853 struct list_head rdata_list; 2837 struct list_head rdata_list;
2838 struct iov_iter to;
2854 pid_t pid; 2839 pid_t pid;
2855 2840
2856 if (!nr_segs) 2841 if (!nr_segs)
@@ -2860,6 +2845,8 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
2860 if (!len) 2845 if (!len)
2861 return 0; 2846 return 0;
2862 2847
2848 iov_iter_init(&to, iov, nr_segs, len, 0);
2849
2863 INIT_LIST_HEAD(&rdata_list); 2850 INIT_LIST_HEAD(&rdata_list);
2864 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 2851 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
2865 open_file = file->private_data; 2852 open_file = file->private_data;
@@ -2917,55 +2904,44 @@ error:
2917 if (!list_empty(&rdata_list)) 2904 if (!list_empty(&rdata_list))
2918 rc = 0; 2905 rc = 0;
2919 2906
2907 len = iov_iter_count(&to);
2920 /* the loop below should proceed in the order of increasing offsets */ 2908 /* the loop below should proceed in the order of increasing offsets */
2921restart_loop:
2922 list_for_each_entry_safe(rdata, tmp, &rdata_list, list) { 2909 list_for_each_entry_safe(rdata, tmp, &rdata_list, list) {
2910 again:
2923 if (!rc) { 2911 if (!rc) {
2924 ssize_t copied;
2925
2926 /* FIXME: freezable sleep too? */ 2912 /* FIXME: freezable sleep too? */
2927 rc = wait_for_completion_killable(&rdata->done); 2913 rc = wait_for_completion_killable(&rdata->done);
2928 if (rc) 2914 if (rc)
2929 rc = -EINTR; 2915 rc = -EINTR;
2930 else if (rdata->result) 2916 else if (rdata->result) {
2931 rc = rdata->result; 2917 rc = rdata->result;
2932 else { 2918 /* resend call if it's a retryable error */
2933 rc = cifs_readdata_to_iov(rdata, iov, 2919 if (rc == -EAGAIN) {
2934 nr_segs, *poffset, 2920 rc = cifs_retry_async_readv(rdata);
2935 &copied); 2921 goto again;
2936 total_read += copied; 2922 }
2923 } else {
2924 rc = cifs_readdata_to_iov(rdata, &to);
2937 } 2925 }
2938 2926
2939 /* resend call if it's a retryable error */
2940 if (rc == -EAGAIN) {
2941 rc = cifs_retry_async_readv(rdata);
2942 goto restart_loop;
2943 }
2944 } 2927 }
2945 list_del_init(&rdata->list); 2928 list_del_init(&rdata->list);
2946 kref_put(&rdata->refcount, cifs_uncached_readdata_release); 2929 kref_put(&rdata->refcount, cifs_uncached_readdata_release);
2947 } 2930 }
2948 2931
2932 total_read = len - iov_iter_count(&to);
2933
2949 cifs_stats_bytes_read(tcon, total_read); 2934 cifs_stats_bytes_read(tcon, total_read);
2950 *poffset += total_read;
2951 2935
2952 /* mask nodata case */ 2936 /* mask nodata case */
2953 if (rc == -ENODATA) 2937 if (rc == -ENODATA)
2954 rc = 0; 2938 rc = 0;
2955 2939
2956 return total_read ? total_read : rc; 2940 if (total_read) {
2957} 2941 iocb->ki_pos = pos + total_read;
2958 2942 return total_read;
2959ssize_t cifs_user_readv(struct kiocb *iocb, const struct iovec *iov, 2943 }
2960 unsigned long nr_segs, loff_t pos) 2944 return rc;
2961{
2962 ssize_t read;
2963
2964 read = cifs_iovec_read(iocb->ki_filp, iov, nr_segs, &pos);
2965 if (read > 0)
2966 iocb->ki_pos = pos;
2967
2968 return read;
2969} 2945}
2970 2946
2971ssize_t 2947ssize_t