Commit ad746be96941ddd2fb31fad7a629de7912051c8d

Authored by Linus Torvalds

Merge tag 'nfs-for-3.6-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs

Pull NFS client bugfixes from Trond Myklebust:
 - NFSv3 mounts need to fail if the FSINFO rpc call fails
 - Ensure that the NFS commit cache gets torn down when we unload the
   NFS module.
 - Fix memory scribble issues when interrupting a LAYOUTGET rpc call
 - Fix NFSv4 legacy idmapper regressions
 - Fix issues with the NFSv4 getacl command
 - Fix a regression when using the legacy "mount -t nfs4"

* tag 'nfs-for-3.6-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
  NFSv3: Ensure that do_proc_get_root() reports errors correctly
  NFSv4: Ensure that nfs4_alloc_client cleans up on error.
  NFS: return -ENOKEY when the upcall fails to map the name
  NFS: Clear key construction data if the idmap upcall fails
  NFSv4: Don't use private xdr_stream fields in decode_getacl
  NFSv4: Fix the acl cache size calculation
  NFSv4: Fix pointer arithmetic in decode_getacl
  NFS: Alias the nfs module to nfs4
  NFS: Fix a regression when loading the NFS v4 module
  NFSv4.1: Remove a bogus BUG_ON() in nfs4_layoutreturn_done
  pnfs-obj: Better IO pattern in case of unaligned offset
  NFS41: add pg_layout_private to nfs_pageio_descriptor
  pnfs: nfs4_proc_layoutget returns void
  pnfs: defer release of pages in layoutget
  nfs: tear down caches in nfs_init_writepagecache when allocation fails

Showing 17 changed files Side-by-side Diff

... ... @@ -12,19 +12,19 @@
12 12 nfs-$(CONFIG_SYSCTL) += sysctl.o
13 13 nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o
14 14  
15   -obj-$(CONFIG_NFS_V2) += nfs2.o
16   -nfs2-y := nfs2super.o proc.o nfs2xdr.o
  15 +obj-$(CONFIG_NFS_V2) += nfsv2.o
  16 +nfsv2-y := nfs2super.o proc.o nfs2xdr.o
17 17  
18   -obj-$(CONFIG_NFS_V3) += nfs3.o
19   -nfs3-y := nfs3super.o nfs3client.o nfs3proc.o nfs3xdr.o
20   -nfs3-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
  18 +obj-$(CONFIG_NFS_V3) += nfsv3.o
  19 +nfsv3-y := nfs3super.o nfs3client.o nfs3proc.o nfs3xdr.o
  20 +nfsv3-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
21 21  
22   -obj-$(CONFIG_NFS_V4) += nfs4.o
23   -nfs4-y := nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o nfs4super.o nfs4file.o \
  22 +obj-$(CONFIG_NFS_V4) += nfsv4.o
  23 +nfsv4-y := nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o nfs4super.o nfs4file.o \
24 24 delegation.o idmap.o callback.o callback_xdr.o callback_proc.o \
25 25 nfs4namespace.o nfs4getroot.o nfs4client.o
26   -nfs4-$(CONFIG_SYSCTL) += nfs4sysctl.o
27   -nfs4-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o
  26 +nfsv4-$(CONFIG_SYSCTL) += nfs4sysctl.o
  27 +nfsv4-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o
28 28  
29 29 obj-$(CONFIG_PNFS_FILE_LAYOUT) += nfs_layout_nfsv41_files.o
30 30 nfs_layout_nfsv41_files-y := nfs4filelayout.o nfs4filelayoutdev.o
... ... @@ -105,7 +105,7 @@
105 105  
106 106 if (IS_ERR(nfs)) {
107 107 mutex_lock(&nfs_version_mutex);
108   - request_module("nfs%d", version);
  108 + request_module("nfsv%d", version);
109 109 nfs = find_nfs_version(version);
110 110 mutex_unlock(&nfs_version_mutex);
111 111 }
... ... @@ -61,6 +61,12 @@
61 61 struct mutex idmap_mutex;
62 62 };
63 63  
  64 +struct idmap_legacy_upcalldata {
  65 + struct rpc_pipe_msg pipe_msg;
  66 + struct idmap_msg idmap_msg;
  67 + struct idmap *idmap;
  68 +};
  69 +
