Skip to content

Commit 5916f43

Browse files
dhowellsbrauner
authored andcommitted
Convert coda to use the new mount API
Convert the coda filesystem to the new internal mount API as the old one will be obsoleted and removed. This allows greater flexibility in communication of mount parameters between userspace, the VFS and the filesystem. See Documentation/filesystems/mount_api.rst for more information. Note this is slightly tricky as coda currently only has a binary mount data interface. This is handled through the parse_monolithic hook. Also add a more conventional interface with a parameter named "fd" that takes an fd that refers to a coda psdev, thereby specifying the index to use. Signed-off-by: David Howells <dhowells@redhat.com> Co-developed-by: Eric Sandeen <sandeen@redhat.com> Signed-off-by: Eric Sandeen <sandeen@redhat.com> [sandeen: forward port to current upstream mount API interfaces] Link: https://lore.kernel.org/r/97650eeb-94c7-4041-b58c-90e81e76b699@redhat.com Tested-by: Jan Harkes <jaharkes@cs.cmu.edu> Reviewed-by: Ian Kent <raven@themaw.net> cc: coda@cs.cmu.edu Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent 0611a64 commit 5916f43

1 file changed

Lines changed: 98 additions & 45 deletions

File tree

fs/coda/inode.c

Lines changed: 98 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include <linux/pid_namespace.h>
2525
#include <linux/uaccess.h>
2626
#include <linux/fs.h>
27+
#include <linux/fs_context.h>
28+
#include <linux/fs_parser.h>
2729
#include <linux/vmalloc.h>
2830

2931
#include <linux/coda.h>
@@ -87,10 +89,10 @@ void coda_destroy_inodecache(void)
8789
kmem_cache_destroy(coda_inode_cachep);
8890
}
8991

90-
static int coda_remount(struct super_block *sb, int *flags, char *data)
92+
static int coda_reconfigure(struct fs_context *fc)
9193
{
92-
sync_filesystem(sb);
93-
*flags |= SB_NOATIME;
94+
sync_filesystem(fc->root->d_sb);
95+
fc->sb_flags |= SB_NOATIME;
9496
return 0;
9597
}
9698

@@ -102,78 +104,102 @@ static const struct super_operations coda_super_operations =
102104
.evict_inode = coda_evict_inode,
103105
.put_super = coda_put_super,
104106
.statfs = coda_statfs,
105-
.remount_fs = coda_remount,
106107
};
107108

