diff options
author | Nick Piggin <npiggin@suse.de> | 2008-02-05 02:48:37 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2008-02-13 23:24:09 -0500 |
commit | 2785259631697ebb0749a3782cca206e2e542939 (patch) | |
tree | 607c61275106a281db0522e0f9b7bed12655c17b /fs/nfs/write.c | |
parent | 8d042218b075de3cdbe066198515b3521553746e (diff) |
nfs: use GFP_NOFS preloads for radix-tree insertion
NFS should use GFP_NOFS mode radix tree preloads rather than GFP_ATOMIC
allocations at radix-tree insertion-time. This is important to reduce the
atomic memory requirement.
Signed-off-by: Nick Piggin <npiggin@suse.de>
Cc: Trond Myklebust <trond.myklebust@fys.uio.no>
Cc: "J. Bruce Fields" <bfields@fieldses.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r-- | fs/nfs/write.c | 34 |
1 files changed, 19 insertions, 15 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index f55c437124a2..7be42e6eb63a 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -360,15 +360,13 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc) | |||
360 | /* | 360 | /* |
361 | * Insert a write request into an inode | 361 | * Insert a write request into an inode |
362 | */ | 362 | */ |
363 | static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req) | 363 | static void nfs_inode_add_request(struct inode *inode, struct nfs_page *req) |
364 | { | 364 | { |
365 | struct nfs_inode *nfsi = NFS_I(inode); | 365 | struct nfs_inode *nfsi = NFS_I(inode); |
366 | int error; | 366 | int error; |
367 | 367 | ||
368 | error = radix_tree_insert(&nfsi->nfs_page_tree, req->wb_index, req); | 368 | error = radix_tree_insert(&nfsi->nfs_page_tree, req->wb_index, req); |
369 | BUG_ON(error == -EEXIST); | 369 | BUG_ON(error); |
370 | if (error) | ||
371 | return error; | ||
372 | if (!nfsi->npages) { | 370 | if (!nfsi->npages) { |
373 | igrab(inode); | 371 | igrab(inode); |
374 | if (nfs_have_delegation(inode, FMODE_WRITE)) | 372 | if (nfs_have_delegation(inode, FMODE_WRITE)) |
@@ -378,8 +376,8 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req) | |||
378 | set_page_private(req->wb_page, (unsigned long)req); | 376 | set_page_private(req->wb_page, (unsigned long)req); |
379 | nfsi->npages++; | 377 | nfsi->npages++; |
380 | kref_get(&req->wb_kref); | 378 | kref_get(&req->wb_kref); |
381 | radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED); | 379 | radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index, |
382 | return 0; | 380 | NFS_PAGE_TAG_LOCKED); |
383 | } | 381 | } |
384 | 382 | ||
385 | /* | 383 | /* |
@@ -591,6 +589,13 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, | |||
591 | /* Loop over all inode entries and see if we find | 589 | /* Loop over all inode entries and see if we find |
592 | * A request for the page we wish to update | 590 | * A request for the page we wish to update |
593 | */ | 591 | */ |
592 | if (new) { | ||
593 | if (radix_tree_preload(GFP_NOFS)) { | ||
594 | nfs_release_request(new); | ||
595 | return ERR_PTR(-ENOMEM); | ||
596 | } | ||
597 | } | ||
598 | |||
594 | spin_lock(&inode->i_lock); | 599 | spin_lock(&inode->i_lock); |
595 | req = nfs_page_find_request_locked(page); | 600 | req = nfs_page_find_request_locked(page); |
596 | if (req) { | 601 | if (req) { |
@@ -601,28 +606,27 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, | |||
601 | error = nfs_wait_on_request(req); | 606 | error = nfs_wait_on_request(req); |
602 | nfs_release_request(req); | 607 | nfs_release_request(req); |
603 | if (error < 0) { | 608 | if (error < 0) { |
604 | if (new) | 609 | if (new) { |
610 | radix_tree_preload_end(); | ||
605 | nfs_release_request(new); | 611 | nfs_release_request(new); |
612 | } | ||
606 | return ERR_PTR(error); | 613 | return ERR_PTR(error); |
607 | } | 614 | } |
608 | continue; | 615 | continue; |
609 | } | 616 | } |
610 | spin_unlock(&inode->i_lock); | 617 | spin_unlock(&inode->i_lock); |
611 | if (new) | 618 | if (new) { |
619 | radix_tree_preload_end(); | ||
612 | nfs_release_request(new); | 620 | nfs_release_request(new); |
621 | } | ||
613 | break; | 622 | break; |
614 | } | 623 | } |
615 | 624 | ||
616 | if (new) { | 625 | if (new) { |
617 | int error; | ||
618 | nfs_lock_request_dontget(new); | 626 | nfs_lock_request_dontget(new); |
619 | error = nfs_inode_add_request(inode, new); | 627 | nfs_inode_add_request(inode, new); |
620 | if (error) { | ||
621 | spin_unlock(&inode->i_lock); | ||
622 | nfs_unlock_request(new); | ||
623 | return ERR_PTR(error); | ||
624 | } | ||
625 | spin_unlock(&inode->i_lock); | 628 | spin_unlock(&inode->i_lock); |
629 | radix_tree_preload_end(); | ||
626 | req = new; | 630 | req = new; |
627 | goto zero_page; | 631 | goto zero_page; |
628 | } | 632 | } |