aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/nfs4proc.c27
-rw-r--r--fs/nfs/nfs4xdr.c25
-rw-r--r--include/linux/nfs_xdr.h7
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
1615static int _nfs4_proc_remove(struct inode *dir, struct qstr *name) 1615static 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
1647struct unlink_desc { 1656struct 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
1652static int nfs4_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir, 1662static 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);
1343out:
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 */
3515static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_change_info *cinfo) 3521static 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);
3526out: 3535out:
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 {
623struct nfs4_remove_arg { 623struct 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
629struct 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
628struct nfs4_rename_arg { 635struct nfs4_rename_arg {