Skip to content

Commit 432f7c7

Browse files
Eric Sandeenbrauner
authored andcommitted
hfsplus: convert hfsplus to use the new mount api
Convert the hfsplus filesystem to use the new mount API. Tested by comparing random mount & remount options before and after the change. Signed-off-by: Eric Sandeen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Jan Kara <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
1 parent ffcd06b commit 432f7c7

File tree

3 files changed

+149
-202
lines changed

3 files changed

+149
-202
lines changed

fs/hfsplus/hfsplus_fs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <linux/mutex.h>
2222
#include <linux/buffer_head.h>
2323
#include <linux/blkdev.h>
24+
#include <linux/fs_context.h>
2425
#include "hfsplus_raw.h"
2526

2627
#define DBG_BNODE_REFS 0x00000001
@@ -496,8 +497,7 @@ long hfsplus_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
496497

497498
/* options.c */
498499
void hfsplus_fill_defaults(struct hfsplus_sb_info *opts);
499-
int hfsplus_parse_options_remount(char *input, int *force);
500-
int hfsplus_parse_options(char *input, struct hfsplus_sb_info *sbi);
500+
int hfsplus_parse_param(struct fs_context *fc, struct fs_parameter *param);
501501
int hfsplus_show_options(struct seq_file *seq, struct dentry *root);
502502

503503
/* part_tbl.c */

fs/hfsplus/options.c

Lines changed: 94 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
#include <linux/string.h>
1313
#include <linux/kernel.h>
1414
#include <linux/sched.h>
15-
#include <linux/parser.h>
15+
#include <linux/fs_context.h>
16+
#include <linux/fs_parser.h>
1617
#include <linux/nls.h>
1718
#include <linux/mount.h>
1819
#include <linux/seq_file.h>
@@ -23,26 +24,23 @@ enum {
2324
opt_creator, opt_type,
2425
opt_umask, opt_uid, opt_gid,
2526
opt_part, opt_session, opt_nls,
26-
opt_nodecompose, opt_decompose,
27-
opt_barrier, opt_nobarrier,
28-
opt_force, opt_err
27+
opt_decompose, opt_barrier,
28+
opt_force,
2929
};
3030

31-
static const match_table_t tokens = {
32-
{ opt_creator, "creator=%s" },
33-
{ opt_type, "type=%s" },
34-
{ opt_umask, "umask=%o" },
35-
{ opt_uid, "uid=%u" },
36-
{ opt_gid, "gid=%u" },
37-
{ opt_part, "part=%u" },
38-
{ opt_session, "session=%u" },
39-
{ opt_nls, "nls=%s" },
40-
{ opt_decompose, "decompose" },
41-
{ opt_nodecompose, "nodecompose" },
42-
{ opt_barrier, "barrier" },
43-
{ opt_nobarrier, "nobarrier" },
44-
{ opt_force, "force" },
45-
{ opt_err, NULL }
31+
static const struct fs_parameter_spec hfs_param_spec[] = {
32+
fsparam_string ("creator", opt_creator),
33+
fsparam_string ("type", opt_type),
34+
fsparam_u32oct ("umask", opt_umask),
35+
fsparam_u32 ("uid", opt_uid),
36+
fsparam_u32 ("gid", opt_gid),
37+
fsparam_u32 ("part", opt_part),
38+
fsparam_u32 ("session", opt_session),
39+
fsparam_string ("nls", opt_nls),
40+
fsparam_flag_no ("decompose", opt_decompose),
41+
fsparam_flag_no ("barrier", opt_barrier),
42+
fsparam_flag ("force", opt_force),
43+
{}
4644
};
4745

4846
/* Initialize an options object to reasonable defaults */
@@ -60,162 +58,89 @@ void hfsplus_fill_defaults(struct hfsplus_sb_info *opts)
6058
opts->session = -1;
6159
}
6260