64 70 /**
65 71 * nfs_fattr_init_names - initialise the nfs_fattr owner_name/group_name fields
66 72 * @fattr: fully initialised struct nfs_fattr
... ... @@ -324,6 +330,7 @@
324 330 ret = nfs_idmap_request_key(&key_type_id_resolver_legacy,
325 331 name, namelen, type, data,
326 332 data_size, idmap);
  333 + idmap->idmap_key_cons = NULL;
327 334 mutex_unlock(&idmap->idmap_mutex);
328 335 }
329 336 return ret;
330 337  
... ... @@ -380,11 +387,13 @@
380 387 static int nfs_idmap_legacy_upcall(struct key_construction *, const char *, void *);
381 388 static ssize_t idmap_pipe_downcall(struct file *, const char __user *,
382 389 size_t);
  390 +static void idmap_release_pipe(struct inode *);
383 391 static void idmap_pipe_destroy_msg(struct rpc_pipe_msg *);
384 392  
385 393 static const struct rpc_pipe_ops idmap_upcall_ops = {
386 394 .upcall = rpc_pipe_generic_upcall,
387 395 .downcall = idmap_pipe_downcall,
  396 + .release_pipe = idmap_release_pipe,
388 397 .destroy_msg = idmap_pipe_destroy_msg,
389 398 };
390 399  
... ... @@ -616,7 +625,8 @@
616 625 nfs_idmap_quit_keyring();
617 626 }
618 627  
619   -static int nfs_idmap_prepare_message(char *desc, struct idmap_msg *im,
  628 +static int nfs_idmap_prepare_message(char *desc, struct idmap *idmap,
  629 + struct idmap_msg *im,
620 630 struct rpc_pipe_msg *msg)
621 631 {
622 632 substring_t substr;
... ... @@ -659,6 +669,7 @@
659 669 const char *op,
660 670 void *aux)
661 671 {
  672 + struct idmap_legacy_upcalldata *data;
662 673 struct rpc_pipe_msg *msg;
663 674 struct idmap_msg *im;
664 675 struct idmap *idmap = (struct idmap *)aux;
665 676  
... ... @@ -666,15 +677,15 @@
666 677 int ret = -ENOMEM;
667 678  
668 679 /* msg and im are freed in idmap_pipe_destroy_msg */
669   - msg = kmalloc(sizeof(*msg), GFP_KERNEL);
670   - if (!msg)
671   - goto out0;
672   -
673   - im = kmalloc(sizeof(*im), GFP_KERNEL);
674   - if (!im)
  680 + data = kmalloc(sizeof(*data), GFP_KERNEL);
  681 + if (!data)
675 682 goto out1;
676 683  
677   - ret = nfs_idmap_prepare_message(key->description, im, msg);
  684 + msg = &data->pipe_msg;
  685 + im = &data->idmap_msg;
  686 + data->idmap = idmap;
  687 +
  688 + ret = nfs_idmap_prepare_message(key->description, idmap, im, msg);
678 689 if (ret < 0)
679 690 goto out2;
680 691  
681 692  
682 693  
683 694  
... ... @@ -683,15 +694,15 @@
683 694  
684 695 ret = rpc_queue_upcall(idmap->idmap_pipe, msg);
685 696 if (ret < 0)
686   - goto out2;
  697 + goto out3;
687 698  
688 699 return ret;
689 700  
  701 +out3:
  702 + idmap->idmap_key_cons = NULL;
690 703 out2:
691   - kfree(im);
  704 + kfree(data);