108-
static int get_device_index(struct coda_mount_data *data)
109+
struct coda_fs_context {
110+
int idx;
111+
};
112+
113+
enum {
114+
Opt_fd,
115+
};
116+
117+
static const struct fs_parameter_spec coda_param_specs[] = {
118+
fsparam_fd ("fd", Opt_fd),
119+
{}
120+
};
121+
122+
static int coda_parse_fd(struct fs_context *fc, int fd)
109123
{
124+
struct coda_fs_context *ctx = fc->fs_private;
110125
struct fd f;
111126
struct inode *inode;
112127
int idx;
113128

114-
if (data == NULL) {
115-
pr_warn("%s: Bad mount data\n", __func__);
116-
return -1;
117-
}
118-
119-
if (data->version != CODA_MOUNT_VERSION) {
120-
pr_warn("%s: Bad mount version\n", __func__);
121-
return -1;
122-
}
123-
124-
f = fdget(data->fd);
129+
f = fdget(fd);
125130
if (!f.file)
126-
goto Ebadf;
131+
return -EBADF;
127132
inode = file_inode(f.file);
128133
if (!S_ISCHR(inode->i_mode) || imajor(inode) != CODA_PSDEV_MAJOR) {
129134
fdput(f);
130-
goto Ebadf;
135+
return invalf(fc, "code: Not coda psdev");
131136
}
132137

133138
idx = iminor(inode);
134139
fdput(f);
135140

136-
if (idx < 0 || idx >= MAX_CODADEVS) {
137-
pr_warn("%s: Bad minor number\n", __func__);
138-
return -1;
141+
if (idx < 0 || idx >= MAX_CODADEVS)
142+
return invalf(fc, "coda: Bad minor number");
143+
ctx->idx = idx;
144+
return 0;
145+
}
146+
147+
static int coda_parse_param(struct fs_context *fc, struct fs_parameter *param)
148+
{
149+
struct fs_parse_result result;
150+
int opt;
151+
152+
opt = fs_parse(fc, coda_param_specs, param, &result);
153+
if (opt < 0)
154+
return opt;
155+
156+
switch (opt) {
157+
case Opt_fd:
158+
return coda_parse_fd(fc, result.uint_32);
139159
}
140160

141-
return idx;
142-
Ebadf:
143-
pr_warn("%s: Bad file\n", __func__);
144-
return -1;
161+
return 0;
162+
}
163+
164+
/*
165+
* Parse coda's binary mount data form. We ignore any errors and go with index
166+
* 0 if we get one for backward compatibility.
167+
*/
168+
static int coda_parse_monolithic(struct fs_context *fc, void *_data)
169+
{
170+
struct coda_mount_data *data = _data;
171+
172+
if (!data)
173+
return invalf(fc, "coda: Bad mount data");
174+
175+
if (data->version != CODA_MOUNT_VERSION)
176+
return invalf(fc, "coda: Bad mount version");
177+
178+
coda_parse_fd(fc, data->fd);
179+
return 0;
145180
}
146181

147-
static int coda_fill_super(struct super_block *sb, void *data, int silent)
182+
static int coda_fill_super(struct super_block *sb, struct fs_context *fc)
148183
{
184+
struct coda_fs_context *ctx = fc->fs_private;
149185
struct inode *root = NULL;
150186
struct venus_comm *vc;
151187
struct CodaFid fid;
152188
int error;
153-
int idx;
154-
155-
if (task_active_pid_ns(current) != &init_pid_ns)
156-
return -EINVAL;
157-
158-
idx = get_device_index((struct coda_mount_data *) data);
159189

160-
/* Ignore errors in data, for backward compatibility */
161-
if(idx == -1)
162-
idx = 0;
163-
164-
pr_info("%s: device index: %i\n", __func__, idx);
190+
infof(fc, "coda: device index: %i\n", ctx->idx);
165191

166-
vc = &coda_comms[idx];
192+
vc = &coda_comms[ctx->idx];
167193
mutex_lock(&vc->vc_mutex);
168194

169195
if (!vc->vc_inuse) {
170-
pr_warn("%s: No pseudo device\n", __func__);
196+
errorf(fc, "coda: No pseudo device");
171197
error = -EINVAL;
172198
goto unlock_out;
173199
}
174200

175201
if (vc->vc_sb) {
176-
pr_warn("%s: Device already mounted\n", __func__);
202+
errorf(fc, "coda: Device already mounted");
177203
error = -EBUSY;
178204
goto unlock_out;
179205
}
@@ -313,18 +339,45 @@ static int coda_statfs(struct dentry *dentry, struct kstatfs *buf)
313339
return 0;
314340
}
315341

316-
/* init_coda: used by filesystems.c to register coda */
342+
static int coda_get_tree(struct fs_context *fc)
343+
{
344+
if (task_active_pid_ns(current) != &init_pid_ns)
345+
return -EINVAL;
317346

318-
static struct dentry *coda_mount(struct file_system_type *fs_type,
319-
int flags, const char *dev_name, void *data)
347+
return get_tree_nodev(fc, coda_fill_super);
348+
}
349+
350+
static void coda_free_fc(struct fs_context *fc)
320351
{
321-
return mount_nodev(fs_type, flags, data, coda_fill_super);
352+
kfree(fc->fs_private);
353+
}
354+
355+
static const struct fs_context_operations coda_context_ops = {
356+
.free = coda_free_fc,
357+
.parse_param = coda_parse_param,
358+
.parse_monolithic = coda_parse_monolithic,
359+
.get_tree = coda_get_tree,
360+
.reconfigure = coda_reconfigure,
361+
};
362+
363+
static int coda_init_fs_context(struct fs_context *fc)
364+
{
365+
struct coda_fs_context *ctx;
366+
367+
ctx = kzalloc(sizeof(struct coda_fs_context), GFP_KERNEL);
368+
if (!ctx)
369+
return -ENOMEM;
370+
371+
fc->fs_private = ctx;
372+
fc->ops = &coda_context_ops;
373+
return 0;
322374
}
323375

324376
struct file_system_type coda_fs_type = {
325377
.owner = THIS_MODULE,
326378
.name = "coda",
327-
.mount = coda_mount,
379+
.init_fs_context = coda_init_fs_context,
380+
.parameters = coda_param_specs,
328381
.kill_sb = kill_anon_super,
329382
.fs_flags = FS_BINARY_MOUNTDATA,
330383
};

0 commit comments

Comments
 (0)