108e0e7c8SDavid Howells /* AFS filesystem file handling 21da177e4SLinus Torvalds * 308e0e7c8SDavid Howells * Copyright (C) 2002, 2007 Red Hat, Inc. All Rights Reserved. 41da177e4SLinus Torvalds * Written by David Howells (dhowells@redhat.com) 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * This program is free software; you can redistribute it and/or 71da177e4SLinus Torvalds * modify it under the terms of the GNU General Public License 81da177e4SLinus Torvalds * as published by the Free Software Foundation; either version 91da177e4SLinus Torvalds * 2 of the License, or (at your option) any later version. 101da177e4SLinus Torvalds */ 111da177e4SLinus Torvalds 121da177e4SLinus Torvalds #include <linux/kernel.h> 131da177e4SLinus Torvalds #include <linux/module.h> 141da177e4SLinus Torvalds #include <linux/init.h> 151da177e4SLinus Torvalds #include <linux/fs.h> 161da177e4SLinus Torvalds #include <linux/pagemap.h> 1731143d5dSDavid Howells #include <linux/writeback.h> 185a0e3ad6STejun Heo #include <linux/gfp.h> 191da177e4SLinus Torvalds #include "internal.h" 201da177e4SLinus Torvalds 21416351f2SDavid Howells static int afs_readpage(struct file *file, struct page *page); 22d47992f8SLukas Czerner static void afs_invalidatepage(struct page *page, unsigned int offset, 23d47992f8SLukas Czerner unsigned int length); 24416351f2SDavid Howells static int afs_releasepage(struct page *page, gfp_t gfp_flags); 2531143d5dSDavid Howells static int afs_launder_page(struct page *page); 261da177e4SLinus Torvalds 279b3f26c9SDavid Howells static int afs_readpages(struct file *filp, struct address_space *mapping, 289b3f26c9SDavid Howells struct list_head *pages, unsigned nr_pages); 299b3f26c9SDavid Howells 3000d3b7a4SDavid Howells const struct file_operations afs_file_operations = { 3100d3b7a4SDavid Howells .open = afs_open, 3200d3b7a4SDavid Howells .release = afs_release, 3300d3b7a4SDavid Howells .llseek = generic_file_llseek, 34aad4f8bbSAl Viro .read_iter = generic_file_read_iter, 3550b5551dSAl Viro .write_iter = afs_file_write, 3600d3b7a4SDavid Howells .mmap = generic_file_readonly_mmap, 375ffc4ef4SJens Axboe .splice_read = generic_file_splice_read, 3831143d5dSDavid Howells .fsync = afs_fsync, 39e8d6c554SDavid Howells .lock = afs_lock, 40e8d6c554SDavid Howells .flock = afs_flock, 4100d3b7a4SDavid Howells }; 4200d3b7a4SDavid Howells 43754661f1SArjan van de Ven const struct inode_operations afs_file_inode_operations = { 44416351f2SDavid Howells .getattr = afs_getattr, 4531143d5dSDavid Howells .setattr = afs_setattr, 4600d3b7a4SDavid Howells .permission = afs_permission, 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 621da177e4SLinus Torvalds /* 6300d3b7a4SDavid Howells * open an AFS file or directory and attach a key to it 6400d3b7a4SDavid Howells */ 6500d3b7a4SDavid Howells int afs_open(struct inode *inode, struct file *file) 6600d3b7a4SDavid Howells { 6700d3b7a4SDavid Howells struct afs_vnode *vnode = AFS_FS_I(inode); 6800d3b7a4SDavid Howells struct key *key; 69260a9803SDavid Howells int ret; 7000d3b7a4SDavid Howells 71416351f2SDavid Howells _enter("{%x:%u},", vnode->fid.vid, vnode->fid.vnode); 7200d3b7a4SDavid Howells 7300d3b7a4SDavid Howells key = afs_request_key(vnode->volume->cell); 7400d3b7a4SDavid Howells if (IS_ERR(key)) { 7500d3b7a4SDavid Howells _leave(" = %ld [key]", PTR_ERR(key)); 7600d3b7a4SDavid Howells return PTR_ERR(key); 7700d3b7a4SDavid Howells } 7800d3b7a4SDavid Howells 79260a9803SDavid Howells ret = afs_validate(vnode, key); 80260a9803SDavid Howells if (ret < 0) { 81260a9803SDavid Howells _leave(" = %d [val]", ret); 82260a9803SDavid Howells return ret; 83260a9803SDavid Howells } 84260a9803SDavid Howells 8500d3b7a4SDavid Howells file->private_data = key; 8600d3b7a4SDavid Howells _leave(" = 0"); 8700d3b7a4SDavid Howells return 0; 8800d3b7a4SDavid Howells } 8900d3b7a4SDavid Howells 9000d3b7a4SDavid Howells /* 9100d3b7a4SDavid Howells * release an AFS file or directory and discard its key 9200d3b7a4SDavid Howells */ 9300d3b7a4SDavid Howells int afs_release(struct inode *inode, struct file *file) 9400d3b7a4SDavid Howells { 9500d3b7a4SDavid Howells struct afs_vnode *vnode = AFS_FS_I(inode); 9600d3b7a4SDavid Howells 97416351f2SDavid Howells _enter("{%x:%u},", vnode->fid.vid, vnode->fid.vnode); 9800d3b7a4SDavid Howells 9900d3b7a4SDavid Howells key_put(file->private_data); 10000d3b7a4SDavid Howells _leave(" = 0"); 10100d3b7a4SDavid Howells return 0; 10200d3b7a4SDavid Howells } 10300d3b7a4SDavid Howells 104*196ee9cdSDavid Howells /* 105*196ee9cdSDavid Howells * Dispose of a ref to a read record. 106*196ee9cdSDavid Howells */ 107*196ee9cdSDavid Howells void afs_put_read(struct afs_read *req) 108*196ee9cdSDavid Howells { 109*196ee9cdSDavid Howells int i; 110*196ee9cdSDavid Howells 111*196ee9cdSDavid Howells if (atomic_dec_and_test(&req->usage)) { 112*196ee9cdSDavid Howells for (i = 0; i < req->nr_pages; i++) 113*196ee9cdSDavid Howells if (req->pages[i]) 114*196ee9cdSDavid Howells put_page(req->pages[i]); 115*196ee9cdSDavid Howells kfree(req); 116*196ee9cdSDavid Howells } 117*196ee9cdSDavid Howells } 118*196ee9cdSDavid Howells 1196566abdbSMatt Kraai #ifdef CONFIG_AFS_FSCACHE 12000d3b7a4SDavid Howells /* 1211da177e4SLinus Torvalds * deal with notification that a page was read from the cache 1221da177e4SLinus Torvalds */ 1239b3f26c9SDavid Howells static void afs_file_readpage_read_complete(struct page *page, 1241da177e4SLinus Torvalds void *data, 1251da177e4SLinus Torvalds int error) 1261da177e4SLinus Torvalds { 1279b3f26c9SDavid Howells _enter("%p,%p,%d", page, data, error); 1281da177e4SLinus Torvalds 1299b3f26c9SDavid Howells /* if the read completes with an error, we just unlock the page and let 1309b3f26c9SDavid Howells * the VM reissue the readpage */ 1319b3f26c9SDavid Howells if (!error) 1321da177e4SLinus Torvalds SetPageUptodate(page); 1331da177e4SLinus Torvalds unlock_page(page); 134ec26815aSDavid Howells } 1356566abdbSMatt Kraai #endif 1361da177e4SLinus Torvalds 1371da177e4SLinus Torvalds /* 138f6d335c0SAl Viro * read page from file, directory or symlink, given a key to use 1391da177e4SLinus Torvalds */ 140f6d335c0SAl Viro int afs_page_filler(void *data, struct page *page) 1411da177e4SLinus Torvalds { 142f6d335c0SAl Viro struct inode *inode = page->mapping->host; 143f6d335c0SAl Viro struct afs_vnode *vnode = AFS_FS_I(inode); 144*196ee9cdSDavid Howells struct afs_read *req; 145f6d335c0SAl Viro struct key *key = data; 1461da177e4SLinus Torvalds int ret; 1471da177e4SLinus Torvalds 14800d3b7a4SDavid Howells _enter("{%x},{%lu},{%lu}", key_serial(key), inode->i_ino, page->index); 1491da177e4SLinus Torvalds 150cd7619d6SMatt Mackall BUG_ON(!PageLocked(page)); 1511da177e4SLinus Torvalds 1521da177e4SLinus Torvalds ret = -ESTALE; 15308e0e7c8SDavid Howells if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) 1541da177e4SLinus Torvalds goto error; 1551da177e4SLinus Torvalds 1561da177e4SLinus Torvalds /* is it cached? */ 1579b3f26c9SDavid Howells #ifdef CONFIG_AFS_FSCACHE 1589b3f26c9SDavid Howells ret = fscache_read_or_alloc_page(vnode->cache, 1591da177e4SLinus Torvalds page, 1601da177e4SLinus Torvalds afs_file_readpage_read_complete, 1611da177e4SLinus Torvalds NULL, 1621da177e4SLinus Torvalds GFP_KERNEL); 1631da177e4SLinus Torvalds #else 1641da177e4SLinus Torvalds ret = -ENOBUFS; 1651da177e4SLinus Torvalds #endif 1661da177e4SLinus Torvalds switch (ret) { 1671da177e4SLinus Torvalds /* read BIO submitted (page in cache) */ 1681da177e4SLinus Torvalds case 0: 1691da177e4SLinus Torvalds break; 1701da177e4SLinus Torvalds 1719b3f26c9SDavid Howells /* page not yet cached */ 1721da177e4SLinus Torvalds case -ENODATA: 1739b3f26c9SDavid Howells _debug("cache said ENODATA"); 1749b3f26c9SDavid Howells goto go_on; 1759b3f26c9SDavid Howells 1769b3f26c9SDavid Howells /* page will not be cached */ 1779b3f26c9SDavid Howells case -ENOBUFS: 1789b3f26c9SDavid Howells _debug("cache said ENOBUFS"); 1791da177e4SLinus Torvalds default: 1809b3f26c9SDavid Howells go_on: 181*196ee9cdSDavid Howells req = kzalloc(sizeof(struct afs_read) + sizeof(struct page *), 182*196ee9cdSDavid Howells GFP_KERNEL); 183*196ee9cdSDavid Howells if (!req) 184*196ee9cdSDavid Howells goto enomem; 185*196ee9cdSDavid Howells 186*196ee9cdSDavid Howells atomic_set(&req->usage, 1); 187*196ee9cdSDavid Howells req->pos = (loff_t)page->index << PAGE_SHIFT; 188*196ee9cdSDavid Howells req->len = min_t(size_t, i_size_read(inode) - req->pos, 189*196ee9cdSDavid Howells PAGE_SIZE); 190*196ee9cdSDavid Howells req->nr_pages = 1; 191*196ee9cdSDavid Howells req->pages[0] = page; 192*196ee9cdSDavid Howells get_page(page); 1931da177e4SLinus Torvalds 1941da177e4SLinus Torvalds /* read the contents of the file from the server into the 1951da177e4SLinus Torvalds * page */ 196*196ee9cdSDavid Howells ret = afs_vnode_fetch_data(vnode, key, req); 197*196ee9cdSDavid Howells afs_put_read(req); 1981da177e4SLinus Torvalds if (ret < 0) { 1991da177e4SLinus Torvalds if (ret == -ENOENT) { 2001da177e4SLinus Torvalds _debug("got NOENT from server" 2011da177e4SLinus Torvalds " - marking file deleted and stale"); 20208e0e7c8SDavid Howells set_bit(AFS_VNODE_DELETED, &vnode->flags); 2031da177e4SLinus Torvalds ret = -ESTALE; 2041da177e4SLinus Torvalds } 2059b3f26c9SDavid Howells 2069b3f26c9SDavid Howells #ifdef CONFIG_AFS_FSCACHE 2079b3f26c9SDavid Howells fscache_uncache_page(vnode->cache, page); 2081da177e4SLinus Torvalds #endif 2099b3f26c9SDavid Howells BUG_ON(PageFsCache(page)); 2101da177e4SLinus Torvalds goto error; 2111da177e4SLinus Torvalds } 2121da177e4SLinus Torvalds 2131da177e4SLinus Torvalds SetPageUptodate(page); 2141da177e4SLinus Torvalds 2159b3f26c9SDavid Howells /* send the page to the cache */ 2169b3f26c9SDavid Howells #ifdef CONFIG_AFS_FSCACHE 2179b3f26c9SDavid Howells if (PageFsCache(page) && 2189b3f26c9SDavid Howells fscache_write_page(vnode->cache, page, GFP_KERNEL) != 0) { 2199b3f26c9SDavid Howells fscache_uncache_page(vnode->cache, page); 2209b3f26c9SDavid Howells BUG_ON(PageFsCache(page)); 2211da177e4SLinus Torvalds } 2221da177e4SLinus Torvalds #endif 2239b3f26c9SDavid Howells unlock_page(page); 2241da177e4SLinus Torvalds } 2251da177e4SLinus Torvalds 2261da177e4SLinus Torvalds _leave(" = 0"); 2271da177e4SLinus Torvalds return 0; 2281da177e4SLinus Torvalds 229*196ee9cdSDavid Howells enomem: 230*196ee9cdSDavid Howells ret = -ENOMEM; 2311da177e4SLinus Torvalds error: 2321da177e4SLinus Torvalds SetPageError(page); 2331da177e4SLinus Torvalds unlock_page(page); 2341da177e4SLinus Torvalds _leave(" = %d", ret); 2351da177e4SLinus Torvalds return ret; 236ec26815aSDavid Howells } 2371da177e4SLinus Torvalds 2381da177e4SLinus Torvalds /* 239f6d335c0SAl Viro * read page from file, directory or symlink, given a file to nominate the key 240f6d335c0SAl Viro * to be used 241f6d335c0SAl Viro */ 242f6d335c0SAl Viro static int afs_readpage(struct file *file, struct page *page) 243f6d335c0SAl Viro { 244f6d335c0SAl Viro struct key *key; 245f6d335c0SAl Viro int ret; 246f6d335c0SAl Viro 247f6d335c0SAl Viro if (file) { 248f6d335c0SAl Viro key = file->private_data; 249f6d335c0SAl Viro ASSERT(key != NULL); 250f6d335c0SAl Viro ret = afs_page_filler(key, page); 251f6d335c0SAl Viro } else { 252f6d335c0SAl Viro struct inode *inode = page->mapping->host; 253f6d335c0SAl Viro key = afs_request_key(AFS_FS_S(inode->i_sb)->volume->cell); 254f6d335c0SAl Viro if (IS_ERR(key)) { 255f6d335c0SAl Viro ret = PTR_ERR(key); 256f6d335c0SAl Viro } else { 257f6d335c0SAl Viro ret = afs_page_filler(key, page); 258f6d335c0SAl Viro key_put(key); 259f6d335c0SAl Viro } 260f6d335c0SAl Viro } 261f6d335c0SAl Viro return ret; 262f6d335c0SAl Viro } 263f6d335c0SAl Viro 264f6d335c0SAl Viro /* 2659b3f26c9SDavid Howells * read a set of pages 2661da177e4SLinus Torvalds */ 2679b3f26c9SDavid Howells static int afs_readpages(struct file *file, struct address_space *mapping, 2689b3f26c9SDavid Howells struct list_head *pages, unsigned nr_pages) 2691da177e4SLinus Torvalds { 270f6d335c0SAl Viro struct key *key = file->private_data; 2719b3f26c9SDavid Howells struct afs_vnode *vnode; 2729b3f26c9SDavid Howells int ret = 0; 2731da177e4SLinus Torvalds 274f6d335c0SAl Viro _enter("{%d},{%lu},,%d", 275f6d335c0SAl Viro key_serial(key), mapping->host->i_ino, nr_pages); 276f6d335c0SAl Viro 277f6d335c0SAl Viro ASSERT(key != NULL); 2781da177e4SLinus Torvalds 2799b3f26c9SDavid Howells vnode = AFS_FS_I(mapping->host); 280ad2a8e60SDan Carpenter if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) { 2819b3f26c9SDavid Howells _leave(" = -ESTALE"); 2829b3f26c9SDavid Howells return -ESTALE; 2831da177e4SLinus Torvalds } 2841da177e4SLinus Torvalds 2859b3f26c9SDavid Howells /* attempt to read as many of the pages as possible */ 2869b3f26c9SDavid Howells #ifdef CONFIG_AFS_FSCACHE 2879b3f26c9SDavid Howells ret = fscache_read_or_alloc_pages(vnode->cache, 2889b3f26c9SDavid Howells mapping, 2899b3f26c9SDavid Howells pages, 2909b3f26c9SDavid Howells &nr_pages, 2919b3f26c9SDavid Howells afs_file_readpage_read_complete, 2929b3f26c9SDavid Howells NULL, 2939b3f26c9SDavid Howells mapping_gfp_mask(mapping)); 2949b3f26c9SDavid Howells #else 2959b3f26c9SDavid Howells ret = -ENOBUFS; 2969b3f26c9SDavid Howells #endif 2979b3f26c9SDavid Howells 2989b3f26c9SDavid Howells switch (ret) { 2999b3f26c9SDavid Howells /* all pages are being read from the cache */ 3009b3f26c9SDavid Howells case 0: 3019b3f26c9SDavid Howells BUG_ON(!list_empty(pages)); 3029b3f26c9SDavid Howells BUG_ON(nr_pages != 0); 3039b3f26c9SDavid Howells _leave(" = 0 [reading all]"); 3049b3f26c9SDavid Howells return 0; 3059b3f26c9SDavid Howells 3069b3f26c9SDavid Howells /* there were pages that couldn't be read from the cache */ 3079b3f26c9SDavid Howells case -ENODATA: 3089b3f26c9SDavid Howells case -ENOBUFS: 3099b3f26c9SDavid Howells break; 3109b3f26c9SDavid Howells 3119b3f26c9SDavid Howells /* other error */ 3129b3f26c9SDavid Howells default: 3131da177e4SLinus Torvalds _leave(" = %d", ret); 3149b3f26c9SDavid Howells return ret; 3159b3f26c9SDavid Howells } 3169b3f26c9SDavid Howells 3179b3f26c9SDavid Howells /* load the missing pages from the network */ 318f6d335c0SAl Viro ret = read_cache_pages(mapping, pages, afs_page_filler, key); 3199b3f26c9SDavid Howells 3209b3f26c9SDavid Howells _leave(" = %d [netting]", ret); 3219b3f26c9SDavid Howells return ret; 322ec26815aSDavid Howells } 3231da177e4SLinus Torvalds 3241da177e4SLinus Torvalds /* 32531143d5dSDavid Howells * write back a dirty page 32631143d5dSDavid Howells */ 32731143d5dSDavid Howells static int afs_launder_page(struct page *page) 32831143d5dSDavid Howells { 32931143d5dSDavid Howells _enter("{%lu}", page->index); 33031143d5dSDavid Howells 33131143d5dSDavid Howells return 0; 33231143d5dSDavid Howells } 33331143d5dSDavid Howells 33431143d5dSDavid Howells /* 3359b3f26c9SDavid Howells * invalidate part or all of a page 3369b3f26c9SDavid Howells * - release a page and clean up its private data if offset is 0 (indicating 3379b3f26c9SDavid Howells * the entire page) 3389b3f26c9SDavid Howells */ 339d47992f8SLukas Czerner static void afs_invalidatepage(struct page *page, unsigned int offset, 340d47992f8SLukas Czerner unsigned int length) 3419b3f26c9SDavid Howells { 3429b3f26c9SDavid Howells struct afs_writeback *wb = (struct afs_writeback *) page_private(page); 3439b3f26c9SDavid Howells 344d47992f8SLukas Czerner _enter("{%lu},%u,%u", page->index, offset, length); 3459b3f26c9SDavid Howells 3469b3f26c9SDavid Howells BUG_ON(!PageLocked(page)); 3479b3f26c9SDavid Howells 3489b3f26c9SDavid Howells /* we clean up only if the entire page is being invalidated */ 34909cbfeafSKirill A. Shutemov if (offset == 0 && length == PAGE_SIZE) { 3509b3f26c9SDavid Howells #ifdef CONFIG_AFS_FSCACHE 3519b3f26c9SDavid Howells if (PageFsCache(page)) { 3529b3f26c9SDavid Howells struct afs_vnode *vnode = AFS_FS_I(page->mapping->host); 3539b3f26c9SDavid Howells fscache_wait_on_page_write(vnode->cache, page); 3549b3f26c9SDavid Howells fscache_uncache_page(vnode->cache, page); 3559b3f26c9SDavid Howells } 3569b3f26c9SDavid Howells #endif 3579b3f26c9SDavid Howells 3589b3f26c9SDavid Howells if (PagePrivate(page)) { 3599b3f26c9SDavid Howells if (wb && !PageWriteback(page)) { 3609b3f26c9SDavid Howells set_page_private(page, 0); 3619b3f26c9SDavid Howells afs_put_writeback(wb); 3629b3f26c9SDavid Howells } 3639b3f26c9SDavid Howells 3649b3f26c9SDavid Howells if (!page_private(page)) 3659b3f26c9SDavid Howells ClearPagePrivate(page); 3669b3f26c9SDavid Howells } 3679b3f26c9SDavid Howells } 3689b3f26c9SDavid Howells 3699b3f26c9SDavid Howells _leave(""); 3709b3f26c9SDavid Howells } 3719b3f26c9SDavid Howells 3729b3f26c9SDavid Howells /* 3739b3f26c9SDavid Howells * release a page and clean up its private state if it's not busy 3749b3f26c9SDavid Howells * - return true if the page can now be released, false if not 3751da177e4SLinus Torvalds */ 376416351f2SDavid Howells static int afs_releasepage(struct page *page, gfp_t gfp_flags) 3771da177e4SLinus Torvalds { 3789b3f26c9SDavid Howells struct afs_writeback *wb = (struct afs_writeback *) page_private(page); 379416351f2SDavid Howells struct afs_vnode *vnode = AFS_FS_I(page->mapping->host); 3801da177e4SLinus Torvalds 381416351f2SDavid Howells _enter("{{%x:%u}[%lu],%lx},%x", 382416351f2SDavid Howells vnode->fid.vid, vnode->fid.vnode, page->index, page->flags, 383416351f2SDavid Howells gfp_flags); 3841da177e4SLinus Torvalds 3859b3f26c9SDavid Howells /* deny if page is being written to the cache and the caller hasn't 3869b3f26c9SDavid Howells * elected to wait */ 3879b3f26c9SDavid Howells #ifdef CONFIG_AFS_FSCACHE 388201a1542SDavid Howells if (!fscache_maybe_release_page(vnode->cache, page, gfp_flags)) { 3899b3f26c9SDavid Howells _leave(" = F [cache busy]"); 3909b3f26c9SDavid Howells return 0; 3919b3f26c9SDavid Howells } 3929b3f26c9SDavid Howells #endif 3939b3f26c9SDavid Howells 3949b3f26c9SDavid Howells if (PagePrivate(page)) { 3959b3f26c9SDavid Howells if (wb) { 3969b3f26c9SDavid Howells set_page_private(page, 0); 3979b3f26c9SDavid Howells afs_put_writeback(wb); 3989b3f26c9SDavid Howells } 3999b3f26c9SDavid Howells ClearPagePrivate(page); 4009b3f26c9SDavid Howells } 4019b3f26c9SDavid Howells 4029b3f26c9SDavid Howells /* indicate that the page can be released */ 4039b3f26c9SDavid Howells _leave(" = T"); 4049b3f26c9SDavid Howells return 1; 405ec26815aSDavid Howells } 406