diff options
author | David Howells <dhowells@redhat.com> | 2019-04-25 09:26:52 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2019-04-25 09:26:52 -0400 |
commit | 6c6c1d63c243025956f061e67fff3a615aa0f6be (patch) | |
tree | 2dc16f2dfa389efcc4b53197a33a9654cf02f794 /fs/afs/super.c | |
parent | 80548b03991f58758a336424a90bf9f988e3b077 (diff) |
afs: Provide mount-time configurable byte-range file locking emulation
Provide byte-range file locking emulation that can be configured at mount
time to one of four modes:
(1) flock=local. Locking is done locally only and no reference is made to
the server.
(2) flock=openafs. Byte-range locking is done locally only; whole-file
locking is done with reference to the server. Whole-file locks cannot
be upgraded unless the client holds an exclusive lock.
(3) flock=strict. Byte-range and whole-file locking both require a
sufficient whole-file lock on the server.
(4) flock=write. As strict, but the client always gets an exclusive
whole-file lock on the server.
Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/afs/super.c')
-rw-r--r-- | fs/afs/super.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/fs/afs/super.c b/fs/afs/super.c index ce85ae61f12d..18334fa1a0d2 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c | |||
@@ -67,19 +67,30 @@ static atomic_t afs_count_active_inodes; | |||
67 | enum afs_param { | 67 | enum afs_param { |
68 | Opt_autocell, | 68 | Opt_autocell, |
69 | Opt_dyn, | 69 | Opt_dyn, |
70 | Opt_flock, | ||
70 | Opt_source, | 71 | Opt_source, |
71 | }; | 72 | }; |
72 | 73 | ||
73 | static const struct fs_parameter_spec afs_param_specs[] = { | 74 | static const struct fs_parameter_spec afs_param_specs[] = { |
74 | fsparam_flag ("autocell", Opt_autocell), | 75 | fsparam_flag ("autocell", Opt_autocell), |
75 | fsparam_flag ("dyn", Opt_dyn), | 76 | fsparam_flag ("dyn", Opt_dyn), |
77 | fsparam_enum ("flock", Opt_flock), | ||
76 | fsparam_string("source", Opt_source), | 78 | fsparam_string("source", Opt_source), |
77 | {} | 79 | {} |
78 | }; | 80 | }; |
79 | 81 | ||
82 | static const struct fs_parameter_enum afs_param_enums[] = { | ||
83 | { Opt_flock, "local", afs_flock_mode_local }, | ||
84 | { Opt_flock, "openafs", afs_flock_mode_openafs }, | ||
85 | { Opt_flock, "strict", afs_flock_mode_strict }, | ||
86 | { Opt_flock, "write", afs_flock_mode_write }, | ||
87 | {} | ||
88 | }; | ||
89 | |||
80 | static const struct fs_parameter_description afs_fs_parameters = { | 90 | static const struct fs_parameter_description afs_fs_parameters = { |
81 | .name = "kAFS", | 91 | .name = "kAFS", |
82 | .specs = afs_param_specs, | 92 | .specs = afs_param_specs, |
93 | .enums = afs_param_enums, | ||
83 | }; | 94 | }; |
84 | 95 | ||
85 | /* | 96 | /* |
@@ -182,11 +193,22 @@ static int afs_show_devname(struct seq_file *m, struct dentry *root) | |||
182 | static int afs_show_options(struct seq_file *m, struct dentry *root) | 193 | static int afs_show_options(struct seq_file *m, struct dentry *root) |
183 | { | 194 | { |
184 | struct afs_super_info *as = AFS_FS_S(root->d_sb); | 195 | struct afs_super_info *as = AFS_FS_S(root->d_sb); |
196 | const char *p = NULL; | ||
185 | 197 | ||
186 | if (as->dyn_root) | 198 | if (as->dyn_root) |
187 | seq_puts(m, ",dyn"); | 199 | seq_puts(m, ",dyn"); |
188 | if (test_bit(AFS_VNODE_AUTOCELL, &AFS_FS_I(d_inode(root))->flags)) | 200 | if (test_bit(AFS_VNODE_AUTOCELL, &AFS_FS_I(d_inode(root))->flags)) |
189 | seq_puts(m, ",autocell"); | 201 | seq_puts(m, ",autocell"); |
202 | switch (as->flock_mode) { | ||
203 | case afs_flock_mode_unset: break; | ||
204 | case afs_flock_mode_local: p = "local"; break; | ||
205 | case afs_flock_mode_openafs: p = "openafs"; break; | ||
206 | case afs_flock_mode_strict: p = "strict"; break; | ||
207 | case afs_flock_mode_write: p = "write"; break; | ||
208 | } | ||
209 | if (p) | ||
210 | seq_printf(m, ",flock=%s", p); | ||
211 | |||
190 | return 0; | 212 | return 0; |
191 | } | 213 | } |
192 | 214 | ||
@@ -315,6 +337,10 @@ static int afs_parse_param(struct fs_context *fc, struct fs_parameter *param) | |||
315 | ctx->dyn_root = true; | 337 | ctx->dyn_root = true; |
316 | break; | 338 | break; |
317 | 339 | ||
340 | case Opt_flock: | ||
341 | ctx->flock_mode = result.uint_32; | ||
342 | break; | ||
343 | |||
318 | default: | 344 | default: |
319 | return -EINVAL; | 345 | return -EINVAL; |
320 | } | 346 | } |
@@ -466,6 +492,7 @@ static struct afs_super_info *afs_alloc_sbi(struct fs_context *fc) | |||
466 | as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL); | 492 | as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL); |
467 | if (as) { | 493 | if (as) { |
468 | as->net_ns = get_net(fc->net_ns); | 494 | as->net_ns = get_net(fc->net_ns); |
495 | as->flock_mode = ctx->flock_mode; | ||
469 | if (ctx->dyn_root) { | 496 | if (ctx->dyn_root) { |
470 | as->dyn_root = true; | 497 | as->dyn_root = true; |
471 | } else { | 498 | } else { |