diff mbox

[v3,13/16] CIFS: Separate page reading from user read

Message ID 1405957558-18476-14-git-send-email-pshilovsky@samba.org (mailing list archive)
State New, archived
Headers show

Commit Message

Pavel Shilovsky July 21, 2014, 3:45 p.m. UTC
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org>
---
 fs/cifs/file.c | 69 ++++++++++++++++++++++++++++++++++------------------------
 1 file changed, 41 insertions(+), 28 deletions(-)

Comments

Shirish Pargaonkar July 27, 2014, 12:21 p.m. UTC | #1
Reviewed-by: Shirish Pargaonkar <spargaonkar@suse.com>

On Mon, Jul 21, 2014 at 10:45 AM, Pavel Shilovsky <pshilovsky@samba.org> wrote:
> Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org>
> ---
>  fs/cifs/file.c | 69 ++++++++++++++++++++++++++++++++++------------------------
>  1 file changed, 41 insertions(+), 28 deletions(-)
>
> diff --git a/fs/cifs/file.c b/fs/cifs/file.c
> index d627918..7df4e46 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,
>         return total_read > 0 && result != -EAGAIN ? total_read : result;
>  }
>
> -ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to)
> +static int
> +cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
> +                    struct cifs_sb_info *cifs_sb, struct list_head *rdata_list)
>  {
> -       struct file *file = iocb->ki_filp;
> -       ssize_t rc;
> -       size_t len, cur_len;
> -       ssize_t total_read = 0;
> -       loff_t offset = iocb->ki_pos;
> +       struct cifs_readdata *rdata;
>         unsigned int npages;
> -       struct cifs_sb_info *cifs_sb;
> -       struct cifs_tcon *tcon;
> -       struct cifsFileInfo *open_file;
> -       struct cifs_readdata *rdata, *tmp;
> -       struct list_head rdata_list;
> +       size_t cur_len;
> +       int rc;
>         pid_t pid;
>
> -       len = iov_iter_count(to);
> -       if (!len)
> -               return 0;
> -
> -       INIT_LIST_HEAD(&rdata_list);
> -       cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
> -       open_file = file->private_data;
> -       tcon = tlink_tcon(open_file->tlink);
> -
> -       if (!tcon->ses->server->ops->async_readv)
> -               return -ENOSYS;
> -
>         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
>                 pid = open_file->pid;
>         else
>                 pid = current->tgid;
>
> -       if ((file->f_flags & O_ACCMODE) == O_WRONLY)
> -               cifs_dbg(FYI, "attempting read on write only file instance\n");
> -
>         do {
> -               cur_len = min_t(const size_t, len - total_read, cifs_sb->rsize);
> +               cur_len = min_t(const size_t, len, cifs_sb->rsize);
>                 npages = DIV_ROUND_UP(cur_len, PAGE_SIZE);
>
>                 /* allocate a readdata struct */
> @@ -2999,11 +2979,44 @@ error:
>                         break;
>                 }
>
> -               list_add_tail(&rdata->list, &rdata_list);
> +               list_add_tail(&rdata->list, rdata_list);
>                 offset += cur_len;
>                 len -= cur_len;
>         } while (len > 0);
>
> +       return rc;
> +}
> +
> +ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to)
> +{
> +       struct file *file = iocb->ki_filp;
> +       ssize_t rc;
> +       size_t len;
> +       ssize_t total_read = 0;
> +       loff_t offset = iocb->ki_pos;
> +       struct cifs_sb_info *cifs_sb;
> +       struct cifs_tcon *tcon;
> +       struct cifsFileInfo *open_file;
> +       struct cifs_readdata *rdata, *tmp;
> +       struct list_head rdata_list;
> +
> +       len = iov_iter_count(to);
> +       if (!len)
> +               return 0;
> +
> +       INIT_LIST_HEAD(&rdata_list);
> +       cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
> +       open_file = file->private_data;
> +       tcon = tlink_tcon(open_file->tlink);
> +
> +       if (!tcon->ses->server->ops->async_readv)
> +               return -ENOSYS;
> +
> +       if ((file->f_flags & O_ACCMODE) == O_WRONLY)
> +               cifs_dbg(FYI, "attempting read on write only file instance\n");
> +
> +       rc = cifs_send_async_read(offset, len, open_file, cifs_sb, &rdata_list);
> +
>         /* if at least one read request send succeeded, then reset rc */
>         if (!list_empty(&rdata_list))
>                 rc = 0;
> --
> 1.8.1.2
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index d627918..7df4e46 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,
 	return total_read > 0 && result != -EAGAIN ? total_read : result;
 }
 
-ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to)
+static int
+cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
+		     struct cifs_sb_info *cifs_sb, struct list_head *rdata_list)
 {
-	struct file *file = iocb->ki_filp;
-	ssize_t rc;
-	size_t len, cur_len;
-	ssize_t total_read = 0;
-	loff_t offset = iocb->ki_pos;
+	struct cifs_readdata *rdata;
 	unsigned int npages;
-	struct cifs_sb_info *cifs_sb;
-	struct cifs_tcon *tcon;
-	struct cifsFileInfo *open_file;
-	struct cifs_readdata *rdata, *tmp;
-	struct list_head rdata_list;
+	size_t cur_len;
+	int rc;
 	pid_t pid;
 
-	len = iov_iter_count(to);
-	if (!len)
-		return 0;
-
-	INIT_LIST_HEAD(&rdata_list);
-	cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
-	open_file = file->private_data;
-	tcon = tlink_tcon(open_file->tlink);
-
-	if (!tcon->ses->server->ops->async_readv)
-		return -ENOSYS;
-
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
 		pid = open_file->pid;
 	else
 		pid = current->tgid;
 
-	if ((file->f_flags & O_ACCMODE) == O_WRONLY)
-		cifs_dbg(FYI, "attempting read on write only file instance\n");
-
 	do {
-		cur_len = min_t(const size_t, len - total_read, cifs_sb->rsize);
+		cur_len = min_t(const size_t, len, cifs_sb->rsize);
 		npages = DIV_ROUND_UP(cur_len, PAGE_SIZE);
 
 		/* allocate a readdata struct */
@@ -2999,11 +2979,44 @@  error:
 			break;
 		}
 
-		list_add_tail(&rdata->list, &rdata_list);
+		list_add_tail(&rdata->list, rdata_list);
 		offset += cur_len;
 		len -= cur_len;
 	} while (len > 0);
 
+	return rc;
+}
+
+ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to)
+{
+	struct file *file = iocb->ki_filp;
+	ssize_t rc;
+	size_t len;
+	ssize_t total_read = 0;
+	loff_t offset = iocb->ki_pos;
+	struct cifs_sb_info *cifs_sb;
+	struct cifs_tcon *tcon;
+	struct cifsFileInfo *open_file;
+	struct cifs_readdata *rdata, *tmp;
+	struct list_head rdata_list;
+
+	len = iov_iter_count(to);
+	if (!len)
+		return 0;
+
+	INIT_LIST_HEAD(&rdata_list);
+	cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
+	open_file = file->private_data;
+	tcon = tlink_tcon(open_file->tlink);
+
+	if (!tcon->ses->server->ops->async_readv)
+		return -ENOSYS;
+
+	if ((file->f_flags & O_ACCMODE) == O_WRONLY)
+		cifs_dbg(FYI, "attempting read on write only file instance\n");
+
+	rc = cifs_send_async_read(offset, len, open_file, cifs_sb, &rdata_list);
+
 	/* if at least one read request send succeeded, then reset rc */
 	if (!list_empty(&rdata_list))
 		rc = 0;