aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/super.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-03-17 20:40:00 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-17 20:40:00 -0400
commit179198373cf374f0ef793f1023c1cdd83b53674d (patch)
tree9c7f9e82b936864b9d8cf91b3d4121a3c8d2671c /fs/nfs/super.c
parent374e55251cacfb68d331bb8a574b2de8160aacc2 (diff)
parent8e26de238fd794c8ea56a5c98bf67c40cfeb051d (diff)
Merge branch 'nfs-for-2.6.39' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6
* 'nfs-for-2.6.39' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6: (54 commits) RPC: killing RPC tasks races fixed xprt: remove redundant check SUNRPC: Convert struct rpc_xprt to use atomic_t counters SUNRPC: Ensure we always run the tk_callback before tk_action sunrpc: fix printk format warning xprt: remove redundant null check nfs: BKL is no longer needed, so remove the include NFS: Fix a warning in fs/nfs/idmap.c Cleanup: Factor out some cut-and-paste code. cleanup: save 60 lines/100 bytes by combining two mostly duplicate functions. NFS: account direct-io into task io accounting gss:krb5 only include enctype numbers in gm_upcall_enctypes RPCRDMA: Fix FRMR registration/invalidate handling. RPCRDMA: Fix to XDR page base interpretation in marshalling logic. NFSv4: Send unmapped uid/gids to the server when using auth_sys NFSv4: Propagate the error NFS4ERR_BADOWNER to nfs4_do_setattr NFSv4: cleanup idmapper functions to take an nfs_server argument NFSv4: Send unmapped uid/gids to the server if the idmapper fails NFSv4: If the server sends us a numeric uid/gid then accept it NFSv4.1: reject zero layout with zeroed stripe unit ...
Diffstat (limited to 'fs/nfs/super.c')
-rw-r--r--fs/nfs/super.c284
1 files changed, 77 insertions, 207 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index d3286583009a..2b8e9a5e366a 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -1008,6 +1008,27 @@ static int nfs_parse_security_flavors(char *value,
1008 return 1; 1008 return 1;
1009} 1009}
1010 1010
1011static int nfs_get_option_str(substring_t args[], char **option)
1012{
1013 kfree(*option);
1014 *option = match_strdup(args);
1015 return !option;
1016}
1017
1018static int nfs_get_option_ul(substring_t args[], unsigned long *option)
1019{
1020 int rc;
1021 char *string;
1022
1023 string = match_strdup(args);
1024 if (string == NULL)
1025 return -ENOMEM;
1026 rc = strict_strtoul(string, 10, option);
1027 kfree(string);
1028
1029 return rc;
1030}
1031
1011/* 1032/*
1012 * Error-check and convert a string of mount options from user space into 1033 * Error-check and convert a string of mount options from user space into
1013 * a data structure. The whole mount string is processed; bad options are 1034 * a data structure. The whole mount string is processed; bad options are
@@ -1156,155 +1177,82 @@ static int nfs_parse_mount_options(char *raw,
1156 * options that take numeric values 1177 * options that take numeric values
1157 */ 1178 */
1158 case Opt_port: 1179 case Opt_port:
1159 string = match_strdup(args); 1180 if (nfs_get_option_ul(args, &option) ||
1160 if (string == NULL) 1181 option > USHRT_MAX)
1161 goto out_nomem;
1162 rc = strict_strtoul(string, 10, &option);
1163 kfree(string);
1164 if (rc != 0 || option > USHRT_MAX)
1165 goto out_invalid_value; 1182 goto out_invalid_value;
1166 mnt->nfs_server.port = option; 1183 mnt->nfs_server.port = option;
1167 break; 1184 break;
1168 case Opt_rsize: 1185 case Opt_rsize:
1169 string = match_strdup(args); 1186 if (nfs_get_option_ul(args, &option))
1170 if (string == NULL)
1171 goto out_nomem;
1172 rc = strict_strtoul(string, 10, &option);
1173 kfree(string);
1174 if (rc != 0)
1175 goto out_invalid_value; 1187 goto out_invalid_value;
1176 mnt->rsize = option; 1188 mnt->rsize = option;
1177 break; 1189 break;
1178 case Opt_wsize: 1190 case Opt_wsize:
1179 string = match_strdup(args); 1191 if (nfs_get_option_ul(args, &option))
1180 if (string == NULL)
1181 goto out_nomem;
1182 rc = strict_strtoul(string, 10, &option);
1183 kfree(string);
1184 if (rc != 0)
1185 goto out_invalid_value; 1192 goto out_invalid_value;
1186 mnt->wsize = option; 1193 mnt->wsize = option;
1187 break; 1194 break;
1188 case Opt_bsize: 1195 case Opt_bsize:
1189 string = match_strdup(args); 1196 if (nfs_get_option_ul(args, &option))
1190 if (string == NULL)
1191 goto out_nomem;
1192 rc = strict_strtoul(string, 10, &option);
1193 kfree(string);
1194 if (rc != 0)
1195 goto out_invalid_value; 1197 goto out_invalid_value;
1196 mnt->bsize = option; 1198 mnt->bsize = option;
1197 break; 1199 break;
1198 case Opt_timeo: 1200 case Opt_timeo:
1199 string = match_strdup(args); 1201 if (nfs_get_option_ul(args, &option) || option == 0)
1200 if (string == NULL)
1201 goto out_nomem;
1202 rc = strict_strtoul(string, 10, &option);
1203 kfree(string);
1204 if (rc != 0 || option == 0)
1205 goto out_invalid_value; 1202 goto out_invalid_value;
1206 mnt->timeo = option; 1203 mnt->timeo = option;
1207 break; 1204 break;
1208 case Opt_retrans: 1205 case Opt_retrans:
1209 string = match_strdup(args); 1206 if (nfs_get_option_ul(args, &option) || option == 0)
1210 if (string == NULL)
1211 goto out_nomem;
1212 rc = strict_strtoul(string, 10, &option);
1213 kfree(string);
1214 if (rc != 0 || option == 0)
1215 goto out_invalid_value; 1207 goto out_invalid_value;
1216 mnt->retrans = option; 1208 mnt->retrans = option;
1217 break; 1209 break;
1218 case Opt_acregmin: 1210 case Opt_acregmin:
1219 string = match_strdup(args); 1211 if (nfs_get_option_ul(args, &option))
1220 if (string == NULL)
1221 goto out_nomem;
1222 rc = strict_strtoul(string, 10, &option);
1223 kfree(string);
1224 if (rc != 0)
1225 goto out_invalid_value; 1212 goto out_invalid_value;
1226 mnt->acregmin = option; 1213 mnt->acregmin = option;
1227 break; 1214 break;
1228 case Opt_acregmax: 1215 case Opt_acregmax:
1229 string = match_strdup(args); 1216 if (nfs_get_option_ul(args, &option))
1230 if (string == NULL)
1231 goto out_nomem;
1232 rc = strict_strtoul(string, 10, &option);
1233 kfree(string);
1234 if (rc != 0)
1235 goto out_invalid_value; 1217 goto out_invalid_value;
1236 mnt->acregmax = option; 1218 mnt->acregmax = option;
1237 break; 1219 break;
1238 case Opt_acdirmin: 1220 case Opt_acdirmin:
1239 string = match_strdup(args); 1221 if (nfs_get_option_ul(args, &option))
1240 if (string == NULL)
1241 goto out_nomem;
1242 rc = strict_strtoul(string, 10, &option);
1243 kfree(string);
1244 if (rc != 0)
1245 goto out_invalid_value; 1222 goto out_invalid_value;
1246 mnt->acdirmin = option; 1223 mnt->acdirmin = option;
1247 break; 1224 break;
1248 case Opt_acdirmax: 1225 case Opt_acdirmax:
1249 string = match_strdup(args); 1226 if (nfs_get_option_ul(args, &option))
1250 if (string == NULL)
1251 goto out_nomem;
1252 rc = strict_strtoul(string, 10, &option);
1253 kfree(string);
1254 if (rc != 0)
1255 goto out_invalid_value; 1227 goto out_invalid_value;
1256 mnt->acdirmax = option; 1228 mnt->acdirmax = option;
1257 break; 1229 break;
1258 case Opt_actimeo: 1230 case Opt_actimeo:
1259 string = match_strdup(args); 1231 if (nfs_get_option_ul(args, &option))
1260 if (string == NULL)
1261 goto out_nomem;
1262 rc = strict_strtoul(string, 10, &option);
1263 kfree(string);
1264 if (rc != 0)
1265 goto out_invalid_value; 1232 goto out_invalid_value;
1266 mnt->acregmin = mnt->acregmax = 1233 mnt->acregmin = mnt->acregmax =
1267 mnt->acdirmin = mnt->acdirmax = option; 1234 mnt->acdirmin = mnt->acdirmax = option;
1268 break; 1235 break;
1269 case Opt_namelen: 1236 case Opt_namelen:
1270 string = match_strdup(args); 1237 if (nfs_get_option_ul(args, &option))
1271 if (string == NULL)
1272 goto out_nomem;
1273 rc = strict_strtoul(string, 10, &option);
1274 kfree(string);
1275 if (rc != 0)
1276 goto out_invalid_value; 1238 goto out_invalid_value;
1277 mnt->namlen = option; 1239 mnt->namlen = option;
1278 break; 1240 break;
1279 case Opt_mountport: 1241 case Opt_mountport:
1280 string = match_strdup(args); 1242 if (nfs_get_option_ul(args, &option) ||
1281 if (string == NULL) 1243 option > USHRT_MAX)
1282 goto out_nomem;
1283 rc = strict_strtoul(string, 10, &option);
1284 kfree(string);
1285 if (rc != 0 || option > USHRT_MAX)
1286 goto out_invalid_value; 1244 goto out_invalid_value;
1287 mnt->mount_server.port = option; 1245 mnt->mount_server.port = option;
1288 break; 1246 break;
1289 case Opt_mountvers: 1247 case Opt_mountvers:
1290 string = match_strdup(args); 1248 if (nfs_get_option_ul(args, &option) ||
1291 if (string == NULL)
1292 goto out_nomem;
1293 rc = strict_strtoul(string, 10, &option);
1294 kfree(string);
1295 if (rc != 0 ||
1296 option < NFS_MNT_VERSION || 1249 option < NFS_MNT_VERSION ||
1297 option > NFS_MNT3_VERSION) 1250 option > NFS_MNT3_VERSION)
1298 goto out_invalid_value; 1251 goto out_invalid_value;
1299 mnt->mount_server.version = option; 1252 mnt->mount_server.version = option;
1300 break; 1253 break;
1301 case Opt_nfsvers: 1254 case Opt_nfsvers:
1302 string = match_strdup(args); 1255 if (nfs_get_option_ul(args, &option))
1303 if (string == NULL)
1304 goto out_nomem;
1305 rc = strict_strtoul(string, 10, &option);
1306 kfree(string);
1307 if (rc != 0)
1308 goto out_invalid_value; 1256 goto out_invalid_value;
1309 switch (option) { 1257 switch (option) {
1310 case NFS2_VERSION: 1258 case NFS2_VERSION:
@@ -1324,12 +1272,7 @@ static int nfs_parse_mount_options(char *raw,
1324 } 1272 }
1325 break; 1273 break;
1326 case Opt_minorversion: 1274 case Opt_minorversion:
1327 string = match_strdup(args); 1275 if (nfs_get_option_ul(args, &option))
1328 if (string == NULL)
1329 goto out_nomem;
1330 rc = strict_strtoul(string, 10, &option);
1331 kfree(string);
1332 if (rc != 0)
1333 goto out_invalid_value; 1276 goto out_invalid_value;
1334 if (option > NFS4_MAX_MINOR_VERSION) 1277 if (option > NFS4_MAX_MINOR_VERSION)
1335 goto out_invalid_value; 1278 goto out_invalid_value;
@@ -1365,21 +1308,18 @@ static int nfs_parse_mount_options(char *raw,
1365 case Opt_xprt_udp: 1308 case Opt_xprt_udp:
1366 mnt->flags &= ~NFS_MOUNT_TCP; 1309 mnt->flags &= ~NFS_MOUNT_TCP;
1367 mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; 1310 mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
1368 kfree(string);
1369 break; 1311 break;
1370 case Opt_xprt_tcp6: 1312 case Opt_xprt_tcp6:
1371 protofamily = AF_INET6; 1313 protofamily = AF_INET6;
1372 case Opt_xprt_tcp: 1314 case Opt_xprt_tcp:
1373 mnt->flags |= NFS_MOUNT_TCP; 1315 mnt->flags |= NFS_MOUNT_TCP;
1374 mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; 1316 mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP;
1375 kfree(string);
1376 break; 1317 break;
1377 case Opt_xprt_rdma: 1318 case Opt_xprt_rdma:
1378 /* vector side protocols to TCP */ 1319 /* vector side protocols to TCP */
1379 mnt->flags |= NFS_MOUNT_TCP; 1320 mnt->flags |= NFS_MOUNT_TCP;
1380 mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA; 1321 mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA;
1381 xprt_load_transport(string); 1322 xprt_load_transport(string);
1382 kfree(string);
1383 break; 1323 break;
1384 default: 1324 default:
1385 dfprintk(MOUNT, "NFS: unrecognized " 1325 dfprintk(MOUNT, "NFS: unrecognized "
@@ -1387,6 +1327,7 @@ static int nfs_parse_mount_options(char *raw,
1387 kfree(string); 1327 kfree(string);
1388 return 0; 1328 return 0;
1389 } 1329 }
1330 kfree(string);
1390 break; 1331 break;
1391 case Opt_mountproto: 1332 case Opt_mountproto:
1392 string = match_strdup(args); 1333 string = match_strdup(args);
@@ -1429,18 +1370,13 @@ static int nfs_parse_mount_options(char *raw,
1429 goto out_invalid_address; 1370 goto out_invalid_address;
1430 break; 1371 break;
1431 case Opt_clientaddr: 1372 case Opt_clientaddr:
1432 string = match_strdup(args); 1373 if (nfs_get_option_str(args, &mnt->client_address))
1433 if (string == NULL)
1434 goto out_nomem; 1374 goto out_nomem;
1435 kfree(mnt->client_address);
1436 mnt->client_address = string;
1437 break; 1375 break;
1438 case Opt_mounthost: 1376 case Opt_mounthost:
1439 string = match_strdup(args); 1377 if (nfs_get_option_str(args,
1440 if (string == NULL) 1378 &mnt->mount_server.hostname))
1441 goto out_nomem; 1379 goto out_nomem;
1442 kfree(mnt->mount_server.hostname);
1443 mnt->mount_server.hostname = string;
1444 break; 1380 break;
1445 case Opt_mountaddr: 1381 case Opt_mountaddr:
1446 string = match_strdup(args); 1382 string = match_strdup(args);
@@ -1480,11 +1416,8 @@ static int nfs_parse_mount_options(char *raw,
1480 }; 1416 };
1481 break; 1417 break;
1482 case Opt_fscache_uniq: 1418 case Opt_fscache_uniq:
1483 string = match_strdup(args); 1419 if (nfs_get_option_str(args, &mnt->fscache_uniq))
1484 if (string == NULL)
1485 goto out_nomem; 1420 goto out_nomem;
1486 kfree(mnt->fscache_uniq);
1487 mnt->fscache_uniq = string;
1488 mnt->options |= NFS_OPTION_FSCACHE; 1421 mnt->options |= NFS_OPTION_FSCACHE;
1489 break; 1422 break;
1490 case Opt_local_lock: 1423 case Opt_local_lock:
@@ -1694,99 +1627,59 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
1694 return nfs_walk_authlist(args, &request); 1627 return nfs_walk_authlist(args, &request);
1695} 1628}
1696 1629
1697static int nfs_parse_simple_hostname(const char *dev_name, 1630/*
1698 char **hostname, size_t maxnamlen, 1631 * Split "dev_name" into "hostname:export_path".
1699 char **export_path, size_t maxpathlen) 1632 *
1633 * The leftmost colon demarks the split between the server's hostname
1634 * and the export path. If the hostname starts with a left square
1635 * bracket, then it may contain colons.
1636 *
1637 * Note: caller frees hostname and export path, even on error.
1638 */
1639static int nfs_parse_devname(const char *dev_name,
1640 char **hostname, size_t maxnamlen,
1641 char **export_path, size_t maxpathlen)
1700{ 1642{
1701 size_t len; 1643 size_t len;
1702 char *colon, *comma; 1644 char *end;
1703 1645
1704 colon = strchr(dev_name, ':'); 1646 /* Is the host name protected with square brakcets? */
1705 if (colon == NULL) 1647 if (*dev_name == '[') {
1706 goto out_bad_devname; 1648 end = strchr(++dev_name, ']');
1707 1649 if (end == NULL || end[1] != ':')
1708 len = colon - dev_name;
1709 if (len > maxnamlen)
1710 goto out_hostname;
1711
1712 /* N.B. caller will free nfs_server.hostname in all cases */
1713 *hostname = kstrndup(dev_name, len, GFP_KERNEL);
1714 if (!*hostname)
1715 goto out_nomem;
1716
1717 /* kill possible hostname list: not supported */
1718 comma = strchr(*hostname, ',');
1719 if (comma != NULL) {
1720 if (comma == *hostname)
1721 goto out_bad_devname; 1650 goto out_bad_devname;
1722 *comma = '\0';
1723 }
1724
1725 colon++;
1726 len = strlen(colon);
1727 if (len > maxpathlen)
1728 goto out_path;
1729 *export_path = kstrndup(colon, len, GFP_KERNEL);
1730 if (!*export_path)
1731 goto out_nomem;
1732
1733 dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", *export_path);
1734 return 0;
1735
1736out_bad_devname:
1737 dfprintk(MOUNT, "NFS: device name not in host:path format\n");
1738 return -EINVAL;
1739 1651
1740out_nomem: 1652 len = end - dev_name;
1741 dfprintk(MOUNT, "NFS: not enough memory to parse device name\n"); 1653 end++;
1742 return -ENOMEM; 1654 } else {
1743 1655 char *comma;
1744out_hostname:
1745 dfprintk(MOUNT, "NFS: server hostname too long\n");
1746 return -ENAMETOOLONG;
1747
1748out_path:
1749 dfprintk(MOUNT, "NFS: export pathname too long\n");
1750 return -ENAMETOOLONG;
1751}
1752
1753/*
1754 * Hostname has square brackets around it because it contains one or
1755 * more colons. We look for the first closing square bracket, and a
1756 * colon must follow it.
1757 */
1758static int nfs_parse_protected_hostname(const char *dev_name,
1759 char **hostname, size_t maxnamlen,
1760 char **export_path, size_t maxpathlen)
1761{
1762 size_t len;
1763 char *start, *end;
1764 1656
1765 start = (char *)(dev_name + 1); 1657 end = strchr(dev_name, ':');
1658 if (end == NULL)
1659 goto out_bad_devname;
1660 len = end - dev_name;
1766 1661
1767 end = strchr(start, ']'); 1662 /* kill possible hostname list: not supported */
1768 if (end == NULL) 1663 comma = strchr(dev_name, ',');
1769 goto out_bad_devname; 1664 if (comma != NULL && comma < end)
1770 if (*(end + 1) != ':') 1665 *comma = 0;
1771 goto out_bad_devname; 1666 }
1772 1667
1773 len = end - start;
1774 if (len > maxnamlen) 1668 if (len > maxnamlen)
1775 goto out_hostname; 1669 goto out_hostname;
1776 1670
1777 /* N.B. caller will free nfs_server.hostname in all cases */ 1671 /* N.B. caller will free nfs_server.hostname in all cases */
1778 *hostname = kstrndup(start, len, GFP_KERNEL); 1672 *hostname = kstrndup(dev_name, len, GFP_KERNEL);
1779 if (*hostname == NULL) 1673 if (*hostname == NULL)
1780 goto out_nomem; 1674 goto out_nomem;
1781 1675 len = strlen(++end);
1782 end += 2;
1783 len = strlen(end);
1784 if (len > maxpathlen) 1676 if (len > maxpathlen)
1785 goto out_path; 1677 goto out_path;
1786 *export_path = kstrndup(end, len, GFP_KERNEL); 1678 *export_path = kstrndup(end, len, GFP_KERNEL);
1787 if (!*export_path) 1679 if (!*export_path)
1788 goto out_nomem; 1680 goto out_nomem;
1789 1681
1682 dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", *export_path);
1790 return 0; 1683 return 0;
1791 1684
1792out_bad_devname: 1685out_bad_devname:
@@ -1807,29 +1700,6 @@ out_path:
1807} 1700}
1808 1701
1809/* 1702/*
1810 * Split "dev_name" into "hostname:export_path".
1811 *
1812 * The leftmost colon demarks the split between the server's hostname
1813 * and the export path. If the hostname starts with a left square
1814 * bracket, then it may contain colons.
1815 *
1816 * Note: caller frees hostname and export path, even on error.
1817 */
1818static int nfs_parse_devname(const char *dev_name,
1819 char **hostname, size_t maxnamlen,
1820 char **export_path, size_t maxpathlen)
1821{
1822 if (*dev_name == '[')
1823 return nfs_parse_protected_hostname(dev_name,
1824 hostname, maxnamlen,
1825 export_path, maxpathlen);
1826
1827 return nfs_parse_simple_hostname(dev_name,
1828 hostname, maxnamlen,
1829 export_path, maxpathlen);
1830}
1831
1832/*
1833 * Validate the NFS2/NFS3 mount data 1703 * Validate the NFS2/NFS3 mount data
1834 * - fills in the mount root filehandle 1704 * - fills in the mount root filehandle
1835 * 1705 *