aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/file.c69
1 files changed, 41 insertions, 28 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index d6279185e2f0..7df4e4658d74 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2932,43 +2932,23 @@ cifs_uncached_read_into_pages(struct TCP_Server_Info *server,
2932 return total_read > 0 && result != -EAGAIN ? total_read : result; 2932 return total_read > 0 && result != -EAGAIN ? total_read : result;
2933} 2933}
2934 2934
2935ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to) 2935static int
2936cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
2937 struct cifs_sb_info *cifs_sb, struct list_head *rdata_list)
2936{ 2938{
2937 struct file *file = iocb->ki_filp; 2939 struct cifs_readdata *rdata;
2938 ssize_t rc;
2939 size_t len, cur_len;
2940 ssize_t total_read = 0;
2941 loff_t offset = iocb->ki_pos;
2942 unsigned int npages; 2940 unsigned int npages;
2943 struct cifs_sb_info *cifs_sb; 2941 size_t cur_len;
2944 struct cifs_tcon *tcon; 2942 int rc;
2945 struct cifsFileInfo *open_file;
2946 struct cifs_readdata *rdata, *tmp;
2947 struct list_head rdata_list;
2948 pid_t pid; 2943 pid_t pid;
2949 2944
2950 len = iov_iter_count(to);
2951 if (!len)
2952 return 0;
2953
2954 INIT_LIST_HEAD(&rdata_list);
2955 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
2956 open_file = file->private_data;
2957 tcon = tlink_tcon(open_file->tlink);
2958
2959 if (!tcon->ses->server->ops->async_readv)
2960 return -ENOSYS;
2961
2962 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD) 2945 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
2963 pid = open_file->pid; 2946 pid = open_file->pid;
2964 else 2947 else
2965 pid = current->tgid; 2948 pid = current->tgid;
2966 2949
2967 if ((file->f_flags & O_ACCMODE) == O_WRONLY)
2968 cifs_dbg(FYI, "attempting read on write only file instance\n");
2969
2970 do { 2950 do {
2971 cur_len = min_t(const size_t, len - total_read, cifs_sb->rsize); 2951 cur_len = min_t(const size_t, len, cifs_sb->rsize);
2972 npages = DIV_ROUND_UP(cur_len, PAGE_SIZE); 2952 npages = DIV_ROUND_UP(cur_len, PAGE_SIZE);
2973 2953
2974 /* allocate a readdata struct */ 2954 /* allocate a readdata struct */
@@ -2999,11 +2979,44 @@ error:
2999 break; 2979 break;
3000 } 2980 }
3001 2981
3002 list_add_tail(&rdata->list, &rdata_list); 2982 list_add_tail(&rdata->list, rdata_list);
3003 offset += cur_len; 2983 offset += cur_len;
3004 len -= cur_len; 2984 len -= cur_len;
3005 } while (len > 0); 2985 } while (len > 0);
3006 2986
2987 return rc;
2988}
2989
2990ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to)
2991{
2992 struct file *file = iocb->ki_filp;
2993 ssize_t rc;
2994 size_t len;
2995 ssize_t total_read = 0;
2996 loff_t offset = iocb->ki_pos;
2997 struct cifs_sb_info *cifs_sb;
2998 struct cifs_tcon *tcon;
2999 struct cifsFileInfo *open_file;
3000 struct cifs_readdata *rdata, *tmp;
3001 struct list_head rdata_list;
3002
3003 len = iov_iter_count(to);
3004 if (!len)
3005 return 0;
3006
3007 INIT_LIST_HEAD(&rdata_list);
3008 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
3009 open_file = file->private_data;
3010 tcon = tlink_tcon(open_file->tlink);
3011
3012 if (!tcon->ses->server->ops->async_readv)
3013 return -ENOSYS;
3014
3015 if ((file->f_flags & O_ACCMODE) == O_WRONLY)
3016 cifs_dbg(FYI, "attempting read on write only file instance\n");
3017
3018 rc = cifs_send_async_read(offset, len, open_file, cifs_sb, &rdata_list);
3019
3007 /* if at least one read request send succeeded, then reset rc */ 3020 /* if at least one read request send succeeded, then reset rc */
3008 if (!list_empty(&rdata_list)) 3021 if (!list_empty(&rdata_list))
3009 rc = 0; 3022 rc = 0;