summaryrefslogtreecommitdiffstats
path: root/fs/afs/super.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2019-04-25 09:26:52 -0400
committerDavid Howells <dhowells@redhat.com>2019-04-25 09:26:52 -0400
commit6c6c1d63c243025956f061e67fff3a615aa0f6be (patch)
tree2dc16f2dfa389efcc4b53197a33a9654cf02f794 /fs/afs/super.c
parent80548b03991f58758a336424a90bf9f988e3b077 (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.c27
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;
67enum afs_param { 67enum 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
73static const struct fs_parameter_spec afs_param_specs[] = { 74static 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
82static 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
80static const struct fs_parameter_description afs_fs_parameters = { 90static 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)
182static int afs_show_options(struct seq_file *m, struct dentry *root) 193static 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 {