]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
cifs: abstract out function to marshal up the iovec array for async writes
authorJeff Layton <jlayton@redhat.com>
Fri, 23 Mar 2012 18:40:56 +0000 (14:40 -0400)
committerJeff Layton <jlayton@redhat.com>
Fri, 23 Mar 2012 18:40:56 +0000 (14:40 -0400)
We'll need to do something a bit different depending on the caller.
Abstract the code that marshals the page array into an iovec.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Reviewed-by: Pavel Shilovsky <piastry@etersoft.ru>
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/file.c

index cbf09cdd42a78d11969d3c1ac661cadee824f98e..57ce6f834220e4d11a0d93a51374ec02c7cbf743 100644 (file)
@@ -490,6 +490,8 @@ struct cifs_writedata {
        pid_t                           pid;
        unsigned int                    bytes;
        int                             result;
+       void (*marshal_iov) (struct kvec *iov,
+                            struct cifs_writedata *wdata);
        unsigned int                    nr_pages;
        struct page                     *pages[1];
 };
index 21ff4bff6c897737a2ecae2a208c5fd743ae82e9..5ec0b90b0444594e15547082af47ad524ded6672 100644 (file)
@@ -2142,7 +2142,6 @@ cifs_async_writev(struct cifs_writedata *wdata)
        WRITE_REQ *smb = NULL;
        int wct;
        struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
-       struct inode *inode = wdata->cfile->dentry->d_inode;
        struct kvec *iov = NULL;
 
        if (tcon->ses->capabilities & CAP_LARGE_FILES) {
@@ -2185,15 +2184,13 @@ cifs_async_writev(struct cifs_writedata *wdata)
        iov[0].iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4 + 1;
        iov[0].iov_base = smb;
 
-       /* marshal up the pages into iov array */
-       wdata->bytes = 0;
-       for (i = 0; i < wdata->nr_pages; i++) {
-               iov[i + 1].iov_len = min(inode->i_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;
-       }
+       /*
+        * This function should marshal up the page array into the kvec
+        * array, reserving [0] for the header. It should kmap the pages
+        * and set the iov_len properly for each one. It may also set
+        * wdata->bytes too.
+        */
+       wdata->marshal_iov(iov, wdata);
 
        cFYI(1, "async write at %llu %u bytes", wdata->offset, wdata->bytes);
 
index 5633202b199cce57b066dbf70896b9d8995759a8..58ac0f0512e78675fe92638aeabd3606eebfdf18 100644 (file)
@@ -1648,6 +1648,27 @@ 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)
 {
@@ -1792,6 +1813,7 @@ 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;
 
                do {
                        if (wdata->cfile != NULL)