Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+241 -119
+9 -9
fs/nfs/Makefile
··· 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
+1 -1
fs/nfs/client.c
··· 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 }
+44 -18
fs/nfs/idmap.c
··· 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 ··· 330 324 ret = nfs_idmap_request_key(&key_type_id_resolver_legacy, 331 325 name, namelen, type, data, 332 326 data_size, idmap); 327 + idmap->idmap_key_cons = NULL; 333 328 mutex_unlock(&idmap->idmap_mutex); 334 329 } 335 330 return ret; ··· 387 380 static int nfs_idmap_legacy_upcall(struct key_construction *, const char *, void *); 388 381 static ssize_t idmap_pipe_downcall(struct file *, const char __user *, 389 382 size_t); 383 + static void idmap_release_pipe(struct inode *); 390 384 static void idmap_pipe_destroy_msg(struct rpc_pipe_msg *); 391 385 392 386 static const struct rpc_pipe_ops idmap_upcall_ops = { 393 387 .upcall = rpc_pipe_generic_upcall, 394 388 .downcall = idmap_pipe_downcall, 389 + .release_pipe = idmap_release_pipe, 395 390 .destroy_msg = idmap_pipe_destroy_msg, 396 391 }; 397 392 ··· 625 616 nfs_idmap_quit_keyring(); 626 617 } 627 618 628 - static int nfs_idmap_prepare_message(char *desc, struct idmap_msg *im, 619 + static int nfs_idmap_prepare_message(char *desc, struct idmap *idmap, 620 + struct idmap_msg *im, 629 621 struct rpc_pipe_msg *msg) 630 622 { 631 623 substring_t substr; ··· 669 659 const char *op, 670 660 void *aux) 671 661 { 662 + struct idmap_legacy_upcalldata *data; 672 663 struct rpc_pipe_msg *msg; 673 664 struct idmap_msg *im; 674 665 struct idmap *idmap = (struct idmap *)aux; ··· 677 666 int ret = -ENOMEM; 678 667 679 668 /* msg and im are freed in idmap_pipe_destroy_msg */ 680 - msg = kmalloc(sizeof(*msg), GFP_KERNEL); 681 - if (!msg) 682 - goto out0; 683 - 684 - im = kmalloc(sizeof(*im), GFP_KERNEL); 685 - if (!im) 669 + data = kmalloc(sizeof(*data), GFP_KERNEL); 670 + if (!data) 686 671 goto out1; 687 672 688 - ret = nfs_idmap_prepare_message(key->description, im, msg); 673 + msg = &data->pipe_msg; 674 + im = &data->idmap_msg; 675 + data->idmap = idmap; 676 + 677 + ret = nfs_idmap_prepare_message(key->description, idmap, im, msg); 689 678 if (ret < 0) 690 679 goto out2; 691 680 ··· 694 683 695 684 ret = rpc_queue_upcall(idmap->idmap_pipe, msg); 696 685 if (ret < 0) 697 - goto out2; 686 + goto out3; 698 687 699 688 return ret; 700 689 690 + out3: 691 + idmap->idmap_key_cons = NULL; 701 692 out2: 702 - kfree(im); 693 + kfree(data); 703 694 out1: 704 - kfree(msg); 705 - out0: 706 695 complete_request_key(cons, ret); 707 696 return ret; 708 697 } ··· 760 749 } 761 750 762 751 if (!(im.im_status & IDMAP_STATUS_SUCCESS)) { 763 - ret = mlen; 764 - complete_request_key(cons, -ENOKEY); 765 - goto out_incomplete; 752 + ret = -ENOKEY; 753 + goto out; 766 754 } 767 755 768 756 namelen_in = strnlen(im.im_name, IDMAP_NAMESZ); ··· 778 768 779 769 out: 780 770 complete_request_key(cons, ret); 781 - out_incomplete: 782 771 return ret; 783 772 } 784 773 785 774 static void 786 775 idmap_pipe_destroy_msg(struct rpc_pipe_msg *msg) 787 776 { 777 + struct idmap_legacy_upcalldata *data = container_of(msg, 778 + struct idmap_legacy_upcalldata, 779 + pipe_msg); 780 + struct idmap *idmap = data->idmap; 781 + struct key_construction *cons; 782 + if (msg->errno) { 783 + cons = ACCESS_ONCE(idmap->idmap_key_cons); 784 + idmap->idmap_key_cons = NULL; 785 + complete_request_key(cons, msg->errno); 786 + } 788 787 /* Free memory allocated in nfs_idmap_legacy_upcall() */ 789 - kfree(msg->data); 790 - kfree(msg); 788 + kfree(data); 789 + } 790 + 791 + static void 792 + idmap_release_pipe(struct inode *inode) 793 + { 794 + struct rpc_inode *rpci = RPC_I(inode); 795 + struct idmap *idmap = (struct idmap *)rpci->private; 796 + idmap->idmap_key_cons = NULL; 791 797 } 792 798 793 799 int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *uid)
+1 -1
fs/nfs/nfs3proc.c
··· 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);
+3
fs/nfs/nfs4_fs.h
··· 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 *);
+1 -1
fs/nfs/nfs4client.c
··· 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
+64 -12
fs/nfs/nfs4proc.c
··· 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; ··· 3820 3819 if (ret) 3821 3820 goto out_free; 3822 3821 3823 - acl_len = res.acl_len - res.acl_data_offset; 3822 + acl_len = res.acl_len; 3824 3823 if (acl_len > args.acl_len) 3825 3824 nfs4_write_cached_acl(inode, NULL, 0, acl_len); 3826 3825 else ··· 6224 6223 dprintk("<-- %s\n", __func__); 6225 6224 } 6226 6225 6226 + static size_t max_response_pages(struct nfs_server *server) 6227 + { 6228 + u32 max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz; 6229 + return nfs_page_array_len(0, max_resp_sz); 6230 + } 6231 + 6232 + static void nfs4_free_pages(struct page **pages, size_t size) 6233 + { 6234 + int i; 6235 + 6236 + if (!pages) 6237 + return; 6238 + 6239 + for (i = 0; i < size; i++) { 6240 + if (!pages[i]) 6241 + break; 6242 + __free_page(pages[i]); 6243 + } 6244 + kfree(pages); 6245 + } 6246 + 6247 + static struct page **nfs4_alloc_pages(size_t size, gfp_t gfp_flags) 6248 + { 6249 + struct page **pages; 6250 + int i; 6251 + 6252 + pages = kcalloc(size, sizeof(struct page *), gfp_flags); 6253 + if (!pages) { 6254 + dprintk("%s: can't alloc array of %zu pages\n", __func__, size); 6255 + return NULL; 6256 + } 6257 + 6258 + for (i = 0; i < size; i++) { 6259 + pages[i] = alloc_page(gfp_flags); 6260 + if (!pages[i]) { 6261 + dprintk("%s: failed to allocate page\n", __func__); 6262 + nfs4_free_pages(pages, size); 6263 + return NULL; 6264 + } 6265 + } 6266 + 6267 + return pages; 6268 + } 6269 + 6227 6270 static void nfs4_layoutget_release(void *calldata) 6228 6271 { 6229 6272 struct nfs4_layoutget *lgp = calldata; 6273 + struct nfs_server *server = NFS_SERVER(lgp->args.inode); 6274 + size_t max_pages = max_response_pages(server); 6230 6275 6231 6276 dprintk("--> %s\n", __func__); 6277 + nfs4_free_pages(lgp->args.layout.pages, max_pages); 6232 6278 put_nfs_open_context(lgp->args.ctx); 6233 6279 kfree(calldata); 6234 6280 dprintk("<-- %s\n", __func__); ··· 6287 6239 .rpc_release = nfs4_layoutget_release, 6288 6240 }; 6289 6241 6290 - int nfs4_proc_layoutget(struct nfs4_layoutget *lgp) 6242 + void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags) 6291 6243 { 6292 6244 struct nfs_server *server = NFS_SERVER(lgp->args.inode); 6245 + size_t max_pages = max_response_pages(server); 6293 6246 struct rpc_task *task; 6294 6247 struct rpc_message msg = { 6295 6248 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTGET], ··· 6308 6259 6309 6260 dprintk("--> %s\n", __func__); 6310 6261 6262 + lgp->args.layout.pages = nfs4_alloc_pages(max_pages, gfp_flags); 6263 + if (!lgp->args.layout.pages) { 6264 + nfs4_layoutget_release(lgp); 6265 + return; 6266 + } 6267 + lgp->args.layout.pglen = max_pages * PAGE_SIZE; 6268 + 6311 6269 lgp->res.layoutp = &lgp->args.layout; 6312 6270 lgp->res.seq_res.sr_slot = NULL; 6313 6271 nfs41_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0); 6314 6272 task = rpc_run_task(&task_setup_data); 6315 6273 if (IS_ERR(task)) 6316 - return PTR_ERR(task); 6274 + return; 6317 6275 status = nfs4_wait_for_completion_rpc_task(task); 6318 6276 if (status == 0) 6319 6277 status = task->tk_status; ··· 6328 6272 status = pnfs_layout_process(lgp); 6329 6273 rpc_put_task(task); 6330 6274 dprintk("<-- %s status=%d\n", __func__, status); 6331 - return status; 6275 + return; 6332 6276 } 6333 6277 6334 6278 static void ··· 6360 6304 return; 6361 6305 } 6362 6306 spin_lock(&lo->plh_inode->i_lock); 6363 - if (task->tk_status == 0) { 6364 - if (lrp->res.lrs_present) { 6365 - pnfs_set_layout_stateid(lo, &lrp->res.stateid, true); 6366 - } else 6367 - BUG_ON(!list_empty(&lo->plh_segs)); 6368 - } 6307 + if (task->tk_status == 0 && lrp->res.lrs_present) 6308 + pnfs_set_layout_stateid(lo, &lrp->res.stateid, true); 6369 6309 lo->plh_block_lgets--; 6370 6310 spin_unlock(&lo->plh_inode->i_lock); 6371 6311 dprintk("<-- %s\n", __func__);
-15
fs/nfs/nfs4super.c
··· 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", ··· 336 344 if (err) 337 345 goto out1; 338 346 339 - err = register_filesystem(&nfs4_fs_type); 340 - if (err < 0) 341 - goto out2; 342 - 343 347 register_nfs_version(&nfs_v4); 344 348 return 0; 345 - out2: 346 - nfs4_unregister_sysctl(); 347 349 out1: 348 350 nfs_idmap_quit(); 349 351 out: ··· 347 361 static void __exit exit_nfs_v4(void) 348 362 { 349 363 unregister_nfs_version(&nfs_v4); 350 - unregister_filesystem(&nfs4_fs_type); 351 364 nfs4_unregister_sysctl(); 352 365 nfs_idmap_quit(); 353 366 }
+10 -16
fs/nfs/nfs4xdr.c
··· 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); 5058 + 5059 + /* Calculate the offset of the page data */ 5060 + pg_offset = xdr->buf->head[0].iov_len; 5064 5061 5065 5062 if ((status = decode_attr_bitmap(xdr, bitmap)) != 0) 5066 5063 goto out; ··· 5071 5074 /* The bitmap (xdr len + bitmaps) and the attr xdr len words 5072 5075 * are stored with the acl data to handle the problem of 5073 5076 * variable length bitmaps.*/ 5074 - xdr->p = bm_p; 5077 + res->acl_data_offset = xdr_stream_pos(xdr) - pg_offset; 5075 5078 5076 5079 /* We ignore &savep and don't do consistency checks on 5077 5080 * the attr length. Let userspace figure it out.... */ 5078 - attrlen += res->acl_data_offset; 5079 - if (attrlen > page_len) { 5081 + res->acl_len = attrlen; 5082 + if (attrlen > (xdr->nwords << 2)) { 5080 5083 if (res->acl_flags & NFS4_ACL_LEN_REQUEST) { 5081 5084 /* getxattr interface called with a NULL buf */ 5082 - res->acl_len = attrlen; 5083 5085 goto out; 5084 5086 } 5085 - dprintk("NFS: acl reply: attrlen %u > page_len %zu\n", 5086 - attrlen, page_len); 5087 + dprintk("NFS: acl reply: attrlen %u > page_len %u\n", 5088 + attrlen, xdr->nwords << 2); 5087 5089 return -EINVAL; 5088 5090 } 5089 - xdr_read_pages(xdr, attrlen); 5090 - res->acl_len = attrlen; 5091 5091 } else 5092 5092 status = -EOPNOTSUPP; 5093 5093
+52 -3
fs/nfs/objlayout/objio_osd.c
··· 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 + } 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 + } 574 623 } 575 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 };
+2
fs/nfs/pagelist.c
··· 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) ··· 269 268 desc->pg_error = 0; 270 269 desc->pg_lseg = NULL; 271 270 desc->pg_dreq = NULL; 271 + desc->pg_layout_private = NULL; 272 272 } 273 273 EXPORT_SYMBOL_GPL(nfs_pageio_init); 274 274
+1 -38
fs/nfs/pnfs.c
··· 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 ··· 590 593 lgp = kzalloc(sizeof(*lgp), gfp_flags); 591 594 if (lgp == NULL) 592 595 return NULL; 593 - 594 - /* allocate pages for xdr post processing */ 595 - max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz; 596 - max_pages = nfs_page_array_len(0, max_resp_sz); 597 - 598 - pages = kcalloc(max_pages, sizeof(struct page *), gfp_flags); 599 - if (!pages) 600 - goto out_err_free; 601 - 602 - for (i = 0; i < max_pages; i++) { 603 - pages[i] = alloc_page(gfp_flags); 604 - if (!pages[i]) 605 - goto out_err_free; 606 - } 607 596 608 597 lgp->args.minlength = PAGE_CACHE_SIZE; 609 598 if (lgp->args.minlength > range->length) ··· 599 616 lgp->args.type = server->pnfs_curr_ld->id; 600 617 lgp->args.inode = ino; 601 618 lgp->args.ctx = get_nfs_open_context(ctx); 602 - lgp->args.layout.pages = pages; 603 - lgp->args.layout.pglen = max_pages * PAGE_SIZE; 604 619 lgp->lsegpp = &lseg; 605 620 lgp->gfp_flags = gfp_flags; 606 621 607 622 /* Synchronously retrieve layout information from server and 608 623 * store in lseg. 609 624 */ 610 - nfs4_proc_layoutget(lgp); 625 + nfs4_proc_layoutget(lgp, gfp_flags); 611 626 if (!lseg) { 612 627 /* remember that LAYOUTGET failed and suspend trying */ 613 628 set_bit(lo_fail_bit(range->iomode), &lo->plh_flags); 614 629 } 615 630 616 - /* free xdr pages */ 617 - for (i = 0; i < max_pages; i++) 618 - __free_page(pages[i]); 619 - kfree(pages); 620 - 621 631 return lseg; 622 - 623 - out_err_free: 624 - /* free any allocated xdr pages, lgp as it's not used */ 625 - if (pages) { 626 - for (i = 0; i < max_pages; i++) { 627 - if (!pages[i]) 628 - break; 629 - __free_page(pages[i]); 630 - } 631 - kfree(pages); 632 - } 633 - kfree(lgp); 634 - return NULL; 635 632 } 636 633 637 634 /*
+1 -1
fs/nfs/pnfs.h
··· 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 */
+38 -1
fs/nfs/super.c
··· 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 = { ··· 365 337 if (ret < 0) 366 338 goto error_0; 367 339 368 - ret = nfs_register_sysctl(); 340 + ret = register_nfs4_fs(); 369 341 if (ret < 0) 370 342 goto error_1; 343 + 344 + ret = nfs_register_sysctl(); 345 + if (ret < 0) 346 + goto error_2; 371 347 register_shrinker(&acl_shrinker); 372 348 return 0; 373 349 350 + error_2: 351 + unregister_nfs4_fs(); 374 352 error_1: 375 353 unregister_filesystem(&nfs_fs_type); 376 354 error_0: ··· 390 356 { 391 357 unregister_shrinker(&acl_shrinker); 392 358 nfs_unregister_sysctl(); 359 + unregister_nfs4_fs(); 393 360 unregister_filesystem(&nfs_fs_type); 394 361 } 395 362 ··· 2680 2645 module_param(send_implementation_id, ushort, 0644); 2681 2646 MODULE_PARM_DESC(send_implementation_id, 2682 2647 "Send implementation ID with NFSv4.1 exchange_id"); 2648 + MODULE_ALIAS("nfs4"); 2649 + 2683 2650 #endif /* CONFIG_NFS_V4 */
+12 -3
fs/nfs/write.c
··· 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. ··· 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 }
+1
include/linux/nfs_page.h
··· 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))
+1
include/linux/nfs_xdr.h
··· 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;