diff options
author | David Howells <dhowells@redhat.com> | 2019-04-25 14:26:52 +0100 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2019-04-25 14:26:52 +0100 |
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; enum afs_param { Opt_autocell, Opt_dyn, + Opt_flock, Opt_source, }; static const struct fs_parameter_spec afs_param_specs[] = { fsparam_flag ("autocell", Opt_autocell), fsparam_flag ("dyn", Opt_dyn), + fsparam_enum ("flock", Opt_flock), fsparam_string("source", Opt_source), {} }; +static const struct fs_parameter_enum afs_param_enums[] = { + { Opt_flock, "local", afs_flock_mode_local }, + { Opt_flock, "openafs", afs_flock_mode_openafs }, + { Opt_flock, "strict", afs_flock_mode_strict }, + { Opt_flock, "write", afs_flock_mode_write }, + {} +}; + static const struct fs_parameter_description afs_fs_parameters = { .name = "kAFS", .specs = afs_param_specs, + .enums = afs_param_enums, }; /* @@ -182,11 +193,22 @@ static int afs_show_devname(struct seq_file *m, struct dentry *root) static int afs_show_options(struct seq_file *m, struct dentry *root) { struct afs_super_info *as = AFS_FS_S(root->d_sb); + const char *p = NULL; if (as->dyn_root) seq_puts(m, ",dyn"); if (test_bit(AFS_VNODE_AUTOCELL, &AFS_FS_I(d_inode(root))->flags)) seq_puts(m, ",autocell"); + switch (as->flock_mode) { + case afs_flock_mode_unset: break; + case afs_flock_mode_local: p = "local"; break; + case afs_flock_mode_openafs: p = "openafs"; break; + case afs_flock_mode_strict: p = "strict"; break; + case afs_flock_mode_write: p = "write"; break; + } + if (p) + seq_printf(m, ",flock=%s", p); + return 0; } @@ -315,6 +337,10 @@ static int afs_parse_param(struct fs_context *fc, struct fs_parameter *param) ctx->dyn_root = true; break; + case Opt_flock: + ctx->flock_mode = result.uint_32; + break; + default: return -EINVAL; } @@ -466,6 +492,7 @@ static struct afs_super_info *afs_alloc_sbi(struct fs_context *fc) as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL); if (as) { as->net_ns = get_net(fc->net_ns); + as->flock_mode = ctx->flock_mode; if (ctx->dyn_root) { as->dyn_root = true; } else { |