aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cifsproto.h2
-rw-r--r--fs/cifs/cifssmb.c17
-rw-r--r--fs/cifs/file.c22
3 files changed, 31 insertions, 10 deletions
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index cbf09cdd42a7..57ce6f834220 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -490,6 +490,8 @@ struct cifs_writedata {
490 pid_t pid; 490 pid_t pid;
491 unsigned int bytes; 491 unsigned int bytes;
492 int result; 492 int result;
493 void (*marshal_iov) (struct kvec *iov,
494 struct cifs_writedata *wdata);
493 unsigned int nr_pages; 495 unsigned int nr_pages;
494 struct page *pages[1]; 496 struct page *pages[1];
495}; 497};
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 21ff4bff6c89..5ec0b90b0444 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -2142,7 +2142,6 @@ cifs_async_writev(struct cifs_writedata *wdata)
2142 WRITE_REQ *smb = NULL; 2142 WRITE_REQ *smb = NULL;
2143 int wct; 2143 int wct;
2144 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink); 2144 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2145 struct inode *inode = wdata->cfile->dentry->d_inode;
2146 struct kvec *iov = NULL; 2145 struct kvec *iov = NULL;
2147 2146
2148 if (tcon->ses->capabilities & CAP_LARGE_FILES) { 2147 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
@@ -2185,15 +2184,13 @@ cifs_async_writev(struct cifs_writedata *wdata)
2185 iov[0].iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4 + 1; 2184 iov[0].iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4 + 1;
2186 iov[0].iov_base = smb; 2185 iov[0].iov_base = smb;
2187 2186
2188 /* marshal up the pages into iov array */ 2187 /*
2189 wdata->bytes = 0; 2188 * This function should marshal up the page array into the kvec
2190 for (i = 0; i < wdata->nr_pages; i++) { 2189 * array, reserving [0] for the header. It should kmap the pages
2191 iov[i + 1].iov_len = min(inode->i_size - 2190 * and set the iov_len properly for each one. It may also set
2192 page_offset(wdata->pages[i]), 2191 * wdata->bytes too.
2193 (loff_t)PAGE_CACHE_SIZE); 2192 */
2194 iov[i + 1].iov_base = kmap(wdata->pages[i]); 2193 wdata->marshal_iov(iov, wdata);
2195 wdata->bytes += iov[i + 1].iov_len;
2196 }
2197 2194
2198 cFYI(1, "async write at %llu %u bytes", wdata->offset, wdata->bytes); 2195 cFYI(1, "async write at %llu %u bytes", wdata->offset, wdata->bytes);
2199 2196
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 5633202b199c..58ac0f0512e7 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1648,6 +1648,27 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
1648 return rc; 1648 return rc;
1649} 1649}
1650 1650
1651/*
1652 * Marshal up the iov array, reserving the first one for the header. Also,
1653 * set wdata->bytes.
1654 */
1655static void
1656cifs_writepages_marshal_iov(struct kvec *iov, struct cifs_writedata *wdata)
1657{
1658 int i;
1659 struct inode *inode = wdata->cfile->dentry->d_inode;
1660 loff_t size = i_size_read(inode);
1661
1662 /* marshal up the pages into iov array */
1663 wdata->bytes = 0;
1664 for (i = 0; i < wdata->nr_pages; i++) {
1665 iov[i + 1].iov_len = min(size - page_offset(wdata->pages[i]),
1666 (loff_t)PAGE_CACHE_SIZE);
1667 iov[i + 1].iov_base = kmap(wdata->pages[i]);
1668 wdata->bytes += iov[i + 1].iov_len;
1669 }
1670}
1671
1651static int cifs_writepages(struct address_space *mapping, 1672static int cifs_writepages(struct address_space *mapping,
1652 struct writeback_control *wbc) 1673 struct writeback_control *wbc)
1653{ 1674{
@@ -1792,6 +1813,7 @@ retry:
1792 wdata->sync_mode = wbc->sync_mode; 1813 wdata->sync_mode = wbc->sync_mode;
1793 wdata->nr_pages = nr_pages; 1814 wdata->nr_pages = nr_pages;
1794 wdata->offset = page_offset(wdata->pages[0]); 1815 wdata->offset = page_offset(wdata->pages[0]);
1816 wdata->marshal_iov = cifs_writepages_marshal_iov;
1795 1817
1796 do { 1818 do {
1797 if (wdata->cfile != NULL) 1819 if (wdata->cfile != NULL)