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