X-Git-Url: https://git.camperquake.de/gitweb.cgi?a=blobdiff_plain;f=module%2Fzfs%2Fzpl_file.c;h=298c0b62df751dcc7ad13c380ef43b2b28a9d70d;hb=5547c2f1bf49802835fd6c52f15115ba344a2a8b;hp=c2e3a6bdcf489811b03035a1fc7f39bb060967c2;hpb=cfc9a5c88f91f7b4d606fce89505e1f404691ea5;p=zfs.git diff --git a/module/zfs/zpl_file.c b/module/zfs/zpl_file.c index c2e3a6b..298c0b6 100644 --- a/module/zfs/zpl_file.c +++ b/module/zfs/zpl_file.c @@ -260,60 +260,6 @@ zpl_mmap(struct file *filp, struct vm_area_struct *vma) return (error); } -static struct page ** -pages_vector_from_list(struct list_head *pages, unsigned nr_pages) -{ - struct page **pl; - struct page *t; - unsigned page_idx; - - pl = kmalloc(sizeof(*pl) * nr_pages, GFP_NOFS); - if (!pl) - return ERR_PTR(-ENOMEM); - - page_idx = 0; - list_for_each_entry_reverse(t, pages, lru) { - pl[page_idx] = t; - page_idx++; - } - - return pl; -} - -static int -zpl_readpages(struct file *file, struct address_space *mapping, - struct list_head *pages, unsigned nr_pages) -{ - struct inode *ip; - struct page **pl; - struct page *p, *n; - int error; - - ip = mapping->host; - - pl = pages_vector_from_list(pages, nr_pages); - if (IS_ERR(pl)) - return PTR_ERR(pl); - - error = -zfs_getpage(ip, pl, nr_pages); - if (error) - goto error; - - list_for_each_entry_safe_reverse(p, n, pages, lru) { - - list_del(&p->lru); - - flush_dcache_page(p); - SetPageUptodate(p); - unlock_page(p); - page_cache_release(p); - } - -error: - kfree(pl); - return error; -} - /* * Populate a page with data for the Linux page cache. This function is * only used to support mmap(2). There will be an identical copy of the @@ -349,10 +295,27 @@ zpl_readpage(struct file *filp, struct page *pp) return error; } +/* + * Populate a set of pages with data for the Linux page cache. This + * function will only be called for read ahead and never for demand + * paging. For simplicity, the code relies on read_cache_pages() to + * correctly lock each page for IO and call zpl_readpage(). + */ +static int +zpl_readpages(struct file *filp, struct address_space *mapping, + struct list_head *pages, unsigned nr_pages) +{ + return (read_cache_pages(mapping, pages, + (filler_t *)zpl_readpage, filp)); +} + int zpl_putpage(struct page *pp, struct writeback_control *wbc, void *data) { - int error; + struct address_space *mapping = data; + + ASSERT(PageLocked(pp)); + ASSERT(!PageWriteback(pp)); /* * Disable the normal reclaim path for zpl_putpage(). This @@ -361,21 +324,15 @@ zpl_putpage(struct page *pp, struct writeback_control *wbc, void *data) * the VM might try to write out additional pages by calling * zpl_putpage() again resulting in a deadlock. */ - current->flags |= PF_MEMALLOC; - error = -zfs_putpage(pp, wbc, data); - current->flags &= ~PF_MEMALLOC; - - if (error) { - SetPageError(pp); - ClearPageUptodate(pp); + if (current->flags & PF_MEMALLOC) { + (void) zfs_putpage(mapping->host, pp, wbc); } else { - ClearPageError(pp); - SetPageUptodate(pp); - flush_dcache_page(pp); + current->flags |= PF_MEMALLOC; + (void) zfs_putpage(mapping->host, pp, wbc); + current->flags &= ~PF_MEMALLOC; } - unlock_page(pp); - return error; + return (0); } static int