1/* 2 * linux/fs/9p/vfs_addr.c 3 * 4 * This file contians vfs address (mmap) ops for 9P2000. 5 * 6 * Copyright (C) 2005 by Eric Van Hensbergen <ericvh@gmail.com> 7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 11 * as published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to: 20 * Free Software Foundation 21 * 51 Franklin Street, Fifth Floor 22 * Boston, MA 02111-1301 USA 23 * 24 */ 25 26#include <linux/module.h> 27#include <linux/errno.h> 28#include <linux/fs.h> 29#include <linux/file.h> 30#include <linux/stat.h> 31#include <linux/string.h> 32#include <linux/inet.h> 33#include <linux/pagemap.h> 34#include <linux/idr.h> 35#include <linux/sched.h> 36#include <linux/uio.h> 37#include <net/9p/9p.h> 38#include <net/9p/client.h> 39 40#include "v9fs.h" 41#include "v9fs_vfs.h" 42#include "cache.h" 43#include "fid.h" 44 45/** 46 * v9fs_fid_readpage - read an entire page in from 9P 47 * 48 * @fid: fid being read 49 * @page: structure to page 50 * 51 */ 52static int v9fs_fid_readpage(struct p9_fid *fid, struct page *page) 53{ 54 struct inode *inode = page->mapping->host; 55 struct bio_vec bvec = {.bv_page = page, .bv_len = PAGE_SIZE}; 56 struct iov_iter to; 57 int retval, err; 58 59 p9_debug(P9_DEBUG_VFS, "\n"); 60 61 BUG_ON(!PageLocked(page)); 62 63 retval = v9fs_readpage_from_fscache(inode, page); 64 if (retval == 0) 65 return retval; 66 67 iov_iter_bvec(&to, ITER_BVEC | READ, &bvec, 1, PAGE_SIZE); 68 69 retval = p9_client_read(fid, page_offset(page), &to, &err); 70 if (err) { 71 v9fs_uncache_page(inode, page); 72 retval = err; 73 goto done; 74 } 75 76 zero_user(page, retval, PAGE_SIZE - retval); 77 flush_dcache_page(page); 78 SetPageUptodate(page); 79 80 v9fs_readpage_to_fscache(inode, page); 81 retval = 0; 82 83done: 84 unlock_page(page); 85 return retval; 86} 87 88/** 89 * v9fs_vfs_readpage - read an entire page in from 9P 90 * 91 * @filp: file being read 92 * @page: structure to page 93 * 94 */ 95 96static int v9fs_vfs_readpage(struct file *filp, struct page *page) 97{ 98 return v9fs_fid_readpage(filp->private_data, page); 99} 100 101/** 102 * v9fs_vfs_readpages - read a set of pages from 9P 103 * 104 * @filp: file being read 105 * @mapping: the address space 106 * @pages: list of pages to read 107 * @nr_pages: count of pages to read 108 * 109 */ 110 111static int v9fs_vfs_readpages(struct file *filp, struct address_space *mapping, 112 struct list_head *pages, unsigned nr_pages) 113{ 114 int ret = 0; 115 struct inode *inode; 116 117 inode = mapping->host; 118 p9_debug(P9_DEBUG_VFS, "inode: %p file: %p\n", inode, filp); 119 120 ret = v9fs_readpages_from_fscache(inode, mapping, pages, &nr_pages); 121 if (ret == 0) 122 return ret; 123 124 ret = read_cache_pages(mapping, pages, (void *)v9fs_vfs_readpage, filp); 125 p9_debug(P9_DEBUG_VFS, " = %d\n", ret); 126 return ret; 127} 128 129/** 130 * v9fs_release_page - release the private state associated with a page 131 * 132 * Returns 1 if the page can be released, false otherwise. 133 */ 134 135static int v9fs_release_page(struct page *page, gfp_t gfp) 136{ 137 if (PagePrivate(page)) 138 return 0; 139 return v9fs_fscache_release_page(page, gfp); 140} 141 142/** 143 * v9fs_invalidate_page - Invalidate a page completely or partially 144 * 145 * @page: structure to page 146 * @offset: offset in the page 147 */ 148 149static void v9fs_invalidate_page(struct page *page, unsigned int offset, 150 unsigned int length) 151{ 152 /* 153 * If called with zero offset, we should release 154 * the private state assocated with the page 155 */ 156 if (offset == 0 && length == PAGE_CACHE_SIZE) 157 v9fs_fscache_invalidate_page(page); 158} 159 160static int v9fs_vfs_writepage_locked(struct page *page) 161{ 162 struct inode *inode = page->mapping->host; 163 struct v9fs_inode *v9inode = V9FS_I(inode); 164 loff_t size = i_size_read(inode); 165 struct iov_iter from; 166 struct bio_vec bvec; 167 int err, len; 168 169 if (page->index == size >> PAGE_CACHE_SHIFT) 170 len = size & ~PAGE_CACHE_MASK; 171 else 172 len = PAGE_CACHE_SIZE; 173 174 bvec.bv_page = page; 175 bvec.bv_offset = 0; 176 bvec.bv_len = len; 177 iov_iter_bvec(&from, ITER_BVEC | WRITE, &bvec, 1, len); 178 179 /* We should have writeback_fid always set */ 180 BUG_ON(!v9inode->writeback_fid); 181 182 set_page_writeback(page); 183 184 p9_client_write(v9inode->writeback_fid, page_offset(page), &from, &err); 185 186 end_page_writeback(page); 187 return err; 188} 189 190static int v9fs_vfs_writepage(struct page *page, struct writeback_control *wbc) 191{ 192 int retval; 193 194 p9_debug(P9_DEBUG_VFS, "page %p\n", page); 195 196 retval = v9fs_vfs_writepage_locked(page); 197 if (retval < 0) { 198 if (retval == -EAGAIN) { 199 redirty_page_for_writepage(wbc, page); 200 retval = 0; 201 } else { 202 SetPageError(page); 203 mapping_set_error(page->mapping, retval); 204 } 205 } else 206 retval = 0; 207 208 unlock_page(page); 209 return retval; 210} 211 212/** 213 * v9fs_launder_page - Writeback a dirty page 214 * Returns 0 on success. 215 */ 216 217static int v9fs_launder_page(struct page *page) 218{ 219 int retval; 220 struct inode *inode = page->mapping->host; 221 222 v9fs_fscache_wait_on_page_write(inode, page); 223 if (clear_page_dirty_for_io(page)) { 224 retval = v9fs_vfs_writepage_locked(page); 225 if (retval) 226 return retval; 227 } 228 return 0; 229} 230 231/** 232 * v9fs_direct_IO - 9P address space operation for direct I/O 233 * @iocb: target I/O control block 234 * @pos: offset in file to begin the operation 235 * 236 * The presence of v9fs_direct_IO() in the address space ops vector 237 * allowes open() O_DIRECT flags which would have failed otherwise. 238 * 239 * In the non-cached mode, we shunt off direct read and write requests before 240 * the VFS gets them, so this method should never be called. 241 * 242 * Direct IO is not 'yet' supported in the cached mode. Hence when 243 * this routine is called through generic_file_aio_read(), the read/write fails 244 * with an error. 245 * 246 */ 247static ssize_t 248v9fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t pos) 249{ 250 struct file *file = iocb->ki_filp; 251 ssize_t n; 252 int err = 0; 253 if (iov_iter_rw(iter) == WRITE) { 254 n = p9_client_write(file->private_data, pos, iter, &err); 255 if (n) { 256 struct inode *inode = file_inode(file); 257 loff_t i_size = i_size_read(inode); 258 if (pos + n > i_size) 259 inode_add_bytes(inode, pos + n - i_size); 260 } 261 } else { 262 n = p9_client_read(file->private_data, pos, iter, &err); 263 } 264 return n ? n : err; 265} 266 267static int v9fs_write_begin(struct file *filp, struct address_space *mapping, 268 loff_t pos, unsigned len, unsigned flags, 269 struct page **pagep, void **fsdata) 270{ 271 int retval = 0; 272 struct page *page; 273 struct v9fs_inode *v9inode; 274 pgoff_t index = pos >> PAGE_CACHE_SHIFT; 275 struct inode *inode = mapping->host; 276 277 278 p9_debug(P9_DEBUG_VFS, "filp %p, mapping %p\n", filp, mapping); 279 280 v9inode = V9FS_I(inode); 281start: 282 page = grab_cache_page_write_begin(mapping, index, flags); 283 if (!page) { 284 retval = -ENOMEM; 285 goto out; 286 } 287 BUG_ON(!v9inode->writeback_fid); 288 if (PageUptodate(page)) 289 goto out; 290 291 if (len == PAGE_CACHE_SIZE) 292 goto out; 293 294 retval = v9fs_fid_readpage(v9inode->writeback_fid, page); 295 page_cache_release(page); 296 if (!retval) 297 goto start; 298out: 299 *pagep = page; 300 return retval; 301} 302 303static int v9fs_write_end(struct file *filp, struct address_space *mapping, 304 loff_t pos, unsigned len, unsigned copied, 305 struct page *page, void *fsdata) 306{ 307 loff_t last_pos = pos + copied; 308 struct inode *inode = page->mapping->host; 309 310 p9_debug(P9_DEBUG_VFS, "filp %p, mapping %p\n", filp, mapping); 311 312 if (unlikely(copied < len)) { 313 /* 314 * zero out the rest of the area 315 */ 316 unsigned from = pos & (PAGE_CACHE_SIZE - 1); 317 318 zero_user(page, from + copied, len - copied); 319 flush_dcache_page(page); 320 } 321 322 if (!PageUptodate(page)) 323 SetPageUptodate(page); 324 /* 325 * No need to use i_size_read() here, the i_size 326 * cannot change under us because we hold the i_mutex. 327 */ 328 if (last_pos > inode->i_size) { 329 inode_add_bytes(inode, last_pos - inode->i_size); 330 i_size_write(inode, last_pos); 331 } 332 set_page_dirty(page); 333 unlock_page(page); 334 page_cache_release(page); 335 336 return copied; 337} 338 339 340const struct address_space_operations v9fs_addr_operations = { 341 .readpage = v9fs_vfs_readpage, 342 .readpages = v9fs_vfs_readpages, 343 .set_page_dirty = __set_page_dirty_nobuffers, 344 .writepage = v9fs_vfs_writepage, 345 .write_begin = v9fs_write_begin, 346 .write_end = v9fs_write_end, 347 .releasepage = v9fs_release_page, 348 .invalidatepage = v9fs_invalidate_page, 349 .launder_page = v9fs_launder_page, 350 .direct_IO = v9fs_direct_IO, 351}; 352