aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/inode.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2009-03-19 15:35:50 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2009-03-19 15:35:50 -0400
commit7fe5c398fc2186ed586db11106a6692d871d0d58 (patch)
tree1133bd775a23fb07ca759e4d6c44132c14576b75 /fs/nfs/inode.c
parentb1e4adf4ea41bb8b5a7bfc1a7001f137e65495df (diff)
NFS: Optimise NFS close()
Close-to-open cache consistency rules really only require us to flush out writes on calls to close(), and require us to revalidate attributes on the very last close of the file. Currently we appear to be doing a lot of extra attribute revalidation and cache flushes. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r--fs/nfs/inode.c41
1 files changed, 29 insertions, 12 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index c40adc5dd609..a834d1d850b7 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -541,6 +541,32 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
541 return err; 541 return err;
542} 542}
543 543
544/**
545 * nfs_close_context - Common close_context() routine NFSv2/v3
546 * @ctx: pointer to context
547 * @is_sync: is this a synchronous close
548 *
549 * always ensure that the attributes are up to date if we're mounted
550 * with close-to-open semantics
551 */
552void nfs_close_context(struct nfs_open_context *ctx, int is_sync)
553{
554 struct inode *inode;
555 struct nfs_server *server;
556
557 if (!(ctx->mode & FMODE_WRITE))
558 return;
559 if (!is_sync)
560 return;
561 inode = ctx->path.dentry->d_inode;
562 if (!list_empty(&NFS_I(inode)->open_files))
563 return;
564 server = NFS_SERVER(inode);
565 if (server->flags & NFS_MOUNT_NOCTO)
566 return;
567 nfs_revalidate_inode(server, inode);
568}
569
544static struct nfs_open_context *alloc_nfs_open_context(struct vfsmount *mnt, struct dentry *dentry, struct rpc_cred *cred) 570static struct nfs_open_context *alloc_nfs_open_context(struct vfsmount *mnt, struct dentry *dentry, struct rpc_cred *cred)
545{ 571{
546 struct nfs_open_context *ctx; 572 struct nfs_open_context *ctx;
@@ -567,24 +593,15 @@ struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx)
567 return ctx; 593 return ctx;
568} 594}
569 595
570static void __put_nfs_open_context(struct nfs_open_context *ctx, int wait) 596static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync)
571{ 597{
572 struct inode *inode; 598 struct inode *inode = ctx->path.dentry->d_inode;
573 599
574 if (ctx == NULL)
575 return;
576
577 inode = ctx->path.dentry->d_inode;
578 if (!atomic_dec_and_lock(&ctx->count, &inode->i_lock)) 600 if (!atomic_dec_and_lock(&ctx->count, &inode->i_lock))
579 return; 601 return;
580 list_del(&ctx->list); 602 list_del(&ctx->list);
581 spin_unlock(&inode->i_lock); 603 spin_unlock(&inode->i_lock);
582 if (ctx->state != NULL) { 604 NFS_PROTO(inode)->close_context(ctx, is_sync);
583 if (wait)
584 nfs4_close_sync(&ctx->path, ctx->state, ctx->mode);
585 else
586 nfs4_close_state(&ctx->path, ctx->state, ctx->mode);
587 }
588 if (ctx->cred != NULL) 605 if (ctx->cred != NULL)
589 put_rpccred(ctx->cred); 606 put_rpccred(ctx->cred);
590 path_put(&ctx->path); 607 path_put(&ctx->path);