diff options
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/cifsproto.h | 2 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 17 | ||||
-rw-r--r-- | fs/cifs/file.c | 22 |
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 | */ | ||
1655 | static void | ||
1656 | cifs_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 | |||
1651 | static int cifs_writepages(struct address_space *mapping, | 1672 | static 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) |