diff options
-rw-r--r-- | fs/nfs/super.c | 43 | ||||
-rw-r--r-- | include/linux/nfs4_mount.h | 3 | ||||
-rw-r--r-- | include/linux/nfs_mount.h | 1 |
3 files changed, 41 insertions, 6 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 064e69d2fdde..1b555cd41e3b 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -100,6 +100,7 @@ enum { | |||
100 | Opt_udp, Opt_tcp, | 100 | Opt_udp, Opt_tcp, |
101 | Opt_acl, Opt_noacl, | 101 | Opt_acl, Opt_noacl, |
102 | Opt_rdirplus, Opt_nordirplus, | 102 | Opt_rdirplus, Opt_nordirplus, |
103 | Opt_sharecache, Opt_nosharecache, | ||
103 | 104 | ||
104 | /* Mount options that take integer arguments */ | 105 | /* Mount options that take integer arguments */ |
105 | Opt_port, | 106 | Opt_port, |
@@ -146,6 +147,8 @@ static match_table_t nfs_mount_option_tokens = { | |||
146 | { Opt_noacl, "noacl" }, | 147 | { Opt_noacl, "noacl" }, |
147 | { Opt_rdirplus, "rdirplus" }, | 148 | { Opt_rdirplus, "rdirplus" }, |
148 | { Opt_nordirplus, "nordirplus" }, | 149 | { Opt_nordirplus, "nordirplus" }, |
150 | { Opt_sharecache, "sharecache" }, | ||
151 | { Opt_nosharecache, "nosharecache" }, | ||
149 | 152 | ||
150 | { Opt_port, "port=%u" }, | 153 | { Opt_port, "port=%u" }, |
151 | { Opt_rsize, "rsize=%u" }, | 154 | { Opt_rsize, "rsize=%u" }, |
@@ -450,6 +453,7 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, | |||
450 | { NFS_MOUNT_NONLM, ",nolock", "" }, | 453 | { NFS_MOUNT_NONLM, ",nolock", "" }, |
451 | { NFS_MOUNT_NOACL, ",noacl", "" }, | 454 | { NFS_MOUNT_NOACL, ",noacl", "" }, |
452 | { NFS_MOUNT_NORDIRPLUS, ",nordirplus", "" }, | 455 | { NFS_MOUNT_NORDIRPLUS, ",nordirplus", "" }, |
456 | { NFS_MOUNT_UNSHARED, ",nosharecache", ""}, | ||
453 | { 0, NULL, NULL } | 457 | { 0, NULL, NULL } |
454 | }; | 458 | }; |
455 | const struct proc_nfs_info *nfs_infop; | 459 | const struct proc_nfs_info *nfs_infop; |
@@ -714,6 +718,12 @@ static int nfs_parse_mount_options(char *raw, | |||
714 | case Opt_nordirplus: | 718 | case Opt_nordirplus: |
715 | mnt->flags |= NFS_MOUNT_NORDIRPLUS; | 719 | mnt->flags |= NFS_MOUNT_NORDIRPLUS; |
716 | break; | 720 | break; |
721 | case Opt_sharecache: | ||
722 | mnt->flags &= ~NFS_MOUNT_UNSHARED; | ||
723 | break; | ||
724 | case Opt_nosharecache: | ||
725 | mnt->flags |= NFS_MOUNT_UNSHARED; | ||
726 | break; | ||
717 | 727 | ||
718 | case Opt_port: | 728 | case Opt_port: |
719 | if (match_int(args, &option)) | 729 | if (match_int(args, &option)) |
@@ -1309,6 +1319,9 @@ static int nfs_compare_super(struct super_block *sb, void *data) | |||
1309 | 1319 | ||
1310 | if (old->nfs_client != server->nfs_client) | 1320 | if (old->nfs_client != server->nfs_client) |
1311 | return 0; | 1321 | return 0; |
1322 | /* Note: NFS_MOUNT_UNSHARED == NFS4_MOUNT_UNSHARED */ | ||
1323 | if (old->flags & NFS_MOUNT_UNSHARED) | ||
1324 | return 0; | ||
1312 | if (memcmp(&old->fsid, &server->fsid, sizeof(old->fsid)) != 0) | 1325 | if (memcmp(&old->fsid, &server->fsid, sizeof(old->fsid)) != 0) |
1313 | return 0; | 1326 | return 0; |
1314 | return 1; | 1327 | return 1; |
@@ -1322,6 +1335,7 @@ static int nfs_get_sb(struct file_system_type *fs_type, | |||
1322 | struct nfs_fh mntfh; | 1335 | struct nfs_fh mntfh; |
1323 | struct nfs_mount_data *data = raw_data; | 1336 | struct nfs_mount_data *data = raw_data; |
1324 | struct dentry *mntroot; | 1337 | struct dentry *mntroot; |
1338 | int (*compare_super)(struct super_block *, void *) = nfs_compare_super; | ||
1325 | int error; | 1339 | int error; |
1326 | 1340 | ||
1327 | /* Validate the mount data */ | 1341 | /* Validate the mount data */ |
@@ -1336,8 +1350,11 @@ static int nfs_get_sb(struct file_system_type *fs_type, | |||
1336 | goto out; | 1350 | goto out; |
1337 | } | 1351 | } |
1338 | 1352 | ||
1353 | if (server->flags & NFS_MOUNT_UNSHARED) | ||
1354 | compare_super = NULL; | ||
1355 | |||
1339 | /* Get a superblock - note that we may end up sharing one that already exists */ | 1356 | /* Get a superblock - note that we may end up sharing one that already exists */ |
1340 | s = sget(fs_type, nfs_compare_super, nfs_set_super, server); | 1357 | s = sget(fs_type, compare_super, nfs_set_super, server); |
1341 | if (IS_ERR(s)) { | 1358 | if (IS_ERR(s)) { |
1342 | error = PTR_ERR(s); | 1359 | error = PTR_ERR(s); |
1343 | goto out_err_nosb; | 1360 | goto out_err_nosb; |
@@ -1402,6 +1419,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags, | |||
1402 | struct super_block *s; | 1419 | struct super_block *s; |
1403 | struct nfs_server *server; | 1420 | struct nfs_server *server; |
1404 | struct dentry *mntroot; | 1421 | struct dentry *mntroot; |
1422 | int (*compare_super)(struct super_block *, void *) = nfs_compare_super; | ||
1405 | int error; | 1423 | int error; |
1406 | 1424 | ||
1407 | dprintk("--> nfs_xdev_get_sb()\n"); | 1425 | dprintk("--> nfs_xdev_get_sb()\n"); |
@@ -1413,8 +1431,11 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags, | |||
1413 | goto out_err_noserver; | 1431 | goto out_err_noserver; |
1414 | } | 1432 | } |
1415 | 1433 | ||
1434 | if (server->flags & NFS_MOUNT_UNSHARED) | ||
1435 | compare_super = NULL; | ||
1436 | |||
1416 | /* Get a superblock - note that we may end up sharing one that already exists */ | 1437 | /* Get a superblock - note that we may end up sharing one that already exists */ |
1417 | s = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server); | 1438 | s = sget(&nfs_fs_type, compare_super, nfs_set_super, server); |
1418 | if (IS_ERR(s)) { | 1439 | if (IS_ERR(s)) { |
1419 | error = PTR_ERR(s); | 1440 | error = PTR_ERR(s); |
1420 | goto out_err_nosb; | 1441 | goto out_err_nosb; |
@@ -1657,6 +1678,7 @@ static int nfs4_get_sb(struct file_system_type *fs_type, | |||
1657 | struct nfs_fh mntfh; | 1678 | struct nfs_fh mntfh; |
1658 | struct dentry *mntroot; | 1679 | struct dentry *mntroot; |
1659 | char *mntpath = NULL, *hostname = NULL, *ip_addr = NULL; | 1680 | char *mntpath = NULL, *hostname = NULL, *ip_addr = NULL; |
1681 | int (*compare_super)(struct super_block *, void *) = nfs_compare_super; | ||
1660 | int error; | 1682 | int error; |
1661 | 1683 | ||
1662 | /* Validate the mount data */ | 1684 | /* Validate the mount data */ |
@@ -1673,8 +1695,11 @@ static int nfs4_get_sb(struct file_system_type *fs_type, | |||
1673 | goto out; | 1695 | goto out; |
1674 | } | 1696 | } |
1675 | 1697 | ||
1698 | if (server->flags & NFS4_MOUNT_UNSHARED) | ||
1699 | compare_super = NULL; | ||
1700 | |||
1676 | /* Get a superblock - note that we may end up sharing one that already exists */ | 1701 | /* Get a superblock - note that we may end up sharing one that already exists */ |
1677 | s = sget(fs_type, nfs_compare_super, nfs_set_super, server); | 1702 | s = sget(fs_type, compare_super, nfs_set_super, server); |
1678 | if (IS_ERR(s)) { | 1703 | if (IS_ERR(s)) { |
1679 | error = PTR_ERR(s); | 1704 | error = PTR_ERR(s); |
1680 | goto out_free; | 1705 | goto out_free; |
@@ -1740,6 +1765,7 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags, | |||
1740 | struct super_block *s; | 1765 | struct super_block *s; |
1741 | struct nfs_server *server; | 1766 | struct nfs_server *server; |
1742 | struct dentry *mntroot; | 1767 | struct dentry *mntroot; |
1768 | int (*compare_super)(struct super_block *, void *) = nfs_compare_super; | ||
1743 | int error; | 1769 | int error; |
1744 | 1770 | ||
1745 | dprintk("--> nfs4_xdev_get_sb()\n"); | 1771 | dprintk("--> nfs4_xdev_get_sb()\n"); |
@@ -1751,8 +1777,11 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags, | |||
1751 | goto out_err_noserver; | 1777 | goto out_err_noserver; |
1752 | } | 1778 | } |
1753 | 1779 | ||
1780 | if (server->flags & NFS4_MOUNT_UNSHARED) | ||
1781 | compare_super = NULL; | ||
1782 | |||
1754 | /* Get a superblock - note that we may end up sharing one that already exists */ | 1783 | /* Get a superblock - note that we may end up sharing one that already exists */ |
1755 | s = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server); | 1784 | s = sget(&nfs_fs_type, compare_super, nfs_set_super, server); |
1756 | if (IS_ERR(s)) { | 1785 | if (IS_ERR(s)) { |
1757 | error = PTR_ERR(s); | 1786 | error = PTR_ERR(s); |
1758 | goto out_err_nosb; | 1787 | goto out_err_nosb; |
@@ -1807,6 +1836,7 @@ static int nfs4_referral_get_sb(struct file_system_type *fs_type, int flags, | |||
1807 | struct nfs_server *server; | 1836 | struct nfs_server *server; |
1808 | struct dentry *mntroot; | 1837 | struct dentry *mntroot; |
1809 | struct nfs_fh mntfh; | 1838 | struct nfs_fh mntfh; |
1839 | int (*compare_super)(struct super_block *, void *) = nfs_compare_super; | ||
1810 | int error; | 1840 | int error; |
1811 | 1841 | ||
1812 | dprintk("--> nfs4_referral_get_sb()\n"); | 1842 | dprintk("--> nfs4_referral_get_sb()\n"); |
@@ -1818,8 +1848,11 @@ static int nfs4_referral_get_sb(struct file_system_type *fs_type, int flags, | |||
1818 | goto out_err_noserver; | 1848 | goto out_err_noserver; |
1819 | } | 1849 | } |
1820 | 1850 | ||
1851 | if (server->flags & NFS4_MOUNT_UNSHARED) | ||
1852 | compare_super = NULL; | ||
1853 | |||
1821 | /* Get a superblock - note that we may end up sharing one that already exists */ | 1854 | /* Get a superblock - note that we may end up sharing one that already exists */ |
1822 | s = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server); | 1855 | s = sget(&nfs_fs_type, compare_super, nfs_set_super, server); |
1823 | if (IS_ERR(s)) { | 1856 | if (IS_ERR(s)) { |
1824 | error = PTR_ERR(s); | 1857 | error = PTR_ERR(s); |
1825 | goto out_err_nosb; | 1858 | goto out_err_nosb; |
diff --git a/include/linux/nfs4_mount.h b/include/linux/nfs4_mount.h index d8d7480e5a47..a0dcf6655657 100644 --- a/include/linux/nfs4_mount.h +++ b/include/linux/nfs4_mount.h | |||
@@ -65,6 +65,7 @@ struct nfs4_mount_data { | |||
65 | #define NFS4_MOUNT_NOCTO 0x0010 /* 1 */ | 65 | #define NFS4_MOUNT_NOCTO 0x0010 /* 1 */ |
66 | #define NFS4_MOUNT_NOAC 0x0020 /* 1 */ | 66 | #define NFS4_MOUNT_NOAC 0x0020 /* 1 */ |
67 | #define NFS4_MOUNT_STRICTLOCK 0x1000 /* 1 */ | 67 | #define NFS4_MOUNT_STRICTLOCK 0x1000 /* 1 */ |
68 | #define NFS4_MOUNT_FLAGMASK 0x1033 | 68 | #define NFS4_MOUNT_UNSHARED 0x8000 /* 1 */ |
69 | #define NFS4_MOUNT_FLAGMASK 0x9033 | ||
69 | 70 | ||
70 | #endif | 71 | #endif |
diff --git a/include/linux/nfs_mount.h b/include/linux/nfs_mount.h index 0b82a17c705b..a3ade89a64d2 100644 --- a/include/linux/nfs_mount.h +++ b/include/linux/nfs_mount.h | |||
@@ -62,6 +62,7 @@ struct nfs_mount_data { | |||
62 | #define NFS_MOUNT_STRICTLOCK 0x1000 /* reserved for NFSv4 */ | 62 | #define NFS_MOUNT_STRICTLOCK 0x1000 /* reserved for NFSv4 */ |
63 | #define NFS_MOUNT_SECFLAVOUR 0x2000 /* 5 */ | 63 | #define NFS_MOUNT_SECFLAVOUR 0x2000 /* 5 */ |
64 | #define NFS_MOUNT_NORDIRPLUS 0x4000 /* 5 */ | 64 | #define NFS_MOUNT_NORDIRPLUS 0x4000 /* 5 */ |
65 | #define NFS_MOUNT_UNSHARED 0x8000 /* 5 */ | ||
65 | #define NFS_MOUNT_FLAGMASK 0xFFFF | 66 | #define NFS_MOUNT_FLAGMASK 0xFFFF |
66 | 67 | ||
67 | #endif | 68 | #endif |