692 705 out1:
693   - kfree(msg);
694   -out0:
695 706 complete_request_key(cons, ret);
696 707 return ret;
697 708 }
... ... @@ -749,9 +760,8 @@
749 760 }
750 761  
751 762 if (!(im.im_status & IDMAP_STATUS_SUCCESS)) {
752   - ret = mlen;
753   - complete_request_key(cons, -ENOKEY);
754   - goto out_incomplete;
  763 + ret = -ENOKEY;
  764 + goto out;
755 765 }
756 766  
757 767 namelen_in = strnlen(im.im_name, IDMAP_NAMESZ);
758 768  
759 769  
... ... @@ -768,16 +778,32 @@
768 778  
769 779 out:
770 780 complete_request_key(cons, ret);
771   -out_incomplete:
772 781 return ret;
773 782 }
774 783  
775 784 static void
776 785 idmap_pipe_destroy_msg(struct rpc_pipe_msg *msg)
777 786 {
  787 + struct idmap_legacy_upcalldata *data = container_of(msg,
  788 + struct idmap_legacy_upcalldata,
  789 + pipe_msg);
  790 + struct idmap *idmap = data->idmap;
  791 + struct key_construction *cons;
  792 + if (msg->errno) {
  793 + cons = ACCESS_ONCE(idmap->idmap_key_cons);
  794 + idmap->idmap_key_cons = NULL;
  795 + complete_request_key(cons, msg->errno);
  796 + }
778 797 /* Free memory allocated in nfs_idmap_legacy_upcall() */
779   - kfree(msg->data);
780   - kfree(msg);
  798 + kfree(data);
  799 +}
  800 +
  801 +static void
  802 +idmap_release_pipe(struct inode *inode)
  803 +{
  804 + struct rpc_inode *rpci = RPC_I(inode);
  805 + struct idmap *idmap = (struct idmap *)rpci->private;
  806 + idmap->idmap_key_cons = NULL;
781 807 }
782 808  
783 809 int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *uid)
... ... @@ -69,7 +69,7 @@
69 69 nfs_fattr_init(info->fattr);
70 70 status = rpc_call_sync(client, &msg, 0);
71 71 dprintk("%s: reply fsinfo: %d\n", __func__, status);
72   - if (!(info->fattr->valid & NFS_ATTR_FATTR)) {
  72 + if (status == 0 && !(info->fattr->valid & NFS_ATTR_FATTR)) {
73 73 msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR];
74 74 msg.rpc_resp = info->fattr;
75 75 status = rpc_call_sync(client, &msg, 0);
... ... @@ -205,6 +205,9 @@
205 205 int nfs_atomic_open(struct inode *, struct dentry *, struct file *,
206 206 unsigned, umode_t, int *);
207 207  
  208 +/* super.c */
  209 +extern struct file_system_type nfs4_fs_type;
  210 +
208 211 /* nfs4namespace.c */
209 212 rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *);
210 213 struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *, struct inode *, struct qstr *);
... ... @@ -74,7 +74,7 @@
74 74 return clp;
75 75  
76 76 error:
77   - kfree(clp);
  77 + nfs_free_client(clp);
