diff options
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
| -rw-r--r-- | fs/nfs/nfs4xdr.c | 305 |
1 files changed, 224 insertions, 81 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 6c564ef9489e..fbbace8a30c4 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
| @@ -95,6 +95,8 @@ static int nfs_stat_to_errno(int); | |||
| 95 | #define decode_getattr_maxsz (op_decode_hdr_maxsz + nfs4_fattr_maxsz) | 95 | #define decode_getattr_maxsz (op_decode_hdr_maxsz + nfs4_fattr_maxsz) |
| 96 | #define encode_savefh_maxsz (op_encode_hdr_maxsz) | 96 | #define encode_savefh_maxsz (op_encode_hdr_maxsz) |
| 97 | #define decode_savefh_maxsz (op_decode_hdr_maxsz) | 97 | #define decode_savefh_maxsz (op_decode_hdr_maxsz) |
| 98 | #define encode_restorefh_maxsz (op_encode_hdr_maxsz) | ||
| 99 | #define decode_restorefh_maxsz (op_decode_hdr_maxsz) | ||
| 98 | #define encode_fsinfo_maxsz (op_encode_hdr_maxsz + 2) | 100 | #define encode_fsinfo_maxsz (op_encode_hdr_maxsz + 2) |
| 99 | #define decode_fsinfo_maxsz (op_decode_hdr_maxsz + 11) | 101 | #define decode_fsinfo_maxsz (op_decode_hdr_maxsz + 11) |
| 100 | #define encode_renew_maxsz (op_encode_hdr_maxsz + 3) | 102 | #define encode_renew_maxsz (op_encode_hdr_maxsz + 3) |
| @@ -157,16 +159,20 @@ static int nfs_stat_to_errno(int); | |||
| 157 | op_decode_hdr_maxsz + 2) | 159 | op_decode_hdr_maxsz + 2) |
| 158 | #define NFS4_enc_write_sz (compound_encode_hdr_maxsz + \ | 160 | #define NFS4_enc_write_sz (compound_encode_hdr_maxsz + \ |
| 159 | encode_putfh_maxsz + \ | 161 | encode_putfh_maxsz + \ |
| 160 | op_encode_hdr_maxsz + 8) | 162 | op_encode_hdr_maxsz + 8 + \ |
| 163 | encode_getattr_maxsz) | ||
| 161 | #define NFS4_dec_write_sz (compound_decode_hdr_maxsz + \ | 164 | #define NFS4_dec_write_sz (compound_decode_hdr_maxsz + \ |
| 162 | decode_putfh_maxsz + \ | 165 | decode_putfh_maxsz + \ |
| 163 | op_decode_hdr_maxsz + 4) | 166 | op_decode_hdr_maxsz + 4 + \ |
| 167 | decode_getattr_maxsz) | ||
| 164 | #define NFS4_enc_commit_sz (compound_encode_hdr_maxsz + \ | 168 | #define NFS4_enc_commit_sz (compound_encode_hdr_maxsz + \ |
| 165 | encode_putfh_maxsz + \ | 169 | encode_putfh_maxsz + \ |
| 166 | op_encode_hdr_maxsz + 3) | 170 | op_encode_hdr_maxsz + 3 + \ |
| 171 | encode_getattr_maxsz) | ||
| 167 | #define NFS4_dec_commit_sz (compound_decode_hdr_maxsz + \ | 172 | #define NFS4_dec_commit_sz (compound_decode_hdr_maxsz + \ |
| 168 | decode_putfh_maxsz + \ | 173 | decode_putfh_maxsz + \ |
| 169 | op_decode_hdr_maxsz + 2) | 174 | op_decode_hdr_maxsz + 2 + \ |
| 175 | decode_getattr_maxsz) | ||
| 170 | #define NFS4_enc_open_sz (compound_encode_hdr_maxsz + \ | 176 | #define NFS4_enc_open_sz (compound_encode_hdr_maxsz + \ |
| 171 | encode_putfh_maxsz + \ | 177 | encode_putfh_maxsz + \ |
| 172 | op_encode_hdr_maxsz + \ | 178 | op_encode_hdr_maxsz + \ |
| @@ -196,17 +202,21 @@ static int nfs_stat_to_errno(int); | |||
| 196 | #define NFS4_enc_open_downgrade_sz \ | 202 | #define NFS4_enc_open_downgrade_sz \ |
| 197 | (compound_encode_hdr_maxsz + \ | 203 | (compound_encode_hdr_maxsz + \ |
| 198 | encode_putfh_maxsz + \ | 204 | encode_putfh_maxsz + \ |
| 199 | op_encode_hdr_maxsz + 7) | 205 | op_encode_hdr_maxsz + 7 + \ |
| 206 | encode_getattr_maxsz) | ||
| 200 | #define NFS4_dec_open_downgrade_sz \ | 207 | #define NFS4_dec_open_downgrade_sz \ |
| 201 | (compound_decode_hdr_maxsz + \ | 208 | (compound_decode_hdr_maxsz + \ |
| 202 | decode_putfh_maxsz + \ | 209 | decode_putfh_maxsz + \ |
| 203 | op_decode_hdr_maxsz + 4) | 210 | op_decode_hdr_maxsz + 4 + \ |
| 211 | decode_getattr_maxsz) | ||
| 204 | #define NFS4_enc_close_sz (compound_encode_hdr_maxsz + \ | 212 | #define NFS4_enc_close_sz (compound_encode_hdr_maxsz + \ |
| 205 | encode_putfh_maxsz + \ | 213 | encode_putfh_maxsz + \ |
| 206 | op_encode_hdr_maxsz + 5) | 214 | op_encode_hdr_maxsz + 5 + \ |
| 215 | encode_getattr_maxsz) | ||
| 207 | #define NFS4_dec_close_sz (compound_decode_hdr_maxsz + \ | 216 | #define NFS4_dec_close_sz (compound_decode_hdr_maxsz + \ |
| 208 | decode_putfh_maxsz + \ | 217 | decode_putfh_maxsz + \ |
| 209 | op_decode_hdr_maxsz + 4) | 218 | op_decode_hdr_maxsz + 4 + \ |
| 219 | decode_getattr_maxsz) | ||
| 210 | #define NFS4_enc_setattr_sz (compound_encode_hdr_maxsz + \ | 220 | #define NFS4_enc_setattr_sz (compound_encode_hdr_maxsz + \ |
| 211 | encode_putfh_maxsz + \ | 221 | encode_putfh_maxsz + \ |
| 212 | op_encode_hdr_maxsz + 4 + \ | 222 | op_encode_hdr_maxsz + 4 + \ |
| @@ -300,30 +310,44 @@ static int nfs_stat_to_errno(int); | |||
| 300 | decode_getfh_maxsz) | 310 | decode_getfh_maxsz) |
| 301 | #define NFS4_enc_remove_sz (compound_encode_hdr_maxsz + \ | 311 | #define NFS4_enc_remove_sz (compound_encode_hdr_maxsz + \ |
| 302 | encode_putfh_maxsz + \ | 312 | encode_putfh_maxsz + \ |
| 303 | encode_remove_maxsz) | 313 | encode_remove_maxsz + \ |
| 314 | encode_getattr_maxsz) | ||
| 304 | #define NFS4_dec_remove_sz (compound_decode_hdr_maxsz + \ | 315 | #define NFS4_dec_remove_sz (compound_decode_hdr_maxsz + \ |
| 305 | decode_putfh_maxsz + \ | 316 | decode_putfh_maxsz + \ |
| 306 | op_decode_hdr_maxsz + 5) | 317 | op_decode_hdr_maxsz + 5 + \ |
| 318 | decode_getattr_maxsz) | ||
| 307 | #define NFS4_enc_rename_sz (compound_encode_hdr_maxsz + \ | 319 | #define NFS4_enc_rename_sz (compound_encode_hdr_maxsz + \ |
| 308 | encode_putfh_maxsz + \ | 320 | encode_putfh_maxsz + \ |
| 309 | encode_savefh_maxsz + \ | 321 | encode_savefh_maxsz + \ |
| 310 | encode_putfh_maxsz + \ | 322 | encode_putfh_maxsz + \ |
| 311 | encode_rename_maxsz) | 323 | encode_rename_maxsz + \ |
| 324 | encode_getattr_maxsz + \ | ||
| 325 | encode_restorefh_maxsz + \ | ||
| 326 | encode_getattr_maxsz) | ||
| 312 | #define NFS4_dec_rename_sz (compound_decode_hdr_maxsz + \ | 327 | #define NFS4_dec_rename_sz (compound_decode_hdr_maxsz + \ |
| 313 | decode_putfh_maxsz + \ | 328 | decode_putfh_maxsz + \ |
| 314 | decode_savefh_maxsz + \ | 329 | decode_savefh_maxsz + \ |
| 315 | decode_putfh_maxsz + \ | 330 | decode_putfh_maxsz + \ |
| 316 | decode_rename_maxsz) | 331 | decode_rename_maxsz + \ |
| 332 | decode_getattr_maxsz + \ | ||
| 333 | decode_restorefh_maxsz + \ | ||
| 334 | decode_getattr_maxsz) | ||
| 317 | #define NFS4_enc_link_sz (compound_encode_hdr_maxsz + \ | 335 | #define NFS4_enc_link_sz (compound_encode_hdr_maxsz + \ |
| 318 | encode_putfh_maxsz + \ | 336 | encode_putfh_maxsz + \ |
| 319 | encode_savefh_maxsz + \ | 337 | encode_savefh_maxsz + \ |
| 320 | encode_putfh_maxsz + \ | 338 | encode_putfh_maxsz + \ |
| 321 | encode_link_maxsz) | 339 | encode_link_maxsz + \ |
| 340 | decode_getattr_maxsz + \ | ||
| 341 | encode_restorefh_maxsz + \ | ||
| 342 | decode_getattr_maxsz) | ||
| 322 | #define NFS4_dec_link_sz (compound_decode_hdr_maxsz + \ | 343 | #define NFS4_dec_link_sz (compound_decode_hdr_maxsz + \ |
| 323 | decode_putfh_maxsz + \ | 344 | decode_putfh_maxsz + \ |
| 324 | decode_savefh_maxsz + \ | 345 | decode_savefh_maxsz + \ |
| 325 | decode_putfh_maxsz + \ | 346 | decode_putfh_maxsz + \ |
| 326 | decode_link_maxsz) | 347 | decode_link_maxsz + \ |
| 348 | decode_getattr_maxsz + \ | ||
| 349 | decode_restorefh_maxsz + \ | ||
| 350 | decode_getattr_maxsz) | ||
| 327 | #define NFS4_enc_symlink_sz (compound_encode_hdr_maxsz + \ | 351 | #define NFS4_enc_symlink_sz (compound_encode_hdr_maxsz + \ |
| 328 | encode_putfh_maxsz + \ | 352 | encode_putfh_maxsz + \ |
| 329 | encode_symlink_maxsz + \ | 353 | encode_symlink_maxsz + \ |
| @@ -336,14 +360,20 @@ static int nfs_stat_to_errno(int); | |||
| 336 | decode_getfh_maxsz) | 360 | decode_getfh_maxsz) |
| 337 | #define NFS4_enc_create_sz (compound_encode_hdr_maxsz + \ | 361 | #define NFS4_enc_create_sz (compound_encode_hdr_maxsz + \ |
| 338 | encode_putfh_maxsz + \ | 362 | encode_putfh_maxsz + \ |
| 363 | encode_savefh_maxsz + \ | ||
| 339 | encode_create_maxsz + \ | 364 | encode_create_maxsz + \ |
| 365 | encode_getfh_maxsz + \ | ||
| 340 | encode_getattr_maxsz + \ | 366 | encode_getattr_maxsz + \ |
| 341 | encode_getfh_maxsz) | 367 | encode_restorefh_maxsz + \ |
| 368 | encode_getattr_maxsz) | ||
| 342 | #define NFS4_dec_create_sz (compound_decode_hdr_maxsz + \ | 369 | #define NFS4_dec_create_sz (compound_decode_hdr_maxsz + \ |
| 343 | decode_putfh_maxsz + \ | 370 | decode_putfh_maxsz + \ |
| 371 | decode_savefh_maxsz + \ | ||
| 344 | decode_create_maxsz + \ | 372 | decode_create_maxsz + \ |
| 373 | decode_getfh_maxsz + \ | ||
| 345 | decode_getattr_maxsz + \ | 374 | decode_getattr_maxsz + \ |
| 346 | decode_getfh_maxsz) | 375 | decode_restorefh_maxsz + \ |
| 376 | decode_getattr_maxsz) | ||
| 347 | #define NFS4_enc_pathconf_sz (compound_encode_hdr_maxsz + \ | 377 | #define NFS4_enc_pathconf_sz (compound_encode_hdr_maxsz + \ |
| 348 | encode_putfh_maxsz + \ | 378 | encode_putfh_maxsz + \ |
| 349 | encode_getattr_maxsz) | 379 | encode_getattr_maxsz) |
| @@ -602,10 +632,10 @@ static int encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg) | |||
| 602 | { | 632 | { |
| 603 | uint32_t *p; | 633 | uint32_t *p; |
| 604 | 634 | ||
| 605 | RESERVE_SPACE(8+sizeof(arg->stateid.data)); | 635 | RESERVE_SPACE(8+sizeof(arg->stateid->data)); |
| 606 | WRITE32(OP_CLOSE); | 636 | WRITE32(OP_CLOSE); |
| 607 | WRITE32(arg->seqid); | 637 | WRITE32(arg->seqid->sequence->counter); |
| 608 | WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data)); | 638 | WRITEMEM(arg->stateid->data, sizeof(arg->stateid->data)); |
| 609 | 639 | ||
| 610 | return 0; | 640 | return 0; |
| 611 | } | 641 | } |
| @@ -729,22 +759,18 @@ static int encode_lock(struct xdr_stream *xdr, const struct nfs_lockargs *arg) | |||
| 729 | WRITE64(arg->length); | 759 | WRITE64(arg->length); |
| 730 | WRITE32(opargs->new_lock_owner); | 760 | WRITE32(opargs->new_lock_owner); |
| 731 | if (opargs->new_lock_owner){ | 761 | if (opargs->new_lock_owner){ |
| 732 | struct nfs_open_to_lock *ol = opargs->u.open_lock; | ||
| 733 | |||
| 734 | RESERVE_SPACE(40); | 762 | RESERVE_SPACE(40); |
| 735 | WRITE32(ol->open_seqid); | 763 | WRITE32(opargs->open_seqid->sequence->counter); |
| 736 | WRITEMEM(&ol->open_stateid, sizeof(ol->open_stateid)); | 764 | WRITEMEM(opargs->open_stateid->data, sizeof(opargs->open_stateid->data)); |
| 737 | WRITE32(ol->lock_seqid); | 765 | WRITE32(opargs->lock_seqid->sequence->counter); |
| 738 | WRITE64(ol->lock_owner.clientid); | 766 | WRITE64(opargs->lock_owner.clientid); |
| 739 | WRITE32(4); | 767 | WRITE32(4); |
| 740 | WRITE32(ol->lock_owner.id); | 768 | WRITE32(opargs->lock_owner.id); |
| 741 | } | 769 | } |
| 742 | else { | 770 | else { |
| 743 | struct nfs_exist_lock *el = opargs->u.exist_lock; | ||
| 744 | |||
| 745 | RESERVE_SPACE(20); | 771 | RESERVE_SPACE(20); |
| 746 | WRITEMEM(&el->stateid, sizeof(el->stateid)); | 772 | WRITEMEM(opargs->lock_stateid->data, sizeof(opargs->lock_stateid->data)); |
| 747 | WRITE32(el->seqid); | 773 | WRITE32(opargs->lock_seqid->sequence->counter); |
| 748 | } | 774 | } |
| 749 | 775 | ||
| 750 | return 0; | 776 | return 0; |
| @@ -775,8 +801,8 @@ static int encode_locku(struct xdr_stream *xdr, const struct nfs_lockargs *arg) | |||
| 775 | RESERVE_SPACE(44); | 801 | RESERVE_SPACE(44); |
| 776 | WRITE32(OP_LOCKU); | 802 | WRITE32(OP_LOCKU); |
| 777 | WRITE32(arg->type); | 803 | WRITE32(arg->type); |
| 778 | WRITE32(opargs->seqid); | 804 | WRITE32(opargs->seqid->sequence->counter); |
| 779 | WRITEMEM(&opargs->stateid, sizeof(opargs->stateid)); | 805 | WRITEMEM(opargs->stateid->data, sizeof(opargs->stateid->data)); |
| 780 | WRITE64(arg->offset); | 806 | WRITE64(arg->offset); |
| 781 | WRITE64(arg->length); | 807 | WRITE64(arg->length); |
| 782 | 808 | ||
| @@ -826,7 +852,7 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena | |||
| 826 | */ | 852 | */ |
| 827 | RESERVE_SPACE(8); | 853 | RESERVE_SPACE(8); |
| 828 | WRITE32(OP_OPEN); | 854 | WRITE32(OP_OPEN); |
| 829 | WRITE32(arg->seqid); | 855 | WRITE32(arg->seqid->sequence->counter); |
| 830 | encode_share_access(xdr, arg->open_flags); | 856 | encode_share_access(xdr, arg->open_flags); |
| 831 | RESERVE_SPACE(16); | 857 | RESERVE_SPACE(16); |
| 832 | WRITE64(arg->clientid); | 858 | WRITE64(arg->clientid); |
| @@ -941,7 +967,7 @@ static int encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_con | |||
| 941 | RESERVE_SPACE(8+sizeof(arg->stateid.data)); | 967 | RESERVE_SPACE(8+sizeof(arg->stateid.data)); |
| 942 | WRITE32(OP_OPEN_CONFIRM); | 968 | WRITE32(OP_OPEN_CONFIRM); |
| 943 | WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data)); | 969 | WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data)); |
| 944 | WRITE32(arg->seqid); | 970 | WRITE32(arg->seqid->sequence->counter); |
| 945 | 971 | ||
| 946 | return 0; | 972 | return 0; |
| 947 | } | 973 | } |
| @@ -950,10 +976,10 @@ static int encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closea | |||
| 950 | { | 976 | { |
| 951 | uint32_t *p; | 977 | uint32_t *p; |
| 952 | 978 | ||
| 953 | RESERVE_SPACE(8+sizeof(arg->stateid.data)); | 979 | RESERVE_SPACE(8+sizeof(arg->stateid->data)); |
| 954 | WRITE32(OP_OPEN_DOWNGRADE); | 980 | WRITE32(OP_OPEN_DOWNGRADE); |
| 955 | WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data)); | 981 | WRITEMEM(arg->stateid->data, sizeof(arg->stateid->data)); |
| 956 | WRITE32(arg->seqid); | 982 | WRITE32(arg->seqid->sequence->counter); |
| 957 | encode_share_access(xdr, arg->open_flags); | 983 | encode_share_access(xdr, arg->open_flags); |
| 958 | return 0; | 984 | return 0; |
| 959 | } | 985 | } |
| @@ -1117,6 +1143,17 @@ static int encode_renew(struct xdr_stream *xdr, const struct nfs4_client *client | |||
| 1117 | } | 1143 | } |
| 1118 | 1144 | ||
| 1119 | static int | 1145 | static int |
| 1146 | encode_restorefh(struct xdr_stream *xdr) | ||
| 1147 | { | ||
| 1148 | uint32_t *p; | ||
| 1149 | |||
| 1150 | RESERVE_SPACE(4); | ||
| 1151 | WRITE32(OP_RESTOREFH); | ||
| 1152 | |||
| 1153 | return 0; | ||
| 1154 | } | ||
| 1155 | |||
| 1156 | static int | ||
| 1120 | encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg) | 1157 | encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg) |
| 1121 | { | 1158 | { |
| 1122 | uint32_t *p; | 1159 | uint32_t *p; |
| @@ -1296,14 +1333,18 @@ static int nfs4_xdr_enc_remove(struct rpc_rqst *req, uint32_t *p, const struct n | |||
| 1296 | { | 1333 | { |
| 1297 | struct xdr_stream xdr; | 1334 | struct xdr_stream xdr; |
| 1298 | struct compound_hdr hdr = { | 1335 | struct compound_hdr hdr = { |
| 1299 | .nops = 2, | 1336 | .nops = 3, |
| 1300 | }; | 1337 | }; |
| 1301 | int status; | 1338 | int status; |
| 1302 | 1339 | ||
| 1303 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 1340 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); |
| 1304 | encode_compound_hdr(&xdr, &hdr); | 1341 | encode_compound_hdr(&xdr, &hdr); |
| 1305 | if ((status = encode_putfh(&xdr, args->fh)) == 0) | 1342 | if ((status = encode_putfh(&xdr, args->fh)) != 0) |
| 1306 | status = encode_remove(&xdr, args->name); | 1343 | goto out; |
| 1344 | if ((status = encode_remove(&xdr, args->name)) != 0) | ||
| 1345 | goto out; | ||
| 1346 | status = encode_getfattr(&xdr, args->bitmask); | ||
| 1347 | out: | ||
| 1307 | return status; | 1348 | return status; |
| 1308 | } | 1349 | } |
| 1309 | 1350 | ||
| @@ -1314,7 +1355,7 @@ static int nfs4_xdr_enc_rename(struct rpc_rqst *req, uint32_t *p, const struct n | |||
| 1314 | { | 1355 | { |
| 1315 | struct xdr_stream xdr; | 1356 | struct xdr_stream xdr; |
| 1316 | struct compound_hdr hdr = { | 1357 | struct compound_hdr hdr = { |
| 1317 | .nops = 4, | 1358 | .nops = 7, |
| 1318 | }; | 1359 | }; |
| 1319 | int status; | 1360 | int status; |
| 1320 | 1361 | ||
| @@ -1326,7 +1367,13 @@ static int nfs4_xdr_enc_rename(struct rpc_rqst *req, uint32_t *p, const struct n | |||
| 1326 | goto out; | 1367 | goto out; |
| 1327 | if ((status = encode_putfh(&xdr, args->new_dir)) != 0) | 1368 | if ((status = encode_putfh(&xdr, args->new_dir)) != 0) |
| 1328 | goto out; | 1369 | goto out; |
| 1329 | status = encode_rename(&xdr, args->old_name, args->new_name); | 1370 | if ((status = encode_rename(&xdr, args->old_name, args->new_name)) != 0) |
| 1371 | goto out; | ||
| 1372 | if ((status = encode_getfattr(&xdr, args->bitmask)) != 0) | ||
| 1373 | goto out; | ||
| 1374 | if ((status = encode_restorefh(&xdr)) != 0) | ||
| 1375 | goto out; | ||
| 1376 | status = encode_getfattr(&xdr, args->bitmask); | ||
| 1330 | out: | 1377 | out: |
| 1331 | return status; | 1378 | return status; |
| 1332 | } | 1379 | } |
| @@ -1338,7 +1385,7 @@ static int nfs4_xdr_enc_link(struct rpc_rqst *req, uint32_t *p, const struct nfs | |||
| 1338 | { | 1385 | { |
| 1339 | struct xdr_stream xdr; | 1386 | struct xdr_stream xdr; |
| 1340 | struct compound_hdr hdr = { | 1387 | struct compound_hdr hdr = { |
| 1341 | .nops = 4, | 1388 | .nops = 7, |
| 1342 | }; | 1389 | }; |
| 1343 | int status; | 1390 | int status; |
| 1344 | 1391 | ||
| @@ -1350,7 +1397,13 @@ static int nfs4_xdr_enc_link(struct rpc_rqst *req, uint32_t *p, const struct nfs | |||
| 1350 | goto out; | 1397 | goto out; |
| 1351 | if ((status = encode_putfh(&xdr, args->dir_fh)) != 0) | 1398 | if ((status = encode_putfh(&xdr, args->dir_fh)) != 0) |
| 1352 | goto out; | 1399 | goto out; |
| 1353 | status = encode_link(&xdr, args->name); | 1400 | if ((status = encode_link(&xdr, args->name)) != 0) |
| 1401 | goto out; | ||
| 1402 | if ((status = encode_getfattr(&xdr, args->bitmask)) != 0) | ||
| 1403 | goto out; | ||
| 1404 | if ((status = encode_restorefh(&xdr)) != 0) | ||
| 1405 | goto out; | ||
| 1406 | status = encode_getfattr(&xdr, args->bitmask); | ||
| 1354 | out: | 1407 | out: |
| 1355 | return status; | 1408 | return status; |
| 1356 | } | 1409 | } |
| @@ -1362,7 +1415,7 @@ static int nfs4_xdr_enc_create(struct rpc_rqst *req, uint32_t *p, const struct n | |||
| 1362 | { | 1415 | { |
| 1363 | struct xdr_stream xdr; | 1416 | struct xdr_stream xdr; |
| 1364 | struct compound_hdr hdr = { | 1417 | struct compound_hdr hdr = { |
| 1365 | .nops = 4, | 1418 | .nops = 7, |
| 1366 | }; | 1419 | }; |
| 1367 | int status; | 1420 | int status; |
| 1368 | 1421 | ||
| @@ -1370,10 +1423,16 @@ static int nfs4_xdr_enc_create(struct rpc_rqst *req, uint32_t *p, const struct n | |||
| 1370 | encode_compound_hdr(&xdr, &hdr); | 1423 | encode_compound_hdr(&xdr, &hdr); |
| 1371 | if ((status = encode_putfh(&xdr, args->dir_fh)) != 0) | 1424 | if ((status = encode_putfh(&xdr, args->dir_fh)) != 0) |
| 1372 | goto out; | 1425 | goto out; |
| 1426 | if ((status = encode_savefh(&xdr)) != 0) | ||
| 1427 | goto out; | ||
| 1373 | if ((status = encode_create(&xdr, args)) != 0) | 1428 | if ((status = encode_create(&xdr, args)) != 0) |
| 1374 | goto out; | 1429 | goto out; |
| 1375 | if ((status = encode_getfh(&xdr)) != 0) | 1430 | if ((status = encode_getfh(&xdr)) != 0) |
| 1376 | goto out; | 1431 | goto out; |
| 1432 | if ((status = encode_getfattr(&xdr, args->bitmask)) != 0) | ||
| 1433 | goto out; | ||
| 1434 | if ((status = encode_restorefh(&xdr)) != 0) | ||
| 1435 | goto out; | ||
| 1377 | status = encode_getfattr(&xdr, args->bitmask); | 1436 | status = encode_getfattr(&xdr, args->bitmask); |
| 1378 | out: | 1437 | out: |
| 1379 | return status; | 1438 | return status; |
| @@ -1412,7 +1471,7 @@ static int nfs4_xdr_enc_close(struct rpc_rqst *req, uint32_t *p, struct nfs_clos | |||
| 1412 | { | 1471 | { |
| 1413 | struct xdr_stream xdr; | 1472 | struct xdr_stream xdr; |
| 1414 | struct compound_hdr hdr = { | 1473 | struct compound_hdr hdr = { |
| 1415 | .nops = 2, | 1474 | .nops = 3, |
| 1416 | }; | 1475 | }; |
| 1417 | int status; | 1476 | int status; |
| 1418 | 1477 | ||
| @@ -1422,6 +1481,9 @@ static int nfs4_xdr_enc_close(struct rpc_rqst *req, uint32_t *p, struct nfs_clos | |||
| 1422 | if(status) | 1481 | if(status) |
| 1423 | goto out; | 1482 | goto out; |
| 1424 | status = encode_close(&xdr, args); | 1483 | status = encode_close(&xdr, args); |
| 1484 | if (status != 0) | ||
| 1485 | goto out; | ||
| 1486 | status = encode_getfattr(&xdr, args->bitmask); | ||
| 1425 | out: | 1487 | out: |
| 1426 | return status; | 1488 | return status; |
| 1427 | } | 1489 | } |
| @@ -1433,15 +1495,21 @@ static int nfs4_xdr_enc_open(struct rpc_rqst *req, uint32_t *p, struct nfs_opena | |||
| 1433 | { | 1495 | { |
| 1434 | struct xdr_stream xdr; | 1496 | struct xdr_stream xdr; |
| 1435 | struct compound_hdr hdr = { | 1497 | struct compound_hdr hdr = { |
| 1436 | .nops = 4, | 1498 | .nops = 7, |
| 1437 | }; | 1499 | }; |
| 1438 | int status; | 1500 | int status; |
| 1439 | 1501 | ||
| 1502 | status = nfs_wait_on_sequence(args->seqid, req->rq_task); | ||
| 1503 | if (status != 0) | ||
| 1504 | goto out; | ||
| 1440 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 1505 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); |
| 1441 | encode_compound_hdr(&xdr, &hdr); | 1506 | encode_compound_hdr(&xdr, &hdr); |
| 1442 | status = encode_putfh(&xdr, args->fh); | 1507 | status = encode_putfh(&xdr, args->fh); |
| 1443 | if (status) | 1508 | if (status) |
| 1444 | goto out; | 1509 | goto out; |
| 1510 | status = encode_savefh(&xdr); | ||
| 1511 | if (status) | ||
| 1512 | goto out; | ||
| 1445 | status = encode_open(&xdr, args); | 1513 | status = encode_open(&xdr, args); |
| 1446 | if (status) | 1514 | if (status) |
| 1447 | goto out; | 1515 | goto out; |
| @@ -1449,6 +1517,12 @@ static int nfs4_xdr_enc_open(struct rpc_rqst *req, uint32_t *p, struct nfs_opena | |||
| 1449 | if (status) | 1517 | if (status) |
| 1450 | goto out; | 1518 | goto out; |
| 1451 | status = encode_getfattr(&xdr, args->bitmask); | 1519 | status = encode_getfattr(&xdr, args->bitmask); |
| 1520 | if (status) | ||
| 1521 | goto out; | ||
| 1522 | status = encode_restorefh(&xdr); | ||
| 1523 | if (status) | ||
| 1524 | goto out; | ||
| 1525 | status = encode_getfattr(&xdr, args->bitmask); | ||
| 1452 | out: | 1526 | out: |
| 1453 | return status; | 1527 | return status; |
| 1454 | } | 1528 | } |
| @@ -1464,6 +1538,9 @@ static int nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, uint32_t *p, struct n | |||
| 1464 | }; | 1538 | }; |
| 1465 | int status; | 1539 | int status; |
| 1466 | 1540 | ||
| 1541 | status = nfs_wait_on_sequence(args->seqid, req->rq_task); | ||
| 1542 | if (status != 0) | ||
| 1543 | goto out; | ||
| 1467 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 1544 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); |
| 1468 | encode_compound_hdr(&xdr, &hdr); | 1545 | encode_compound_hdr(&xdr, &hdr); |
| 1469 | status = encode_putfh(&xdr, args->fh); | 1546 | status = encode_putfh(&xdr, args->fh); |
| @@ -1485,6 +1562,9 @@ static int nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, uint32_t *p, struct nf | |||
| 1485 | }; | 1562 | }; |
| 1486 | int status; | 1563 | int status; |
| 1487 | 1564 | ||
| 1565 | status = nfs_wait_on_sequence(args->seqid, req->rq_task); | ||
| 1566 | if (status != 0) | ||
| 1567 | goto out; | ||
| 1488 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 1568 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); |
| 1489 | encode_compound_hdr(&xdr, &hdr); | 1569 | encode_compound_hdr(&xdr, &hdr); |
| 1490 | status = encode_putfh(&xdr, args->fh); | 1570 | status = encode_putfh(&xdr, args->fh); |
| @@ -1502,7 +1582,7 @@ static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, uint32_t *p, struct | |||
| 1502 | { | 1582 | { |
| 1503 | struct xdr_stream xdr; | 1583 | struct xdr_stream xdr; |
| 1504 | struct compound_hdr hdr = { | 1584 | struct compound_hdr hdr = { |
| 1505 | .nops = 2, | 1585 | .nops = 3, |
| 1506 | }; | 1586 | }; |
| 1507 | int status; | 1587 | int status; |
| 1508 | 1588 | ||
| @@ -1512,6 +1592,9 @@ static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, uint32_t *p, struct | |||
| 1512 | if (status) | 1592 | if (status) |
| 1513 | goto out; | 1593 | goto out; |
| 1514 | status = encode_open_downgrade(&xdr, args); | 1594 | status = encode_open_downgrade(&xdr, args); |
| 1595 | if (status != 0) | ||
| 1596 | goto out; | ||
| 1597 | status = encode_getfattr(&xdr, args->bitmask); | ||
| 1515 | out: | 1598 | out: |
| 1516 | return status; | 1599 | return status; |
| 1517 | } | 1600 | } |
| @@ -1525,8 +1608,15 @@ static int nfs4_xdr_enc_lock(struct rpc_rqst *req, uint32_t *p, struct nfs_locka | |||
| 1525 | struct compound_hdr hdr = { | 1608 | struct compound_hdr hdr = { |
| 1526 | .nops = 2, | 1609 | .nops = 2, |
| 1527 | }; | 1610 | }; |
| 1611 | struct nfs_lock_opargs *opargs = args->u.lock; | ||
| 1528 | int status; | 1612 | int status; |
| 1529 | 1613 | ||
| 1614 | status = nfs_wait_on_sequence(opargs->lock_seqid, req->rq_task); | ||
| 1615 | if (status != 0) | ||
| 1616 | goto out; | ||
| 1617 | /* Do we need to do an open_to_lock_owner? */ | ||
| 1618 | if (opargs->lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED) | ||
| 1619 | opargs->new_lock_owner = 0; | ||
| 1530 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 1620 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); |
| 1531 | encode_compound_hdr(&xdr, &hdr); | 1621 | encode_compound_hdr(&xdr, &hdr); |
| 1532 | status = encode_putfh(&xdr, args->fh); | 1622 | status = encode_putfh(&xdr, args->fh); |
| @@ -1713,7 +1803,7 @@ static int nfs4_xdr_enc_write(struct rpc_rqst *req, uint32_t *p, struct nfs_writ | |||
| 1713 | { | 1803 | { |
| 1714 | struct xdr_stream xdr; | 1804 | struct xdr_stream xdr; |
| 1715 | struct compound_hdr hdr = { | 1805 | struct compound_hdr hdr = { |
| 1716 | .nops = 2, | 1806 | .nops = 3, |
| 1717 | }; | 1807 | }; |
| 1718 | int status; | 1808 | int status; |
| 1719 | 1809 | ||
| @@ -1723,6 +1813,9 @@ static int nfs4_xdr_enc_write(struct rpc_rqst *req, uint32_t *p, struct nfs_writ | |||
| 1723 | if (status) | 1813 | if (status) |
| 1724 | goto out; | 1814 | goto out; |
| 1725 | status = encode_write(&xdr, args); | 1815 | status = encode_write(&xdr, args); |
| 1816 | if (status) | ||
| 1817 | goto out; | ||
| 1818 | status = encode_getfattr(&xdr, args->bitmask); | ||
| 1726 | out: | 1819 | out: |
| 1727 | return status; | 1820 | return status; |
| 1728 | } | 1821 | } |
| @@ -1734,7 +1827,7 @@ static int nfs4_xdr_enc_commit(struct rpc_rqst *req, uint32_t *p, struct nfs_wri | |||
| 1734 | { | 1827 | { |
| 1735 | struct xdr_stream xdr; | 1828 | struct xdr_stream xdr; |
| 1736 | struct compound_hdr hdr = { | 1829 | struct compound_hdr hdr = { |
| 1737 | .nops = 2, | 1830 | .nops = 3, |
| 1738 | }; | 1831 | }; |
| 1739 | int status; | 1832 | int status; |
| 1740 | 1833 | ||
| @@ -1744,6 +1837,9 @@ static int nfs4_xdr_enc_commit(struct rpc_rqst *req, uint32_t *p, struct nfs_wri | |||
| 1744 | if (status) | 1837 | if (status) |
| 1745 | goto out; | 1838 | goto out; |
| 1746 | status = encode_commit(&xdr, args); | 1839 | status = encode_commit(&xdr, args); |
| 1840 | if (status) | ||
| 1841 | goto out; | ||
| 1842 | status = encode_getfattr(&xdr, args->bitmask); | ||
| 1747 | out: | 1843 | out: |
| 1748 | return status; | 1844 | return status; |
| 1749 | } | 1845 | } |
| @@ -2670,8 +2766,7 @@ static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_re | |||
| 2670 | goto xdr_error; | 2766 | goto xdr_error; |
| 2671 | status = verify_attr_len(xdr, savep, attrlen); | 2767 | status = verify_attr_len(xdr, savep, attrlen); |
| 2672 | xdr_error: | 2768 | xdr_error: |
| 2673 | if (status != 0) | 2769 | dprintk("%s: xdr returned %d!\n", __FUNCTION__, -status); |
| 2674 | printk(KERN_NOTICE "%s: xdr error %d!\n", __FUNCTION__, -status); | ||
| 2675 | return status; | 2770 | return status; |
| 2676 | } | 2771 | } |
| 2677 | 2772 | ||
| @@ -2704,8 +2799,7 @@ static int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat) | |||
| 2704 | 2799 | ||
| 2705 | status = verify_attr_len(xdr, savep, attrlen); | 2800 | status = verify_attr_len(xdr, savep, attrlen); |
| 2706 | xdr_error: | 2801 | xdr_error: |
| 2707 | if (status != 0) | 2802 | dprintk("%s: xdr returned %d!\n", __FUNCTION__, -status); |
| 2708 | printk(KERN_NOTICE "%s: xdr error %d!\n", __FUNCTION__, -status); | ||
| 2709 | return status; | 2803 | return status; |
| 2710 | } | 2804 | } |
| 2711 | 2805 | ||
| @@ -2730,8 +2824,7 @@ static int decode_pathconf(struct xdr_stream *xdr, struct nfs_pathconf *pathconf | |||
| 2730 | 2824 | ||
| 2731 | status = verify_attr_len(xdr, savep, attrlen); | 2825 | status = verify_attr_len(xdr, savep, attrlen); |
| 2732 | xdr_error: | 2826 | xdr_error: |
| 2733 | if (status != 0) | 2827 | dprintk("%s: xdr returned %d!\n", __FUNCTION__, -status); |
| 2734 | printk(KERN_NOTICE "%s: xdr error %d!\n", __FUNCTION__, -status); | ||
| 2735 | return status; | 2828 | return status; |
| 2736 | } | 2829 | } |
| 2737 | 2830 | ||
| @@ -2787,13 +2880,10 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, cons | |||
| 2787 | goto xdr_error; | 2880 | goto xdr_error; |
| 2788 | if ((status = decode_attr_time_modify(xdr, bitmap, &fattr->mtime)) != 0) | 2881 | if ((status = decode_attr_time_modify(xdr, bitmap, &fattr->mtime)) != 0) |
| 2789 | goto xdr_error; | 2882 | goto xdr_error; |
| 2790 | if ((status = verify_attr_len(xdr, savep, attrlen)) == 0) { | 2883 | if ((status = verify_attr_len(xdr, savep, attrlen)) == 0) |
| 2791 | fattr->valid = NFS_ATTR_FATTR | NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4; | 2884 | fattr->valid = NFS_ATTR_FATTR | NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4; |
| 2792 | fattr->timestamp = jiffies; | ||
| 2793 | } | ||
| 2794 | xdr_error: | 2885 | xdr_error: |
| 2795 | if (status != 0) | 2886 | dprintk("%s: xdr returned %d\n", __FUNCTION__, -status); |
| 2796 | printk(KERN_NOTICE "%s: xdr error %d!\n", __FUNCTION__, -status); | ||
| 2797 | return status; | 2887 | return status; |
| 2798 | } | 2888 | } |
| 2799 | 2889 | ||
| @@ -2826,8 +2916,7 @@ static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) | |||
| 2826 | 2916 | ||
| 2827 | status = verify_attr_len(xdr, savep, attrlen); | 2917 | status = verify_attr_len(xdr, savep, attrlen); |
| 2828 | xdr_error: | 2918 | xdr_error: |
| 2829 | if (status != 0) | 2919 | dprintk("%s: xdr returned %d!\n", __FUNCTION__, -status); |
| 2830 | printk(KERN_NOTICE "%s: xdr error %d!\n", __FUNCTION__, -status); | ||
| 2831 | return status; | 2920 | return status; |
| 2832 | } | 2921 | } |
| 2833 | 2922 | ||
| @@ -2890,8 +2979,8 @@ static int decode_lock(struct xdr_stream *xdr, struct nfs_lockres *res) | |||
| 2890 | 2979 | ||
| 2891 | status = decode_op_hdr(xdr, OP_LOCK); | 2980 | status = decode_op_hdr(xdr, OP_LOCK); |
| 2892 | if (status == 0) { | 2981 | if (status == 0) { |
| 2893 | READ_BUF(sizeof(nfs4_stateid)); | 2982 | READ_BUF(sizeof(res->u.stateid.data)); |
| 2894 | COPYMEM(&res->u.stateid, sizeof(res->u.stateid)); | 2983 | COPYMEM(res->u.stateid.data, sizeof(res->u.stateid.data)); |
| 2895 | } else if (status == -NFS4ERR_DENIED) | 2984 | } else if (status == -NFS4ERR_DENIED) |
| 2896 | return decode_lock_denied(xdr, &res->u.denied); | 2985 | return decode_lock_denied(xdr, &res->u.denied); |
| 2897 | return status; | 2986 | return status; |
| @@ -2913,8 +3002,8 @@ static int decode_locku(struct xdr_stream *xdr, struct nfs_lockres *res) | |||
| 2913 | 3002 | ||
| 2914 | status = decode_op_hdr(xdr, OP_LOCKU); | 3003 | status = decode_op_hdr(xdr, OP_LOCKU); |
| 2915 | if (status == 0) { | 3004 | if (status == 0) { |
| 2916 | READ_BUF(sizeof(nfs4_stateid)); | 3005 | READ_BUF(sizeof(res->u.stateid.data)); |
| 2917 | COPYMEM(&res->u.stateid, sizeof(res->u.stateid)); | 3006 | COPYMEM(res->u.stateid.data, sizeof(res->u.stateid.data)); |
| 2918 | } | 3007 | } |
| 2919 | return status; | 3008 | return status; |
| 2920 | } | 3009 | } |
| @@ -2994,7 +3083,7 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) | |||
| 2994 | p += bmlen; | 3083 | p += bmlen; |
| 2995 | return decode_delegation(xdr, res); | 3084 | return decode_delegation(xdr, res); |
| 2996 | xdr_error: | 3085 | xdr_error: |
| 2997 | printk(KERN_NOTICE "%s: xdr error!\n", __FUNCTION__); | 3086 | dprintk("%s: Bitmap too large! Length = %u\n", __FUNCTION__, bmlen); |
| 2998 | return -EIO; | 3087 | return -EIO; |
| 2999 | } | 3088 | } |
| 3000 | 3089 | ||
| @@ -3208,6 +3297,12 @@ static int decode_renew(struct xdr_stream *xdr) | |||
| 3208 | return decode_op_hdr(xdr, OP_RENEW); | 3297 | return decode_op_hdr(xdr, OP_RENEW); |
| 3209 | } | 3298 | } |
| 3210 | 3299 | ||
| 3300 | static int | ||
| 3301 | decode_restorefh(struct xdr_stream *xdr) | ||
| 3302 | { | ||
| 3303 | return decode_op_hdr(xdr, OP_RESTOREFH); | ||
| 3304 | } | ||
| 3305 | |||
| 3211 | static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, | 3306 | static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, |
| 3212 | size_t *acl_len) | 3307 | size_t *acl_len) |
| 3213 | { | 3308 | { |
| @@ -3243,7 +3338,8 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, | |||
| 3243 | if (attrlen <= *acl_len) | 3338 | if (attrlen <= *acl_len) |
| 3244 | xdr_read_pages(xdr, attrlen); | 3339 | xdr_read_pages(xdr, attrlen); |
| 3245 | *acl_len = attrlen; | 3340 | *acl_len = attrlen; |
| 3246 | } | 3341 | } else |
| 3342 | status = -EOPNOTSUPP; | ||
| 3247 | 3343 | ||
| 3248 | out: | 3344 | out: |
| 3249 | return status; | 3345 | return status; |
| @@ -3352,6 +3448,9 @@ static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp, uint32_t *p, stru | |||
| 3352 | if (status) | 3448 | if (status) |
| 3353 | goto out; | 3449 | goto out; |
| 3354 | status = decode_open_downgrade(&xdr, res); | 3450 | status = decode_open_downgrade(&xdr, res); |
| 3451 | if (status != 0) | ||
| 3452 | goto out; | ||
| 3453 | decode_getfattr(&xdr, res->fattr, res->server); | ||
| 3355 | out: | 3454 | out: |
| 3356 | return status; | 3455 | return status; |
| 3357 | } | 3456 | } |
| @@ -3424,7 +3523,7 @@ out: | |||
| 3424 | /* | 3523 | /* |
| 3425 | * Decode REMOVE response | 3524 | * Decode REMOVE response |
| 3426 | */ | 3525 | */ |
| 3427 | static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_change_info *cinfo) | 3526 | static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_remove_res *res) |
| 3428 | { | 3527 | { |
| 3429 | struct xdr_stream xdr; | 3528 | struct xdr_stream xdr; |
| 3430 | struct compound_hdr hdr; | 3529 | struct compound_hdr hdr; |
| @@ -3433,8 +3532,11 @@ static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_ | |||
| 3433 | xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); | 3532 | xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); |
| 3434 | if ((status = decode_compound_hdr(&xdr, &hdr)) != 0) | 3533 | if ((status = decode_compound_hdr(&xdr, &hdr)) != 0) |
| 3435 | goto out; | 3534 | goto out; |
| 3436 | if ((status = decode_putfh(&xdr)) == 0) | 3535 | if ((status = decode_putfh(&xdr)) != 0) |
| 3437 | status = decode_remove(&xdr, cinfo); | 3536 | goto out; |
| 3537 | if ((status = decode_remove(&xdr, &res->cinfo)) != 0) | ||
| 3538 | goto out; | ||
| 3539 | decode_getfattr(&xdr, res->dir_attr, res->server); | ||
| 3438 | out: | 3540 | out: |
| 3439 | return status; | 3541 | return status; |
| 3440 | } | 3542 | } |
| @@ -3457,7 +3559,14 @@ static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_ | |||
| 3457 | goto out; | 3559 | goto out; |
| 3458 | if ((status = decode_putfh(&xdr)) != 0) | 3560 | if ((status = decode_putfh(&xdr)) != 0) |
| 3459 | goto out; | 3561 | goto out; |
| 3460 | status = decode_rename(&xdr, &res->old_cinfo, &res->new_cinfo); | 3562 | if ((status = decode_rename(&xdr, &res->old_cinfo, &res->new_cinfo)) != 0) |
| 3563 | goto out; | ||
| 3564 | /* Current FH is target directory */ | ||
| 3565 | if (decode_getfattr(&xdr, res->new_fattr, res->server) != 0) | ||
| 3566 | goto out; | ||
| 3567 | if ((status = decode_restorefh(&xdr)) != 0) | ||
| 3568 | goto out; | ||
| 3569 | decode_getfattr(&xdr, res->old_fattr, res->server); | ||
| 3461 | out: | 3570 | out: |
| 3462 | return status; | 3571 | return status; |
| 3463 | } | 3572 | } |
| @@ -3465,7 +3574,7 @@ out: | |||
| 3465 | /* | 3574 | /* |
| 3466 | * Decode LINK response | 3575 | * Decode LINK response |
| 3467 | */ | 3576 | */ |
| 3468 | static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_change_info *cinfo) | 3577 | static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_link_res *res) |
| 3469 | { | 3578 | { |
| 3470 | struct xdr_stream xdr; | 3579 | struct xdr_stream xdr; |
| 3471 | struct compound_hdr hdr; | 3580 | struct compound_hdr hdr; |
| @@ -3480,7 +3589,17 @@ static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_ch | |||
| 3480 | goto out; | 3589 | goto out; |
| 3481 | if ((status = decode_putfh(&xdr)) != 0) | 3590 | if ((status = decode_putfh(&xdr)) != 0) |
| 3482 | goto out; | 3591 | goto out; |
| 3483 | status = decode_link(&xdr, cinfo); | 3592 | if ((status = decode_link(&xdr, &res->cinfo)) != 0) |
| 3593 | goto out; | ||
| 3594 | /* | ||
| 3595 | * Note order: OP_LINK leaves the directory as the current | ||
| 3596 | * filehandle. | ||
| 3597 | */ | ||
| 3598 | if (decode_getfattr(&xdr, res->dir_attr, res->server) != 0) | ||
| 3599 | goto out; | ||
| 3600 | if ((status = decode_restorefh(&xdr)) != 0) | ||
| 3601 | goto out; | ||
| 3602 | decode_getfattr(&xdr, res->fattr, res->server); | ||
| 3484 | out: | 3603 | out: |
| 3485 | return status; | 3604 | return status; |
| 3486 | } | 3605 | } |
| @@ -3499,13 +3618,17 @@ static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_ | |||
| 3499 | goto out; | 3618 | goto out; |
| 3500 | if ((status = decode_putfh(&xdr)) != 0) | 3619 | if ((status = decode_putfh(&xdr)) != 0) |
| 3501 | goto out; | 3620 | goto out; |
| 3621 | if ((status = decode_savefh(&xdr)) != 0) | ||
| 3622 | goto out; | ||
| 3502 | if ((status = decode_create(&xdr,&res->dir_cinfo)) != 0) | 3623 | if ((status = decode_create(&xdr,&res->dir_cinfo)) != 0) |
| 3503 | goto out; | 3624 | goto out; |
| 3504 | if ((status = decode_getfh(&xdr, res->fh)) != 0) | 3625 | if ((status = decode_getfh(&xdr, res->fh)) != 0) |
| 3505 | goto out; | 3626 | goto out; |
| 3506 | status = decode_getfattr(&xdr, res->fattr, res->server); | 3627 | if (decode_getfattr(&xdr, res->fattr, res->server) != 0) |
| 3507 | if (status == NFS4ERR_DELAY) | 3628 | goto out; |
| 3508 | status = 0; | 3629 | if ((status = decode_restorefh(&xdr)) != 0) |
| 3630 | goto out; | ||
| 3631 | decode_getfattr(&xdr, res->dir_fattr, res->server); | ||
| 3509 | out: | 3632 | out: |
| 3510 | return status; | 3633 | return status; |
| 3511 | } | 3634 | } |
| @@ -3623,6 +3746,15 @@ static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_cl | |||
| 3623 | if (status) | 3746 | if (status) |
| 3624 | goto out; | 3747 | goto out; |
| 3625 | status = decode_close(&xdr, res); | 3748 | status = decode_close(&xdr, res); |
| 3749 | if (status != 0) | ||
| 3750 | goto out; | ||
| 3751 | /* | ||
| 3752 | * Note: Server may do delete on close for this file | ||
| 3753 | * in which case the getattr call will fail with | ||
| 3754 | * an ESTALE error. Shouldn't be a problem, | ||
| 3755 | * though, since fattr->valid will remain unset. | ||
| 3756 | */ | ||
| 3757 | decode_getfattr(&xdr, res->fattr, res->server); | ||
| 3626 | out: | 3758 | out: |
| 3627 | return status; | 3759 | return status; |
| 3628 | } | 3760 | } |
| @@ -3643,15 +3775,20 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_ope | |||
| 3643 | status = decode_putfh(&xdr); | 3775 | status = decode_putfh(&xdr); |
| 3644 | if (status) | 3776 | if (status) |
| 3645 | goto out; | 3777 | goto out; |
| 3778 | status = decode_savefh(&xdr); | ||
| 3779 | if (status) | ||
| 3780 | goto out; | ||
| 3646 | status = decode_open(&xdr, res); | 3781 | status = decode_open(&xdr, res); |
| 3647 | if (status) | 3782 | if (status) |
| 3648 | goto out; | 3783 | goto out; |
| 3649 | status = decode_getfh(&xdr, &res->fh); | 3784 | status = decode_getfh(&xdr, &res->fh); |
| 3650 | if (status) | 3785 | if (status) |
| 3651 | goto out; | 3786 | goto out; |
| 3652 | status = decode_getfattr(&xdr, res->f_attr, res->server); | 3787 | if (decode_getfattr(&xdr, res->f_attr, res->server) != 0) |
| 3653 | if (status == NFS4ERR_DELAY) | 3788 | goto out; |
| 3654 | status = 0; | 3789 | if ((status = decode_restorefh(&xdr)) != 0) |
| 3790 | goto out; | ||
| 3791 | decode_getfattr(&xdr, res->dir_attr, res->server); | ||
| 3655 | out: | 3792 | out: |
| 3656 | return status; | 3793 | return status; |
| 3657 | } | 3794 | } |
| @@ -3869,6 +4006,9 @@ static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_wr | |||
| 3869 | if (status) | 4006 | if (status) |
| 3870 | goto out; | 4007 | goto out; |
| 3871 | status = decode_write(&xdr, res); | 4008 | status = decode_write(&xdr, res); |
| 4009 | if (status) | ||
| 4010 | goto out; | ||
| 4011 | decode_getfattr(&xdr, res->fattr, res->server); | ||
| 3872 | if (!status) | 4012 | if (!status) |
| 3873 | status = res->count; | 4013 | status = res->count; |
| 3874 | out: | 4014 | out: |
| @@ -3892,6 +4032,9 @@ static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_w | |||
| 3892 | if (status) | 4032 | if (status) |
| 3893 | goto out; | 4033 | goto out; |
| 3894 | status = decode_commit(&xdr, res); | 4034 | status = decode_commit(&xdr, res); |
| 4035 | if (status) | ||
| 4036 | goto out; | ||
| 4037 | decode_getfattr(&xdr, res->fattr, res->server); | ||
| 3895 | out: | 4038 | out: |
| 3896 | return status; | 4039 | return status; |
| 3897 | } | 4040 | } |
