From 371098c6a689da81fbb53bf7acf128f89a6efa09 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 1 Apr 2015 21:54:42 -0400 Subject: 9p: switch ->writepage() to direct use of p9_client_write() Don't mess with kmap() - just use ITER_BVEC. Signed-off-by: Al Viro --- fs/9p/vfs_addr.c | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) (limited to 'fs/9p/vfs_addr.c') diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index ff1a5bac4200..0e153f07e0fc 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c @@ -161,41 +161,32 @@ static void v9fs_invalidate_page(struct page *page, unsigned int offset, static int v9fs_vfs_writepage_locked(struct page *page) { - char *buffer; - int retval, len; - loff_t offset, size; - mm_segment_t old_fs; - struct v9fs_inode *v9inode; struct inode *inode = page->mapping->host; + struct v9fs_inode *v9inode = V9FS_I(inode); + loff_t size = i_size_read(inode); + struct iov_iter from; + struct bio_vec bvec; + int err, len; - v9inode = V9FS_I(inode); - size = i_size_read(inode); if (page->index == size >> PAGE_CACHE_SHIFT) len = size & ~PAGE_CACHE_MASK; else len = PAGE_CACHE_SIZE; - set_page_writeback(page); - - buffer = kmap(page); - offset = page_offset(page); + bvec.bv_page = page; + bvec.bv_offset = 0; + bvec.bv_len = len; + iov_iter_bvec(&from, ITER_BVEC | WRITE, &bvec, 1, len); - old_fs = get_fs(); - set_fs(get_ds()); /* We should have writeback_fid always set */ BUG_ON(!v9inode->writeback_fid); - retval = v9fs_file_write_internal(inode, - v9inode->writeback_fid, - (__force const char __user *)buffer, - len, &offset, 0); - if (retval > 0) - retval = 0; + set_page_writeback(page); + + p9_client_write(v9inode->writeback_fid, page_offset(page), &from, &err); - set_fs(old_fs); - kunmap(page); end_page_writeback(page); - return retval; + return err; } static int v9fs_vfs_writepage(struct page *page, struct writeback_control *wbc) -- cgit v1.2.3 From 9565a5445240cd441f2c670aa7260ee8eb5dff79 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 1 Apr 2015 22:32:23 -0400 Subject: 9p: get rid of v9fs_direct_file_write() just handle it in ->direct_IO() Signed-off-by: Al Viro --- fs/9p/vfs_addr.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'fs/9p/vfs_addr.c') diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index 0e153f07e0fc..402269c108cd 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c @@ -252,15 +252,21 @@ static int v9fs_launder_page(struct page *page) static ssize_t v9fs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, loff_t pos) { - /* - * FIXME - * Now that we do caching with cache mode enabled, We need - * to support direct IO - */ - p9_debug(P9_DEBUG_VFS, "v9fs_direct_IO: v9fs_direct_IO (%pD) off/no(%lld/%lu) EINVAL\n", - iocb->ki_filp, - (long long)pos, iter->nr_segs); - + struct file *file = iocb->ki_filp; + if (rw == WRITE) { + ssize_t written; + int err = 0; + + written = p9_client_write(file->private_data, pos, iter, &err); + if (written) { + struct inode *inode = file_inode(file); + loff_t i_size = i_size_read(inode); + if (pos + written > i_size) + inode_add_bytes(inode, pos + written - i_size); + return written; + } + return err; + } return -EINVAL; } -- cgit v1.2.3 From e1200fe68f20759f359698f8a8dc81d06d1265f5 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 1 Apr 2015 23:42:28 -0400 Subject: 9p: switch p9_client_read() to passing struct iov_iter * ... and make it loop Signed-off-by: Al Viro --- fs/9p/vfs_addr.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'fs/9p/vfs_addr.c') diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index 402269c108cd..afe3225aaf36 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c @@ -51,12 +51,11 @@ */ static int v9fs_fid_readpage(struct p9_fid *fid, struct page *page) { - int retval; - loff_t offset; - char *buffer; - struct inode *inode; + struct inode *inode = page->mapping->host; + struct bio_vec bvec = {.bv_page = page, .bv_len = PAGE_SIZE}; + struct iov_iter to; + int retval, err; - inode = page->mapping->host; p9_debug(P9_DEBUG_VFS, "\n"); BUG_ON(!PageLocked(page)); @@ -65,16 +64,16 @@ static int v9fs_fid_readpage(struct p9_fid *fid, struct page *page) if (retval == 0) return retval; - buffer = kmap(page); - offset = page_offset(page); + iov_iter_bvec(&to, ITER_BVEC | READ, &bvec, 1, PAGE_SIZE); - retval = v9fs_fid_readn(fid, buffer, NULL, PAGE_CACHE_SIZE, offset); - if (retval < 0) { + retval = p9_client_read(fid, page_offset(page), &to, &err); + if (err) { v9fs_uncache_page(inode, page); + retval = err; goto done; } - memset(buffer + retval, 0, PAGE_CACHE_SIZE - retval); + zero_user(page, retval, PAGE_SIZE - retval); flush_dcache_page(page); SetPageUptodate(page); @@ -82,7 +81,6 @@ static int v9fs_fid_readpage(struct p9_fid *fid, struct page *page) retval = 0; done: - kunmap(page); unlock_page(page); return retval; } -- cgit v1.2.3 From 42b1ab979d92d21ae2ea376e77f33f18973b9581 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 1 Apr 2015 23:49:24 -0400 Subject: 9p: get rid of v9fs_direct_file_read() do it in ->direct_IO()... Signed-off-by: Al Viro --- fs/9p/vfs_addr.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'fs/9p/vfs_addr.c') diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index afe3225aaf36..2e38f9a5b472 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c @@ -251,21 +251,20 @@ static ssize_t v9fs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, loff_t pos) { struct file *file = iocb->ki_filp; - if (rw == WRITE) { - ssize_t written; - int err = 0; - - written = p9_client_write(file->private_data, pos, iter, &err); - if (written) { + ssize_t n; + int err = 0; + if (rw & WRITE) { + n = p9_client_write(file->private_data, pos, iter, &err); + if (n) { struct inode *inode = file_inode(file); loff_t i_size = i_size_read(inode); - if (pos + written > i_size) - inode_add_bytes(inode, pos + written - i_size); - return written; + if (pos + n > i_size) + inode_add_bytes(inode, pos + n - i_size); } - return err; + } else { + n = p9_client_read(file->private_data, pos, iter, &err); } - return -EINVAL; + return n ? n : err; } static int v9fs_write_begin(struct file *filp, struct address_space *mapping, -- cgit v1.2.3