aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorPeng Tao <tao.peng@primarydata.com>2014-07-03 01:05:01 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2014-07-12 18:23:04 -0400
commitfe08c54691f26cbdaf8c88c9c946a3e07d6feb00 (patch)
treef5f842e99fb59308d82644c29772eaa4ee97aeef /fs/nfs
parent15bb3afe900dfe1714ba7c53b2582517627da995 (diff)
nfs41: return layout on last close
If client has valid delegation, do not return layout on close at all. Signed-off-by: Peng Tao <tao.peng@primarydata.com> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/nfs4proc.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 1300013e9b4e..734f7da10241 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2655,6 +2655,48 @@ static const struct rpc_call_ops nfs4_close_ops = {
2655 .rpc_release = nfs4_free_closedata, 2655 .rpc_release = nfs4_free_closedata,
2656}; 2656};
2657 2657
2658static bool nfs4_state_has_opener(struct nfs4_state *state)
2659{
2660 /* first check existing openers */
2661 if (test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0 &&
2662 state->n_rdonly != 0)
2663 return true;
2664
2665 if (test_bit(NFS_O_WRONLY_STATE, &state->flags) != 0 &&
2666 state->n_wronly != 0)
2667 return true;
2668
2669 if (test_bit(NFS_O_RDWR_STATE, &state->flags) != 0 &&
2670 state->n_rdwr != 0)
2671 return true;
2672
2673 return false;
2674}
2675
2676static bool nfs4_roc(struct inode *inode)
2677{
2678 struct nfs_inode *nfsi = NFS_I(inode);
2679 struct nfs_open_context *ctx;
2680 struct nfs4_state *state;
2681
2682 spin_lock(&inode->i_lock);
2683 list_for_each_entry(ctx, &nfsi->open_files, list) {
2684 state = ctx->state;
2685 if (state == NULL)
2686 continue;
2687 if (nfs4_state_has_opener(state)) {
2688 spin_unlock(&inode->i_lock);
2689 return false;
2690 }
2691 }
2692 spin_unlock(&inode->i_lock);
2693
2694 if (nfs4_check_delegation(inode, FMODE_READ))
2695 return false;
2696
2697 return pnfs_roc(inode);
2698}
2699
2658/* 2700/*
2659 * It is possible for data to be read/written from a mem-mapped file 2701 * It is possible for data to be read/written from a mem-mapped file
2660 * after the sys_close call (which hits the vfs layer as a flush). 2702 * after the sys_close call (which hits the vfs layer as a flush).
@@ -2705,7 +2747,7 @@ int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait)
2705 calldata->res.fattr = &calldata->fattr; 2747 calldata->res.fattr = &calldata->fattr;
2706 calldata->res.seqid = calldata->arg.seqid; 2748 calldata->res.seqid = calldata->arg.seqid;
2707 calldata->res.server = server; 2749 calldata->res.server = server;
2708 calldata->roc = pnfs_roc(state->inode); 2750 calldata->roc = nfs4_roc(state->inode);
2709 nfs_sb_active(calldata->inode->i_sb); 2751 nfs_sb_active(calldata->inode->i_sb);
2710 2752
2711 msg.rpc_argp = &calldata->arg; 2753 msg.rpc_argp = &calldata->arg;