78 78 return ERR_PTR(err);
79 79 }
80 80  
... ... @@ -3737,9 +3737,10 @@
3737 3737 static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size_t pgbase, size_t acl_len)
3738 3738 {
3739 3739 struct nfs4_cached_acl *acl;
  3740 + size_t buflen = sizeof(*acl) + acl_len;
3740 3741  
3741   - if (pages && acl_len <= PAGE_SIZE) {
3742   - acl = kmalloc(sizeof(*acl) + acl_len, GFP_KERNEL);
  3742 + if (pages && buflen <= PAGE_SIZE) {
  3743 + acl = kmalloc(buflen, GFP_KERNEL);
3743 3744 if (acl == NULL)
3744 3745 goto out;
3745 3746 acl->cached = 1;
... ... @@ -3819,7 +3820,7 @@
3819 3820 if (ret)
3820 3821 goto out_free;
3821 3822  
3822   - acl_len = res.acl_len - res.acl_data_offset;
  3823 + acl_len = res.acl_len;
3823 3824 if (acl_len > args.acl_len)
3824 3825 nfs4_write_cached_acl(inode, NULL, 0, acl_len);
3825 3826 else
3826 3827  
3827 3828  
... ... @@ -6223,11 +6224,58 @@
6223 6224 dprintk("<-- %s\n", __func__);
6224 6225 }
6225 6226  
  6227 +static size_t max_response_pages(struct nfs_server *server)
  6228 +{
  6229 + u32 max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
  6230 + return nfs_page_array_len(0, max_resp_sz);
  6231 +}
  6232 +
  6233 +static void nfs4_free_pages(struct page **pages, size_t size)
  6234 +{
  6235 + int i;
  6236 +
  6237 + if (!pages)
  6238 + return;
  6239 +
  6240 + for (i = 0; i < size; i++) {
  6241 + if (!pages[i])
  6242 + break;
  6243 + __free_page(pages[i]);
  6244 + }
  6245 + kfree(pages);
  6246 +}
  6247 +
  6248 +static struct page **nfs4_alloc_pages(size_t size, gfp_t gfp_flags)
  6249 +{
  6250 + struct page **pages;
  6251 + int i;
  6252 +
  6253 + pages = kcalloc(size, sizeof(struct page *), gfp_flags);
  6254 + if (!pages) {
  6255 + dprintk("%s: can't alloc array of %zu pages\n", __func__, size);
  6256 + return NULL;
  6257 + }
  6258 +
  6259 + for (i = 0; i < size; i++) {
  6260 + pages[i] = alloc_page(gfp_flags);
  6261 + if (!pages[i]) {
  6262 + dprintk("%s: failed to allocate page\n", __func__);
  6263 + nfs4_free_pages(pages, size);
  6264 + return NULL;
  6265 + }
  6266 + }
  6267 +
  6268 + return pages;
  6269 +}
  6270 +
6226 6271 static void nfs4_layoutget_release(void *calldata)
6227 6272 {
6228 6273 struct nfs4_layoutget *lgp = calldata;
  6274 + struct nfs_server *server = NFS_SERVER(lgp->args.inode);
  6275 + size_t max_pages = max_response_pages(server);
6229 6276  
6230 6277 dprintk("--> %s\n", __func__);
  6278 + nfs4_free_pages(lgp->args.layout.pages, max_pages);
6231 6279 put_nfs_open_context(lgp->args.ctx);
6232 6280 kfree(calldata);
6233 6281 dprintk("<-- %s\n", __func__);
6234 6282  
... ... @@ -6239,9 +6287,10 @@
6239 6287 .rpc_release = nfs4_layoutget_release,
6240 6288 };
6241 6289  
6242   -int nfs4_proc_layoutget(struct nfs4_layoutget *lgp)
  6290 +void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
6243 6291 {
6244 6292 struct nfs_server *server = NFS_SERVER(lgp->args.inode);
  6293 + size_t max_pages = max_response_pages(server);
6245 6294 struct rpc_task *task;
6246 6295 struct rpc_message msg = {
6247 6296 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTGET],
6248 6297  
... ... @@ -6259,12 +6308,19 @@
6259 6308  
6260 6309 dprintk("--> %s\n", __func__);
6261 6310  
  6311 + lgp->args.layout.pages = nfs4_alloc_pages(max_pages, gfp_flags);
  6312 + if (!lgp->args.layout.pages) {
  6313 + nfs4_layoutget_release(lgp);
  6314 + return;
  6315 + }
  6316 + lgp->args.layout.pglen = max_pages * PAGE_SIZE;
  6317 +
6262 6318 lgp->res.layoutp = &lgp->args.layout;
6263 6319 lgp->res.seq_res.sr_slot = NULL;
6264 6320 nfs41_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0);
6265 6321 task = rpc_run_task(&task_setup_data);
6266 6322 if (IS_ERR(task))
6267   - return PTR_ERR(task);
  6323 + return;
6268 6324 status = nfs4_wait_for_completion_rpc_task(task);
6269 6325 if (status == 0)
6270 6326 status = task->tk_status;
... ... @@ -6272,7 +6328,7 @@
6272 6328 status = pnfs_layout_process(lgp);
6273 6329 rpc_put_task(task);
6274 6330 dprintk("<-- %s status=%d\n", __func__, status);
6275   - return status;
  6331 + return;
6276 6332 }
6277 6333  
6278 6334 static void
... ... @@ -6304,12 +6360,8 @@
6304 6360 return;
6305 6361 }
6306 6362 spin_lock(&lo->plh_inode->i_lock);
6307   - if (task->tk_status == 0) {
6308   - if (lrp->res.lrs_present) {
6309   - pnfs_set_layout_stateid(lo, &lrp->res.stateid, true);
6310   - } else
6311   - BUG_ON(!list_empty(&lo->plh_segs));
6312   - }
  6363 + if (task->tk_status == 0 && lrp->res.lrs_present)
  6364 + pnfs_set_layout_stateid(lo, &lrp->res.stateid, true);
