summaryrefslogtreecommitdiffstats
path: root/fs/cifs/file.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2012-09-18 16:20:35 -0700
committerSteve French <smfrench@gmail.com>2012-09-24 21:46:31 -0500
commiteddb079deb4deb1259f87425094c7a586fc59313 (patch)
treeca5c475cfd138a8e764673b0ecc2a54b4df2b7b3 /fs/cifs/file.c
parentfec344e3f31aa911297cd3a4639432d983b1f324 (diff)
downloadlinux-eddb079deb4deb1259f87425094c7a586fc59313.tar.gz
linux-eddb079deb4deb1259f87425094c7a586fc59313.tar.bz2
linux-eddb079deb4deb1259f87425094c7a586fc59313.zip
cifs: convert async write code to pass in data via rq_pages array
Reviewed-by: Pavel Shilovsky <pshilovsky@samba.org> Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r--fs/cifs/file.c48
1 files changed, 10 insertions, 38 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 2418618118b6..8a781226ae33 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1738,27 +1738,6 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
return rc;
}
-/*
- * Marshal up the iov array, reserving the first one for the header. Also,
- * set wdata->bytes.
- */
-static void
-cifs_writepages_marshal_iov(struct kvec *iov, struct cifs_writedata *wdata)
-{
- int i;
- struct inode *inode = wdata->cfile->dentry->d_inode;
- loff_t size = i_size_read(inode);
-
- /* marshal up the pages into iov array */
- wdata->bytes = 0;
- for (i = 0; i < wdata->nr_pages; i++) {
- iov[i + 1].iov_len = min(size - page_offset(wdata->pages[i]),
- (loff_t)PAGE_CACHE_SIZE);
- iov[i + 1].iov_base = kmap(wdata->pages[i]);
- wdata->bytes += iov[i + 1].iov_len;
- }
-}
-
static int cifs_writepages(struct address_space *mapping,
struct writeback_control *wbc)
{
@@ -1769,6 +1748,7 @@ static int cifs_writepages(struct address_space *mapping,
struct TCP_Server_Info *server;
struct page *page;
int rc = 0;
+ loff_t isize = i_size_read(mapping->host);
/*
* If wsize is smaller than the page cache size, default to writing
@@ -1873,7 +1853,7 @@ retry:
*/
set_page_writeback(page);
- if (page_offset(page) >= mapping->host->i_size) {
+ if (page_offset(page) >= isize) {
done = true;
unlock_page(page);
end_page_writeback(page);
@@ -1904,7 +1884,12 @@ retry:
wdata->sync_mode = wbc->sync_mode;
wdata->nr_pages = nr_pages;
wdata->offset = page_offset(wdata->pages[0]);
- wdata->marshal_iov = cifs_writepages_marshal_iov;
+ wdata->pagesz = PAGE_CACHE_SIZE;
+ wdata->tailsz =
+ min(isize - page_offset(wdata->pages[nr_pages - 1]),
+ (loff_t)PAGE_CACHE_SIZE);
+ wdata->bytes = ((nr_pages - 1) * PAGE_CACHE_SIZE) +
+ wdata->tailsz;
do {
if (wdata->cfile != NULL)
@@ -2206,20 +2191,6 @@ size_t get_numpages(const size_t wsize, const size_t len, size_t *cur_len)
}
static void
-cifs_uncached_marshal_iov(struct kvec *iov, struct cifs_writedata *wdata)
-{
- int i;
- size_t bytes = wdata->bytes;
-
- /* marshal up the pages into iov array */
- for (i = 0; i < wdata->nr_pages; i++) {
- iov[i + 1].iov_len = min_t(size_t, bytes, PAGE_SIZE);
- iov[i + 1].iov_base = kmap(wdata->pages[i]);
- bytes -= iov[i + 1].iov_len;
- }
-}
-
-static void
cifs_uncached_writev_complete(struct work_struct *work)
{
int i;
@@ -2339,7 +2310,8 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
wdata->cfile = cifsFileInfo_get(open_file);
wdata->pid = pid;
wdata->bytes = cur_len;
- wdata->marshal_iov = cifs_uncached_marshal_iov;
+ wdata->pagesz = PAGE_SIZE;
+ wdata->tailsz = cur_len - ((nr_pages - 1) * PAGE_SIZE);
rc = cifs_uncached_retry_writev(wdata);
if (rc) {
kref_put(&wdata->refcount, cifs_writedata_release);