aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/file.c
diff options
context:
space:
mode:
authorPavel Shilovsky <pshilovsky@samba.org>2014-06-20 08:10:52 -0400
committerSteve French <smfrench@gmail.com>2014-08-02 02:23:02 -0400
commit43de94eadf0ceda54509335343bdc1349a2c5ab3 (patch)
treea05ef39f1db0ebe4f50fc4c96f239b6077b3864a /fs/cifs/file.c
parent66386c08be5d1a2eefc1f7ab8c008561b6c811e5 (diff)
CIFS: Separate writing from iovec write
Reviewed-by: Shirish Pargaonkar <spargaonkar@suse.com> Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org> Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r--fs/cifs/file.c76
1 files changed, 44 insertions, 32 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index f96f61c849fe..666069811ab8 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2465,41 +2465,17 @@ wdata_fill_from_iovec(struct cifs_writedata *wdata, struct iov_iter *from,
2465 return 0; 2465 return 0;
2466} 2466}
2467 2467
2468static ssize_t 2468static int
2469cifs_iovec_write(struct file *file, struct iov_iter *from, loff_t *poffset) 2469cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
2470 struct cifsFileInfo *open_file,
2471 struct cifs_sb_info *cifs_sb, struct list_head *wdata_list)
2470{ 2472{
2473 int rc = 0;
2474 size_t cur_len;
2471 unsigned long nr_pages, num_pages, i; 2475 unsigned long nr_pages, num_pages, i;
2472 size_t len, cur_len; 2476 struct cifs_writedata *wdata;
2473 ssize_t total_written = 0;
2474 loff_t offset;
2475 struct cifsFileInfo *open_file;
2476 struct cifs_tcon *tcon;
2477 struct cifs_sb_info *cifs_sb;
2478 struct cifs_writedata *wdata, *tmp;
2479 struct list_head wdata_list;
2480 int rc;
2481 pid_t pid; 2477 pid_t pid;
2482 2478
2483 len = iov_iter_count(from);
2484 rc = generic_write_checks(file, poffset, &len, 0);
2485 if (rc)
2486 return rc;
2487
2488 if (!len)
2489 return 0;
2490
2491 iov_iter_truncate(from, len);
2492
2493 INIT_LIST_HEAD(&wdata_list);
2494 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
2495 open_file = file->private_data;
2496 tcon = tlink_tcon(open_file->tlink);
2497
2498 if (!tcon->ses->server->ops->async_writev)
2499 return -ENOSYS;
2500
2501 offset = *poffset;
2502
2503 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD) 2479 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
2504 pid = open_file->pid; 2480 pid = open_file->pid;
2505 else 2481 else
@@ -2551,11 +2527,47 @@ cifs_iovec_write(struct file *file, struct iov_iter *from, loff_t *poffset)
2551 break; 2527 break;
2552 } 2528 }
2553 2529
2554 list_add_tail(&wdata->list, &wdata_list); 2530 list_add_tail(&wdata->list, wdata_list);
2555 offset += cur_len; 2531 offset += cur_len;
2556 len -= cur_len; 2532 len -= cur_len;
2557 } while (len > 0); 2533 } while (len > 0);
2558 2534
2535 return rc;
2536}
2537
2538static ssize_t
2539cifs_iovec_write(struct file *file, struct iov_iter *from, loff_t *poffset)
2540{
2541 size_t len;
2542 ssize_t total_written = 0;
2543 struct cifsFileInfo *open_file;
2544 struct cifs_tcon *tcon;
2545 struct cifs_sb_info *cifs_sb;
2546 struct cifs_writedata *wdata, *tmp;
2547 struct list_head wdata_list;
2548 int rc;
2549
2550 len = iov_iter_count(from);
2551 rc = generic_write_checks(file, poffset, &len, 0);
2552 if (rc)
2553 return rc;
2554
2555 if (!len)
2556 return 0;
2557
2558 iov_iter_truncate(from, len);
2559
2560 INIT_LIST_HEAD(&wdata_list);
2561 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
2562 open_file = file->private_data;
2563 tcon = tlink_tcon(open_file->tlink);
2564
2565 if (!tcon->ses->server->ops->async_writev)
2566 return -ENOSYS;
2567
2568 rc = cifs_write_from_iter(*poffset, len, from, open_file, cifs_sb,
2569 &wdata_list);
2570
2559 /* 2571 /*
2560 * If at least one write was successfully sent, then discard any rc 2572 * If at least one write was successfully sent, then discard any rc
2561 * value from the later writes. If the other write succeeds, then 2573 * value from the later writes. If the other write succeeds, then