diff options
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r-- | fs/nfs/inode.c | 41 |
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 | */ | ||
552 | void 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 | |||
544 | static struct nfs_open_context *alloc_nfs_open_context(struct vfsmount *mnt, struct dentry *dentry, struct rpc_cred *cred) | 570 | static 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 | ||
570 | static void __put_nfs_open_context(struct nfs_open_context *ctx, int wait) | 596 | static 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); |