aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/super.c')
-rw-r--r--fs/nfs/super.c59
1 files changed, 58 insertions, 1 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index ec3966e4706b..2e866d86c220 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -100,6 +100,7 @@ enum {
100 Opt_addr, Opt_mountaddr, Opt_clientaddr, 100 Opt_addr, Opt_mountaddr, Opt_clientaddr,
101 Opt_lookupcache, 101 Opt_lookupcache,
102 Opt_fscache_uniq, 102 Opt_fscache_uniq,
103 Opt_local_lock,
103 104
104 /* Special mount options */ 105 /* Special mount options */
105 Opt_userspace, Opt_deprecated, Opt_sloppy, 106 Opt_userspace, Opt_deprecated, Opt_sloppy,
@@ -171,6 +172,7 @@ static const match_table_t nfs_mount_option_tokens = {
171 172
172 { Opt_lookupcache, "lookupcache=%s" }, 173 { Opt_lookupcache, "lookupcache=%s" },
173 { Opt_fscache_uniq, "fsc=%s" }, 174 { Opt_fscache_uniq, "fsc=%s" },
175 { Opt_local_lock, "local_lock=%s" },
174 176
175 { Opt_err, NULL } 177 { Opt_err, NULL }
176}; 178};
@@ -236,6 +238,22 @@ static match_table_t nfs_lookupcache_tokens = {
236 { Opt_lookupcache_err, NULL } 238 { Opt_lookupcache_err, NULL }
237}; 239};
238 240
241enum {
242 Opt_local_lock_all, Opt_local_lock_flock, Opt_local_lock_posix,
243 Opt_local_lock_none,
244
245 Opt_local_lock_err
246};
247
248static match_table_t nfs_local_lock_tokens = {
249 { Opt_local_lock_all, "all" },
250 { Opt_local_lock_flock, "flock" },
251 { Opt_local_lock_posix, "posix" },
252 { Opt_local_lock_none, "none" },
253
254 { Opt_local_lock_err, NULL }
255};
256
239 257
240static void nfs_umount_begin(struct super_block *); 258static void nfs_umount_begin(struct super_block *);
241static int nfs_statfs(struct dentry *, struct kstatfs *); 259static int nfs_statfs(struct dentry *, struct kstatfs *);
@@ -1009,9 +1027,13 @@ static int nfs_parse_mount_options(char *raw,
1009 break; 1027 break;
1010 case Opt_lock: 1028 case Opt_lock:
1011 mnt->flags &= ~NFS_MOUNT_NONLM; 1029 mnt->flags &= ~NFS_MOUNT_NONLM;
1030 mnt->flags &= ~(NFS_MOUNT_LOCAL_FLOCK |
1031 NFS_MOUNT_LOCAL_FCNTL);
1012 break; 1032 break;
1013 case Opt_nolock: 1033 case Opt_nolock:
1014 mnt->flags |= NFS_MOUNT_NONLM; 1034 mnt->flags |= NFS_MOUNT_NONLM;
1035 mnt->flags |= (NFS_MOUNT_LOCAL_FLOCK |
1036 NFS_MOUNT_LOCAL_FCNTL);
1015 break; 1037 break;
1016 case Opt_v2: 1038 case Opt_v2:
1017 mnt->flags &= ~NFS_MOUNT_VER3; 1039 mnt->flags &= ~NFS_MOUNT_VER3;
@@ -1412,6 +1434,34 @@ static int nfs_parse_mount_options(char *raw,
1412 mnt->fscache_uniq = string; 1434 mnt->fscache_uniq = string;
1413 mnt->options |= NFS_OPTION_FSCACHE; 1435 mnt->options |= NFS_OPTION_FSCACHE;
1414 break; 1436 break;
1437 case Opt_local_lock:
1438 string = match_strdup(args);
1439 if (string == NULL)
1440 goto out_nomem;
1441 token = match_token(string, nfs_local_lock_tokens,
1442 args);
1443 kfree(string);
1444 switch (token) {
1445 case Opt_local_lock_all:
1446 mnt->flags |= (NFS_MOUNT_LOCAL_FLOCK |
1447 NFS_MOUNT_LOCAL_FCNTL);
1448 break;
1449 case Opt_local_lock_flock:
1450 mnt->flags |= NFS_MOUNT_LOCAL_FLOCK;
1451 break;
1452 case Opt_local_lock_posix:
1453 mnt->flags |= NFS_MOUNT_LOCAL_FCNTL;
1454 break;
1455 case Opt_local_lock_none:
1456 mnt->flags &= ~(NFS_MOUNT_LOCAL_FLOCK |
1457 NFS_MOUNT_LOCAL_FCNTL);
1458 break;
1459 default:
1460 dfprintk(MOUNT, "NFS: invalid "
1461 "local_lock argument\n");
1462 return 0;
1463 };
1464 break;
1415 1465
1416 /* 1466 /*
1417 * Special options 1467 * Special options
@@ -1817,6 +1867,12 @@ static int nfs_validate_mount_data(void *options,
1817 if (!args->nfs_server.hostname) 1867 if (!args->nfs_server.hostname)
1818 goto out_nomem; 1868 goto out_nomem;
1819 1869
1870 if (!(data->flags & NFS_MOUNT_NONLM))
1871 args->flags &= ~(NFS_MOUNT_LOCAL_FLOCK|
1872 NFS_MOUNT_LOCAL_FCNTL);
1873 else
1874 args->flags |= (NFS_MOUNT_LOCAL_FLOCK|
1875 NFS_MOUNT_LOCAL_FCNTL);
1820 /* 1876 /*
1821 * The legacy version 6 binary mount data from userspace has a 1877 * The legacy version 6 binary mount data from userspace has a
1822 * field used only to transport selinux information into the 1878 * field used only to transport selinux information into the
@@ -2433,7 +2489,8 @@ static void nfs4_fill_super(struct super_block *sb)
2433 2489
2434static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *args) 2490static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *args)
2435{ 2491{
2436 args->flags &= ~(NFS_MOUNT_NONLM|NFS_MOUNT_NOACL|NFS_MOUNT_VER3); 2492 args->flags &= ~(NFS_MOUNT_NONLM|NFS_MOUNT_NOACL|NFS_MOUNT_VER3|
2493 NFS_MOUNT_LOCAL_FLOCK|NFS_MOUNT_LOCAL_FCNTL);
2437} 2494}
2438 2495
2439static int nfs4_validate_text_mount_data(void *options, 2496static int nfs4_validate_text_mount_data(void *options,