diff options
-rw-r--r-- | fs/cifs/file.c | 69 |
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 | ||
2935 | ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to) | 2935 | static int |
2936 | cifs_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 | |||
2990 | ssize_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; |