6313 6365 lo->plh_block_lgets--;
6314 6366 spin_unlock(&lo->plh_inode->i_lock);
6315 6367 dprintk("<-- %s\n", __func__);
... ... @@ -23,14 +23,6 @@
23 23 static struct dentry *nfs4_remote_referral_mount(struct file_system_type *fs_type,
24 24 int flags, const char *dev_name, void *raw_data);
25 25  
26   -static struct file_system_type nfs4_fs_type = {
27   - .owner = THIS_MODULE,
28   - .name = "nfs4",
29   - .mount = nfs_fs_mount,
30   - .kill_sb = nfs_kill_super,
31   - .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
32   -};
33   -
34 26 static struct file_system_type nfs4_remote_fs_type = {
35 27 .owner = THIS_MODULE,
36 28 .name = "nfs4",
37 29  
... ... @@ -344,14 +336,8 @@
344 336 if (err)
345 337 goto out1;
346 338  
347   - err = register_filesystem(&nfs4_fs_type);
348   - if (err < 0)
349   - goto out2;
350   -
351 339 register_nfs_version(&nfs_v4);
352 340 return 0;
353   -out2:
354   - nfs4_unregister_sysctl();
355 341 out1:
356 342 nfs_idmap_quit();
357 343 out:
... ... @@ -361,7 +347,6 @@
361 347 static void __exit exit_nfs_v4(void)
362 348 {
363 349 unregister_nfs_version(&nfs_v4);
364   - unregister_filesystem(&nfs4_fs_type);
365 350 nfs4_unregister_sysctl();
366 351 nfs_idmap_quit();
367 352 }
... ... @@ -5045,23 +5045,20 @@
5045 5045 struct nfs_getaclres *res)
5046 5046 {
5047 5047 unsigned int savep;
5048   - __be32 *bm_p;
5049 5048 uint32_t attrlen,
5050 5049 bitmap[3] = {0};
5051 5050 int status;
5052   - size_t page_len = xdr->buf->page_len;
  5051 + unsigned int pg_offset;
5053 5052  
5054 5053 res->acl_len = 0;
5055 5054 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
5056 5055 goto out;
5057 5056  
5058   - bm_p = xdr->p;
5059   - res->acl_data_offset = be32_to_cpup(bm_p) + 2;
5060   - res->acl_data_offset <<= 2;
5061   - /* Check if the acl data starts beyond the allocated buffer */
5062   - if (res->acl_data_offset > page_len)
5063   - return -ERANGE;
  5057 + xdr_enter_page(xdr, xdr->buf->page_len);
5064 5058  
  5059 + /* Calculate the offset of the page data */
  5060 + pg_offset = xdr->buf->head[0].iov_len;
  5061 +
5065 5062 if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
5066 5063 goto out;
5067 5064 if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
5068 5065  
5069 5066  
5070 5067  
5071 5068  
... ... @@ -5074,23 +5071,20 @@
5074 5071 /* The bitmap (xdr len + bitmaps) and the attr xdr len words
5075 5072 * are stored with the acl data to handle the problem of
5076 5073 * variable length bitmaps.*/
5077   - xdr->p = bm_p;
  5074 + res->acl_data_offset = xdr_stream_pos(xdr) - pg_offset;
5078 5075  
5079 5076 /* We ignore &savep and don't do consistency checks on
5080 5077 * the attr length. Let userspace figure it out.... */
5081   - attrlen += res->acl_data_offset;
5082   - if (attrlen > page_len) {
  5078 + res->acl_len = attrlen;
  5079 + if (attrlen > (xdr->nwords << 2)) {
5083 5080 if (res->acl_flags & NFS4_ACL_LEN_REQUEST) {
5084 5081 /* getxattr interface called with a NULL buf */
5085   - res->acl_len = attrlen;
5086 5082 goto out;
5087 5083 }
5088   - dprintk("NFS: acl reply: attrlen %u > page_len %zu\n",
5089   - attrlen, page_len);
  5084 + dprintk("NFS: acl reply: attrlen %u > page_len %u\n",
  5085 + attrlen, xdr->nwords << 2);
5090 5086 return -EINVAL;
5091 5087 }
5092   - xdr_read_pages(xdr, attrlen);
5093   - res->acl_len = attrlen;
5094 5088 } else
5095 5089 status = -EOPNOTSUPP;
5096 5090  
fs/nfs/objlayout/objio_osd.c
... ... @@ -570,17 +570,66 @@
570 570 return false;
571 571  
572 572 return pgio->pg_count + req->wb_bytes <=
573   - OBJIO_LSEG(pgio->pg_lseg)->layout.max_io_length;
  573 + (unsigned long)pgio->pg_layout_private;
574 574 }
575 575  
  576 +void objio_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
  577 +{
  578 + pnfs_generic_pg_init_read(pgio, req);
  579 + if (unlikely(pgio->pg_lseg == NULL))
  580 + return; /* Not pNFS */
  581 +
  582 + pgio->pg_layout_private = (void *)
  583 + OBJIO_LSEG(pgio->pg_lseg)->layout.max_io_length;
  584 +}
  585 +
  586 +static bool aligned_on_raid_stripe(u64 offset, struct ore_layout *layout,
  587 + unsigned long *stripe_end)
  588 +{
  589 + u32 stripe_off;
  590 + unsigned stripe_size;
  591 +
  592 + if (layout->raid_algorithm == PNFS_OSD_RAID_0)
  593 + return true;
  594 +
  595 + stripe_size = layout->stripe_unit *
  596 + (layout->group_width - layout->parity);
  597 +
  598 + div_u64_rem(offset, stripe_size, &stripe_off);
  599 + if (!stripe_off)
  600 + return true;
  601 +
  602 + *stripe_end = stripe_size - stripe_off;
  603 + return false;
  604 +}
  605 +
  606 +void objio_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
  607 +{
  608 + unsigned long stripe_end = 0;
  609 +
  610 + pnfs_generic_pg_init_write(pgio, req);
  611 + if (unlikely(pgio->pg_lseg == NULL))
  612 + return; /* Not pNFS */
  613 +
  614 + if (req->wb_offset ||
  615 + !aligned_on_raid_stripe(req->wb_index * PAGE_SIZE,
  616 + &OBJIO_LSEG(pgio->pg_lseg)->layout,
  617 + &stripe_end)) {
  618 + pgio->pg_layout_private = (void *)stripe_end;
  619 + } else {
  620 + pgio->pg_layout_private = (void *)
  621 + OBJIO_LSEG(pgio->pg_lseg)->layout.max_io_length;
  622 + }
  623 +}
  624 +
