CIFS: Separate writing from iovec write
authorPavel Shilovsky <pshilovsky@samba.org>
Fri, 20 Jun 2014 12:10:52 +0000 (16:10 +0400)
committerSteve French <smfrench@gmail.com>
Sat, 2 Aug 2014 06:23:02 +0000 (01:23 -0500)
Reviewed-by: Shirish Pargaonkar <spargaonkar@suse.com>
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org>
Signed-off-by: Steve French <smfrench@gmail.com>
fs/cifs/file.c

index f96f61c849fe2b34c14d1fe9bb347ac9049ed05a..666069811ab854daabf8683d39457e2f7129b001 100644 (file)
@@ -2465,41 +2465,17 @@ wdata_fill_from_iovec(struct cifs_writedata *wdata, struct iov_iter *from,
        return 0;
 }
 
-static ssize_t
-cifs_iovec_write(struct file *file, struct iov_iter *from, loff_t *poffset)
+static int
+cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
+                    struct cifsFileInfo *open_file,
+                    struct cifs_sb_info *cifs_sb, struct list_head *wdata_list)
 {
+       int rc = 0;
+       size_t cur_len;
        unsigned long nr_pages, num_pages, i;
-       size_t len, cur_len;
-       ssize_t total_written = 0;
-       loff_t offset;
-       struct cifsFileInfo *open_file;
-       struct cifs_tcon *tcon;
-       struct cifs_sb_info *cifs_sb;
-       struct cifs_writedata *wdata, *tmp;
-       struct list_head wdata_list;
-       int rc;
+       struct cifs_writedata *wdata;
        pid_t pid;
 
-       len = iov_iter_count(from);
-       rc = generic_write_checks(file, poffset, &len, 0);
-       if (rc)
-               return rc;
-
-       if (!len)
-               return 0;
-
-       iov_iter_truncate(from, len);
-
-       INIT_LIST_HEAD(&wdata_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_writev)
-               return -ENOSYS;
-
-       offset = *poffset;
-
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
                pid = open_file->pid;
        else
@@ -2551,11 +2527,47 @@ cifs_iovec_write(struct file *file, struct iov_iter *from, loff_t *poffset)
                        break;
                }
 
-               list_add_tail(&wdata->list, &wdata_list);
+               list_add_tail(&wdata->list, wdata_list);
                offset += cur_len;
                len -= cur_len;
        } while (len > 0);
 
+       return rc;
+}
+
+static ssize_t
+cifs_iovec_write(struct file *file, struct iov_iter *from, loff_t *poffset)
+{
+       size_t len;
+       ssize_t total_written = 0;
+       struct cifsFileInfo *open_file;
+       struct cifs_tcon *tcon;
+       struct cifs_sb_info *cifs_sb;
+       struct cifs_writedata *wdata, *tmp;
+       struct list_head wdata_list;
+       int rc;
+
+       len = iov_iter_count(from);
+       rc = generic_write_checks(file, poffset, &len, 0);
+       if (rc)
+               return rc;
+
+       if (!len)
+               return 0;
+
+       iov_iter_truncate(from, len);
+
+       INIT_LIST_HEAD(&wdata_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_writev)
+               return -ENOSYS;
+
+       rc = cifs_write_from_iter(*poffset, len, from, open_file, cifs_sb,
+                                 &wdata_list);
+
        /*
         * If at least one write was successfully sent, then discard any rc
         * value from the later writes. If the other write succeeds, then