aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4filelayout.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2011-05-11 18:00:51 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2011-05-11 22:52:13 -0400
commita75b9df9d3bfc3cd1083974c045ae31ce5f3434f (patch)
tree039cc65774c895d704f23a2c89b7f1bcd736e0b9 /fs/nfs/nfs4filelayout.c
parent2887fe45522843149ccf72e01f43813be4fb36c5 (diff)
NFSv4.1: Ensure that layoutget uses the correct gfp modes
Currently, writebacks may end up recursing back into the filesystem due to GFP_KERNEL direct reclaims in the pnfs subsystem. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4filelayout.c')
-rw-r--r--fs/nfs/nfs4filelayout.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index 7841ea603c91..be79dc9f386d 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -418,7 +418,8 @@ static int
418filelayout_check_layout(struct pnfs_layout_hdr *lo, 418filelayout_check_layout(struct pnfs_layout_hdr *lo,
419 struct nfs4_filelayout_segment *fl, 419 struct nfs4_filelayout_segment *fl,
420 struct nfs4_layoutget_res *lgr, 420 struct nfs4_layoutget_res *lgr,
421 struct nfs4_deviceid *id) 421 struct nfs4_deviceid *id,
422 gfp_t gfp_flags)
422{ 423{
423 struct nfs4_file_layout_dsaddr *dsaddr; 424 struct nfs4_file_layout_dsaddr *dsaddr;
424 int status = -EINVAL; 425 int status = -EINVAL;
@@ -441,7 +442,7 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo,
441 /* find and reference the deviceid */ 442 /* find and reference the deviceid */
442 dsaddr = nfs4_fl_find_get_deviceid(id); 443 dsaddr = nfs4_fl_find_get_deviceid(id);
443 if (dsaddr == NULL) { 444 if (dsaddr == NULL) {
444 dsaddr = get_device_info(lo->plh_inode, id); 445 dsaddr = get_device_info(lo->plh_inode, id, gfp_flags);
445 if (dsaddr == NULL) 446 if (dsaddr == NULL)
446 goto out; 447 goto out;
447 } 448 }
@@ -502,7 +503,8 @@ static int
502filelayout_decode_layout(struct pnfs_layout_hdr *flo, 503filelayout_decode_layout(struct pnfs_layout_hdr *flo,
503 struct nfs4_filelayout_segment *fl, 504 struct nfs4_filelayout_segment *fl,
504 struct nfs4_layoutget_res *lgr, 505 struct nfs4_layoutget_res *lgr,
505 struct nfs4_deviceid *id) 506 struct nfs4_deviceid *id,
507 gfp_t gfp_flags)
506{ 508{
507 struct xdr_stream stream; 509 struct xdr_stream stream;
508 struct xdr_buf buf = { 510 struct xdr_buf buf = {
@@ -518,7 +520,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo,
518 520
519 dprintk("%s: set_layout_map Begin\n", __func__); 521 dprintk("%s: set_layout_map Begin\n", __func__);
520 522
521 scratch = alloc_page(GFP_KERNEL); 523 scratch = alloc_page(gfp_flags);
522 if (!scratch) 524 if (!scratch)
523 return -ENOMEM; 525 return -ENOMEM;
524 526
@@ -556,13 +558,13 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo,
556 goto out_err; 558 goto out_err;
557 559
558 fl->fh_array = kzalloc(fl->num_fh * sizeof(struct nfs_fh *), 560 fl->fh_array = kzalloc(fl->num_fh * sizeof(struct nfs_fh *),
559 GFP_KERNEL); 561 gfp_flags);
560 if (!fl->fh_array) 562 if (!fl->fh_array)
561 goto out_err; 563 goto out_err;
562 564
563 for (i = 0; i < fl->num_fh; i++) { 565 for (i = 0; i < fl->num_fh; i++) {
564 /* Do we want to use a mempool here? */ 566 /* Do we want to use a mempool here? */
565 fl->fh_array[i] = kmalloc(sizeof(struct nfs_fh), GFP_KERNEL); 567 fl->fh_array[i] = kmalloc(sizeof(struct nfs_fh), gfp_flags);
566 if (!fl->fh_array[i]) 568 if (!fl->fh_array[i])
567 goto out_err_free; 569 goto out_err_free;
568 570
@@ -607,19 +609,20 @@ filelayout_free_lseg(struct pnfs_layout_segment *lseg)
607 609
608static struct pnfs_layout_segment * 610static struct pnfs_layout_segment *
609filelayout_alloc_lseg(struct pnfs_layout_hdr *layoutid, 611filelayout_alloc_lseg(struct pnfs_layout_hdr *layoutid,
610 struct nfs4_layoutget_res *lgr) 612 struct nfs4_layoutget_res *lgr,
613 gfp_t gfp_flags)
611{ 614{
612 struct nfs4_filelayout_segment *fl; 615 struct nfs4_filelayout_segment *fl;
613 int rc; 616 int rc;
614 struct nfs4_deviceid id; 617 struct nfs4_deviceid id;
615 618
616 dprintk("--> %s\n", __func__); 619 dprintk("--> %s\n", __func__);
617 fl = kzalloc(sizeof(*fl), GFP_KERNEL); 620 fl = kzalloc(sizeof(*fl), gfp_flags);
618 if (!fl) 621 if (!fl)
619 return NULL; 622 return NULL;
620 623
621 rc = filelayout_decode_layout(layoutid, fl, lgr, &id); 624 rc = filelayout_decode_layout(layoutid, fl, lgr, &id, gfp_flags);
622 if (rc != 0 || filelayout_check_layout(layoutid, fl, lgr, &id)) { 625 if (rc != 0 || filelayout_check_layout(layoutid, fl, lgr, &id, gfp_flags)) {
623 _filelayout_free_lseg(fl); 626 _filelayout_free_lseg(fl);
624 return NULL; 627 return NULL;
625 } 628 }
@@ -635,7 +638,7 @@ filelayout_alloc_lseg(struct pnfs_layout_hdr *layoutid,
635 int size = (fl->stripe_type == STRIPE_SPARSE) ? 638 int size = (fl->stripe_type == STRIPE_SPARSE) ?
636 fl->dsaddr->ds_num : fl->dsaddr->stripe_count; 639 fl->dsaddr->ds_num : fl->dsaddr->stripe_count;
637 640
638 fl->commit_buckets = kcalloc(size, sizeof(struct list_head), GFP_KERNEL); 641 fl->commit_buckets = kcalloc(size, sizeof(struct list_head), gfp_flags);
639 if (!fl->commit_buckets) { 642 if (!fl->commit_buckets) {
640 filelayout_free_lseg(&fl->generic_hdr); 643 filelayout_free_lseg(&fl->generic_hdr);
641 return NULL; 644 return NULL;