576 625 static const struct nfs_pageio_ops objio_pg_read_ops = {
577   - .pg_init = pnfs_generic_pg_init_read,
  626 + .pg_init = objio_init_read,
578 627 .pg_test = objio_pg_test,
579 628 .pg_doio = pnfs_generic_pg_readpages,
580 629 };
581 630  
582 631 static const struct nfs_pageio_ops objio_pg_write_ops = {
583   - .pg_init = pnfs_generic_pg_init_write,
  632 + .pg_init = objio_init_write,
584 633 .pg_test = objio_pg_test,
585 634 .pg_doio = pnfs_generic_pg_writepages,
586 635 };
... ... @@ -49,6 +49,7 @@
49 49 hdr->io_start = req_offset(hdr->req);
50 50 hdr->good_bytes = desc->pg_count;
51 51 hdr->dreq = desc->pg_dreq;
  52 + hdr->layout_private = desc->pg_layout_private;
52 53 hdr->release = release;
53 54 hdr->completion_ops = desc->pg_completion_ops;
54 55 if (hdr->completion_ops->init_hdr)
... ... @@ -268,6 +269,7 @@
268 269 desc->pg_error = 0;
269 270 desc->pg_lseg = NULL;
270 271 desc->pg_dreq = NULL;
  272 + desc->pg_layout_private = NULL;
