diff options
-rw-r--r-- | fs/nfs/nfs4proc.c | 27 | ||||
-rw-r--r-- | fs/nfs/nfs4xdr.c | 25 | ||||
-rw-r--r-- | include/linux/nfs_xdr.h | 7 |
3 files changed, 45 insertions, 14 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index f96bc12c0fa0..bab47c4cb41c 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -1614,11 +1614,17 @@ out: | |||
1614 | 1614 | ||
1615 | static int _nfs4_proc_remove(struct inode *dir, struct qstr *name) | 1615 | static int _nfs4_proc_remove(struct inode *dir, struct qstr *name) |
1616 | { | 1616 | { |
1617 | struct nfs_server *server = NFS_SERVER(dir); | ||
1617 | struct nfs4_remove_arg args = { | 1618 | struct nfs4_remove_arg args = { |
1618 | .fh = NFS_FH(dir), | 1619 | .fh = NFS_FH(dir), |
1619 | .name = name, | 1620 | .name = name, |
1621 | .bitmask = server->attr_bitmask, | ||
1622 | }; | ||
1623 | struct nfs_fattr dir_attr; | ||
1624 | struct nfs4_remove_res res = { | ||
1625 | .server = server, | ||
1626 | .dir_attr = &dir_attr, | ||
1620 | }; | 1627 | }; |
1621 | struct nfs4_change_info res; | ||
1622 | struct rpc_message msg = { | 1628 | struct rpc_message msg = { |
1623 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE], | 1629 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE], |
1624 | .rpc_argp = &args, | 1630 | .rpc_argp = &args, |
@@ -1626,9 +1632,12 @@ static int _nfs4_proc_remove(struct inode *dir, struct qstr *name) | |||
1626 | }; | 1632 | }; |
1627 | int status; | 1633 | int status; |
1628 | 1634 | ||
1629 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); | 1635 | nfs_fattr_init(res.dir_attr); |
1630 | if (status == 0) | 1636 | status = rpc_call_sync(server->client, &msg, 0); |
1631 | update_changeattr(dir, &res); | 1637 | if (status == 0) { |
1638 | update_changeattr(dir, &res.cinfo); | ||
1639 | nfs_post_op_update_inode(dir, res.dir_attr); | ||
1640 | } | ||
1632 | return status; | 1641 | return status; |
1633 | } | 1642 | } |
1634 | 1643 | ||
@@ -1646,12 +1655,14 @@ static int nfs4_proc_remove(struct inode *dir, struct qstr *name) | |||
1646 | 1655 | ||
1647 | struct unlink_desc { | 1656 | struct unlink_desc { |
1648 | struct nfs4_remove_arg args; | 1657 | struct nfs4_remove_arg args; |
1649 | struct nfs4_change_info res; | 1658 | struct nfs4_remove_res res; |
1659 | struct nfs_fattr dir_attr; | ||
1650 | }; | 1660 | }; |
1651 | 1661 | ||
1652 | static int nfs4_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir, | 1662 | static int nfs4_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir, |
1653 | struct qstr *name) | 1663 | struct qstr *name) |
1654 | { | 1664 | { |
1665 | struct nfs_server *server = NFS_SERVER(dir->d_inode); | ||
1655 | struct unlink_desc *up; | 1666 | struct unlink_desc *up; |
1656 | 1667 | ||
1657 | up = (struct unlink_desc *) kmalloc(sizeof(*up), GFP_KERNEL); | 1668 | up = (struct unlink_desc *) kmalloc(sizeof(*up), GFP_KERNEL); |
@@ -1660,6 +1671,9 @@ static int nfs4_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir, | |||
1660 | 1671 | ||
1661 | up->args.fh = NFS_FH(dir->d_inode); | 1672 | up->args.fh = NFS_FH(dir->d_inode); |
1662 | up->args.name = name; | 1673 | up->args.name = name; |
1674 | up->args.bitmask = server->attr_bitmask; | ||
1675 | up->res.server = server; | ||
1676 | up->res.dir_attr = &up->dir_attr; | ||
1663 | 1677 | ||
1664 | msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE]; | 1678 | msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE]; |
1665 | msg->rpc_argp = &up->args; | 1679 | msg->rpc_argp = &up->args; |
@@ -1674,7 +1688,8 @@ static int nfs4_proc_unlink_done(struct dentry *dir, struct rpc_task *task) | |||
1674 | 1688 | ||
1675 | if (msg->rpc_resp != NULL) { | 1689 | if (msg->rpc_resp != NULL) { |
1676 | up = container_of(msg->rpc_resp, struct unlink_desc, res); | 1690 | up = container_of(msg->rpc_resp, struct unlink_desc, res); |
1677 | update_changeattr(dir->d_inode, &up->res); | 1691 | update_changeattr(dir->d_inode, &up->res.cinfo); |
1692 | nfs_post_op_update_inode(dir->d_inode, up->res.dir_attr); | ||
1678 | kfree(up); | 1693 | kfree(up); |
1679 | msg->rpc_resp = NULL; | 1694 | msg->rpc_resp = NULL; |
1680 | msg->rpc_argp = NULL; | 1695 | msg->rpc_argp = NULL; |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 2a07755bd347..3ee3a1669d28 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -306,10 +306,12 @@ static int nfs_stat_to_errno(int); | |||
306 | decode_getfh_maxsz) | 306 | decode_getfh_maxsz) |
307 | #define NFS4_enc_remove_sz (compound_encode_hdr_maxsz + \ | 307 | #define NFS4_enc_remove_sz (compound_encode_hdr_maxsz + \ |
308 | encode_putfh_maxsz + \ | 308 | encode_putfh_maxsz + \ |
309 | encode_remove_maxsz) | 309 | encode_remove_maxsz + \ |
310 | encode_getattr_maxsz) | ||
310 | #define NFS4_dec_remove_sz (compound_decode_hdr_maxsz + \ | 311 | #define NFS4_dec_remove_sz (compound_decode_hdr_maxsz + \ |
311 | decode_putfh_maxsz + \ | 312 | decode_putfh_maxsz + \ |
312 | op_decode_hdr_maxsz + 5) | 313 | op_decode_hdr_maxsz + 5 + \ |
314 | decode_getattr_maxsz) | ||
313 | #define NFS4_enc_rename_sz (compound_encode_hdr_maxsz + \ | 315 | #define NFS4_enc_rename_sz (compound_encode_hdr_maxsz + \ |
314 | encode_putfh_maxsz + \ | 316 | encode_putfh_maxsz + \ |
315 | encode_savefh_maxsz + \ | 317 | encode_savefh_maxsz + \ |
@@ -1327,14 +1329,18 @@ static int nfs4_xdr_enc_remove(struct rpc_rqst *req, uint32_t *p, const struct n | |||
1327 | { | 1329 | { |
1328 | struct xdr_stream xdr; | 1330 | struct xdr_stream xdr; |
1329 | struct compound_hdr hdr = { | 1331 | struct compound_hdr hdr = { |
1330 | .nops = 2, | 1332 | .nops = 3, |
1331 | }; | 1333 | }; |
1332 | int status; | 1334 | int status; |
1333 | 1335 | ||
1334 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 1336 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); |
1335 | encode_compound_hdr(&xdr, &hdr); | 1337 | encode_compound_hdr(&xdr, &hdr); |
1336 | if ((status = encode_putfh(&xdr, args->fh)) == 0) | 1338 | if ((status = encode_putfh(&xdr, args->fh)) != 0) |
1337 | status = encode_remove(&xdr, args->name); | 1339 | goto out; |
1340 | if ((status = encode_remove(&xdr, args->name)) != 0) | ||
1341 | goto out; | ||
1342 | status = encode_getfattr(&xdr, args->bitmask); | ||
1343 | out: | ||
1338 | return status; | 1344 | return status; |
1339 | } | 1345 | } |
1340 | 1346 | ||
@@ -3512,7 +3518,7 @@ out: | |||
3512 | /* | 3518 | /* |
3513 | * Decode REMOVE response | 3519 | * Decode REMOVE response |
3514 | */ | 3520 | */ |
3515 | static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_change_info *cinfo) | 3521 | static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_remove_res *res) |
3516 | { | 3522 | { |
3517 | struct xdr_stream xdr; | 3523 | struct xdr_stream xdr; |
3518 | struct compound_hdr hdr; | 3524 | struct compound_hdr hdr; |
@@ -3521,8 +3527,11 @@ static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_ | |||
3521 | xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); | 3527 | xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); |
3522 | if ((status = decode_compound_hdr(&xdr, &hdr)) != 0) | 3528 | if ((status = decode_compound_hdr(&xdr, &hdr)) != 0) |
3523 | goto out; | 3529 | goto out; |
3524 | if ((status = decode_putfh(&xdr)) == 0) | 3530 | if ((status = decode_putfh(&xdr)) != 0) |
3525 | status = decode_remove(&xdr, cinfo); | 3531 | goto out; |
3532 | if ((status = decode_remove(&xdr, &res->cinfo)) != 0) | ||
3533 | goto out; | ||
3534 | decode_getfattr(&xdr, res->dir_attr, res->server); | ||
3526 | out: | 3535 | out: |
3527 | return status; | 3536 | return status; |
3528 | } | 3537 | } |
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 6f0804280824..deeba7e2c518 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h | |||
@@ -623,6 +623,13 @@ struct nfs4_readlink { | |||
623 | struct nfs4_remove_arg { | 623 | struct nfs4_remove_arg { |
624 | const struct nfs_fh * fh; | 624 | const struct nfs_fh * fh; |
625 | const struct qstr * name; | 625 | const struct qstr * name; |
626 | const u32 * bitmask; | ||
627 | }; | ||
628 | |||
629 | struct nfs4_remove_res { | ||
630 | const struct nfs_server * server; | ||
631 | struct nfs4_change_info cinfo; | ||
632 | struct nfs_fattr * dir_attr; | ||
626 | }; | 633 | }; |
627 | 634 | ||
628 | struct nfs4_rename_arg { | 635 | struct nfs4_rename_arg { |