Loading fs/afs/file.c +129 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include <linux/pagemap.h> #include <linux/writeback.h> #include <linux/gfp.h> #include <linux/task_io_accounting_ops.h> #include "internal.h" static int afs_readpage(struct file *file, struct page *page); Loading Loading @@ -261,6 +262,129 @@ static int afs_readpage(struct file *file, struct page *page) return ret; } /* * Make pages available as they're filled. */ static void afs_readpages_page_done(struct afs_call *call, struct afs_read *req) { struct afs_vnode *vnode = call->reply; struct page *page = req->pages[req->index]; req->pages[req->index] = NULL; 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); put_page(page); } /* * Read a contiguous set of pages. */ static int afs_readpages_one(struct file *file, struct address_space *mapping, struct list_head *pages) { struct afs_vnode *vnode = AFS_FS_I(mapping->host); struct afs_read *req; struct list_head *p; struct page *first, *page; struct key *key = file->private_data; pgoff_t index; int ret, n, i; /* Count the number of contiguous pages at the front of the list. Note * that the list goes prev-wards rather than next-wards. */ first = list_entry(pages->prev, struct page, lru); index = first->index + 1; n = 1; for (p = first->lru.prev; p != pages; p = p->prev) { page = list_entry(p, struct page, lru); if (page->index != index) break; index++; n++; } req = kzalloc(sizeof(struct afs_read) + sizeof(struct page *) * n, GFP_NOFS); if (!req) return -ENOMEM; atomic_set(&req->usage, 1); req->page_done = afs_readpages_page_done; req->pos = first->index; req->pos <<= PAGE_SHIFT; /* Transfer the pages to the request. We add them in until one fails * to add to the LRU and then we stop (as that'll make a hole in the * contiguous run. * * Note that it's possible for the file size to change whilst we're * doing this, but we rely on the server returning less than we asked * for if the file shrank. We also rely on this to deal with a partial * page at the end of the file. */ do { page = list_entry(pages->prev, struct page, lru); list_del(&page->lru); index = page->index; if (add_to_page_cache_lru(page, mapping, index, readahead_gfp_mask(mapping))) { #ifdef CONFIG_AFS_FSCACHE fscache_uncache_page(vnode->cache, page); #endif put_page(page); break; } req->pages[req->nr_pages++] = page; req->len += PAGE_SIZE; } while (req->nr_pages < n); if (req->nr_pages == 0) { kfree(req); return 0; } ret = afs_vnode_fetch_data(vnode, key, req); if (ret < 0) goto error; task_io_account_read(PAGE_SIZE * req->nr_pages); afs_put_read(req); return 0; error: if (ret == -ENOENT) { _debug("got NOENT from server" " - marking file deleted and stale"); set_bit(AFS_VNODE_DELETED, &vnode->flags); ret = -ESTALE; } for (i = 0; i < req->nr_pages; i++) { page = req->pages[i]; if (page) { #ifdef CONFIG_AFS_FSCACHE fscache_uncache_page(vnode->cache, page); #endif SetPageError(page); unlock_page(page); } } afs_put_read(req); return ret; } /* * read a set of pages */ Loading Loading @@ -314,8 +438,11 @@ static int afs_readpages(struct file *file, struct address_space *mapping, return ret; } /* load the missing pages from the network */ ret = read_cache_pages(mapping, pages, afs_page_filler, key); while (!list_empty(pages)) { ret = afs_readpages_one(file, mapping, pages); if (ret < 0) break; } _leave(" = %d [netting]", ret); return ret; Loading fs/afs/volume.c +1 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,7 @@ struct afs_volume *afs_volume_lookup(struct afs_mount_params *params) volume->cell = params->cell; volume->vid = vlocation->vldb.vid[params->type]; volume->bdi.ra_pages = VM_MAX_READAHEAD*1024/PAGE_SIZE; ret = bdi_setup_and_register(&volume->bdi, "afs"); if (ret) goto error_bdi; Loading Loading
fs/afs/file.c +129 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include <linux/pagemap.h> #include <linux/writeback.h> #include <linux/gfp.h> #include <linux/task_io_accounting_ops.h> #include "internal.h" static int afs_readpage(struct file *file, struct page *page); Loading Loading @@ -261,6 +262,129 @@ static int afs_readpage(struct file *file, struct page *page) return ret; } /* * Make pages available as they're filled. */ static void afs_readpages_page_done(struct afs_call *call, struct afs_read *req) { struct afs_vnode *vnode = call->reply; struct page *page = req->pages[req->index]; req->pages[req->index] = NULL; 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); put_page(page); } /* * Read a contiguous set of pages. */ static int afs_readpages_one(struct file *file, struct address_space *mapping, struct list_head *pages) { struct afs_vnode *vnode = AFS_FS_I(mapping->host); struct afs_read *req; struct list_head *p; struct page *first, *page; struct key *key = file->private_data; pgoff_t index; int ret, n, i; /* Count the number of contiguous pages at the front of the list. Note * that the list goes prev-wards rather than next-wards. */ first = list_entry(pages->prev, struct page, lru); index = first->index + 1; n = 1; for (p = first->lru.prev; p != pages; p = p->prev) { page = list_entry(p, struct page, lru); if (page->index != index) break; index++; n++; } req = kzalloc(sizeof(struct afs_read) + sizeof(struct page *) * n, GFP_NOFS); if (!req) return -ENOMEM; atomic_set(&req->usage, 1); req->page_done = afs_readpages_page_done; req->pos = first->index; req->pos <<= PAGE_SHIFT; /* Transfer the pages to the request. We add them in until one fails * to add to the LRU and then we stop (as that'll make a hole in the * contiguous run. * * Note that it's possible for the file size to change whilst we're * doing this, but we rely on the server returning less than we asked * for if the file shrank. We also rely on this to deal with a partial * page at the end of the file. */ do { page = list_entry(pages->prev, struct page, lru); list_del(&page->lru); index = page->index; if (add_to_page_cache_lru(page, mapping, index, readahead_gfp_mask(mapping))) { #ifdef CONFIG_AFS_FSCACHE fscache_uncache_page(vnode->cache, page); #endif put_page(page); break; } req->pages[req->nr_pages++] = page; req->len += PAGE_SIZE; } while (req->nr_pages < n); if (req->nr_pages == 0) { kfree(req); return 0; } ret = afs_vnode_fetch_data(vnode, key, req); if (ret < 0) goto error; task_io_account_read(PAGE_SIZE * req->nr_pages); afs_put_read(req); return 0; error: if (ret == -ENOENT) { _debug("got NOENT from server" " - marking file deleted and stale"); set_bit(AFS_VNODE_DELETED, &vnode->flags); ret = -ESTALE; } for (i = 0; i < req->nr_pages; i++) { page = req->pages[i]; if (page) { #ifdef CONFIG_AFS_FSCACHE fscache_uncache_page(vnode->cache, page); #endif SetPageError(page); unlock_page(page); } } afs_put_read(req); return ret; } /* * read a set of pages */ Loading Loading @@ -314,8 +438,11 @@ static int afs_readpages(struct file *file, struct address_space *mapping, return ret; } /* load the missing pages from the network */ ret = read_cache_pages(mapping, pages, afs_page_filler, key); while (!list_empty(pages)) { ret = afs_readpages_one(file, mapping, pages); if (ret < 0) break; } _leave(" = %d [netting]", ret); return ret; Loading
fs/afs/volume.c +1 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,7 @@ struct afs_volume *afs_volume_lookup(struct afs_mount_params *params) volume->cell = params->cell; volume->vid = vlocation->vldb.vid[params->type]; volume->bdi.ra_pages = VM_MAX_READAHEAD*1024/PAGE_SIZE; ret = bdi_setup_and_register(&volume->bdi, "afs"); if (ret) goto error_bdi; Loading