aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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.