aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/client.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/client.c')
-rw-r--r--fs/nfs/client.c158
1 files changed, 85 insertions, 73 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index acc9c4943b84..4e7df2adb212 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -150,6 +150,7 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
150 clp->cl_boot_time = CURRENT_TIME; 150 clp->cl_boot_time = CURRENT_TIME;
151 clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED; 151 clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED;
152 clp->cl_minorversion = cl_init->minorversion; 152 clp->cl_minorversion = cl_init->minorversion;
153 clp->cl_mvops = nfs_v4_minor_ops[cl_init->minorversion];
153#endif 154#endif
154 cred = rpc_lookup_machine_cred(); 155 cred = rpc_lookup_machine_cred();
155 if (!IS_ERR(cred)) 156 if (!IS_ERR(cred))
@@ -178,7 +179,7 @@ static void nfs4_clear_client_minor_version(struct nfs_client *clp)
178 clp->cl_session = NULL; 179 clp->cl_session = NULL;
179 } 180 }
180 181
181 clp->cl_call_sync = _nfs4_call_sync; 182 clp->cl_mvops = nfs_v4_minor_ops[0];
182#endif /* CONFIG_NFS_V4_1 */ 183#endif /* CONFIG_NFS_V4_1 */
183} 184}
184 185
@@ -188,7 +189,7 @@ static void nfs4_clear_client_minor_version(struct nfs_client *clp)
188static void nfs4_destroy_callback(struct nfs_client *clp) 189static void nfs4_destroy_callback(struct nfs_client *clp)
189{ 190{
190 if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state)) 191 if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state))
191 nfs_callback_down(clp->cl_minorversion); 192 nfs_callback_down(clp->cl_mvops->minor_version);
192} 193}
193 194
194static void nfs4_shutdown_client(struct nfs_client *clp) 195static void nfs4_shutdown_client(struct nfs_client *clp)
@@ -934,7 +935,6 @@ static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, str
934 } 935 }
935 936
936 fsinfo.fattr = fattr; 937 fsinfo.fattr = fattr;
937 nfs_fattr_init(fattr);
938 error = clp->rpc_ops->fsinfo(server, mntfh, &fsinfo); 938 error = clp->rpc_ops->fsinfo(server, mntfh, &fsinfo);
939 if (error < 0) 939 if (error < 0)
940 goto out_error; 940 goto out_error;
@@ -1047,13 +1047,18 @@ struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data,
1047 struct nfs_fh *mntfh) 1047 struct nfs_fh *mntfh)
1048{ 1048{
1049 struct nfs_server *server; 1049 struct nfs_server *server;
1050 struct nfs_fattr fattr; 1050 struct nfs_fattr *fattr;
1051 int error; 1051 int error;
1052 1052
1053 server = nfs_alloc_server(); 1053 server = nfs_alloc_server();
1054 if (!server) 1054 if (!server)
1055 return ERR_PTR(-ENOMEM); 1055 return ERR_PTR(-ENOMEM);
1056 1056
1057 error = -ENOMEM;
1058 fattr = nfs_alloc_fattr();
1059 if (fattr == NULL)
1060 goto error;
1061
1057 /* Get a client representation */ 1062 /* Get a client representation */
1058 error = nfs_init_server(server, data); 1063 error = nfs_init_server(server, data);
1059 if (error < 0) 1064 if (error < 0)
@@ -1064,7 +1069,7 @@ struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data,
1064 BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); 1069 BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
1065 1070
1066 /* Probe the root fh to retrieve its FSID */ 1071 /* Probe the root fh to retrieve its FSID */
1067 error = nfs_probe_fsinfo(server, mntfh, &fattr); 1072 error = nfs_probe_fsinfo(server, mntfh, fattr);
1068 if (error < 0) 1073 if (error < 0)
1069 goto error; 1074 goto error;
1070 if (server->nfs_client->rpc_ops->version == 3) { 1075 if (server->nfs_client->rpc_ops->version == 3) {
@@ -1077,14 +1082,14 @@ struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data,
1077 server->namelen = NFS2_MAXNAMLEN; 1082 server->namelen = NFS2_MAXNAMLEN;
1078 } 1083 }
1079 1084
1080 if (!(fattr.valid & NFS_ATTR_FATTR)) { 1085 if (!(fattr->valid & NFS_ATTR_FATTR)) {
1081 error = server->nfs_client->rpc_ops->getattr(server, mntfh, &fattr); 1086 error = server->nfs_client->rpc_ops->getattr(server, mntfh, fattr);
1082 if (error < 0) { 1087 if (error < 0) {
1083 dprintk("nfs_create_server: getattr error = %d\n", -error); 1088 dprintk("nfs_create_server: getattr error = %d\n", -error);
1084 goto error; 1089 goto error;
1085 } 1090 }
1086 } 1091 }
1087 memcpy(&server->fsid, &fattr.fsid, sizeof(server->fsid)); 1092 memcpy(&server->fsid, &fattr->fsid, sizeof(server->fsid));
1088 1093
1089 dprintk("Server FSID: %llx:%llx\n", 1094 dprintk("Server FSID: %llx:%llx\n",
1090 (unsigned long long) server->fsid.major, 1095 (unsigned long long) server->fsid.major,
@@ -1096,9 +1101,11 @@ struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data,
1096 spin_unlock(&nfs_client_lock); 1101 spin_unlock(&nfs_client_lock);
1097 1102
1098 server->mount_time = jiffies; 1103 server->mount_time = jiffies;
1104 nfs_free_fattr(fattr);
1099 return server; 1105 return server;
1100 1106
1101error: 1107error:
1108 nfs_free_fattr(fattr);
1102 nfs_free_server(server); 1109 nfs_free_server(server);
1103 return ERR_PTR(error); 1110 return ERR_PTR(error);
1104} 1111}
@@ -1120,7 +1127,7 @@ static int nfs4_init_callback(struct nfs_client *clp)
1120 return error; 1127 return error;
1121 } 1128 }
1122 1129
1123 error = nfs_callback_up(clp->cl_minorversion, 1130 error = nfs_callback_up(clp->cl_mvops->minor_version,
1124 clp->cl_rpcclient->cl_xprt); 1131 clp->cl_rpcclient->cl_xprt);
1125 if (error < 0) { 1132 if (error < 0) {
1126 dprintk("%s: failed to start callback. Error = %d\n", 1133 dprintk("%s: failed to start callback. Error = %d\n",
@@ -1137,10 +1144,8 @@ static int nfs4_init_callback(struct nfs_client *clp)
1137 */ 1144 */
1138static int nfs4_init_client_minor_version(struct nfs_client *clp) 1145static int nfs4_init_client_minor_version(struct nfs_client *clp)
1139{ 1146{
1140 clp->cl_call_sync = _nfs4_call_sync;
1141
1142#if defined(CONFIG_NFS_V4_1) 1147#if defined(CONFIG_NFS_V4_1)
1143 if (clp->cl_minorversion) { 1148 if (clp->cl_mvops->minor_version) {
1144 struct nfs4_session *session = NULL; 1149 struct nfs4_session *session = NULL;
1145 /* 1150 /*
1146 * Create the session and mark it expired. 1151 * Create the session and mark it expired.
@@ -1152,7 +1157,13 @@ static int nfs4_init_client_minor_version(struct nfs_client *clp)
1152 return -ENOMEM; 1157 return -ENOMEM;
1153 1158
1154 clp->cl_session = session; 1159 clp->cl_session = session;
1155 clp->cl_call_sync = _nfs4_call_sync_session; 1160 /*
1161 * The create session reply races with the server back
1162 * channel probe. Mark the client NFS_CS_SESSION_INITING
1163 * so that the client back channel can find the
1164 * nfs_client struct
1165 */
1166 clp->cl_cons_state = NFS_CS_SESSION_INITING;
1156 } 1167 }
1157#endif /* CONFIG_NFS_V4_1 */ 1168#endif /* CONFIG_NFS_V4_1 */
1158 1169
@@ -1280,6 +1291,55 @@ static void nfs4_session_set_rwsize(struct nfs_server *server)
1280#endif /* CONFIG_NFS_V4_1 */ 1291#endif /* CONFIG_NFS_V4_1 */
1281} 1292}
1282 1293
1294static int nfs4_server_common_setup(struct nfs_server *server,
1295 struct nfs_fh *mntfh)
1296{
1297 struct nfs_fattr *fattr;
1298 int error;
1299
1300 BUG_ON(!server->nfs_client);
1301 BUG_ON(!server->nfs_client->rpc_ops);
1302 BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
1303
1304 fattr = nfs_alloc_fattr();
1305 if (fattr == NULL)
1306 return -ENOMEM;
1307
1308 /* We must ensure the session is initialised first */
1309 error = nfs4_init_session(server);
1310 if (error < 0)
1311 goto out;
1312
1313 /* Probe the root fh to retrieve its FSID and filehandle */
1314 error = nfs4_get_rootfh(server, mntfh);
1315 if (error < 0)
1316 goto out;
1317
1318 dprintk("Server FSID: %llx:%llx\n",
1319 (unsigned long long) server->fsid.major,
1320 (unsigned long long) server->fsid.minor);
1321 dprintk("Mount FH: %d\n", mntfh->size);
1322
1323 nfs4_session_set_rwsize(server);
1324
1325 error = nfs_probe_fsinfo(server, mntfh, fattr);
1326 if (error < 0)
1327 goto out;
1328
1329 if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN)
1330 server->namelen = NFS4_MAXNAMLEN;
1331
1332 spin_lock(&nfs_client_lock);
1333 list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks);
1334 list_add_tail(&server->master_link, &nfs_volume_list);
1335 spin_unlock(&nfs_client_lock);
1336
1337 server->mount_time = jiffies;
1338out:
1339 nfs_free_fattr(fattr);
1340 return error;
1341}
1342
1283/* 1343/*
1284 * Create a version 4 volume record 1344 * Create a version 4 volume record
1285 */ 1345 */
@@ -1340,7 +1400,6 @@ error:
1340struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data, 1400struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
1341 struct nfs_fh *mntfh) 1401 struct nfs_fh *mntfh)
1342{ 1402{
1343 struct nfs_fattr fattr;
1344 struct nfs_server *server; 1403 struct nfs_server *server;
1345 int error; 1404 int error;
1346 1405
@@ -1355,39 +1414,10 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
1355 if (error < 0) 1414 if (error < 0)
1356 goto error; 1415 goto error;
1357 1416
1358 BUG_ON(!server->nfs_client); 1417 error = nfs4_server_common_setup(server, mntfh);
1359 BUG_ON(!server->nfs_client->rpc_ops);
1360 BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
1361
1362 error = nfs4_init_session(server);
1363 if (error < 0)
1364 goto error;
1365
1366 /* Probe the root fh to retrieve its FSID */
1367 error = nfs4_path_walk(server, mntfh, data->nfs_server.export_path);
1368 if (error < 0)
1369 goto error;
1370
1371 dprintk("Server FSID: %llx:%llx\n",
1372 (unsigned long long) server->fsid.major,
1373 (unsigned long long) server->fsid.minor);
1374 dprintk("Mount FH: %d\n", mntfh->size);
1375
1376 nfs4_session_set_rwsize(server);
1377
1378 error = nfs_probe_fsinfo(server, mntfh, &fattr);
1379 if (error < 0) 1418 if (error < 0)
1380 goto error; 1419 goto error;
1381 1420
1382 if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN)
1383 server->namelen = NFS4_MAXNAMLEN;
1384
1385 spin_lock(&nfs_client_lock);
1386 list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks);
1387 list_add_tail(&server->master_link, &nfs_volume_list);
1388 spin_unlock(&nfs_client_lock);
1389
1390 server->mount_time = jiffies;
1391 dprintk("<-- nfs4_create_server() = %p\n", server); 1421 dprintk("<-- nfs4_create_server() = %p\n", server);
1392 return server; 1422 return server;
1393 1423
@@ -1405,7 +1435,6 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
1405{ 1435{
1406 struct nfs_client *parent_client; 1436 struct nfs_client *parent_client;
1407 struct nfs_server *server, *parent_server; 1437 struct nfs_server *server, *parent_server;
1408 struct nfs_fattr fattr;
1409 int error; 1438 int error;
1410 1439
1411 dprintk("--> nfs4_create_referral_server()\n"); 1440 dprintk("--> nfs4_create_referral_server()\n");
@@ -1430,7 +1459,7 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
1430 data->authflavor, 1459 data->authflavor,
1431 parent_server->client->cl_xprt->prot, 1460 parent_server->client->cl_xprt->prot,
1432 parent_server->client->cl_timeout, 1461 parent_server->client->cl_timeout,
1433 parent_client->cl_minorversion); 1462 parent_client->cl_mvops->minor_version);
1434 if (error < 0) 1463 if (error < 0)
1435 goto error; 1464 goto error;
1436 1465
@@ -1438,34 +1467,10 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
1438 if (error < 0) 1467 if (error < 0)
1439 goto error; 1468 goto error;
1440 1469
1441 BUG_ON(!server->nfs_client); 1470 error = nfs4_server_common_setup(server, mntfh);
1442 BUG_ON(!server->nfs_client->rpc_ops);
1443 BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
1444
1445 /* Probe the root fh to retrieve its FSID and filehandle */
1446 error = nfs4_path_walk(server, mntfh, data->mnt_path);
1447 if (error < 0) 1471 if (error < 0)
1448 goto error; 1472 goto error;
1449 1473
1450 /* probe the filesystem info for this server filesystem */
1451 error = nfs_probe_fsinfo(server, mntfh, &fattr);
1452 if (error < 0)
1453 goto error;
1454
1455 if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN)
1456 server->namelen = NFS4_MAXNAMLEN;
1457
1458 dprintk("Referral FSID: %llx:%llx\n",
1459 (unsigned long long) server->fsid.major,
1460 (unsigned long long) server->fsid.minor);
1461
1462 spin_lock(&nfs_client_lock);
1463 list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks);
1464 list_add_tail(&server->master_link, &nfs_volume_list);
1465 spin_unlock(&nfs_client_lock);
1466
1467 server->mount_time = jiffies;
1468
1469 dprintk("<-- nfs_create_referral_server() = %p\n", server); 1474 dprintk("<-- nfs_create_referral_server() = %p\n", server);
1470 return server; 1475 return server;
1471 1476
@@ -1485,7 +1490,7 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
1485 struct nfs_fattr *fattr) 1490 struct nfs_fattr *fattr)
1486{ 1491{
1487 struct nfs_server *server; 1492 struct nfs_server *server;
1488 struct nfs_fattr fattr_fsinfo; 1493 struct nfs_fattr *fattr_fsinfo;
1489 int error; 1494 int error;
1490 1495
1491 dprintk("--> nfs_clone_server(,%llx:%llx,)\n", 1496 dprintk("--> nfs_clone_server(,%llx:%llx,)\n",
@@ -1496,6 +1501,11 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
1496 if (!server) 1501 if (!server)
1497 return ERR_PTR(-ENOMEM); 1502 return ERR_PTR(-ENOMEM);
1498 1503
1504 error = -ENOMEM;
1505 fattr_fsinfo = nfs_alloc_fattr();
1506 if (fattr_fsinfo == NULL)
1507 goto out_free_server;
1508
1499 /* Copy data from the source */ 1509 /* Copy data from the source */
1500 server->nfs_client = source->nfs_client; 1510 server->nfs_client = source->nfs_client;
1501 atomic_inc(&server->nfs_client->cl_count); 1511 atomic_inc(&server->nfs_client->cl_count);
@@ -1512,7 +1522,7 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
1512 nfs_init_server_aclclient(server); 1522 nfs_init_server_aclclient(server);
1513 1523
1514 /* probe the filesystem info for this server filesystem */ 1524 /* probe the filesystem info for this server filesystem */
1515 error = nfs_probe_fsinfo(server, fh, &fattr_fsinfo); 1525 error = nfs_probe_fsinfo(server, fh, fattr_fsinfo);
1516 if (error < 0) 1526 if (error < 0)
1517 goto out_free_server; 1527 goto out_free_server;
1518 1528
@@ -1534,10 +1544,12 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
1534 1544
1535 server->mount_time = jiffies; 1545 server->mount_time = jiffies;
1536 1546
1547 nfs_free_fattr(fattr_fsinfo);
1537 dprintk("<-- nfs_clone_server() = %p\n", server); 1548 dprintk("<-- nfs_clone_server() = %p\n", server);
1538 return server; 1549 return server;
1539 1550
1540out_free_server: 1551out_free_server:
1552 nfs_free_fattr(fattr_fsinfo);
1541 nfs_free_server(server); 1553 nfs_free_server(server);
1542 dprintk("<-- nfs_clone_server() = error %d\n", error); 1554 dprintk("<-- nfs_clone_server() = error %d\n", error);
1543 return ERR_PTR(error); 1555 return ERR_PTR(error);