aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2005-10-27 22:12:41 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2005-10-27 22:12:41 -0400
commit516a6af641bb50c608329a5bd751acd0d65cc4ab (patch)
tree93b240cb19460073cac3363517fcc0e253fb48d9
parent3338c143b4fde2d256016b63043ec8e2c93eba19 (diff)
NFS: Add optional post-op getattr instruction to the NFSv4 file close.
"Optional" means that the close call will not fail if the getattr at the end of the compound fails. If it does succeed, try to refresh inode attributes. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/nfs4proc.c9
-rw-r--r--fs/nfs/nfs4xdr.c34
-rw-r--r--include/linux/nfs_xdr.h3
3 files changed, 39 insertions, 7 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index f363fd6c7f4d..7be3d2d15d6f 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -865,6 +865,7 @@ struct nfs4_closedata {
865 struct nfs4_state *state; 865 struct nfs4_state *state;
866 struct nfs_closeargs arg; 866 struct nfs_closeargs arg;
867 struct nfs_closeres res; 867 struct nfs_closeres res;
868 struct nfs_fattr fattr;
868}; 869};
869 870
870static void nfs4_free_closedata(struct nfs4_closedata *calldata) 871static void nfs4_free_closedata(struct nfs4_closedata *calldata)
@@ -904,6 +905,7 @@ static void nfs4_close_done(struct rpc_task *task)
904 return; 905 return;
905 } 906 }
906 } 907 }
908 nfs_refresh_inode(calldata->inode, calldata->res.fattr);
907 state->state = calldata->arg.open_flags; 909 state->state = calldata->arg.open_flags;
908 nfs4_free_closedata(calldata); 910 nfs4_free_closedata(calldata);
909} 911}
@@ -941,6 +943,7 @@ static void nfs4_close_begin(struct rpc_task *task)
941 rpc_exit(task, 0); 943 rpc_exit(task, 0);
942 return; 944 return;
943 } 945 }
946 nfs_fattr_init(calldata->res.fattr);
944 if (mode != 0) 947 if (mode != 0)
945 msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE]; 948 msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE];
946 calldata->arg.open_flags = mode; 949 calldata->arg.open_flags = mode;
@@ -960,6 +963,7 @@ static void nfs4_close_begin(struct rpc_task *task)
960 */ 963 */
961int nfs4_do_close(struct inode *inode, struct nfs4_state *state, mode_t mode) 964int nfs4_do_close(struct inode *inode, struct nfs4_state *state, mode_t mode)
962{ 965{
966 struct nfs_server *server = NFS_SERVER(inode);
963 struct nfs4_closedata *calldata; 967 struct nfs4_closedata *calldata;
964 int status = -ENOMEM; 968 int status = -ENOMEM;
965 969
@@ -974,8 +978,11 @@ int nfs4_do_close(struct inode *inode, struct nfs4_state *state, mode_t mode)
974 calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid); 978 calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid);
975 if (calldata->arg.seqid == NULL) 979 if (calldata->arg.seqid == NULL)
976 goto out_free_calldata; 980 goto out_free_calldata;
981 calldata->arg.bitmask = server->attr_bitmask;
982 calldata->res.fattr = &calldata->fattr;
983 calldata->res.server = server;
977 984
978 status = nfs4_call_async(NFS_SERVER(inode)->client, nfs4_close_begin, 985 status = nfs4_call_async(server->client, nfs4_close_begin,
979 nfs4_close_done, calldata); 986 nfs4_close_done, calldata);
980 if (status == 0) 987 if (status == 0)
981 goto out; 988 goto out;
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 7f91d613d31a..cd9e26cfa868 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -198,17 +198,21 @@ static int nfs_stat_to_errno(int);
198#define NFS4_enc_open_downgrade_sz \ 198#define NFS4_enc_open_downgrade_sz \
199 (compound_encode_hdr_maxsz + \ 199 (compound_encode_hdr_maxsz + \
200 encode_putfh_maxsz + \ 200 encode_putfh_maxsz + \
201 op_encode_hdr_maxsz + 7) 201 op_encode_hdr_maxsz + 7 + \
202 encode_getattr_maxsz)
202#define NFS4_dec_open_downgrade_sz \ 203#define NFS4_dec_open_downgrade_sz \
203 (compound_decode_hdr_maxsz + \ 204 (compound_decode_hdr_maxsz + \
204 decode_putfh_maxsz + \ 205 decode_putfh_maxsz + \
205 op_decode_hdr_maxsz + 4) 206 op_decode_hdr_maxsz + 4 + \
207 decode_getattr_maxsz)
206#define NFS4_enc_close_sz (compound_encode_hdr_maxsz + \ 208#define NFS4_enc_close_sz (compound_encode_hdr_maxsz + \
207 encode_putfh_maxsz + \ 209 encode_putfh_maxsz + \
208 op_encode_hdr_maxsz + 5) 210 op_encode_hdr_maxsz + 5 + \
211 encode_getattr_maxsz)
209#define NFS4_dec_close_sz (compound_decode_hdr_maxsz + \ 212#define NFS4_dec_close_sz (compound_decode_hdr_maxsz + \
210 decode_putfh_maxsz + \ 213 decode_putfh_maxsz + \
211 op_decode_hdr_maxsz + 4) 214 op_decode_hdr_maxsz + 4 + \
215 decode_getattr_maxsz)
212#define NFS4_enc_setattr_sz (compound_encode_hdr_maxsz + \ 216#define NFS4_enc_setattr_sz (compound_encode_hdr_maxsz + \
213 encode_putfh_maxsz + \ 217 encode_putfh_maxsz + \
214 op_encode_hdr_maxsz + 4 + \ 218 op_encode_hdr_maxsz + 4 + \
@@ -1433,7 +1437,7 @@ static int nfs4_xdr_enc_close(struct rpc_rqst *req, uint32_t *p, struct nfs_clos
1433{ 1437{
1434 struct xdr_stream xdr; 1438 struct xdr_stream xdr;
1435 struct compound_hdr hdr = { 1439 struct compound_hdr hdr = {
1436 .nops = 2, 1440 .nops = 3,
1437 }; 1441 };
1438 int status; 1442 int status;
1439 1443
@@ -1443,6 +1447,9 @@ static int nfs4_xdr_enc_close(struct rpc_rqst *req, uint32_t *p, struct nfs_clos
1443 if(status) 1447 if(status)
1444 goto out; 1448 goto out;
1445 status = encode_close(&xdr, args); 1449 status = encode_close(&xdr, args);
1450 if (status != 0)
1451 goto out;
1452 status = encode_getfattr(&xdr, args->bitmask);
1446out: 1453out:
1447 return status; 1454 return status;
1448} 1455}
@@ -1541,7 +1548,7 @@ static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, uint32_t *p, struct
1541{ 1548{
1542 struct xdr_stream xdr; 1549 struct xdr_stream xdr;
1543 struct compound_hdr hdr = { 1550 struct compound_hdr hdr = {
1544 .nops = 2, 1551 .nops = 3,
1545 }; 1552 };
1546 int status; 1553 int status;
1547 1554
@@ -1551,6 +1558,9 @@ static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, uint32_t *p, struct
1551 if (status) 1558 if (status)
1552 goto out; 1559 goto out;
1553 status = encode_open_downgrade(&xdr, args); 1560 status = encode_open_downgrade(&xdr, args);
1561 if (status != 0)
1562 goto out;
1563 status = encode_getfattr(&xdr, args->bitmask);
1554out: 1564out:
1555 return status; 1565 return status;
1556} 1566}
@@ -3403,6 +3413,9 @@ static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp, uint32_t *p, stru
3403 if (status) 3413 if (status)
3404 goto out; 3414 goto out;
3405 status = decode_open_downgrade(&xdr, res); 3415 status = decode_open_downgrade(&xdr, res);
3416 if (status != 0)
3417 goto out;
3418 decode_getfattr(&xdr, res->fattr, res->server);
3406out: 3419out:
3407 return status; 3420 return status;
3408} 3421}
@@ -3678,6 +3691,15 @@ static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_cl
3678 if (status) 3691 if (status)
3679 goto out; 3692 goto out;
3680 status = decode_close(&xdr, res); 3693 status = decode_close(&xdr, res);
3694 if (status != 0)
3695 goto out;
3696 /*
3697 * Note: Server may do delete on close for this file
3698 * in which case the getattr call will fail with
3699 * an ESTALE error. Shouldn't be a problem,
3700 * though, since fattr->valid will remain unset.
3701 */
3702 decode_getfattr(&xdr, res->fattr, res->server);
3681out: 3703out:
3682 return status; 3704 return status;
3683} 3705}
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 6485b8b41b83..4f03dc21cf4a 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -153,10 +153,13 @@ struct nfs_closeargs {
153 nfs4_stateid * stateid; 153 nfs4_stateid * stateid;
154 struct nfs_seqid * seqid; 154 struct nfs_seqid * seqid;
155 int open_flags; 155 int open_flags;
156 const u32 * bitmask;
156}; 157};
157 158
158struct nfs_closeres { 159struct nfs_closeres {
159 nfs4_stateid stateid; 160 nfs4_stateid stateid;
161 struct nfs_fattr * fattr;
162 const struct nfs_server *server;
160}; 163};
161/* 164/*
162 * * Arguments to the lock,lockt, and locku call. 165 * * Arguments to the lock,lockt, and locku call.