/* * AFS read page from file, directory or symlink */ static int afs_readpage(struct file *file, struct page *page) { struct afs_vnode *vnode; struct inode *inode; struct key *key; size_t len; off_t offset; int ret; inode = page->mapping->host; if (file) { key = file->private_data; ASSERT(key != NULL); } else { key = afs_request_key(AFS_FS_S(inode->i_sb)->volume->cell); if (IS_ERR(key)) { ret = PTR_ERR(key); goto error_nokey; } } _enter("{%x},{%lu},{%lu}", key_serial(key), inode->i_ino, page->index); vnode = AFS_FS_I(inode); BUG_ON(!PageLocked(page)); ret = -ESTALE; if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) goto error; /* is it cached? */ #ifdef CONFIG_AFS_FSCACHE ret = fscache_read_or_alloc_page(vnode->cache, page, afs_file_readpage_read_complete, NULL, GFP_KERNEL); #else ret = -ENOBUFS; #endif switch (ret) { /* read BIO submitted (page in cache) */ case 0: break; /* page not yet cached */ case -ENODATA: _debug("cache said ENODATA"); goto go_on; /* page will not be cached */ case -ENOBUFS: _debug("cache said ENOBUFS"); default: go_on: offset = page->index << PAGE_CACHE_SHIFT; len = min_t(size_t, i_size_read(inode) - offset, PAGE_SIZE); /* read the contents of the file from the server into the * page */ ret = afs_vnode_fetch_data(vnode, key, offset, len, page); if (ret < 0) { if (ret == -ENOENT) { _debug("got NOENT from server" " - marking file deleted and stale"); set_bit(AFS_VNODE_DELETED, &vnode->flags); ret = -ESTALE; } #ifdef CONFIG_AFS_FSCACHE fscache_uncache_page(vnode->cache, page); #endif BUG_ON(PageFsCache(page)); goto error; } SetPageUptodate(page); /* send the page to the cache */ #ifdef CONFIG_AFS_FSCACHE if (PageFsCache(page) && fscache_write_page(vnode->cache, page, GFP_KERNEL) != 0) { fscache_uncache_page(vnode->cache, page); BUG_ON(PageFsCache(page)); } #endif unlock_page(page); } if (!file) key_put(key); _leave(" = 0"); return 0; error: SetPageError(page); unlock_page(page); if (!file) key_put(key); error_nokey: _leave(" = %d", ret); return ret; }
/* * AFS read page from file, directory or symlink */ static int afs_readpage(struct file *file, struct page *page) { struct afs_vnode *vnode; struct inode *inode; struct key *key; size_t len; off_t offset; int ret; inode = page->mapping->host; ASSERT(file != NULL); key = file->private_data; ASSERT(key != NULL); _enter("{%x},{%lu},{%lu}", key_serial(key), inode->i_ino, page->index); vnode = AFS_FS_I(inode); BUG_ON(!PageLocked(page)); ret = -ESTALE; if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) goto error; #ifdef AFS_CACHING_SUPPORT /* is it cached? */ ret = cachefs_read_or_alloc_page(vnode->cache, page, afs_file_readpage_read_complete, NULL, GFP_KERNEL); #else ret = -ENOBUFS; #endif switch (ret) { /* read BIO submitted and wb-journal entry found */ case 1: BUG(); // TODO - handle wb-journal match /* read BIO submitted (page in cache) */ case 0: break; /* no page available in cache */ case -ENOBUFS: case -ENODATA: default: offset = page->index << PAGE_CACHE_SHIFT; len = min_t(size_t, i_size_read(inode) - offset, PAGE_SIZE); /* read the contents of the file from the server into the * page */ ret = afs_vnode_fetch_data(vnode, key, offset, len, page); if (ret < 0) { if (ret == -ENOENT) { _debug("got NOENT from server" " - marking file deleted and stale"); set_bit(AFS_VNODE_DELETED, &vnode->flags); ret = -ESTALE; } #ifdef AFS_CACHING_SUPPORT cachefs_uncache_page(vnode->cache, page); #endif goto error; } SetPageUptodate(page); #ifdef AFS_CACHING_SUPPORT if (cachefs_write_page(vnode->cache, page, afs_file_readpage_write_complete, NULL, GFP_KERNEL) != 0 ) { cachefs_uncache_page(vnode->cache, page); unlock_page(page); } #else unlock_page(page); #endif } _leave(" = 0"); return 0; error: SetPageError(page); unlock_page(page); _leave(" = %d", ret); return ret; }
/* * AFS read page from file (or symlink) */ static int afs_file_readpage(struct file *file, struct page *page) { struct afs_rxfs_fetch_descriptor desc; #ifdef AFS_CACHING_SUPPORT struct cachefs_page *pageio; #endif struct afs_vnode *vnode; struct inode *inode; int ret; inode = page->mapping->host; _enter("{%lu},{%lu}", inode->i_ino, page->index); vnode = AFS_FS_I(inode); BUG_ON(!PageLocked(page)); ret = -ESTALE; if (vnode->flags & AFS_VNODE_DELETED) goto error; #ifdef AFS_CACHING_SUPPORT ret = cachefs_page_get_private(page, &pageio, GFP_NOIO); if (ret < 0) goto error; /* is it cached? */ ret = cachefs_read_or_alloc_page(vnode->cache, page, afs_file_readpage_read_complete, NULL, GFP_KERNEL); #else ret = -ENOBUFS; #endif switch (ret) { /* read BIO submitted and wb-journal entry found */ case 1: BUG(); // TODO - handle wb-journal match /* read BIO submitted (page in cache) */ case 0: break; /* no page available in cache */ case -ENOBUFS: case -ENODATA: default: desc.fid = vnode->fid; desc.offset = page->index << PAGE_CACHE_SHIFT; desc.size = min((size_t) (inode->i_size - desc.offset), (size_t) PAGE_SIZE); desc.buffer = kmap(page); clear_page(desc.buffer); /* read the contents of the file from the server into the * page */ ret = afs_vnode_fetch_data(vnode, &desc); kunmap(page); if (ret < 0) { if (ret==-ENOENT) { _debug("got NOENT from server" " - marking file deleted and stale"); vnode->flags |= AFS_VNODE_DELETED; ret = -ESTALE; } #ifdef AFS_CACHING_SUPPORT cachefs_uncache_page(vnode->cache, page); #endif goto error; } SetPageUptodate(page); #ifdef AFS_CACHING_SUPPORT if (cachefs_write_page(vnode->cache, page, afs_file_readpage_write_complete, NULL, GFP_KERNEL) != 0 ) { cachefs_uncache_page(vnode->cache, page); unlock_page(page); } #else unlock_page(page); #endif } _leave(" = 0"); return 0; error: SetPageError(page); unlock_page(page); _leave(" = %d", ret); return ret; } /* end afs_file_readpage() */
/* * AFS read page from file (or symlink) */ static int afs_file_readpage(struct file *file, struct page *page) { struct afs_rxfs_fetch_descriptor desc; struct afs_vnode *vnode; struct inode *inode; int ret; inode = page->mapping->host; _enter("{%lu},%p{%lu}", inode->i_ino, page, page->index); vnode = AFS_FS_I(inode); BUG_ON(!PageLocked(page)); ret = -ESTALE; if (vnode->flags & AFS_VNODE_DELETED) goto error; #ifdef CONFIG_AFS_FSCACHE /* is it cached? */ ret = fscache_read_or_alloc_page(vnode->cache, page, afs_file_readpage_read_complete, NULL, GFP_KERNEL); #else ret = -ENOBUFS; #endif switch (ret) { /* read BIO submitted (page in cache) */ case 0: break; /* page not yet cached */ case -ENODATA: _debug("cache said ENODATA"); goto go_on; /* page will not be cached */ case -ENOBUFS: _debug("cache said ENOBUFS"); default: go_on: desc.fid = vnode->fid; desc.offset = page->index << PAGE_CACHE_SHIFT; desc.size = min((size_t) (inode->i_size - desc.offset), (size_t) PAGE_SIZE); desc.buffer = kmap(page); clear_page(desc.buffer); /* read the contents of the file from the server into the * page */ ret = afs_vnode_fetch_data(vnode, &desc); kunmap(page); if (ret < 0) { if (ret == -ENOENT) { kdebug("got NOENT from server" " - marking file deleted and stale"); vnode->flags |= AFS_VNODE_DELETED; ret = -ESTALE; } #ifdef CONFIG_AFS_FSCACHE fscache_uncache_page(vnode->cache, page); ClearPagePrivate(page); #endif goto error; } SetPageUptodate(page); /* send the page to the cache */ #ifdef CONFIG_AFS_FSCACHE if (PagePrivate(page)) { if (TestSetPageFsMisc(page)) BUG(); if (fscache_write_page(vnode->cache, page, afs_file_readpage_write_complete, NULL, GFP_KERNEL) != 0 ) { fscache_uncache_page(vnode->cache, page); ClearPagePrivate(page); end_page_fs_misc(page); } } #endif unlock_page(page); } _leave(" = 0"); return 0; error: SetPageError(page); unlock_page(page); _leave(" = %d", ret); return ret; } /* end afs_file_readpage() */