aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c438
1 files changed, 286 insertions, 152 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index d86c0db7b1e8..47c7e6e3910d 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -55,7 +55,7 @@
55 55
56#define NFSDBG_FACILITY NFSDBG_PROC 56#define NFSDBG_FACILITY NFSDBG_PROC
57 57
58#define NFS4_POLL_RETRY_MIN (1*HZ) 58#define NFS4_POLL_RETRY_MIN (HZ/10)
59#define NFS4_POLL_RETRY_MAX (15*HZ) 59#define NFS4_POLL_RETRY_MAX (15*HZ)
60 60
61struct nfs4_opendata; 61struct nfs4_opendata;
@@ -64,9 +64,7 @@ static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinf
64static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *); 64static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *);
65static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry); 65static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry);
66static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception); 66static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception);
67static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs4_client *clp); 67static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs_client *clp);
68extern u32 *nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus);
69extern struct rpc_procinfo nfs4_procedures[];
70 68
71/* Prevent leaks of NFSv4 errors into userland */ 69/* Prevent leaks of NFSv4 errors into userland */
72int nfs4_map_errors(int err) 70int nfs4_map_errors(int err)
@@ -121,6 +119,25 @@ const u32 nfs4_fsinfo_bitmap[2] = { FATTR4_WORD0_MAXFILESIZE
121 0 119 0
122}; 120};
123 121
122const u32 nfs4_fs_locations_bitmap[2] = {
123 FATTR4_WORD0_TYPE
124 | FATTR4_WORD0_CHANGE
125 | FATTR4_WORD0_SIZE
126 | FATTR4_WORD0_FSID
127 | FATTR4_WORD0_FILEID
128 | FATTR4_WORD0_FS_LOCATIONS,
129 FATTR4_WORD1_MODE
130 | FATTR4_WORD1_NUMLINKS
131 | FATTR4_WORD1_OWNER
132 | FATTR4_WORD1_OWNER_GROUP
133 | FATTR4_WORD1_RAWDEV
134 | FATTR4_WORD1_SPACE_USED
135 | FATTR4_WORD1_TIME_ACCESS
136 | FATTR4_WORD1_TIME_METADATA
137 | FATTR4_WORD1_TIME_MODIFY
138 | FATTR4_WORD1_MOUNTED_ON_FILEID
139};
140
124static void nfs4_setup_readdir(u64 cookie, u32 *verifier, struct dentry *dentry, 141static void nfs4_setup_readdir(u64 cookie, u32 *verifier, struct dentry *dentry,
125 struct nfs4_readdir_arg *readdir) 142 struct nfs4_readdir_arg *readdir)
126{ 143{
@@ -178,22 +195,22 @@ static void nfs4_setup_readdir(u64 cookie, u32 *verifier, struct dentry *dentry,
178 195
179static void renew_lease(const struct nfs_server *server, unsigned long timestamp) 196static void renew_lease(const struct nfs_server *server, unsigned long timestamp)
180{ 197{
181 struct nfs4_client *clp = server->nfs4_state; 198 struct nfs_client *clp = server->nfs_client;
182 spin_lock(&clp->cl_lock); 199 spin_lock(&clp->cl_lock);
183 if (time_before(clp->cl_last_renewal,timestamp)) 200 if (time_before(clp->cl_last_renewal,timestamp))
184 clp->cl_last_renewal = timestamp; 201 clp->cl_last_renewal = timestamp;
185 spin_unlock(&clp->cl_lock); 202 spin_unlock(&clp->cl_lock);
186} 203}
187 204
188static void update_changeattr(struct inode *inode, struct nfs4_change_info *cinfo) 205static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo)
189{ 206{
190 struct nfs_inode *nfsi = NFS_I(inode); 207 struct nfs_inode *nfsi = NFS_I(dir);
191 208
192 spin_lock(&inode->i_lock); 209 spin_lock(&dir->i_lock);
193 nfsi->cache_validity |= NFS_INO_INVALID_ATTR; 210 nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_DATA;
194 if (cinfo->before == nfsi->change_attr && cinfo->atomic) 211 if (cinfo->before == nfsi->change_attr && cinfo->atomic)
195 nfsi->change_attr = cinfo->after; 212 nfsi->change_attr = cinfo->after;
196 spin_unlock(&inode->i_lock); 213 spin_unlock(&dir->i_lock);
197} 214}
198 215
199struct nfs4_opendata { 216struct nfs4_opendata {
@@ -235,7 +252,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
235 atomic_inc(&sp->so_count); 252 atomic_inc(&sp->so_count);
236 p->o_arg.fh = NFS_FH(dir); 253 p->o_arg.fh = NFS_FH(dir);
237 p->o_arg.open_flags = flags, 254 p->o_arg.open_flags = flags,
238 p->o_arg.clientid = server->nfs4_state->cl_clientid; 255 p->o_arg.clientid = server->nfs_client->cl_clientid;
239 p->o_arg.id = sp->so_id; 256 p->o_arg.id = sp->so_id;
240 p->o_arg.name = &dentry->d_name; 257 p->o_arg.name = &dentry->d_name;
241 p->o_arg.server = server; 258 p->o_arg.server = server;
@@ -533,7 +550,7 @@ int nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state)
533 case -NFS4ERR_STALE_STATEID: 550 case -NFS4ERR_STALE_STATEID:
534 case -NFS4ERR_EXPIRED: 551 case -NFS4ERR_EXPIRED:
535 /* Don't recall a delegation if it was lost */ 552 /* Don't recall a delegation if it was lost */
536 nfs4_schedule_state_recovery(server->nfs4_state); 553 nfs4_schedule_state_recovery(server->nfs_client);
537 return err; 554 return err;
538 } 555 }
539 err = nfs4_handle_exception(server, err, &exception); 556 err = nfs4_handle_exception(server, err, &exception);
@@ -741,7 +758,7 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
741 } 758 }
742 nfs_confirm_seqid(&data->owner->so_seqid, 0); 759 nfs_confirm_seqid(&data->owner->so_seqid, 0);
743 if (!(o_res->f_attr->valid & NFS_ATTR_FATTR)) 760 if (!(o_res->f_attr->valid & NFS_ATTR_FATTR))
744 return server->rpc_ops->getattr(server, &o_res->fh, o_res->f_attr); 761 return server->nfs_client->rpc_ops->getattr(server, &o_res->fh, o_res->f_attr);
745 return 0; 762 return 0;
746} 763}
747 764
@@ -775,11 +792,18 @@ out:
775 792
776int nfs4_recover_expired_lease(struct nfs_server *server) 793int nfs4_recover_expired_lease(struct nfs_server *server)
777{ 794{
778 struct nfs4_client *clp = server->nfs4_state; 795 struct nfs_client *clp = server->nfs_client;
796 int ret;
779 797
780 if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) 798 for (;;) {
799 ret = nfs4_wait_clnt_recover(server->client, clp);
800 if (ret != 0)
801 return ret;
802 if (!test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state))
803 break;
781 nfs4_schedule_state_recovery(clp); 804 nfs4_schedule_state_recovery(clp);
782 return nfs4_wait_clnt_recover(server->client, clp); 805 }
806 return 0;
783} 807}
784 808
785/* 809/*
@@ -850,7 +874,7 @@ static int _nfs4_open_delegated(struct inode *inode, int flags, struct rpc_cred
850{ 874{
851 struct nfs_delegation *delegation; 875 struct nfs_delegation *delegation;
852 struct nfs_server *server = NFS_SERVER(inode); 876 struct nfs_server *server = NFS_SERVER(inode);
853 struct nfs4_client *clp = server->nfs4_state; 877 struct nfs_client *clp = server->nfs_client;
854 struct nfs_inode *nfsi = NFS_I(inode); 878 struct nfs_inode *nfsi = NFS_I(inode);
855 struct nfs4_state_owner *sp = NULL; 879 struct nfs4_state_owner *sp = NULL;
856 struct nfs4_state *state = NULL; 880 struct nfs4_state *state = NULL;
@@ -936,7 +960,7 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
936 struct nfs4_state_owner *sp; 960 struct nfs4_state_owner *sp;
937 struct nfs4_state *state = NULL; 961 struct nfs4_state *state = NULL;
938 struct nfs_server *server = NFS_SERVER(dir); 962 struct nfs_server *server = NFS_SERVER(dir);
939 struct nfs4_client *clp = server->nfs4_state; 963 struct nfs_client *clp = server->nfs_client;
940 struct nfs4_opendata *opendata; 964 struct nfs4_opendata *opendata;
941 int status; 965 int status;
942 966
@@ -953,7 +977,7 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
953 status = -ENOMEM; 977 status = -ENOMEM;
954 opendata = nfs4_opendata_alloc(dentry, sp, flags, sattr); 978 opendata = nfs4_opendata_alloc(dentry, sp, flags, sattr);
955 if (opendata == NULL) 979 if (opendata == NULL)
956 goto err_put_state_owner; 980 goto err_release_rwsem;
957 981
958 status = _nfs4_proc_open(opendata); 982 status = _nfs4_proc_open(opendata);
959 if (status != 0) 983 if (status != 0)
@@ -972,11 +996,11 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
972 return 0; 996 return 0;
973err_opendata_free: 997err_opendata_free:
974 nfs4_opendata_free(opendata); 998 nfs4_opendata_free(opendata);
999err_release_rwsem:
1000 up_read(&clp->cl_sem);
975err_put_state_owner: 1001err_put_state_owner:
976 nfs4_put_state_owner(sp); 1002 nfs4_put_state_owner(sp);
977out_err: 1003out_err:
978 /* Note: clp->cl_sem must be released before nfs4_put_open_state()! */
979 up_read(&clp->cl_sem);
980 *res = NULL; 1004 *res = NULL;
981 return status; 1005 return status;
982} 1006}
@@ -1116,7 +1140,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
1116 break; 1140 break;
1117 case -NFS4ERR_STALE_STATEID: 1141 case -NFS4ERR_STALE_STATEID:
1118 case -NFS4ERR_EXPIRED: 1142 case -NFS4ERR_EXPIRED:
1119 nfs4_schedule_state_recovery(server->nfs4_state); 1143 nfs4_schedule_state_recovery(server->nfs_client);
1120 break; 1144 break;
1121 default: 1145 default:
1122 if (nfs4_async_handle_error(task, server) == -EAGAIN) { 1146 if (nfs4_async_handle_error(task, server) == -EAGAIN) {
@@ -1251,7 +1275,7 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
1251 BUG_ON(nd->intent.open.flags & O_CREAT); 1275 BUG_ON(nd->intent.open.flags & O_CREAT);
1252 } 1276 }
1253 1277
1254 cred = rpcauth_lookupcred(NFS_SERVER(dir)->client->cl_auth, 0); 1278 cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0);
1255 if (IS_ERR(cred)) 1279 if (IS_ERR(cred))
1256 return (struct dentry *)cred; 1280 return (struct dentry *)cred;
1257 state = nfs4_do_open(dir, dentry, nd->intent.open.flags, &attr, cred); 1281 state = nfs4_do_open(dir, dentry, nd->intent.open.flags, &attr, cred);
@@ -1274,7 +1298,7 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st
1274 struct rpc_cred *cred; 1298 struct rpc_cred *cred;
1275 struct nfs4_state *state; 1299 struct nfs4_state *state;
1276 1300
1277 cred = rpcauth_lookupcred(NFS_SERVER(dir)->client->cl_auth, 0); 1301 cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0);
1278 if (IS_ERR(cred)) 1302 if (IS_ERR(cred))
1279 return PTR_ERR(cred); 1303 return PTR_ERR(cred);
1280 state = nfs4_open_delegated(dentry->d_inode, openflags, cred); 1304 state = nfs4_open_delegated(dentry->d_inode, openflags, cred);
@@ -1331,7 +1355,7 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
1331 return status; 1355 return status;
1332} 1356}
1333 1357
1334static int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle) 1358int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
1335{ 1359{
1336 struct nfs4_exception exception = { }; 1360 struct nfs4_exception exception = { };
1337 int err; 1361 int err;
@@ -1376,73 +1400,66 @@ static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
1376 return err; 1400 return err;
1377} 1401}
1378 1402
1403/*
1404 * get the file handle for the "/" directory on the server
1405 */
1379static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, 1406static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
1380 struct nfs_fsinfo *info) 1407 struct nfs_fsinfo *info)
1381{ 1408{
1382 struct nfs_fattr * fattr = info->fattr;
1383 unsigned char * p;
1384 struct qstr q;
1385 struct nfs4_lookup_arg args = {
1386 .dir_fh = fhandle,
1387 .name = &q,
1388 .bitmask = nfs4_fattr_bitmap,
1389 };
1390 struct nfs4_lookup_res res = {
1391 .server = server,
1392 .fattr = fattr,
1393 .fh = fhandle,
1394 };
1395 struct rpc_message msg = {
1396 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOOKUP],
1397 .rpc_argp = &args,
1398 .rpc_resp = &res,
1399 };
1400 int status; 1409 int status;
1401 1410
1402 /*
1403 * Now we do a separate LOOKUP for each component of the mount path.
1404 * The LOOKUPs are done separately so that we can conveniently
1405 * catch an ERR_WRONGSEC if it occurs along the way...
1406 */
1407 status = nfs4_lookup_root(server, fhandle, info); 1411 status = nfs4_lookup_root(server, fhandle, info);
1408 if (status)
1409 goto out;
1410
1411 p = server->mnt_path;
1412 for (;;) {
1413 struct nfs4_exception exception = { };
1414
1415 while (*p == '/')
1416 p++;
1417 if (!*p)
1418 break;
1419 q.name = p;
1420 while (*p && (*p != '/'))
1421 p++;
1422 q.len = p - q.name;
1423
1424 do {
1425 nfs_fattr_init(fattr);
1426 status = nfs4_handle_exception(server,
1427 rpc_call_sync(server->client, &msg, 0),
1428 &exception);
1429 } while (exception.retry);
1430 if (status == 0)
1431 continue;
1432 if (status == -ENOENT) {
1433 printk(KERN_NOTICE "NFS: mount path %s does not exist!\n", server->mnt_path);
1434 printk(KERN_NOTICE "NFS: suggestion: try mounting '/' instead.\n");
1435 }
1436 break;
1437 }
1438 if (status == 0) 1412 if (status == 0)
1439 status = nfs4_server_capabilities(server, fhandle); 1413 status = nfs4_server_capabilities(server, fhandle);
1440 if (status == 0) 1414 if (status == 0)
1441 status = nfs4_do_fsinfo(server, fhandle, info); 1415 status = nfs4_do_fsinfo(server, fhandle, info);
1442out:
1443 return nfs4_map_errors(status); 1416 return nfs4_map_errors(status);
1444} 1417}
1445 1418
1419/*
1420 * Get locations and (maybe) other attributes of a referral.
1421 * Note that we'll actually follow the referral later when
1422 * we detect fsid mismatch in inode revalidation
1423 */
1424static int nfs4_get_referral(struct inode *dir, struct qstr *name, struct nfs_fattr *fattr, struct nfs_fh *fhandle)
1425{
1426 int status = -ENOMEM;
1427 struct page *page = NULL;
1428 struct nfs4_fs_locations *locations = NULL;
1429 struct dentry dentry = {};
1430
1431 page = alloc_page(GFP_KERNEL);
1432 if (page == NULL)
1433 goto out;
1434 locations = kmalloc(sizeof(struct nfs4_fs_locations), GFP_KERNEL);
1435 if (locations == NULL)
1436 goto out;
1437
1438 dentry.d_name.name = name->name;
1439 dentry.d_name.len = name->len;
1440 status = nfs4_proc_fs_locations(dir, &dentry, locations, page);
1441 if (status != 0)
1442 goto out;
1443 /* Make sure server returned a different fsid for the referral */
1444 if (nfs_fsid_equal(&NFS_SERVER(dir)->fsid, &locations->fattr.fsid)) {
1445 dprintk("%s: server did not return a different fsid for a referral at %s\n", __FUNCTION__, name->name);
1446 status = -EIO;
1447 goto out;
1448 }
1449
1450 memcpy(fattr, &locations->fattr, sizeof(struct nfs_fattr));
1451 fattr->valid |= NFS_ATTR_FATTR_V4_REFERRAL;
1452 if (!fattr->mode)
1453 fattr->mode = S_IFDIR;
1454 memset(fhandle, 0, sizeof(struct nfs_fh));
1455out:
1456 if (page)
1457 __free_page(page);
1458 if (locations)
1459 kfree(locations);
1460 return status;
1461}
1462
1446static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr) 1463static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
1447{ 1464{
1448 struct nfs4_getattr_arg args = { 1465 struct nfs4_getattr_arg args = {
@@ -1504,7 +1521,7 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
1504 1521
1505 nfs_fattr_init(fattr); 1522 nfs_fattr_init(fattr);
1506 1523
1507 cred = rpcauth_lookupcred(NFS_SERVER(inode)->client->cl_auth, 0); 1524 cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0);
1508 if (IS_ERR(cred)) 1525 if (IS_ERR(cred))
1509 return PTR_ERR(cred); 1526 return PTR_ERR(cred);
1510 1527
@@ -1522,6 +1539,52 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
1522 return status; 1539 return status;
1523} 1540}
1524 1541
1542static int _nfs4_proc_lookupfh(struct nfs_server *server, struct nfs_fh *dirfh,
1543 struct qstr *name, struct nfs_fh *fhandle,
1544 struct nfs_fattr *fattr)
1545{
1546 int status;
1547 struct nfs4_lookup_arg args = {
1548 .bitmask = server->attr_bitmask,
1549 .dir_fh = dirfh,
1550 .name = name,
1551 };
1552 struct nfs4_lookup_res res = {
1553 .server = server,
1554 .fattr = fattr,
1555 .fh = fhandle,
1556 };
1557 struct rpc_message msg = {
1558 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOOKUP],
1559 .rpc_argp = &args,
1560 .rpc_resp = &res,
1561 };
1562
1563 nfs_fattr_init(fattr);
1564
1565 dprintk("NFS call lookupfh %s\n", name->name);
1566 status = rpc_call_sync(server->client, &msg, 0);
1567 dprintk("NFS reply lookupfh: %d\n", status);
1568 if (status == -NFS4ERR_MOVED)
1569 status = -EREMOTE;
1570 return status;
1571}
1572
1573static int nfs4_proc_lookupfh(struct nfs_server *server, struct nfs_fh *dirfh,
1574 struct qstr *name, struct nfs_fh *fhandle,
1575 struct nfs_fattr *fattr)
1576{
1577 struct nfs4_exception exception = { };
1578 int err;
1579 do {
1580 err = nfs4_handle_exception(server,
1581 _nfs4_proc_lookupfh(server, dirfh, name,
1582 fhandle, fattr),
1583 &exception);
1584 } while (exception.retry);
1585 return err;
1586}
1587
1525static int _nfs4_proc_lookup(struct inode *dir, struct qstr *name, 1588static int _nfs4_proc_lookup(struct inode *dir, struct qstr *name,
1526 struct nfs_fh *fhandle, struct nfs_fattr *fattr) 1589 struct nfs_fh *fhandle, struct nfs_fattr *fattr)
1527{ 1590{
@@ -1547,6 +1610,8 @@ static int _nfs4_proc_lookup(struct inode *dir, struct qstr *name,
1547 1610
1548 dprintk("NFS call lookup %s\n", name->name); 1611 dprintk("NFS call lookup %s\n", name->name);
1549 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); 1612 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
1613 if (status == -NFS4ERR_MOVED)
1614 status = nfs4_get_referral(dir, name, fattr, fhandle);
1550 dprintk("NFS reply lookup: %d\n", status); 1615 dprintk("NFS reply lookup: %d\n", status);
1551 return status; 1616 return status;
1552} 1617}
@@ -1818,7 +1883,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
1818 struct rpc_cred *cred; 1883 struct rpc_cred *cred;
1819 int status = 0; 1884 int status = 0;
1820 1885
1821 cred = rpcauth_lookupcred(NFS_SERVER(dir)->client->cl_auth, 0); 1886 cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0);
1822 if (IS_ERR(cred)) { 1887 if (IS_ERR(cred)) {
1823 status = PTR_ERR(cred); 1888 status = PTR_ERR(cred);
1824 goto out; 1889 goto out;
@@ -2008,7 +2073,7 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *
2008 if (!status) { 2073 if (!status) {
2009 update_changeattr(dir, &res.cinfo); 2074 update_changeattr(dir, &res.cinfo);
2010 nfs_post_op_update_inode(dir, res.dir_attr); 2075 nfs_post_op_update_inode(dir, res.dir_attr);
2011 nfs_refresh_inode(inode, res.fattr); 2076 nfs_post_op_update_inode(inode, res.fattr);
2012 } 2077 }
2013 2078
2014 return status; 2079 return status;
@@ -2026,24 +2091,24 @@ static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *n
2026 return err; 2091 return err;
2027} 2092}
2028 2093
2029static int _nfs4_proc_symlink(struct inode *dir, struct qstr *name, 2094static int _nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
2030 struct qstr *path, struct iattr *sattr, struct nfs_fh *fhandle, 2095 struct page *page, unsigned int len, struct iattr *sattr)
2031 struct nfs_fattr *fattr)
2032{ 2096{
2033 struct nfs_server *server = NFS_SERVER(dir); 2097 struct nfs_server *server = NFS_SERVER(dir);
2034 struct nfs_fattr dir_fattr; 2098 struct nfs_fh fhandle;
2099 struct nfs_fattr fattr, dir_fattr;
2035 struct nfs4_create_arg arg = { 2100 struct nfs4_create_arg arg = {
2036 .dir_fh = NFS_FH(dir), 2101 .dir_fh = NFS_FH(dir),
2037 .server = server, 2102 .server = server,
2038 .name = name, 2103 .name = &dentry->d_name,
2039 .attrs = sattr, 2104 .attrs = sattr,
2040 .ftype = NF4LNK, 2105 .ftype = NF4LNK,
2041 .bitmask = server->attr_bitmask, 2106 .bitmask = server->attr_bitmask,
2042 }; 2107 };
2043 struct nfs4_create_res res = { 2108 struct nfs4_create_res res = {
2044 .server = server, 2109 .server = server,
2045 .fh = fhandle, 2110 .fh = &fhandle,
2046 .fattr = fattr, 2111 .fattr = &fattr,
2047 .dir_fattr = &dir_fattr, 2112 .dir_fattr = &dir_fattr,
2048 }; 2113 };
2049 struct rpc_message msg = { 2114 struct rpc_message msg = {
@@ -2053,29 +2118,32 @@ static int _nfs4_proc_symlink(struct inode *dir, struct qstr *name,
2053 }; 2118 };
2054 int status; 2119 int status;
2055 2120
2056 if (path->len > NFS4_MAXPATHLEN) 2121 if (len > NFS4_MAXPATHLEN)
2057 return -ENAMETOOLONG; 2122 return -ENAMETOOLONG;
2058 arg.u.symlink = path; 2123
2059 nfs_fattr_init(fattr); 2124 arg.u.symlink.pages = &page;
2125 arg.u.symlink.len = len;
2126 nfs_fattr_init(&fattr);
2060 nfs_fattr_init(&dir_fattr); 2127 nfs_fattr_init(&dir_fattr);
2061 2128
2062 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); 2129 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
2063 if (!status) 2130 if (!status) {
2064 update_changeattr(dir, &res.dir_cinfo); 2131 update_changeattr(dir, &res.dir_cinfo);
2065 nfs_post_op_update_inode(dir, res.dir_fattr); 2132 nfs_post_op_update_inode(dir, res.dir_fattr);
2133 status = nfs_instantiate(dentry, &fhandle, &fattr);
2134 }
2066 return status; 2135 return status;
2067} 2136}
2068 2137
2069static int nfs4_proc_symlink(struct inode *dir, struct qstr *name, 2138static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
2070 struct qstr *path, struct iattr *sattr, struct nfs_fh *fhandle, 2139 struct page *page, unsigned int len, struct iattr *sattr)
2071 struct nfs_fattr *fattr)
2072{ 2140{
2073 struct nfs4_exception exception = { }; 2141 struct nfs4_exception exception = { };
2074 int err; 2142 int err;
2075 do { 2143 do {
2076 err = nfs4_handle_exception(NFS_SERVER(dir), 2144 err = nfs4_handle_exception(NFS_SERVER(dir),
2077 _nfs4_proc_symlink(dir, name, path, sattr, 2145 _nfs4_proc_symlink(dir, dentry, page,
2078 fhandle, fattr), 2146 len, sattr),
2079 &exception); 2147 &exception);
2080 } while (exception.retry); 2148 } while (exception.retry);
2081 return err; 2149 return err;
@@ -2458,7 +2526,7 @@ static void nfs4_proc_commit_setup(struct nfs_write_data *data, int how)
2458 */ 2526 */
2459static void nfs4_renew_done(struct rpc_task *task, void *data) 2527static void nfs4_renew_done(struct rpc_task *task, void *data)
2460{ 2528{
2461 struct nfs4_client *clp = (struct nfs4_client *)task->tk_msg.rpc_argp; 2529 struct nfs_client *clp = (struct nfs_client *)task->tk_msg.rpc_argp;
2462 unsigned long timestamp = (unsigned long)data; 2530 unsigned long timestamp = (unsigned long)data;
2463 2531
2464 if (task->tk_status < 0) { 2532 if (task->tk_status < 0) {
@@ -2480,7 +2548,7 @@ static const struct rpc_call_ops nfs4_renew_ops = {
2480 .rpc_call_done = nfs4_renew_done, 2548 .rpc_call_done = nfs4_renew_done,
2481}; 2549};
2482 2550
2483int nfs4_proc_async_renew(struct nfs4_client *clp, struct rpc_cred *cred) 2551int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred)
2484{ 2552{
2485 struct rpc_message msg = { 2553 struct rpc_message msg = {
2486 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW], 2554 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW],
@@ -2492,7 +2560,7 @@ int nfs4_proc_async_renew(struct nfs4_client *clp, struct rpc_cred *cred)
2492 &nfs4_renew_ops, (void *)jiffies); 2560 &nfs4_renew_ops, (void *)jiffies);
2493} 2561}
2494 2562
2495int nfs4_proc_renew(struct nfs4_client *clp, struct rpc_cred *cred) 2563int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred)
2496{ 2564{
2497 struct rpc_message msg = { 2565 struct rpc_message msg = {
2498 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW], 2566 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW],
@@ -2605,7 +2673,7 @@ out:
2605 nfs4_set_cached_acl(inode, acl); 2673 nfs4_set_cached_acl(inode, acl);
2606} 2674}
2607 2675
2608static inline ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen) 2676static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
2609{ 2677{
2610 struct page *pages[NFS4ACL_MAXPAGES]; 2678 struct page *pages[NFS4ACL_MAXPAGES];
2611 struct nfs_getaclargs args = { 2679 struct nfs_getaclargs args = {
@@ -2658,6 +2726,19 @@ out_free:
2658 return ret; 2726 return ret;
2659} 2727}
2660 2728
2729static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
2730{
2731 struct nfs4_exception exception = { };
2732 ssize_t ret;
2733 do {
2734 ret = __nfs4_get_acl_uncached(inode, buf, buflen);
2735 if (ret >= 0)
2736 break;
2737 ret = nfs4_handle_exception(NFS_SERVER(inode), ret, &exception);
2738 } while (exception.retry);
2739 return ret;
2740}
2741
2661static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen) 2742static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen)
2662{ 2743{
2663 struct nfs_server *server = NFS_SERVER(inode); 2744 struct nfs_server *server = NFS_SERVER(inode);
@@ -2674,7 +2755,7 @@ static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen)
2674 return nfs4_get_acl_uncached(inode, buf, buflen); 2755 return nfs4_get_acl_uncached(inode, buf, buflen);
2675} 2756}
2676 2757
2677static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen) 2758static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
2678{ 2759{
2679 struct nfs_server *server = NFS_SERVER(inode); 2760 struct nfs_server *server = NFS_SERVER(inode);
2680 struct page *pages[NFS4ACL_MAXPAGES]; 2761 struct page *pages[NFS4ACL_MAXPAGES];
@@ -2694,16 +2775,28 @@ static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen
2694 return -EOPNOTSUPP; 2775 return -EOPNOTSUPP;
2695 nfs_inode_return_delegation(inode); 2776 nfs_inode_return_delegation(inode);
2696 buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase); 2777 buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
2697 ret = rpc_call_sync(NFS_SERVER(inode)->client, &msg, 0); 2778 ret = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
2698 if (ret == 0) 2779 if (ret == 0)
2699 nfs4_write_cached_acl(inode, buf, buflen); 2780 nfs4_write_cached_acl(inode, buf, buflen);
2700 return ret; 2781 return ret;
2701} 2782}
2702 2783
2784static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
2785{
2786 struct nfs4_exception exception = { };
2787 int err;
2788 do {
2789 err = nfs4_handle_exception(NFS_SERVER(inode),
2790 __nfs4_proc_set_acl(inode, buf, buflen),
2791 &exception);
2792 } while (exception.retry);
2793 return err;
2794}
2795
2703static int 2796static int
2704nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server) 2797nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server)
2705{ 2798{
2706 struct nfs4_client *clp = server->nfs4_state; 2799 struct nfs_client *clp = server->nfs_client;
2707 2800
2708 if (!clp || task->tk_status >= 0) 2801 if (!clp || task->tk_status >= 0)
2709 return 0; 2802 return 0;
@@ -2740,7 +2833,7 @@ static int nfs4_wait_bit_interruptible(void *word)
2740 return 0; 2833 return 0;
2741} 2834}
2742 2835
2743static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs4_client *clp) 2836static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs_client *clp)
2744{ 2837{
2745 sigset_t oldset; 2838 sigset_t oldset;
2746 int res; 2839 int res;
@@ -2783,7 +2876,7 @@ static int nfs4_delay(struct rpc_clnt *clnt, long *timeout)
2783 */ 2876 */
2784int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception) 2877int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
2785{ 2878{
2786 struct nfs4_client *clp = server->nfs4_state; 2879 struct nfs_client *clp = server->nfs_client;
2787 int ret = errorcode; 2880 int ret = errorcode;
2788 2881
2789 exception->retry = 0; 2882 exception->retry = 0;
@@ -2798,6 +2891,7 @@ int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct
2798 if (ret == 0) 2891 if (ret == 0)
2799 exception->retry = 1; 2892 exception->retry = 1;
2800 break; 2893 break;
2894 case -NFS4ERR_FILE_OPEN:
2801 case -NFS4ERR_GRACE: 2895 case -NFS4ERR_GRACE:
2802 case -NFS4ERR_DELAY: 2896 case -NFS4ERR_DELAY:
2803 ret = nfs4_delay(server->client, &exception->timeout); 2897 ret = nfs4_delay(server->client, &exception->timeout);
@@ -2810,7 +2904,7 @@ int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct
2810 return nfs4_map_errors(ret); 2904 return nfs4_map_errors(ret);
2811} 2905}
2812 2906
2813int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short port, struct rpc_cred *cred) 2907int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short port, struct rpc_cred *cred)
2814{ 2908{
2815 nfs4_verifier sc_verifier; 2909 nfs4_verifier sc_verifier;
2816 struct nfs4_setclientid setclientid = { 2910 struct nfs4_setclientid setclientid = {
@@ -2834,7 +2928,7 @@ int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short p
2834 for(;;) { 2928 for(;;) {
2835 setclientid.sc_name_len = scnprintf(setclientid.sc_name, 2929 setclientid.sc_name_len = scnprintf(setclientid.sc_name,
2836 sizeof(setclientid.sc_name), "%s/%u.%u.%u.%u %s %u", 2930 sizeof(setclientid.sc_name), "%s/%u.%u.%u.%u %s %u",
2837 clp->cl_ipaddr, NIPQUAD(clp->cl_addr.s_addr), 2931 clp->cl_ipaddr, NIPQUAD(clp->cl_addr.sin_addr),
2838 cred->cr_ops->cr_name, 2932 cred->cr_ops->cr_name,
2839 clp->cl_id_uniquifier); 2933 clp->cl_id_uniquifier);
2840 setclientid.sc_netid_len = scnprintf(setclientid.sc_netid, 2934 setclientid.sc_netid_len = scnprintf(setclientid.sc_netid,
@@ -2857,7 +2951,7 @@ int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short p
2857 return status; 2951 return status;
2858} 2952}
2859 2953
2860static int _nfs4_proc_setclientid_confirm(struct nfs4_client *clp, struct rpc_cred *cred) 2954static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cred *cred)
2861{ 2955{
2862 struct nfs_fsinfo fsinfo; 2956 struct nfs_fsinfo fsinfo;
2863 struct rpc_message msg = { 2957 struct rpc_message msg = {
@@ -2881,7 +2975,7 @@ static int _nfs4_proc_setclientid_confirm(struct nfs4_client *clp, struct rpc_cr
2881 return status; 2975 return status;
2882} 2976}
2883 2977
2884int nfs4_proc_setclientid_confirm(struct nfs4_client *clp, struct rpc_cred *cred) 2978int nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cred *cred)
2885{ 2979{
2886 long timeout; 2980 long timeout;
2887 int err; 2981 int err;
@@ -2989,7 +3083,7 @@ int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4
2989 switch (err) { 3083 switch (err) {
2990 case -NFS4ERR_STALE_STATEID: 3084 case -NFS4ERR_STALE_STATEID:
2991 case -NFS4ERR_EXPIRED: 3085 case -NFS4ERR_EXPIRED:
2992 nfs4_schedule_state_recovery(server->nfs4_state); 3086 nfs4_schedule_state_recovery(server->nfs_client);
2993 case 0: 3087 case 0:
2994 return 0; 3088 return 0;
2995 } 3089 }
@@ -3018,7 +3112,7 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock
3018{ 3112{
3019 struct inode *inode = state->inode; 3113 struct inode *inode = state->inode;
3020 struct nfs_server *server = NFS_SERVER(inode); 3114 struct nfs_server *server = NFS_SERVER(inode);
3021 struct nfs4_client *clp = server->nfs4_state; 3115 struct nfs_client *clp = server->nfs_client;
3022 struct nfs_lockt_args arg = { 3116 struct nfs_lockt_args arg = {
3023 .fh = NFS_FH(inode), 3117 .fh = NFS_FH(inode),
3024 .fl = request, 3118 .fl = request,
@@ -3081,9 +3175,6 @@ static int do_vfs_lock(struct file *file, struct file_lock *fl)
3081 default: 3175 default:
3082 BUG(); 3176 BUG();
3083 } 3177 }
3084 if (res < 0)
3085 printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n",
3086 __FUNCTION__);
3087 return res; 3178 return res;
3088} 3179}
3089 3180
@@ -3146,7 +3237,7 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
3146 break; 3237 break;
3147 case -NFS4ERR_STALE_STATEID: 3238 case -NFS4ERR_STALE_STATEID:
3148 case -NFS4ERR_EXPIRED: 3239 case -NFS4ERR_EXPIRED:
3149 nfs4_schedule_state_recovery(calldata->server->nfs4_state); 3240 nfs4_schedule_state_recovery(calldata->server->nfs_client);
3150 break; 3241 break;
3151 default: 3242 default:
3152 if (nfs4_async_handle_error(task, calldata->server) == -EAGAIN) { 3243 if (nfs4_async_handle_error(task, calldata->server) == -EAGAIN) {
@@ -3195,8 +3286,6 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl,
3195 return ERR_PTR(-ENOMEM); 3286 return ERR_PTR(-ENOMEM);
3196 } 3287 }
3197 3288
3198 /* Unlock _before_ we do the RPC call */
3199 do_vfs_lock(fl->fl_file, fl);
3200 return rpc_run_task(NFS_CLIENT(lsp->ls_state->inode), RPC_TASK_ASYNC, &nfs4_locku_ops, data); 3289 return rpc_run_task(NFS_CLIENT(lsp->ls_state->inode), RPC_TASK_ASYNC, &nfs4_locku_ops, data);
3201} 3290}
3202 3291
@@ -3207,30 +3296,28 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *
3207 struct rpc_task *task; 3296 struct rpc_task *task;
3208 int status = 0; 3297 int status = 0;
3209 3298
3210 /* Is this a delegated lock? */
3211 if (test_bit(NFS_DELEGATED_STATE, &state->flags))
3212 goto out_unlock;
3213 /* Is this open_owner holding any locks on the server? */
3214 if (test_bit(LK_STATE_IN_USE, &state->flags) == 0)
3215 goto out_unlock;
3216
3217 status = nfs4_set_lock_state(state, request); 3299 status = nfs4_set_lock_state(state, request);
3300 /* Unlock _before_ we do the RPC call */
3301 request->fl_flags |= FL_EXISTS;
3302 if (do_vfs_lock(request->fl_file, request) == -ENOENT)
3303 goto out;
3218 if (status != 0) 3304 if (status != 0)
3219 goto out_unlock; 3305 goto out;
3306 /* Is this a delegated lock? */
3307 if (test_bit(NFS_DELEGATED_STATE, &state->flags))
3308 goto out;
3220 lsp = request->fl_u.nfs4_fl.owner; 3309 lsp = request->fl_u.nfs4_fl.owner;
3221 status = -ENOMEM;
3222 seqid = nfs_alloc_seqid(&lsp->ls_seqid); 3310 seqid = nfs_alloc_seqid(&lsp->ls_seqid);
3311 status = -ENOMEM;
3223 if (seqid == NULL) 3312 if (seqid == NULL)
3224 goto out_unlock; 3313 goto out;
3225 task = nfs4_do_unlck(request, request->fl_file->private_data, lsp, seqid); 3314 task = nfs4_do_unlck(request, request->fl_file->private_data, lsp, seqid);
3226 status = PTR_ERR(task); 3315 status = PTR_ERR(task);
3227 if (IS_ERR(task)) 3316 if (IS_ERR(task))
3228 goto out_unlock; 3317 goto out;
3229 status = nfs4_wait_for_completion_rpc_task(task); 3318 status = nfs4_wait_for_completion_rpc_task(task);
3230 rpc_release_task(task); 3319 rpc_release_task(task);
3231 return status; 3320out:
3232out_unlock:
3233 do_vfs_lock(request->fl_file, request);
3234 return status; 3321 return status;
3235} 3322}
3236 3323
@@ -3262,7 +3349,7 @@ static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
3262 if (p->arg.lock_seqid == NULL) 3349 if (p->arg.lock_seqid == NULL)
3263 goto out_free; 3350 goto out_free;
3264 p->arg.lock_stateid = &lsp->ls_stateid; 3351 p->arg.lock_stateid = &lsp->ls_stateid;
3265 p->arg.lock_owner.clientid = server->nfs4_state->cl_clientid; 3352 p->arg.lock_owner.clientid = server->nfs_client->cl_clientid;
3266 p->arg.lock_owner.id = lsp->ls_id; 3353 p->arg.lock_owner.id = lsp->ls_id;
3267 p->lsp = lsp; 3354 p->lsp = lsp;
3268 atomic_inc(&lsp->ls_count); 3355 atomic_inc(&lsp->ls_count);
@@ -3398,10 +3485,10 @@ static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request
3398 struct nfs4_exception exception = { }; 3485 struct nfs4_exception exception = { };
3399 int err; 3486 int err;
3400 3487
3401 /* Cache the lock if possible... */
3402 if (test_bit(NFS_DELEGATED_STATE, &state->flags))
3403 return 0;
3404 do { 3488 do {
3489 /* Cache the lock if possible... */
3490 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0)
3491 return 0;
3405 err = _nfs4_do_setlk(state, F_SETLK, request, 1); 3492 err = _nfs4_do_setlk(state, F_SETLK, request, 1);
3406 if (err != -NFS4ERR_DELAY) 3493 if (err != -NFS4ERR_DELAY)
3407 break; 3494 break;
@@ -3420,6 +3507,8 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request
3420 if (err != 0) 3507 if (err != 0)
3421 return err; 3508 return err;
3422 do { 3509 do {
3510 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0)
3511 return 0;
3423 err = _nfs4_do_setlk(state, F_SETLK, request, 0); 3512 err = _nfs4_do_setlk(state, F_SETLK, request, 0);
3424 if (err != -NFS4ERR_DELAY) 3513 if (err != -NFS4ERR_DELAY)
3425 break; 3514 break;
@@ -3430,30 +3519,43 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request
3430 3519
3431static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request) 3520static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
3432{ 3521{
3433 struct nfs4_client *clp = state->owner->so_client; 3522 struct nfs_client *clp = state->owner->so_client;
3523 unsigned char fl_flags = request->fl_flags;
3434 int status; 3524 int status;
3435 3525
3436 /* Is this a delegated open? */ 3526 /* Is this a delegated open? */
3437 if (NFS_I(state->inode)->delegation_state != 0) {
3438 /* Yes: cache locks! */
3439 status = do_vfs_lock(request->fl_file, request);
3440 /* ...but avoid races with delegation recall... */
3441 if (status < 0 || test_bit(NFS_DELEGATED_STATE, &state->flags))
3442 return status;
3443 }
3444 down_read(&clp->cl_sem);
3445 status = nfs4_set_lock_state(state, request); 3527 status = nfs4_set_lock_state(state, request);
3446 if (status != 0) 3528 if (status != 0)
3447 goto out; 3529 goto out;
3530 request->fl_flags |= FL_ACCESS;
3531 status = do_vfs_lock(request->fl_file, request);
3532 if (status < 0)
3533 goto out;
3534 down_read(&clp->cl_sem);
3535 if (test_bit(NFS_DELEGATED_STATE, &state->flags)) {
3536 struct nfs_inode *nfsi = NFS_I(state->inode);
3537 /* Yes: cache locks! */
3538 down_read(&nfsi->rwsem);
3539 /* ...but avoid races with delegation recall... */
3540 if (test_bit(NFS_DELEGATED_STATE, &state->flags)) {
3541 request->fl_flags = fl_flags & ~FL_SLEEP;
3542 status = do_vfs_lock(request->fl_file, request);
3543 up_read(&nfsi->rwsem);
3544 goto out_unlock;
3545 }
3546 up_read(&nfsi->rwsem);
3547 }
3448 status = _nfs4_do_setlk(state, cmd, request, 0); 3548 status = _nfs4_do_setlk(state, cmd, request, 0);
3449 if (status != 0) 3549 if (status != 0)
3450 goto out; 3550 goto out_unlock;
3451 /* Note: we always want to sleep here! */ 3551 /* Note: we always want to sleep here! */
3452 request->fl_flags |= FL_SLEEP; 3552 request->fl_flags = fl_flags | FL_SLEEP;
3453 if (do_vfs_lock(request->fl_file, request) < 0) 3553 if (do_vfs_lock(request->fl_file, request) < 0)
3454 printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __FUNCTION__); 3554 printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __FUNCTION__);
3455out: 3555out_unlock:
3456 up_read(&clp->cl_sem); 3556 up_read(&clp->cl_sem);
3557out:
3558 request->fl_flags = fl_flags;
3457 return status; 3559 return status;
3458} 3560}
3459 3561
@@ -3570,6 +3672,36 @@ ssize_t nfs4_listxattr(struct dentry *dentry, char *buf, size_t buflen)
3570 return len; 3672 return len;
3571} 3673}
3572 3674
3675int nfs4_proc_fs_locations(struct inode *dir, struct dentry *dentry,
3676 struct nfs4_fs_locations *fs_locations, struct page *page)
3677{
3678 struct nfs_server *server = NFS_SERVER(dir);
3679 u32 bitmask[2] = {
3680 [0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS,
3681 [1] = FATTR4_WORD1_MOUNTED_ON_FILEID,
3682 };
3683 struct nfs4_fs_locations_arg args = {
3684 .dir_fh = NFS_FH(dir),
3685 .name = &dentry->d_name,
3686 .page = page,
3687 .bitmask = bitmask,
3688 };
3689 struct rpc_message msg = {
3690 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FS_LOCATIONS],
3691 .rpc_argp = &args,
3692 .rpc_resp = fs_locations,
3693 };
3694 int status;
3695
3696 dprintk("%s: start\n", __FUNCTION__);
3697 fs_locations->fattr.valid = 0;
3698 fs_locations->server = server;
3699 fs_locations->nlocations = 0;
3700 status = rpc_call_sync(server->client, &msg, 0);
3701 dprintk("%s: returned status = %d\n", __FUNCTION__, status);
3702 return status;
3703}
3704
3573struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops = { 3705struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops = {
3574 .recover_open = nfs4_open_reclaim, 3706 .recover_open = nfs4_open_reclaim,
3575 .recover_lock = nfs4_lock_reclaim, 3707 .recover_lock = nfs4_lock_reclaim,
@@ -3589,7 +3721,7 @@ static struct inode_operations nfs4_file_inode_operations = {
3589 .listxattr = nfs4_listxattr, 3721 .listxattr = nfs4_listxattr,
3590}; 3722};
3591 3723
3592struct nfs_rpc_ops nfs_v4_clientops = { 3724const struct nfs_rpc_ops nfs_v4_clientops = {
3593 .version = 4, /* protocol version */ 3725 .version = 4, /* protocol version */
3594 .dentry_ops = &nfs4_dentry_operations, 3726 .dentry_ops = &nfs4_dentry_operations,
3595 .dir_inode_ops = &nfs4_dir_inode_operations, 3727 .dir_inode_ops = &nfs4_dir_inode_operations,
@@ -3597,6 +3729,7 @@ struct nfs_rpc_ops nfs_v4_clientops = {
3597 .getroot = nfs4_proc_get_root, 3729 .getroot = nfs4_proc_get_root,
3598 .getattr = nfs4_proc_getattr, 3730 .getattr = nfs4_proc_getattr,
3599 .setattr = nfs4_proc_setattr, 3731 .setattr = nfs4_proc_setattr,
3732 .lookupfh = nfs4_proc_lookupfh,
3600 .lookup = nfs4_proc_lookup, 3733 .lookup = nfs4_proc_lookup,
3601 .access = nfs4_proc_access, 3734 .access = nfs4_proc_access,
3602 .readlink = nfs4_proc_readlink, 3735 .readlink = nfs4_proc_readlink,
@@ -3617,6 +3750,7 @@ struct nfs_rpc_ops nfs_v4_clientops = {
3617 .statfs = nfs4_proc_statfs, 3750 .statfs = nfs4_proc_statfs,
3618 .fsinfo = nfs4_proc_fsinfo, 3751 .fsinfo = nfs4_proc_fsinfo,
3619 .pathconf = nfs4_proc_pathconf, 3752 .pathconf = nfs4_proc_pathconf,
3753 .set_capabilities = nfs4_server_capabilities,
3620 .decode_dirent = nfs4_decode_dirent, 3754 .decode_dirent = nfs4_decode_dirent,
3621 .read_setup = nfs4_proc_read_setup, 3755 .read_setup = nfs4_proc_read_setup,
3622 .read_done = nfs4_read_done, 3756 .read_done = nfs4_read_done,