aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/nfs4proc.c28
-rw-r--r--fs/nfs/nfs4xdr.c69
-rw-r--r--include/linux/nfs_xdr.h2
3 files changed, 84 insertions, 15 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 3274f2d354f3..f363fd6c7f4d 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -443,7 +443,11 @@ static int _nfs4_proc_open(struct inode *dir, struct nfs4_state_owner *sp, stru
443 nfs_increment_open_seqid(status, o_arg->seqid); 443 nfs_increment_open_seqid(status, o_arg->seqid);
444 if (status != 0) 444 if (status != 0)
445 goto out; 445 goto out;
446 update_changeattr(dir, &o_res->cinfo); 446 if (o_arg->open_flags & O_CREAT) {
447 update_changeattr(dir, &o_res->cinfo);
448 nfs_post_op_update_inode(dir, o_res->dir_attr);
449 } else
450 nfs_refresh_inode(dir, o_res->dir_attr);
447 if(o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) { 451 if(o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) {
448 status = _nfs4_proc_open_confirm(server->client, &o_res->fh, 452 status = _nfs4_proc_open_confirm(server->client, &o_res->fh,
449 sp, &o_res->stateid, o_arg->seqid); 453 sp, &o_res->stateid, o_arg->seqid);
@@ -497,7 +501,7 @@ static int _nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st
497 struct inode *inode = state->inode; 501 struct inode *inode = state->inode;
498 struct nfs_server *server = NFS_SERVER(dir); 502 struct nfs_server *server = NFS_SERVER(dir);
499 struct nfs_delegation *delegation = NFS_I(inode)->delegation; 503 struct nfs_delegation *delegation = NFS_I(inode)->delegation;
500 struct nfs_fattr f_attr; 504 struct nfs_fattr f_attr, dir_attr;
501 struct nfs_openargs o_arg = { 505 struct nfs_openargs o_arg = {
502 .fh = NFS_FH(dir), 506 .fh = NFS_FH(dir),
503 .open_flags = state->state, 507 .open_flags = state->state,
@@ -507,6 +511,7 @@ static int _nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st
507 }; 511 };
508 struct nfs_openres o_res = { 512 struct nfs_openres o_res = {
509 .f_attr = &f_attr, 513 .f_attr = &f_attr,
514 .dir_attr = &dir_attr,
510 .server = server, 515 .server = server,
511 }; 516 };
512 int status = 0; 517 int status = 0;
@@ -524,6 +529,7 @@ static int _nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st
524 if (o_arg.seqid == NULL) 529 if (o_arg.seqid == NULL)
525 goto out; 530 goto out;
526 nfs_fattr_init(&f_attr); 531 nfs_fattr_init(&f_attr);
532 nfs_fattr_init(&dir_attr);
527 status = _nfs4_proc_open(dir, sp, &o_arg, &o_res); 533 status = _nfs4_proc_open(dir, sp, &o_arg, &o_res);
528 if (status != 0) 534 if (status != 0)
529 goto out_nodeleg; 535 goto out_nodeleg;
@@ -694,7 +700,7 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
694 struct nfs4_client *clp = server->nfs4_state; 700 struct nfs4_client *clp = server->nfs4_state;
695 struct inode *inode = NULL; 701 struct inode *inode = NULL;
696 int status; 702 int status;
697 struct nfs_fattr f_attr; 703 struct nfs_fattr f_attr, dir_attr;
698 struct nfs_openargs o_arg = { 704 struct nfs_openargs o_arg = {
699 .fh = NFS_FH(dir), 705 .fh = NFS_FH(dir),
700 .open_flags = flags, 706 .open_flags = flags,
@@ -705,6 +711,7 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
705 }; 711 };
706 struct nfs_openres o_res = { 712 struct nfs_openres o_res = {
707 .f_attr = &f_attr, 713 .f_attr = &f_attr,
714 .dir_attr = &dir_attr,
708 .server = server, 715 .server = server,
709 }; 716 };
710 717
@@ -727,6 +734,7 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
727 if (o_arg.seqid == NULL) 734 if (o_arg.seqid == NULL)
728 return -ENOMEM; 735 return -ENOMEM;
729 nfs_fattr_init(&f_attr); 736 nfs_fattr_init(&f_attr);
737 nfs_fattr_init(&dir_attr);
730 status = _nfs4_proc_open(dir, sp, &o_arg, &o_res); 738 status = _nfs4_proc_open(dir, sp, &o_arg, &o_res);
731 if (status != 0) 739 if (status != 0)
732 goto out_err; 740 goto out_err;
@@ -1746,6 +1754,7 @@ static int _nfs4_proc_symlink(struct inode *dir, struct qstr *name,
1746 struct nfs_fattr *fattr) 1754 struct nfs_fattr *fattr)
1747{ 1755{
1748 struct nfs_server *server = NFS_SERVER(dir); 1756 struct nfs_server *server = NFS_SERVER(dir);
1757 struct nfs_fattr dir_fattr;
1749 struct nfs4_create_arg arg = { 1758 struct nfs4_create_arg arg = {
1750 .dir_fh = NFS_FH(dir), 1759 .dir_fh = NFS_FH(dir),
1751 .server = server, 1760 .server = server,
@@ -1758,6 +1767,7 @@ static int _nfs4_proc_symlink(struct inode *dir, struct qstr *name,
1758 .server = server, 1767 .server = server,
1759 .fh = fhandle, 1768 .fh = fhandle,
1760 .fattr = fattr, 1769 .fattr = fattr,
1770 .dir_fattr = &dir_fattr,
1761 }; 1771 };
1762 struct rpc_message msg = { 1772 struct rpc_message msg = {
1763 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SYMLINK], 1773 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SYMLINK],
@@ -1770,10 +1780,12 @@ static int _nfs4_proc_symlink(struct inode *dir, struct qstr *name,
1770 return -ENAMETOOLONG; 1780 return -ENAMETOOLONG;
1771 arg.u.symlink = path; 1781 arg.u.symlink = path;
1772 nfs_fattr_init(fattr); 1782 nfs_fattr_init(fattr);
1783 nfs_fattr_init(&dir_fattr);
1773 1784
1774 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); 1785 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
1775 if (!status) 1786 if (!status)
1776 update_changeattr(dir, &res.dir_cinfo); 1787 update_changeattr(dir, &res.dir_cinfo);
1788 nfs_post_op_update_inode(dir, res.dir_fattr);
1777 return status; 1789 return status;
1778} 1790}
1779 1791
@@ -1797,7 +1809,7 @@ static int _nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
1797{ 1809{
1798 struct nfs_server *server = NFS_SERVER(dir); 1810 struct nfs_server *server = NFS_SERVER(dir);
1799 struct nfs_fh fhandle; 1811 struct nfs_fh fhandle;
1800 struct nfs_fattr fattr; 1812 struct nfs_fattr fattr, dir_fattr;
1801 struct nfs4_create_arg arg = { 1813 struct nfs4_create_arg arg = {
1802 .dir_fh = NFS_FH(dir), 1814 .dir_fh = NFS_FH(dir),
1803 .server = server, 1815 .server = server,
@@ -1810,6 +1822,7 @@ static int _nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
1810 .server = server, 1822 .server = server,
1811 .fh = &fhandle, 1823 .fh = &fhandle,
1812 .fattr = &fattr, 1824 .fattr = &fattr,
1825 .dir_fattr = &dir_fattr,
1813 }; 1826 };
1814 struct rpc_message msg = { 1827 struct rpc_message msg = {
1815 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE], 1828 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE],
@@ -1819,10 +1832,12 @@ static int _nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
1819 int status; 1832 int status;
1820 1833
1821 nfs_fattr_init(&fattr); 1834 nfs_fattr_init(&fattr);
1835 nfs_fattr_init(&dir_fattr);
1822 1836
1823 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); 1837 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
1824 if (!status) { 1838 if (!status) {
1825 update_changeattr(dir, &res.dir_cinfo); 1839 update_changeattr(dir, &res.dir_cinfo);
1840 nfs_post_op_update_inode(dir, res.dir_fattr);
1826 status = nfs_instantiate(dentry, &fhandle, &fattr); 1841 status = nfs_instantiate(dentry, &fhandle, &fattr);
1827 } 1842 }
1828 return status; 1843 return status;
@@ -1895,7 +1910,7 @@ static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
1895{ 1910{
1896 struct nfs_server *server = NFS_SERVER(dir); 1911 struct nfs_server *server = NFS_SERVER(dir);
1897 struct nfs_fh fh; 1912 struct nfs_fh fh;
1898 struct nfs_fattr fattr; 1913 struct nfs_fattr fattr, dir_fattr;
1899 struct nfs4_create_arg arg = { 1914 struct nfs4_create_arg arg = {
1900 .dir_fh = NFS_FH(dir), 1915 .dir_fh = NFS_FH(dir),
1901 .server = server, 1916 .server = server,
@@ -1907,6 +1922,7 @@ static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
1907 .server = server, 1922 .server = server,
1908 .fh = &fh, 1923 .fh = &fh,
1909 .fattr = &fattr, 1924 .fattr = &fattr,
1925 .dir_fattr = &dir_fattr,
1910 }; 1926 };
1911 struct rpc_message msg = { 1927 struct rpc_message msg = {
1912 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE], 1928 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE],
@@ -1917,6 +1933,7 @@ static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
1917 int mode = sattr->ia_mode; 1933 int mode = sattr->ia_mode;
1918 1934
1919 nfs_fattr_init(&fattr); 1935 nfs_fattr_init(&fattr);
1936 nfs_fattr_init(&dir_fattr);
1920 1937
1921 BUG_ON(!(sattr->ia_valid & ATTR_MODE)); 1938 BUG_ON(!(sattr->ia_valid & ATTR_MODE));
1922 BUG_ON(!S_ISFIFO(mode) && !S_ISBLK(mode) && !S_ISCHR(mode) && !S_ISSOCK(mode)); 1939 BUG_ON(!S_ISFIFO(mode) && !S_ISBLK(mode) && !S_ISCHR(mode) && !S_ISSOCK(mode));
@@ -1938,6 +1955,7 @@ static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
1938 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); 1955 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
1939 if (status == 0) { 1956 if (status == 0) {
1940 update_changeattr(dir, &res.dir_cinfo); 1957 update_changeattr(dir, &res.dir_cinfo);
1958 nfs_post_op_update_inode(dir, res.dir_fattr);
1941 status = nfs_instantiate(dentry, &fh, &fattr); 1959 status = nfs_instantiate(dentry, &fh, &fattr);
1942 } 1960 }
1943 return status; 1961 return status;
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 8b21de8a06fa..7f91d613d31a 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)
@@ -336,14 +338,20 @@ static int nfs_stat_to_errno(int);
336 decode_getfh_maxsz) 338 decode_getfh_maxsz)
337#define NFS4_enc_create_sz (compound_encode_hdr_maxsz + \ 339#define NFS4_enc_create_sz (compound_encode_hdr_maxsz + \
338 encode_putfh_maxsz + \ 340 encode_putfh_maxsz + \
341 encode_savefh_maxsz + \
339 encode_create_maxsz + \ 342 encode_create_maxsz + \
343 encode_getfh_maxsz + \
340 encode_getattr_maxsz + \ 344 encode_getattr_maxsz + \
341 encode_getfh_maxsz) 345 encode_restorefh_maxsz + \
346 encode_getattr_maxsz)
342#define NFS4_dec_create_sz (compound_decode_hdr_maxsz + \ 347#define NFS4_dec_create_sz (compound_decode_hdr_maxsz + \
343 decode_putfh_maxsz + \ 348 decode_putfh_maxsz + \
349 decode_savefh_maxsz + \
344 decode_create_maxsz + \ 350 decode_create_maxsz + \
351 decode_getfh_maxsz + \
345 decode_getattr_maxsz + \ 352 decode_getattr_maxsz + \
346 decode_getfh_maxsz) 353 decode_restorefh_maxsz + \
354 decode_getattr_maxsz)
347#define NFS4_enc_pathconf_sz (compound_encode_hdr_maxsz + \ 355#define NFS4_enc_pathconf_sz (compound_encode_hdr_maxsz + \
348 encode_putfh_maxsz + \ 356 encode_putfh_maxsz + \
349 encode_getattr_maxsz) 357 encode_getattr_maxsz)
@@ -1113,6 +1121,17 @@ static int encode_renew(struct xdr_stream *xdr, const struct nfs4_client *client
1113} 1121}
1114 1122
1115static int 1123static int
1124encode_restorefh(struct xdr_stream *xdr)
1125{
1126 uint32_t *p;
1127
1128 RESERVE_SPACE(4);
1129 WRITE32(OP_RESTOREFH);
1130
1131 return 0;
1132}
1133
1134static int
1116encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg) 1135encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg)
1117{ 1136{
1118 uint32_t *p; 1137 uint32_t *p;
@@ -1358,7 +1377,7 @@ static int nfs4_xdr_enc_create(struct rpc_rqst *req, uint32_t *p, const struct n
1358{ 1377{
1359 struct xdr_stream xdr; 1378 struct xdr_stream xdr;
1360 struct compound_hdr hdr = { 1379 struct compound_hdr hdr = {
1361 .nops = 4, 1380 .nops = 7,
1362 }; 1381 };
1363 int status; 1382 int status;
1364 1383
@@ -1366,10 +1385,16 @@ static int nfs4_xdr_enc_create(struct rpc_rqst *req, uint32_t *p, const struct n
1366 encode_compound_hdr(&xdr, &hdr); 1385 encode_compound_hdr(&xdr, &hdr);
1367 if ((status = encode_putfh(&xdr, args->dir_fh)) != 0) 1386 if ((status = encode_putfh(&xdr, args->dir_fh)) != 0)
1368 goto out; 1387 goto out;
1388 if ((status = encode_savefh(&xdr)) != 0)
1389 goto out;
1369 if ((status = encode_create(&xdr, args)) != 0) 1390 if ((status = encode_create(&xdr, args)) != 0)
1370 goto out; 1391 goto out;
1371 if ((status = encode_getfh(&xdr)) != 0) 1392 if ((status = encode_getfh(&xdr)) != 0)
1372 goto out; 1393 goto out;
1394 if ((status = encode_getfattr(&xdr, args->bitmask)) != 0)
1395 goto out;
1396 if ((status = encode_restorefh(&xdr)) != 0)
1397 goto out;
1373 status = encode_getfattr(&xdr, args->bitmask); 1398 status = encode_getfattr(&xdr, args->bitmask);
1374out: 1399out:
1375 return status; 1400 return status;
@@ -1429,7 +1454,7 @@ static int nfs4_xdr_enc_open(struct rpc_rqst *req, uint32_t *p, struct nfs_opena
1429{ 1454{
1430 struct xdr_stream xdr; 1455 struct xdr_stream xdr;
1431 struct compound_hdr hdr = { 1456 struct compound_hdr hdr = {
1432 .nops = 4, 1457 .nops = 7,
1433 }; 1458 };
1434 int status; 1459 int status;
1435 1460
@@ -1441,6 +1466,9 @@ static int nfs4_xdr_enc_open(struct rpc_rqst *req, uint32_t *p, struct nfs_opena
1441 status = encode_putfh(&xdr, args->fh); 1466 status = encode_putfh(&xdr, args->fh);
1442 if (status) 1467 if (status)
1443 goto out; 1468 goto out;
1469 status = encode_savefh(&xdr);
1470 if (status)
1471 goto out;
1444 status = encode_open(&xdr, args); 1472 status = encode_open(&xdr, args);
1445 if (status) 1473 if (status)
1446 goto out; 1474 goto out;
@@ -1448,6 +1476,12 @@ static int nfs4_xdr_enc_open(struct rpc_rqst *req, uint32_t *p, struct nfs_opena
1448 if (status) 1476 if (status)
1449 goto out; 1477 goto out;
1450 status = encode_getfattr(&xdr, args->bitmask); 1478 status = encode_getfattr(&xdr, args->bitmask);
1479 if (status)
1480 goto out;
1481 status = encode_restorefh(&xdr);
1482 if (status)
1483 goto out;
1484 status = encode_getfattr(&xdr, args->bitmask);
1451out: 1485out:
1452 return status; 1486 return status;
1453} 1487}
@@ -3218,6 +3252,12 @@ static int decode_renew(struct xdr_stream *xdr)
3218 return decode_op_hdr(xdr, OP_RENEW); 3252 return decode_op_hdr(xdr, OP_RENEW);
3219} 3253}
3220 3254
3255static int
3256decode_restorefh(struct xdr_stream *xdr)
3257{
3258 return decode_op_hdr(xdr, OP_RESTOREFH);
3259}
3260
3221static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, 3261static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
3222 size_t *acl_len) 3262 size_t *acl_len)
3223{ 3263{
@@ -3510,13 +3550,17 @@ static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_
3510 goto out; 3550 goto out;
3511 if ((status = decode_putfh(&xdr)) != 0) 3551 if ((status = decode_putfh(&xdr)) != 0)
3512 goto out; 3552 goto out;
3553 if ((status = decode_savefh(&xdr)) != 0)
3554 goto out;
3513 if ((status = decode_create(&xdr,&res->dir_cinfo)) != 0) 3555 if ((status = decode_create(&xdr,&res->dir_cinfo)) != 0)
3514 goto out; 3556 goto out;
3515 if ((status = decode_getfh(&xdr, res->fh)) != 0) 3557 if ((status = decode_getfh(&xdr, res->fh)) != 0)
3516 goto out; 3558 goto out;
3517 status = decode_getfattr(&xdr, res->fattr, res->server); 3559 if (decode_getfattr(&xdr, res->fattr, res->server) != 0)
3518 if (status == NFS4ERR_DELAY) 3560 goto out;
3519 status = 0; 3561 if ((status = decode_restorefh(&xdr)) != 0)
3562 goto out;
3563 decode_getfattr(&xdr, res->dir_fattr, res->server);
3520out: 3564out:
3521 return status; 3565 return status;
3522} 3566}
@@ -3654,15 +3698,20 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_ope
3654 status = decode_putfh(&xdr); 3698 status = decode_putfh(&xdr);
3655 if (status) 3699 if (status)
3656 goto out; 3700 goto out;
3701 status = decode_savefh(&xdr);
3702 if (status)
3703 goto out;
3657 status = decode_open(&xdr, res); 3704 status = decode_open(&xdr, res);
3658 if (status) 3705 if (status)
3659 goto out; 3706 goto out;
3660 status = decode_getfh(&xdr, &res->fh); 3707 status = decode_getfh(&xdr, &res->fh);
3661 if (status) 3708 if (status)
3662 goto out; 3709 goto out;
3663 status = decode_getfattr(&xdr, res->f_attr, res->server); 3710 if (decode_getfattr(&xdr, res->f_attr, res->server) != 0)
3664 if (status == NFS4ERR_DELAY) 3711 goto out;
3665 status = 0; 3712 if ((status = decode_restorefh(&xdr)) != 0)
3713 goto out;
3714 decode_getfattr(&xdr, res->dir_attr, res->server);
3666out: 3715out:
3667 return status; 3716 return status;
3668} 3717}
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index aeaee7e7c51d..6485b8b41b83 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -124,6 +124,7 @@ struct nfs_openres {
124 struct nfs4_change_info cinfo; 124 struct nfs4_change_info cinfo;
125 __u32 rflags; 125 __u32 rflags;
126 struct nfs_fattr * f_attr; 126 struct nfs_fattr * f_attr;
127 struct nfs_fattr * dir_attr;
127 const struct nfs_server *server; 128 const struct nfs_server *server;
128 int delegation_type; 129 int delegation_type;
129 nfs4_stateid delegation; 130 nfs4_stateid delegation;
@@ -540,6 +541,7 @@ struct nfs4_create_res {
540 struct nfs_fh * fh; 541 struct nfs_fh * fh;
541 struct nfs_fattr * fattr; 542 struct nfs_fattr * fattr;
542 struct nfs4_change_info dir_cinfo; 543 struct nfs4_change_info dir_cinfo;
544 struct nfs_fattr * dir_fattr;
543}; 545};
544 546
545struct nfs4_fsinfo_arg { 547struct nfs4_fsinfo_arg {