12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 208e0e7c8SDavid Howells /* AFS filesystem file handling 31da177e4SLinus Torvalds * 408e0e7c8SDavid Howells * Copyright (C) 2002, 2007 Red Hat, Inc. All Rights Reserved. 51da177e4SLinus Torvalds * Written by David Howells (dhowells@redhat.com) 61da177e4SLinus Torvalds */ 71da177e4SLinus Torvalds 81da177e4SLinus Torvalds #include <linux/kernel.h> 91da177e4SLinus Torvalds #include <linux/module.h> 101da177e4SLinus Torvalds #include <linux/init.h> 111da177e4SLinus Torvalds #include <linux/fs.h> 121da177e4SLinus Torvalds #include <linux/pagemap.h> 1331143d5dSDavid Howells #include <linux/writeback.h> 145a0e3ad6STejun Heo #include <linux/gfp.h> 1591b467e0SDavid Howells #include <linux/task_io_accounting_ops.h> 16f86196eaSNikolay Borisov #include <linux/mm.h> 171da177e4SLinus Torvalds #include "internal.h" 181da177e4SLinus Torvalds 191cf7a151SDavid Howells static int afs_file_mmap(struct file *file, struct vm_area_struct *vma); 20416351f2SDavid Howells static int afs_readpage(struct file *file, struct page *page); 21d47992f8SLukas Czerner static void afs_invalidatepage(struct page *page, unsigned int offset, 22d47992f8SLukas Czerner unsigned int length); 23416351f2SDavid Howells static int afs_releasepage(struct page *page, gfp_t gfp_flags); 241da177e4SLinus Torvalds 259b3f26c9SDavid Howells static int afs_readpages(struct file *filp, struct address_space *mapping, 269b3f26c9SDavid Howells struct list_head *pages, unsigned nr_pages); 279b3f26c9SDavid Howells 2800d3b7a4SDavid Howells const struct file_operations afs_file_operations = { 2900d3b7a4SDavid Howells .open = afs_open, 3000d3b7a4SDavid Howells .release = afs_release, 3100d3b7a4SDavid Howells .llseek = generic_file_llseek, 32aad4f8bbSAl Viro .read_iter = generic_file_read_iter, 3350b5551dSAl Viro .write_iter = afs_file_write, 341cf7a151SDavid Howells .mmap = afs_file_mmap, 355ffc4ef4SJens Axboe .splice_read = generic_file_splice_read, 36*06a17bbeSDavid Howells .splice_write = iter_file_splice_write, 3731143d5dSDavid Howells .fsync = afs_fsync, 38e8d6c554SDavid Howells .lock = afs_lock, 39e8d6c554SDavid Howells .flock = afs_flock, 4000d3b7a4SDavid Howells }; 4100d3b7a4SDavid Howells 42754661f1SArjan van de Ven const struct inode_operations afs_file_inode_operations = { 43416351f2SDavid Howells .getattr = afs_getattr, 4431143d5dSDavid Howells .setattr = afs_setattr, 4500d3b7a4SDavid Howells .permission = afs_permission, 46d3e3b7eaSDavid Howells .listxattr = afs_listxattr, 471da177e4SLinus Torvalds }; 481da177e4SLinus Torvalds 49f5e54d6eSChristoph Hellwig const struct address_space_operations afs_fs_aops = { 50416351f2SDavid Howells .readpage = afs_readpage, 519b3f26c9SDavid Howells .readpages = afs_readpages, 5231143d5dSDavid Howells .set_page_dirty = afs_set_page_dirty, 5331143d5dSDavid Howells .launder_page = afs_launder_page, 54416351f2SDavid Howells .releasepage = afs_releasepage, 55416351f2SDavid Howells .invalidatepage = afs_invalidatepage, 5615b4650eSNick Piggin .write_begin = afs_write_begin, 5715b4650eSNick Piggin .write_end = afs_write_end, 5831143d5dSDavid Howells .writepage = afs_writepage, 5931143d5dSDavid Howells .writepages = afs_writepages, 601da177e4SLinus Torvalds }; 611da177e4SLinus Torvalds 621cf7a151SDavid Howells static const struct vm_operations_struct afs_vm_ops = { 631cf7a151SDavid Howells .fault = filemap_fault, 641cf7a151SDavid Howells .map_pages = filemap_map_pages, 651cf7a151SDavid Howells .page_mkwrite = afs_page_mkwrite, 661cf7a151SDavid Howells }; 671cf7a151SDavid Howells 681da177e4SLinus Torvalds /* 694343d008SDavid Howells * Discard a pin on a writeback key. 704343d008SDavid Howells */ 714343d008SDavid Howells void afs_put_wb_key(struct afs_wb_key *wbk) 724343d008SDavid Howells { 73e49c7b2fSDavid Howells if (wbk && refcount_dec_and_test(&wbk->usage)) { 744343d008SDavid Howells key_put(wbk->key); 754343d008SDavid Howells kfree(wbk); 764343d008SDavid Howells } 774343d008SDavid Howells } 784343d008SDavid Howells 794343d008SDavid Howells /* 804343d008SDavid Howells * Cache key for writeback. 814343d008SDavid Howells */ 824343d008SDavid Howells int afs_cache_wb_key(struct afs_vnode *vnode, struct afs_file *af) 834343d008SDavid Howells { 844343d008SDavid Howells struct afs_wb_key *wbk, *p; 854343d008SDavid Howells 864343d008SDavid Howells wbk = kzalloc(sizeof(struct afs_wb_key), GFP_KERNEL); 874343d008SDavid Howells if (!wbk) 884343d008SDavid Howells return -ENOMEM; 894343d008SDavid Howells refcount_set(&wbk->usage, 2); 904343d008SDavid Howells wbk->key = af->key; 914343d008SDavid Howells 924343d008SDavid Howells spin_lock(&vnode->wb_lock); 934343d008SDavid Howells list_for_each_entry(p, &vnode->wb_keys, vnode_link) { 944343d008SDavid Howells if (p->key == wbk->key) 954343d008SDavid Howells goto found; 964343d008SDavid Howells } 974343d008SDavid Howells 984343d008SDavid Howells key_get(wbk->key); 994343d008SDavid Howells list_add_tail(&wbk->vnode_link, &vnode->wb_keys); 1004343d008SDavid Howells spin_unlock(&vnode->wb_lock); 1014343d008SDavid Howells af->wb = wbk; 1024343d008SDavid Howells return 0; 1034343d008SDavid Howells 1044343d008SDavid Howells found: 1054343d008SDavid Howells refcount_inc(&p->usage); 1064343d008SDavid Howells spin_unlock(&vnode->wb_lock); 1074343d008SDavid Howells af->wb = p; 1084343d008SDavid Howells kfree(wbk); 1094343d008SDavid Howells return 0; 1104343d008SDavid Howells } 1114343d008SDavid Howells 1124343d008SDavid Howells /* 11300d3b7a4SDavid Howells * open an AFS file or directory and attach a key to it 11400d3b7a4SDavid Howells */ 11500d3b7a4SDavid Howells int afs_open(struct inode *inode, struct file *file) 11600d3b7a4SDavid Howells { 11700d3b7a4SDavid Howells struct afs_vnode *vnode = AFS_FS_I(inode); 118215804a9SDavid Howells struct afs_file *af; 11900d3b7a4SDavid Howells struct key *key; 120260a9803SDavid Howells int ret; 12100d3b7a4SDavid Howells 1223b6492dfSDavid Howells _enter("{%llx:%llu},", vnode->fid.vid, vnode->fid.vnode); 12300d3b7a4SDavid Howells 12400d3b7a4SDavid Howells key = afs_request_key(vnode->volume->cell); 12500d3b7a4SDavid Howells if (IS_ERR(key)) { 126215804a9SDavid Howells ret = PTR_ERR(key); 127215804a9SDavid Howells goto error; 128215804a9SDavid Howells } 129215804a9SDavid Howells 130215804a9SDavid Howells af = kzalloc(sizeof(*af), GFP_KERNEL); 131215804a9SDavid Howells if (!af) { 132215804a9SDavid Howells ret = -ENOMEM; 133215804a9SDavid Howells goto error_key; 13400d3b7a4SDavid Howells } 1354343d008SDavid Howells af->key = key; 13600d3b7a4SDavid Howells 137260a9803SDavid Howells ret = afs_validate(vnode, key); 138215804a9SDavid Howells if (ret < 0) 139215804a9SDavid Howells goto error_af; 140260a9803SDavid Howells 1414343d008SDavid Howells if (file->f_mode & FMODE_WRITE) { 1424343d008SDavid Howells ret = afs_cache_wb_key(vnode, af); 1434343d008SDavid Howells if (ret < 0) 1444343d008SDavid Howells goto error_af; 1454343d008SDavid Howells } 1464343d008SDavid Howells 1475a813276SDavid Howells if (file->f_flags & O_TRUNC) 1485a813276SDavid Howells set_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags); 1495a813276SDavid Howells 150215804a9SDavid Howells file->private_data = af; 15100d3b7a4SDavid Howells _leave(" = 0"); 15200d3b7a4SDavid Howells return 0; 153215804a9SDavid Howells 154215804a9SDavid Howells error_af: 155215804a9SDavid Howells kfree(af); 156215804a9SDavid Howells error_key: 157215804a9SDavid Howells key_put(key); 158215804a9SDavid Howells error: 159215804a9SDavid Howells _leave(" = %d", ret); 160215804a9SDavid Howells return ret; 16100d3b7a4SDavid Howells } 16200d3b7a4SDavid Howells 16300d3b7a4SDavid Howells /* 16400d3b7a4SDavid Howells * release an AFS file or directory and discard its key 16500d3b7a4SDavid Howells */ 16600d3b7a4SDavid Howells int afs_release(struct inode *inode, struct file *file) 16700d3b7a4SDavid Howells { 16800d3b7a4SDavid Howells struct afs_vnode *vnode = AFS_FS_I(inode); 169215804a9SDavid Howells struct afs_file *af = file->private_data; 170a1b879eeSDavid Howells int ret = 0; 17100d3b7a4SDavid Howells 1723b6492dfSDavid Howells _enter("{%llx:%llu},", vnode->fid.vid, vnode->fid.vnode); 17300d3b7a4SDavid Howells 1745a813276SDavid Howells if ((file->f_mode & FMODE_WRITE)) 175a1b879eeSDavid Howells ret = vfs_fsync(file, 0); 1765a813276SDavid Howells 177215804a9SDavid Howells file->private_data = NULL; 1784343d008SDavid Howells if (af->wb) 1794343d008SDavid Howells afs_put_wb_key(af->wb); 180215804a9SDavid Howells key_put(af->key); 181215804a9SDavid Howells kfree(af); 1824343d008SDavid Howells afs_prune_wb_keys(vnode); 183a1b879eeSDavid Howells _leave(" = %d", ret); 184a1b879eeSDavid Howells return ret; 18500d3b7a4SDavid Howells } 18600d3b7a4SDavid Howells 187196ee9cdSDavid Howells /* 188196ee9cdSDavid Howells * Dispose of a ref to a read record. 189196ee9cdSDavid Howells */ 190196ee9cdSDavid Howells void afs_put_read(struct afs_read *req) 191196ee9cdSDavid Howells { 192196ee9cdSDavid Howells int i; 193196ee9cdSDavid Howells 194f3ddee8dSDavid Howells if (refcount_dec_and_test(&req->usage)) { 195a6eed4abSJia-Ju Bai if (req->pages) { 196196ee9cdSDavid Howells for (i = 0; i < req->nr_pages; i++) 197196ee9cdSDavid Howells if (req->pages[i]) 198196ee9cdSDavid Howells put_page(req->pages[i]); 199f3ddee8dSDavid Howells if (req->pages != req->array) 200f3ddee8dSDavid Howells kfree(req->pages); 201a6eed4abSJia-Ju Bai } 202196ee9cdSDavid Howells kfree(req); 203196ee9cdSDavid Howells } 204196ee9cdSDavid Howells } 205196ee9cdSDavid Howells 2066566abdbSMatt Kraai #ifdef CONFIG_AFS_FSCACHE 20700d3b7a4SDavid Howells /* 2081da177e4SLinus Torvalds * deal with notification that a page was read from the cache 2091da177e4SLinus Torvalds */ 2109b3f26c9SDavid Howells static void afs_file_readpage_read_complete(struct page *page, 2111da177e4SLinus Torvalds void *data, 2121da177e4SLinus Torvalds int error) 2131da177e4SLinus Torvalds { 2149b3f26c9SDavid Howells _enter("%p,%p,%d", page, data, error); 2151da177e4SLinus Torvalds 2169b3f26c9SDavid Howells /* if the read completes with an error, we just unlock the page and let 2179b3f26c9SDavid Howells * the VM reissue the readpage */ 2189b3f26c9SDavid Howells if (!error) 2191da177e4SLinus Torvalds SetPageUptodate(page); 2201da177e4SLinus Torvalds unlock_page(page); 221ec26815aSDavid Howells } 2226566abdbSMatt Kraai #endif 2231da177e4SLinus Torvalds 224e49c7b2fSDavid Howells static void afs_fetch_data_success(struct afs_operation *op) 225e49c7b2fSDavid Howells { 226e49c7b2fSDavid Howells struct afs_vnode *vnode = op->file[0].vnode; 227e49c7b2fSDavid Howells 228e49c7b2fSDavid Howells _enter("op=%08x", op->debug_id); 229e49c7b2fSDavid Howells afs_vnode_commit_status(op, &op->file[0]); 230e49c7b2fSDavid Howells afs_stat_v(vnode, n_fetches); 231e49c7b2fSDavid Howells atomic_long_add(op->fetch.req->actual_len, &op->net->n_fetch_bytes); 232e49c7b2fSDavid Howells } 233e49c7b2fSDavid Howells 234e49c7b2fSDavid Howells static void afs_fetch_data_put(struct afs_operation *op) 235e49c7b2fSDavid Howells { 236e49c7b2fSDavid Howells afs_put_read(op->fetch.req); 237e49c7b2fSDavid Howells } 238e49c7b2fSDavid Howells 239e49c7b2fSDavid Howells static const struct afs_operation_ops afs_fetch_data_operation = { 240e49c7b2fSDavid Howells .issue_afs_rpc = afs_fs_fetch_data, 241e49c7b2fSDavid Howells .issue_yfs_rpc = yfs_fs_fetch_data, 242e49c7b2fSDavid Howells .success = afs_fetch_data_success, 243728279a5SDavid Howells .aborted = afs_check_for_remote_deletion, 244e49c7b2fSDavid Howells .put = afs_fetch_data_put, 245e49c7b2fSDavid Howells }; 246e49c7b2fSDavid Howells 2471da177e4SLinus Torvalds /* 248d2ddc776SDavid Howells * Fetch file data from the volume. 249d2ddc776SDavid Howells */ 2500b9c0174SDavid Howells int afs_fetch_data(struct afs_vnode *vnode, struct key *key, struct afs_read *req) 251d2ddc776SDavid Howells { 252e49c7b2fSDavid Howells struct afs_operation *op; 253d2ddc776SDavid Howells 2543b6492dfSDavid Howells _enter("%s{%llx:%llu.%u},%x,,,", 255d2ddc776SDavid Howells vnode->volume->name, 256d2ddc776SDavid Howells vnode->fid.vid, 257d2ddc776SDavid Howells vnode->fid.vnode, 258d2ddc776SDavid Howells vnode->fid.unique, 259d2ddc776SDavid Howells key_serial(key)); 260d2ddc776SDavid Howells 261e49c7b2fSDavid Howells op = afs_alloc_operation(key, vnode->volume); 262e49c7b2fSDavid Howells if (IS_ERR(op)) 263e49c7b2fSDavid Howells return PTR_ERR(op); 264a58823acSDavid Howells 265e49c7b2fSDavid Howells afs_op_set_vnode(op, 0, vnode); 266a58823acSDavid Howells 267e49c7b2fSDavid Howells op->fetch.req = afs_get_read(req); 268e49c7b2fSDavid Howells op->ops = &afs_fetch_data_operation; 269e49c7b2fSDavid Howells return afs_do_sync_operation(op); 270d2ddc776SDavid Howells } 271d2ddc776SDavid Howells 272d2ddc776SDavid Howells /* 273f6d335c0SAl Viro * read page from file, directory or symlink, given a key to use 2741da177e4SLinus Torvalds */ 275f6d335c0SAl Viro int afs_page_filler(void *data, struct page *page) 2761da177e4SLinus Torvalds { 277f6d335c0SAl Viro struct inode *inode = page->mapping->host; 278f6d335c0SAl Viro struct afs_vnode *vnode = AFS_FS_I(inode); 279196ee9cdSDavid Howells struct afs_read *req; 280f6d335c0SAl Viro struct key *key = data; 2811da177e4SLinus Torvalds int ret; 2821da177e4SLinus Torvalds 28300d3b7a4SDavid Howells _enter("{%x},{%lu},{%lu}", key_serial(key), inode->i_ino, page->index); 2841da177e4SLinus Torvalds 285cd7619d6SMatt Mackall BUG_ON(!PageLocked(page)); 2861da177e4SLinus Torvalds 2871da177e4SLinus Torvalds ret = -ESTALE; 28808e0e7c8SDavid Howells if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) 2891da177e4SLinus Torvalds goto error; 2901da177e4SLinus Torvalds 2911da177e4SLinus Torvalds /* is it cached? */ 2929b3f26c9SDavid Howells #ifdef CONFIG_AFS_FSCACHE 2939b3f26c9SDavid Howells ret = fscache_read_or_alloc_page(vnode->cache, 2941da177e4SLinus Torvalds page, 2951da177e4SLinus Torvalds afs_file_readpage_read_complete, 2961da177e4SLinus Torvalds NULL, 2971da177e4SLinus Torvalds GFP_KERNEL); 2981da177e4SLinus Torvalds #else 2991da177e4SLinus Torvalds ret = -ENOBUFS; 3001da177e4SLinus Torvalds #endif 3011da177e4SLinus Torvalds switch (ret) { 3021da177e4SLinus Torvalds /* read BIO submitted (page in cache) */ 3031da177e4SLinus Torvalds case 0: 3041da177e4SLinus Torvalds break; 3051da177e4SLinus Torvalds 3069b3f26c9SDavid Howells /* page not yet cached */ 3071da177e4SLinus Torvalds case -ENODATA: 3089b3f26c9SDavid Howells _debug("cache said ENODATA"); 3099b3f26c9SDavid Howells goto go_on; 3109b3f26c9SDavid Howells 3119b3f26c9SDavid Howells /* page will not be cached */ 3129b3f26c9SDavid Howells case -ENOBUFS: 3139b3f26c9SDavid Howells _debug("cache said ENOBUFS"); 314e690c9e3SGustavo A. R. Silva 315df561f66SGustavo A. R. Silva fallthrough; 3161da177e4SLinus Torvalds default: 3179b3f26c9SDavid Howells go_on: 318ee102584SZhengyuan Liu req = kzalloc(struct_size(req, array, 1), GFP_KERNEL); 319196ee9cdSDavid Howells if (!req) 320196ee9cdSDavid Howells goto enomem; 321196ee9cdSDavid Howells 3226db3ac3cSDavid Howells /* We request a full page. If the page is a partial one at the 3236db3ac3cSDavid Howells * end of the file, the server will return a short read and the 3246db3ac3cSDavid Howells * unmarshalling code will clear the unfilled space. 3256db3ac3cSDavid Howells */ 326f3ddee8dSDavid Howells refcount_set(&req->usage, 1); 327196ee9cdSDavid Howells req->pos = (loff_t)page->index << PAGE_SHIFT; 3286db3ac3cSDavid Howells req->len = PAGE_SIZE; 329196ee9cdSDavid Howells req->nr_pages = 1; 330f3ddee8dSDavid Howells req->pages = req->array; 331196ee9cdSDavid Howells req->pages[0] = page; 332196ee9cdSDavid Howells get_page(page); 3331da177e4SLinus Torvalds 3341da177e4SLinus Torvalds /* read the contents of the file from the server into the 3351da177e4SLinus Torvalds * page */ 336d2ddc776SDavid Howells ret = afs_fetch_data(vnode, key, req); 337196ee9cdSDavid Howells afs_put_read(req); 338dab17c1aSDavid Howells 3391da177e4SLinus Torvalds if (ret < 0) { 3401da177e4SLinus Torvalds if (ret == -ENOENT) { 3411da177e4SLinus Torvalds _debug("got NOENT from server" 3421da177e4SLinus Torvalds " - marking file deleted and stale"); 34308e0e7c8SDavid Howells set_bit(AFS_VNODE_DELETED, &vnode->flags); 3441da177e4SLinus Torvalds ret = -ESTALE; 3451da177e4SLinus Torvalds } 3469b3f26c9SDavid Howells 3479b3f26c9SDavid Howells #ifdef CONFIG_AFS_FSCACHE 3489b3f26c9SDavid Howells fscache_uncache_page(vnode->cache, page); 3491da177e4SLinus Torvalds #endif 3509b3f26c9SDavid Howells BUG_ON(PageFsCache(page)); 35168ae849dSDavid Howells 35268ae849dSDavid Howells if (ret == -EINTR || 35368ae849dSDavid Howells ret == -ENOMEM || 35468ae849dSDavid Howells ret == -ERESTARTSYS || 35568ae849dSDavid Howells ret == -EAGAIN) 3561da177e4SLinus Torvalds goto error; 35768ae849dSDavid Howells goto io_error; 3581da177e4SLinus Torvalds } 3591da177e4SLinus Torvalds 3601da177e4SLinus Torvalds SetPageUptodate(page); 3611da177e4SLinus Torvalds 3629b3f26c9SDavid Howells /* send the page to the cache */ 3639b3f26c9SDavid Howells #ifdef CONFIG_AFS_FSCACHE 3649b3f26c9SDavid Howells if (PageFsCache(page) && 365ee1235a9SDavid Howells fscache_write_page(vnode->cache, page, vnode->status.size, 366ee1235a9SDavid Howells GFP_KERNEL) != 0) { 3679b3f26c9SDavid Howells fscache_uncache_page(vnode->cache, page); 3689b3f26c9SDavid Howells BUG_ON(PageFsCache(page)); 3691da177e4SLinus Torvalds } 3701da177e4SLinus Torvalds #endif 3719b3f26c9SDavid Howells unlock_page(page); 3721da177e4SLinus Torvalds } 3731da177e4SLinus Torvalds 3741da177e4SLinus Torvalds _leave(" = 0"); 3751da177e4SLinus Torvalds return 0; 3761da177e4SLinus Torvalds 37768ae849dSDavid Howells io_error: 37868ae849dSDavid Howells SetPageError(page); 37968ae849dSDavid Howells goto error; 380196ee9cdSDavid Howells enomem: 381196ee9cdSDavid Howells ret = -ENOMEM; 3821da177e4SLinus Torvalds error: 3831da177e4SLinus Torvalds unlock_page(page); 3841da177e4SLinus Torvalds _leave(" = %d", ret); 3851da177e4SLinus Torvalds return ret; 386ec26815aSDavid Howells } 3871da177e4SLinus Torvalds 3881da177e4SLinus Torvalds /* 389f6d335c0SAl Viro * read page from file, directory or symlink, given a file to nominate the key 390f6d335c0SAl Viro * to be used 391f6d335c0SAl Viro */ 392f6d335c0SAl Viro static int afs_readpage(struct file *file, struct page *page) 393f6d335c0SAl Viro { 394f6d335c0SAl Viro struct key *key; 395f6d335c0SAl Viro int ret; 396f6d335c0SAl Viro 397f6d335c0SAl Viro if (file) { 398215804a9SDavid Howells key = afs_file_key(file); 399f6d335c0SAl Viro ASSERT(key != NULL); 400f6d335c0SAl Viro ret = afs_page_filler(key, page); 401f6d335c0SAl Viro } else { 402f6d335c0SAl Viro struct inode *inode = page->mapping->host; 403d2ddc776SDavid Howells key = afs_request_key(AFS_FS_S(inode->i_sb)->cell); 404f6d335c0SAl Viro if (IS_ERR(key)) { 405f6d335c0SAl Viro ret = PTR_ERR(key); 406f6d335c0SAl Viro } else { 407f6d335c0SAl Viro ret = afs_page_filler(key, page); 408f6d335c0SAl Viro key_put(key); 409f6d335c0SAl Viro } 410f6d335c0SAl Viro } 411f6d335c0SAl Viro return ret; 412f6d335c0SAl Viro } 413f6d335c0SAl Viro 414f6d335c0SAl Viro /* 41591b467e0SDavid Howells * Make pages available as they're filled. 41691b467e0SDavid Howells */ 417a58823acSDavid Howells static void afs_readpages_page_done(struct afs_read *req) 41891b467e0SDavid Howells { 41951c89e6aSArnd Bergmann #ifdef CONFIG_AFS_FSCACHE 420a58823acSDavid Howells struct afs_vnode *vnode = req->vnode; 42151c89e6aSArnd Bergmann #endif 42291b467e0SDavid Howells struct page *page = req->pages[req->index]; 42391b467e0SDavid Howells 42491b467e0SDavid Howells req->pages[req->index] = NULL; 42591b467e0SDavid Howells SetPageUptodate(page); 42691b467e0SDavid Howells 42791b467e0SDavid Howells /* send the page to the cache */ 42891b467e0SDavid Howells #ifdef CONFIG_AFS_FSCACHE 42991b467e0SDavid Howells if (PageFsCache(page) && 430ee1235a9SDavid Howells fscache_write_page(vnode->cache, page, vnode->status.size, 431ee1235a9SDavid Howells GFP_KERNEL) != 0) { 43291b467e0SDavid Howells fscache_uncache_page(vnode->cache, page); 43391b467e0SDavid Howells BUG_ON(PageFsCache(page)); 43491b467e0SDavid Howells } 43591b467e0SDavid Howells #endif 43691b467e0SDavid Howells unlock_page(page); 43791b467e0SDavid Howells put_page(page); 43891b467e0SDavid Howells } 43991b467e0SDavid Howells 44091b467e0SDavid Howells /* 44191b467e0SDavid Howells * Read a contiguous set of pages. 44291b467e0SDavid Howells */ 44391b467e0SDavid Howells static int afs_readpages_one(struct file *file, struct address_space *mapping, 44491b467e0SDavid Howells struct list_head *pages) 44591b467e0SDavid Howells { 44691b467e0SDavid Howells struct afs_vnode *vnode = AFS_FS_I(mapping->host); 44791b467e0SDavid Howells struct afs_read *req; 44891b467e0SDavid Howells struct list_head *p; 44991b467e0SDavid Howells struct page *first, *page; 450215804a9SDavid Howells struct key *key = afs_file_key(file); 45191b467e0SDavid Howells pgoff_t index; 45291b467e0SDavid Howells int ret, n, i; 45391b467e0SDavid Howells 45491b467e0SDavid Howells /* Count the number of contiguous pages at the front of the list. Note 45591b467e0SDavid Howells * that the list goes prev-wards rather than next-wards. 45691b467e0SDavid Howells */ 457f86196eaSNikolay Borisov first = lru_to_page(pages); 45891b467e0SDavid Howells index = first->index + 1; 45991b467e0SDavid Howells n = 1; 46091b467e0SDavid Howells for (p = first->lru.prev; p != pages; p = p->prev) { 46191b467e0SDavid Howells page = list_entry(p, struct page, lru); 46291b467e0SDavid Howells if (page->index != index) 46391b467e0SDavid Howells break; 46491b467e0SDavid Howells index++; 46591b467e0SDavid Howells n++; 46691b467e0SDavid Howells } 46791b467e0SDavid Howells 468ee102584SZhengyuan Liu req = kzalloc(struct_size(req, array, n), GFP_NOFS); 46991b467e0SDavid Howells if (!req) 47091b467e0SDavid Howells return -ENOMEM; 47191b467e0SDavid Howells 472f3ddee8dSDavid Howells refcount_set(&req->usage, 1); 473a58823acSDavid Howells req->vnode = vnode; 47491b467e0SDavid Howells req->page_done = afs_readpages_page_done; 47591b467e0SDavid Howells req->pos = first->index; 47691b467e0SDavid Howells req->pos <<= PAGE_SHIFT; 477f3ddee8dSDavid Howells req->pages = req->array; 47891b467e0SDavid Howells 47991b467e0SDavid Howells /* Transfer the pages to the request. We add them in until one fails 48091b467e0SDavid Howells * to add to the LRU and then we stop (as that'll make a hole in the 48191b467e0SDavid Howells * contiguous run. 48291b467e0SDavid Howells * 48391b467e0SDavid Howells * Note that it's possible for the file size to change whilst we're 48491b467e0SDavid Howells * doing this, but we rely on the server returning less than we asked 48591b467e0SDavid Howells * for if the file shrank. We also rely on this to deal with a partial 48691b467e0SDavid Howells * page at the end of the file. 48791b467e0SDavid Howells */ 48891b467e0SDavid Howells do { 489f86196eaSNikolay Borisov page = lru_to_page(pages); 49091b467e0SDavid Howells list_del(&page->lru); 49191b467e0SDavid Howells index = page->index; 49291b467e0SDavid Howells if (add_to_page_cache_lru(page, mapping, index, 49391b467e0SDavid Howells readahead_gfp_mask(mapping))) { 49491b467e0SDavid Howells #ifdef CONFIG_AFS_FSCACHE 49591b467e0SDavid Howells fscache_uncache_page(vnode->cache, page); 49691b467e0SDavid Howells #endif 49791b467e0SDavid Howells put_page(page); 49891b467e0SDavid Howells break; 49991b467e0SDavid Howells } 50091b467e0SDavid Howells 50191b467e0SDavid Howells req->pages[req->nr_pages++] = page; 50291b467e0SDavid Howells req->len += PAGE_SIZE; 50391b467e0SDavid Howells } while (req->nr_pages < n); 50491b467e0SDavid Howells 50591b467e0SDavid Howells if (req->nr_pages == 0) { 50691b467e0SDavid Howells kfree(req); 50791b467e0SDavid Howells return 0; 50891b467e0SDavid Howells } 50991b467e0SDavid Howells 510d2ddc776SDavid Howells ret = afs_fetch_data(vnode, key, req); 51191b467e0SDavid Howells if (ret < 0) 51291b467e0SDavid Howells goto error; 51391b467e0SDavid Howells 51491b467e0SDavid Howells task_io_account_read(PAGE_SIZE * req->nr_pages); 51591b467e0SDavid Howells afs_put_read(req); 51691b467e0SDavid Howells return 0; 51791b467e0SDavid Howells 51891b467e0SDavid Howells error: 51991b467e0SDavid Howells if (ret == -ENOENT) { 52091b467e0SDavid Howells _debug("got NOENT from server" 52191b467e0SDavid Howells " - marking file deleted and stale"); 52291b467e0SDavid Howells set_bit(AFS_VNODE_DELETED, &vnode->flags); 52391b467e0SDavid Howells ret = -ESTALE; 52491b467e0SDavid Howells } 52591b467e0SDavid Howells 52691b467e0SDavid Howells for (i = 0; i < req->nr_pages; i++) { 52791b467e0SDavid Howells page = req->pages[i]; 52891b467e0SDavid Howells if (page) { 52991b467e0SDavid Howells #ifdef CONFIG_AFS_FSCACHE 53091b467e0SDavid Howells fscache_uncache_page(vnode->cache, page); 53191b467e0SDavid Howells #endif 53291b467e0SDavid Howells SetPageError(page); 53391b467e0SDavid Howells unlock_page(page); 53491b467e0SDavid Howells } 53591b467e0SDavid Howells } 53691b467e0SDavid Howells 53791b467e0SDavid Howells afs_put_read(req); 53891b467e0SDavid Howells return ret; 53991b467e0SDavid Howells } 54091b467e0SDavid Howells 54191b467e0SDavid Howells /* 5429b3f26c9SDavid Howells * read a set of pages 5431da177e4SLinus Torvalds */ 5449b3f26c9SDavid Howells static int afs_readpages(struct file *file, struct address_space *mapping, 5459b3f26c9SDavid Howells struct list_head *pages, unsigned nr_pages) 5461da177e4SLinus Torvalds { 547215804a9SDavid Howells struct key *key = afs_file_key(file); 5489b3f26c9SDavid Howells struct afs_vnode *vnode; 5499b3f26c9SDavid Howells int ret = 0; 5501da177e4SLinus Torvalds 551f6d335c0SAl Viro _enter("{%d},{%lu},,%d", 552f6d335c0SAl Viro key_serial(key), mapping->host->i_ino, nr_pages); 553f6d335c0SAl Viro 554f6d335c0SAl Viro ASSERT(key != NULL); 5551da177e4SLinus Torvalds 5569b3f26c9SDavid Howells vnode = AFS_FS_I(mapping->host); 557ad2a8e60SDan Carpenter if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) { 5589b3f26c9SDavid Howells _leave(" = -ESTALE"); 5599b3f26c9SDavid Howells return -ESTALE; 5601da177e4SLinus Torvalds } 5611da177e4SLinus Torvalds 5629b3f26c9SDavid Howells /* attempt to read as many of the pages as possible */ 5639b3f26c9SDavid Howells #ifdef CONFIG_AFS_FSCACHE 5649b3f26c9SDavid Howells ret = fscache_read_or_alloc_pages(vnode->cache, 5659b3f26c9SDavid Howells mapping, 5669b3f26c9SDavid Howells pages, 5679b3f26c9SDavid Howells &nr_pages, 5689b3f26c9SDavid Howells afs_file_readpage_read_complete, 5699b3f26c9SDavid Howells NULL, 5709b3f26c9SDavid Howells mapping_gfp_mask(mapping)); 5719b3f26c9SDavid Howells #else 5729b3f26c9SDavid Howells ret = -ENOBUFS; 5739b3f26c9SDavid Howells #endif 5749b3f26c9SDavid Howells 5759b3f26c9SDavid Howells switch (ret) { 5769b3f26c9SDavid Howells /* all pages are being read from the cache */ 5779b3f26c9SDavid Howells case 0: 5789b3f26c9SDavid Howells BUG_ON(!list_empty(pages)); 5799b3f26c9SDavid Howells BUG_ON(nr_pages != 0); 5809b3f26c9SDavid Howells _leave(" = 0 [reading all]"); 5819b3f26c9SDavid Howells return 0; 5829b3f26c9SDavid Howells 5839b3f26c9SDavid Howells /* there were pages that couldn't be read from the cache */ 5849b3f26c9SDavid Howells case -ENODATA: 5859b3f26c9SDavid Howells case -ENOBUFS: 5869b3f26c9SDavid Howells break; 5879b3f26c9SDavid Howells 5889b3f26c9SDavid Howells /* other error */ 5899b3f26c9SDavid Howells default: 5901da177e4SLinus Torvalds _leave(" = %d", ret); 5919b3f26c9SDavid Howells return ret; 5929b3f26c9SDavid Howells } 5939b3f26c9SDavid Howells 59491b467e0SDavid Howells while (!list_empty(pages)) { 59591b467e0SDavid Howells ret = afs_readpages_one(file, mapping, pages); 59691b467e0SDavid Howells if (ret < 0) 59791b467e0SDavid Howells break; 59891b467e0SDavid Howells } 5999b3f26c9SDavid Howells 6009b3f26c9SDavid Howells _leave(" = %d [netting]", ret); 6019b3f26c9SDavid Howells return ret; 602ec26815aSDavid Howells } 6031da177e4SLinus Torvalds 6041da177e4SLinus Torvalds /* 6059b3f26c9SDavid Howells * invalidate part or all of a page 6069b3f26c9SDavid Howells * - release a page and clean up its private data if offset is 0 (indicating 6079b3f26c9SDavid Howells * the entire page) 6089b3f26c9SDavid Howells */ 609d47992f8SLukas Czerner static void afs_invalidatepage(struct page *page, unsigned int offset, 610d47992f8SLukas Czerner unsigned int length) 6119b3f26c9SDavid Howells { 61213524ab3SDavid Howells struct afs_vnode *vnode = AFS_FS_I(page->mapping->host); 61313524ab3SDavid Howells unsigned long priv; 61413524ab3SDavid Howells 615d47992f8SLukas Czerner _enter("{%lu},%u,%u", page->index, offset, length); 6169b3f26c9SDavid Howells 6179b3f26c9SDavid Howells BUG_ON(!PageLocked(page)); 6189b3f26c9SDavid Howells 6199b3f26c9SDavid Howells /* we clean up only if the entire page is being invalidated */ 62009cbfeafSKirill A. Shutemov if (offset == 0 && length == PAGE_SIZE) { 6219b3f26c9SDavid Howells #ifdef CONFIG_AFS_FSCACHE 6229b3f26c9SDavid Howells if (PageFsCache(page)) { 6239b3f26c9SDavid Howells struct afs_vnode *vnode = AFS_FS_I(page->mapping->host); 6249b3f26c9SDavid Howells fscache_wait_on_page_write(vnode->cache, page); 6259b3f26c9SDavid Howells fscache_uncache_page(vnode->cache, page); 6269b3f26c9SDavid Howells } 6279b3f26c9SDavid Howells #endif 6289b3f26c9SDavid Howells 6299b3f26c9SDavid Howells if (PagePrivate(page)) { 63013524ab3SDavid Howells priv = page_private(page); 63113524ab3SDavid Howells trace_afs_page_dirty(vnode, tracepoint_string("inval"), 63213524ab3SDavid Howells page->index, priv); 6339b3f26c9SDavid Howells set_page_private(page, 0); 6349b3f26c9SDavid Howells ClearPagePrivate(page); 6359b3f26c9SDavid Howells } 6369b3f26c9SDavid Howells } 6379b3f26c9SDavid Howells 6389b3f26c9SDavid Howells _leave(""); 6399b3f26c9SDavid Howells } 6409b3f26c9SDavid Howells 6419b3f26c9SDavid Howells /* 6429b3f26c9SDavid Howells * release a page and clean up its private state if it's not busy 6439b3f26c9SDavid Howells * - return true if the page can now be released, false if not 6441da177e4SLinus Torvalds */ 645416351f2SDavid Howells static int afs_releasepage(struct page *page, gfp_t gfp_flags) 6461da177e4SLinus Torvalds { 647416351f2SDavid Howells struct afs_vnode *vnode = AFS_FS_I(page->mapping->host); 64813524ab3SDavid Howells unsigned long priv; 6491da177e4SLinus Torvalds 6503b6492dfSDavid Howells _enter("{{%llx:%llu}[%lu],%lx},%x", 651416351f2SDavid Howells vnode->fid.vid, vnode->fid.vnode, page->index, page->flags, 652416351f2SDavid Howells gfp_flags); 6531da177e4SLinus Torvalds 6549b3f26c9SDavid Howells /* deny if page is being written to the cache and the caller hasn't 6559b3f26c9SDavid Howells * elected to wait */ 6569b3f26c9SDavid Howells #ifdef CONFIG_AFS_FSCACHE 657201a1542SDavid Howells if (!fscache_maybe_release_page(vnode->cache, page, gfp_flags)) { 6589b3f26c9SDavid Howells _leave(" = F [cache busy]"); 6599b3f26c9SDavid Howells return 0; 6609b3f26c9SDavid Howells } 6619b3f26c9SDavid Howells #endif 6629b3f26c9SDavid Howells 6639b3f26c9SDavid Howells if (PagePrivate(page)) { 66413524ab3SDavid Howells priv = page_private(page); 66513524ab3SDavid Howells trace_afs_page_dirty(vnode, tracepoint_string("rel"), 66613524ab3SDavid Howells page->index, priv); 6679b3f26c9SDavid Howells set_page_private(page, 0); 6689b3f26c9SDavid Howells ClearPagePrivate(page); 6699b3f26c9SDavid Howells } 6709b3f26c9SDavid Howells 6719b3f26c9SDavid Howells /* indicate that the page can be released */ 6729b3f26c9SDavid Howells _leave(" = T"); 6739b3f26c9SDavid Howells return 1; 674ec26815aSDavid Howells } 6751cf7a151SDavid Howells 6761cf7a151SDavid Howells /* 6771cf7a151SDavid Howells * Handle setting up a memory mapping on an AFS file. 6781cf7a151SDavid Howells */ 6791cf7a151SDavid Howells static int afs_file_mmap(struct file *file, struct vm_area_struct *vma) 6801cf7a151SDavid Howells { 6811cf7a151SDavid Howells int ret; 6821cf7a151SDavid Howells 6831cf7a151SDavid Howells ret = generic_file_mmap(file, vma); 6841cf7a151SDavid Howells if (ret == 0) 6851cf7a151SDavid Howells vma->vm_ops = &afs_vm_ops; 6861cf7a151SDavid Howells return ret; 6871cf7a151SDavid Howells } 688