aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2008-10-05 14:48:22 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-10-07 17:59:43 -0400
commit691beb13cdc88358334ef0ba867c080a247a760f (patch)
tree35e0bb75f726f32962418902f33c5f779711dddc /fs/nfs
parent2f28ea614ff497202d5a52af82da523ae4a20718 (diff)
NFS: Allow concurrent inode revalidation
Currently, if two processes are both trying to revalidate metadata for the same inode, they will find themselves being serialised. There is no good justification for this now that we have improved our ability to detect stale attribute data, so we should remove that serialisation. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/inode.c43
1 files changed, 2 insertions, 41 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index f3b8ed904df7..e25009f35cc2 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -472,37 +472,6 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr)
472 } 472 }
473} 473}
474 474
475static int nfs_wait_schedule(void *word)
476{
477 if (signal_pending(current))
478 return -ERESTARTSYS;
479 schedule();
480 return 0;
481}
482
483/*
484 * Wait for the inode to get unlocked.
485 */
486static int nfs_wait_on_inode(struct inode *inode)
487{
488 struct nfs_inode *nfsi = NFS_I(inode);
489 int error;
490
491 error = wait_on_bit_lock(&nfsi->flags, NFS_INO_REVALIDATING,
492 nfs_wait_schedule, TASK_KILLABLE);
493
494 return error;
495}
496
497static void nfs_wake_up_inode(struct inode *inode)
498{
499 struct nfs_inode *nfsi = NFS_I(inode);
500
501 clear_bit(NFS_INO_REVALIDATING, &nfsi->flags);
502 smp_mb__after_clear_bit();
503 wake_up_bit(&nfsi->flags, NFS_INO_REVALIDATING);
504}
505
506int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) 475int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
507{ 476{
508 struct inode *inode = dentry->d_inode; 477 struct inode *inode = dentry->d_inode;
@@ -697,20 +666,15 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
697 dfprintk(PAGECACHE, "NFS: revalidating (%s/%Ld)\n", 666 dfprintk(PAGECACHE, "NFS: revalidating (%s/%Ld)\n",
698 inode->i_sb->s_id, (long long)NFS_FILEID(inode)); 667 inode->i_sb->s_id, (long long)NFS_FILEID(inode));
699 668
700 nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE);
701 if (is_bad_inode(inode)) 669 if (is_bad_inode(inode))
702 goto out_nowait; 670 goto out;
703 if (NFS_STALE(inode)) 671 if (NFS_STALE(inode))
704 goto out_nowait;
705
706 status = nfs_wait_on_inode(inode);
707 if (status < 0)
708 goto out; 672 goto out;
709 673
710 status = -ESTALE;
711 if (NFS_STALE(inode)) 674 if (NFS_STALE(inode))
712 goto out; 675 goto out;
713 676
677 nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE);
714 status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), &fattr); 678 status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), &fattr);
715 if (status != 0) { 679 if (status != 0) {
716 dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n", 680 dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n",
@@ -740,9 +704,6 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
740 (long long)NFS_FILEID(inode)); 704 (long long)NFS_FILEID(inode));
741 705
742 out: 706 out:
743 nfs_wake_up_inode(inode);
744
745 out_nowait:
746 return status; 707 return status;
747} 708}
748 709