271 273 }
272 274 EXPORT_SYMBOL_GPL(nfs_pageio_init);
273 275  
... ... @@ -583,9 +583,6 @@
583 583 struct nfs_server *server = NFS_SERVER(ino);
584 584 struct nfs4_layoutget *lgp;
585 585 struct pnfs_layout_segment *lseg = NULL;
586   - struct page **pages = NULL;
587   - int i;
588   - u32 max_resp_sz, max_pages;
589 586  
590 587 dprintk("--> %s\n", __func__);
591 588  
... ... @@ -594,20 +591,6 @@
594 591 if (lgp == NULL)
595 592 return NULL;
596 593  
597   - /* allocate pages for xdr post processing */
598   - max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
599   - max_pages = nfs_page_array_len(0, max_resp_sz);
600   -
601   - pages = kcalloc(max_pages, sizeof(struct page *), gfp_flags);
602   - if (!pages)
603   - goto out_err_free;
604   -
605   - for (i = 0; i < max_pages; i++) {
606   - pages[i] = alloc_page(gfp_flags);
607   - if (!pages[i])
608   - goto out_err_free;
609   - }
610   -
611 594 lgp->args.minlength = PAGE_CACHE_SIZE;
612 595 if (lgp->args.minlength > range->length)
613 596 lgp->args.minlength = range->length;
614 597  
615 598  
616 599  
... ... @@ -616,39 +599,19 @@
616 599 lgp->args.type = server->pnfs_curr_ld->id;
617 600 lgp->args.inode = ino;
618 601 lgp->args.ctx = get_nfs_open_context(ctx);
619   - lgp->args.layout.pages = pages;
620   - lgp->args.layout.pglen = max_pages * PAGE_SIZE;
621 602 lgp->lsegpp = &lseg;
622 603 lgp->gfp_flags = gfp_flags;
623 604  
624 605 /* Synchronously retrieve layout information from server and
625 606 * store in lseg.
626 607 */
627   - nfs4_proc_layoutget(lgp);
  608 + nfs4_proc_layoutget(lgp, gfp_flags);
628 609 if (!lseg) {
629 610 /* remember that LAYOUTGET failed and suspend trying */
630 611 set_bit(lo_fail_bit(range->iomode), &lo->plh_flags);
631 612 }
632 613  
633   - /* free xdr pages */
634   - for (i = 0; i < max_pages; i++)
635   - __free_page(pages[i]);
636   - kfree(pages);
637   -
638 614 return lseg;
639   -
640   -out_err_free:
641   - /* free any allocated xdr pages, lgp as it's not used */
642   - if (pages) {
643   - for (i = 0; i < max_pages; i++) {
644   - if (!pages[i])
645   - break;
646   - __free_page(pages[i]);
647   - }
648   - kfree(pages);
649   - }
650   - kfree(lgp);
651   - return NULL;
652 615 }
653 616  
654 617 /*
... ... @@ -172,7 +172,7 @@
172 172 struct pnfs_devicelist *devlist);
173 173 extern int nfs4_proc_getdeviceinfo(struct nfs_server *server,
174 174 struct pnfs_device *dev);
175   -extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp);
  175 +extern void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags);
176 176 extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp);
177 177  
178 178 /* pnfs.c */
... ... @@ -319,6 +319,34 @@
319 319 static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *);
320 320 static int nfs4_validate_mount_data(void *options,
321 321 struct nfs_parsed_mount_data *args, const char *dev_name);
  322 +
  323 +struct file_system_type nfs4_fs_type = {
  324 + .owner = THIS_MODULE,
  325 + .name = "nfs4",
  326 + .mount = nfs_fs_mount,
  327 + .kill_sb = nfs_kill_super,
  328 + .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
  329 +};
  330 +EXPORT_SYMBOL_GPL(nfs4_fs_type);
  331 +
  332 +static int __init register_nfs4_fs(void)
  333 +{
  334 + return register_filesystem(&nfs4_fs_type);
  335 +}
  336 +
  337 +static void unregister_nfs4_fs(void)
  338 +{
  339 + unregister_filesystem(&nfs4_fs_type);
  340 +}
  341 +#else
  342 +static int __init register_nfs4_fs(void)
  343 +{
  344 + return 0;
  345 +}
  346 +
  347 +static void unregister_nfs4_fs(void)
  348 +{
  349 +}