63-
/* convert a "four byte character" to a 32 bit int with error checks */
64-
static inline int match_fourchar(substring_t *arg, u32 *result)
61+
/* Parse options from mount. Returns nonzero errno on failure */
62+
int hfsplus_parse_param(struct fs_context *fc, struct fs_parameter *param)
6563
{
66-
if (arg->to - arg->from != 4)
67-
return -EINVAL;
68-
memcpy(result, arg->from, 4);
69-
return 0;
70-
}
71-
72-
int hfsplus_parse_options_remount(char *input, int *force)
73-
{
74-
char *p;
75-
substring_t args[MAX_OPT_ARGS];
76-
int token;
77-
78-
if (!input)
79-
return 1;
80-
81-
while ((p = strsep(&input, ",")) != NULL) {
82-
if (!*p)
83-
continue;
84-
85-
token = match_token(p, tokens, args);
86-
switch (token) {
87-
case opt_force:
88-
*force = 1;
89-
break;
90-
default:
91-
break;
64+
struct hfsplus_sb_info *sbi = fc->s_fs_info;
65+
struct fs_parse_result result;
66+
int opt;
67+
68+
/*
69+
* Only the force option is examined during remount, all others
70+
* are ignored.
71+
*/
72+
if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE &&
73+
strncmp(param->key, "force", 5))
74+
return 0;
75+
76+
opt = fs_parse(fc, hfs_param_spec, param, &result);
77+
if (opt < 0)
78+
return opt;
79+
80+
switch (opt) {
81+
case opt_creator:
82+
if (strlen(param->string) != 4) {
83+
pr_err("creator requires a 4 character value\n");
84+
return -EINVAL;
9285
}
93-
}
94-
95-
return 1;
96-
}
97-
98-
/* Parse options from mount. Returns 0 on failure */
99-
/* input is the options passed to mount() as a string */
100-
int hfsplus_parse_options(char *input, struct hfsplus_sb_info *sbi)
101-
{
102-
char *p;
103-
substring_t args[MAX_OPT_ARGS];
104-
int tmp, token;
105-
106-
if (!input)
107-
goto done;
108-
109-
while ((p = strsep(&input, ",")) != NULL) {
110-
if (!*p)
111-
continue;
112-
113-
token = match_token(p, tokens, args);
114-
switch (token) {
115-
case opt_creator:
116-
if (match_fourchar(&args[0], &sbi->creator)) {
117-
pr_err("creator requires a 4 character value\n");
118-
return 0;
119-
}
120-
break;
121-
case opt_type:
122-
if (match_fourchar(&args[0], &sbi->type)) {
123-
pr_err("type requires a 4 character value\n");
124-
return 0;
125-
}
126-
break;
127-
case opt_umask:
128-
if (match_octal(&args[0], &tmp)) {
129-
pr_err("umask requires a value\n");
130-
return 0;
131-
}
132-
sbi->umask = (umode_t)tmp;
133-
break;
134-
case opt_uid:
135-
if (match_int(&args[0], &tmp)) {
136-
pr_err("uid requires an argument\n");
137-
return 0;
138-
}
139-
sbi->uid = make_kuid(current_user_ns(), (uid_t)tmp);
140-
if (!uid_valid(sbi->uid)) {
141-
pr_err("invalid uid specified\n");
142-
return 0;
143-
} else {
144-
set_bit(HFSPLUS_SB_UID, &sbi->flags);
145-
}
146-
break;
147-
case opt_gid:
148-
if (match_int(&args[0], &tmp)) {
149-
pr_err("gid requires an argument\n");
150-
return 0;
151-
}
152-
sbi->gid = make_kgid(current_user_ns(), (gid_t)tmp);
153-
if (!gid_valid(sbi->gid)) {
154-
pr_err("invalid gid specified\n");
155-
return 0;
156-
} else {
157-
set_bit(HFSPLUS_SB_GID, &sbi->flags);
158-
}
159-
break;
160-
case opt_part:
161-
if (match_int(&args[0], &sbi->part)) {
162-
pr_err("part requires an argument\n");
163-
return 0;
164-
}
165-
break;
166-
case opt_session:
167-
if (match_int(&args[0], &sbi->session)) {
168-
pr_err("session requires an argument\n");
169-
return 0;
170-
}
171-
break;
172-
case opt_nls:
173-
if (sbi->nls) {
174-
pr_err("unable to change nls mapping\n");
175-
return 0;
176-
}
177-
p = match_strdup(&args[0]);
178-
if (p)
179-
sbi->nls = load_nls(p);
180-
if (!sbi->nls) {
181-
pr_err("unable to load nls mapping \"%s\"\n",
182-
p);
183-
kfree(p);
184-
return 0;
185-
}
186-
kfree(p);
187-
break;
188-
case opt_decompose:
189-
clear_bit(HFSPLUS_SB_NODECOMPOSE, &sbi->flags);
190-
break;
191-
case opt_nodecompose:
86+
memcpy(&sbi->creator, param->string, 4);
87+
break;
88+
case opt_type:
89+
if (strlen(param->string) != 4) {
90+
pr_err("type requires a 4 character value\n");
91+
return -EINVAL;
92+
}
93+
memcpy(&sbi->type, param->string, 4);
94+
break;
95+
case opt_umask:
96+
sbi->umask = (umode_t)result.uint_32;
97+
break;
98+
case opt_uid:
99+
sbi->uid = result.uid;
100+
set_bit(HFSPLUS_SB_UID, &sbi->flags);
101+
break;
102+
case opt_gid:
103+
sbi->gid = result.gid;
104+
set_bit(HFSPLUS_SB_GID, &sbi->flags);
105+
break;
106+
case opt_part:
107+
sbi->part = result.uint_32;
108+
break;
109+
case opt_session:
110+
sbi->session = result.uint_32;
111+
break;
112+
case opt_nls:
113+
if (sbi->nls) {
114+
pr_err("unable to change nls mapping\n");
115+
return -EINVAL;
116+
}
117+
sbi->nls = load_nls(param->string);
118+
if (!sbi->nls) {
119+
pr_err("unable to load nls mapping \"%s\"\n",
120+
param->string);
121+
return -EINVAL;
122+
}
123+
break;
124+
case opt_decompose:
125+
if (result.negated)
192126
set_bit(HFSPLUS_SB_NODECOMPOSE, &sbi->flags);
193-
break;
194-
case opt_barrier:
195-
clear_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags);
196-
break;
197-
case opt_nobarrier:
127+
else
128+
clear_bit(HFSPLUS_SB_NODECOMPOSE, &sbi->flags);
129+
break;
130+
case opt_barrier:
131+
if (result.negated)
198132
set_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags);
199-
break;
200-
case opt_force:
201-
set_bit(HFSPLUS_SB_FORCE, &sbi->flags);
202-
break;
203-
default:
204-
return 0;
205-
}
206-
}
207-
208-
done:
209-
if (!sbi->nls) {
210-
/* try utf8 first, as this is the old default behaviour */
211-
sbi->nls = load_nls("utf8");
212-
if (!sbi->nls)
213-
sbi->nls = load_nls_default();
214-
if (!sbi->nls)
215-
return 0;
133+
else
134+
clear_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags);
135+
break;
136+
case opt_force:
137+
set_bit(HFSPLUS_SB_FORCE, &sbi->flags);
138+
break;
139+
default:
140+
return -EINVAL;
216141
}
217142

218-
return 1;
143+
return 0;
219144
}
220145

221146
int hfsplus_show_options(struct seq_file *seq, struct dentry *root)

0 commit comments

Comments
 (0)