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>
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];
};
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) {
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);
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)
{
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)