322 350 #endif
323 351  
324 352 static struct shrinker acl_shrinker = {
325 353  
326 354  
... ... @@ -337,12 +365,18 @@
337 365 if (ret < 0)
338 366 goto error_0;
339 367  
340   - ret = nfs_register_sysctl();
  368 + ret = register_nfs4_fs();
341 369 if (ret < 0)
342 370 goto error_1;
  371 +
  372 + ret = nfs_register_sysctl();
  373 + if (ret < 0)
  374 + goto error_2;
343 375 register_shrinker(&acl_shrinker);
344 376 return 0;
345 377  
  378 +error_2:
  379 + unregister_nfs4_fs();
346 380 error_1:
347 381 unregister_filesystem(&nfs_fs_type);
348 382 error_0:
... ... @@ -356,6 +390,7 @@
356 390 {
357 391 unregister_shrinker(&acl_shrinker);
358 392 nfs_unregister_sysctl();
  393 + unregister_nfs4_fs();
359 394 unregister_filesystem(&nfs_fs_type);
360 395 }
361 396  
... ... @@ -2645,5 +2680,7 @@
2645 2680 module_param(send_implementation_id, ushort, 0644);
2646 2681 MODULE_PARM_DESC(send_implementation_id,
2647 2682 "Send implementation ID with NFSv4.1 exchange_id");
  2683 +MODULE_ALIAS("nfs4");
  2684 +
2648 2685 #endif /* CONFIG_NFS_V4 */
... ... @@ -1814,19 +1814,19 @@
1814 1814 nfs_wdata_mempool = mempool_create_slab_pool(MIN_POOL_WRITE,
1815 1815 nfs_wdata_cachep);
1816 1816 if (nfs_wdata_mempool == NULL)
1817   - return -ENOMEM;
  1817 + goto out_destroy_write_cache;
1818 1818  
1819 1819 nfs_cdata_cachep = kmem_cache_create("nfs_commit_data",
1820 1820 sizeof(struct nfs_commit_data),
1821 1821 0, SLAB_HWCACHE_ALIGN,
1822 1822 NULL);
1823 1823 if (nfs_cdata_cachep == NULL)
1824   - return -ENOMEM;
  1824 + goto out_destroy_write_mempool;
1825 1825  
1826 1826 nfs_commit_mempool = mempool_create_slab_pool(MIN_POOL_COMMIT,
1827 1827 nfs_wdata_cachep);
1828 1828 if (nfs_commit_mempool == NULL)
1829   - return -ENOMEM;
  1829 + goto out_destroy_commit_cache;
1830 1830  
1831 1831 /*
1832 1832 * NFS congestion size, scale with available memory.
1833 1833  
... ... @@ -1849,11 +1849,20 @@
1849 1849 nfs_congestion_kb = 256*1024;
1850 1850  
1851 1851 return 0;
  1852 +
  1853 +out_destroy_commit_cache:
  1854 + kmem_cache_destroy(nfs_cdata_cachep);
  1855 +out_destroy_write_mempool:
  1856 + mempool_destroy(nfs_wdata_mempool);
  1857 +out_destroy_write_cache:
  1858 + kmem_cache_destroy(nfs_wdata_cachep);
  1859 + return -ENOMEM;
1852 1860 }
1853 1861  
1854 1862 void nfs_destroy_writepagecache(void)
1855 1863 {
1856 1864 mempool_destroy(nfs_commit_mempool);
  1865 + kmem_cache_destroy(nfs_cdata_cachep);
1857 1866 mempool_destroy(nfs_wdata_mempool);
1858 1867 kmem_cache_destroy(nfs_wdata_cachep);
1859 1868 }
include/linux/nfs_page.h
... ... @@ -69,6 +69,7 @@
69 69 const struct nfs_pgio_completion_ops *pg_completion_ops;
70 70 struct pnfs_layout_segment *pg_lseg;
71 71 struct nfs_direct_req *pg_dreq;
  72 + void *pg_layout_private;
72 73 };
73 74  
74 75 #define NFS_WBACK_BUSY(req) (test_bit(PG_BUSY,&(req)->wb_flags))
include/linux/nfs_xdr.h
... ... @@ -1248,6 +1248,7 @@
1248 1248 void (*release) (struct nfs_pgio_header *hdr);
1249 1249 const struct nfs_pgio_completion_ops *completion_ops;
1250 1250 struct nfs_direct_req *dreq;
  1251 + void *layout_private;
1251 1252 spinlock_t lock;
1252 1253 /* fields protected by lock */
1253 1254 int pnfs_error;