diff options
-rw-r--r-- | fs/nfs/nfs4proc.c | 9 | ||||
-rw-r--r-- | fs/nfs/nfs4xdr.c | 34 | ||||
-rw-r--r-- | include/linux/nfs_xdr.h | 3 |
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 | ||
870 | static void nfs4_free_closedata(struct nfs4_closedata *calldata) | 871 | static 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 | */ |
961 | int nfs4_do_close(struct inode *inode, struct nfs4_state *state, mode_t mode) | 964 | int 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); | ||
1446 | out: | 1453 | out: |
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); | ||
1554 | out: | 1564 | out: |
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); | ||
3406 | out: | 3419 | out: |
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); | ||
3681 | out: | 3703 | out: |
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 | ||
158 | struct nfs_closeres { | 159 | struct 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. |