diff --git a/fs/nfs/blocklayout/extent_tree.c b/fs/nfs/blocklayout/extent_tree.c index c59a59c37f3dabae1211db9efcb963442c013b36..35ab51c04814d67baecf83d3b3627d66fdd79359 100644 --- a/fs/nfs/blocklayout/extent_tree.c +++ b/fs/nfs/blocklayout/extent_tree.c @@ -476,6 +476,7 @@ static void ext_tree_free_commitdata(struct nfs4_layoutcommit_args *arg, for (i = 0; i < nr_pages; i++) put_page(arg->layoutupdate_pages[i]); + vfree(arg->start_p); kfree(arg->layoutupdate_pages); } else { put_page(arg->layoutupdate_page); @@ -559,10 +560,15 @@ ext_tree_prepare_commit(struct nfs4_layoutcommit_args *arg) if (unlikely(arg->layoutupdate_pages != &arg->layoutupdate_page)) { void *p = start_p, *end = p + arg->layoutupdate_len; + struct page *page = NULL; int i = 0; - for ( ; p < end; p += PAGE_SIZE) - arg->layoutupdate_pages[i++] = vmalloc_to_page(p); + arg->start_p = start_p; + for ( ; p < end; p += PAGE_SIZE) { + page = vmalloc_to_page(p); + arg->layoutupdate_pages[i++] = page; + get_page(page); + } } dprintk("%s found %zu ranges\n", __func__, count); diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 791098a08a8765bea64b4137baaf12ef4af62ac8..d320906cf13e5d7d3d443a6249992202eb171f59 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -275,6 +275,7 @@ struct nfs4_layoutcommit_args { size_t layoutupdate_len; struct page *layoutupdate_page; struct page **layoutupdate_pages; + __be32 *start_p; }; struct nfs4_layoutcommit_res {