1 // SPDX-License-Identifier: GPL-2.0
3 * linux/fs/hfsplus/options.c
6 * Brad Boyer (flar@allandria.com)
7 * (C) 2003 Ardis Technologies <roman@ardistech.com>
12 #include <linux/string.h>
13 #include <linux/kernel.h>
14 #include <linux/sched.h>
15 #include <linux/parser.h>
16 #include <linux/nls.h>
17 #include <linux/mount.h>
18 #include <linux/seq_file.h>
19 #include <linux/slab.h>
20 #include "hfsplus_fs.h"
23 opt_creator
, opt_type
,
24 opt_umask
, opt_uid
, opt_gid
,
25 opt_part
, opt_session
, opt_nls
,
26 opt_nodecompose
, opt_decompose
,
27 opt_barrier
, opt_nobarrier
,
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" },
48 /* Initialize an options object to reasonable defaults */
49 void hfsplus_fill_defaults(struct hfsplus_sb_info
*opts
)
54 opts
->creator
= HFSPLUS_DEF_CR_TYPE
;
55 opts
->type
= HFSPLUS_DEF_CR_TYPE
;
56 opts
->umask
= current_umask();
57 opts
->uid
= current_uid();
58 opts
->gid
= current_gid();
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
)
66 if (arg
->to
- arg
->from
!= 4)
68 memcpy(result
, arg
->from
, 4);
72 int hfsplus_parse_options_remount(char *input
, int *force
)
75 substring_t args
[MAX_OPT_ARGS
];
81 while ((p
= strsep(&input
, ",")) != NULL
) {
85 token
= match_token(p
, tokens
, args
);
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
)
103 substring_t args
[MAX_OPT_ARGS
];
109 while ((p
= strsep(&input
, ",")) != NULL
) {
113 token
= match_token(p
, tokens
, args
);
116 if (match_fourchar(&args
[0], &sbi
->creator
)) {
117 pr_err("creator requires a 4 character value\n");
122 if (match_fourchar(&args
[0], &sbi
->type
)) {
123 pr_err("type requires a 4 character value\n");
128 if (match_octal(&args
[0], &tmp
)) {
129 pr_err("umask requires a value\n");
132 sbi
->umask
= (umode_t
)tmp
;
135 if (match_int(&args
[0], &tmp
)) {
136 pr_err("uid requires an argument\n");
139 sbi
->uid
= make_kuid(current_user_ns(), (uid_t
)tmp
);
140 if (!uid_valid(sbi
->uid
)) {
141 pr_err("invalid uid specified\n");
144 set_bit(HFSPLUS_SB_UID
, &sbi
->flags
);
148 if (match_int(&args
[0], &tmp
)) {
149 pr_err("gid requires an argument\n");
152 sbi
->gid
= make_kgid(current_user_ns(), (gid_t
)tmp
);
153 if (!gid_valid(sbi
->gid
)) {
154 pr_err("invalid gid specified\n");
157 set_bit(HFSPLUS_SB_GID
, &sbi
->flags
);
161 if (match_int(&args
[0], &sbi
->part
)) {
162 pr_err("part requires an argument\n");
167 if (match_int(&args
[0], &sbi
->session
)) {
168 pr_err("session requires an argument\n");
174 pr_err("unable to change nls mapping\n");
177 p
= match_strdup(&args
[0]);
179 sbi
->nls
= load_nls(p
);
181 pr_err("unable to load nls mapping \"%s\"\n",
189 clear_bit(HFSPLUS_SB_NODECOMPOSE
, &sbi
->flags
);
191 case opt_nodecompose
:
192 set_bit(HFSPLUS_SB_NODECOMPOSE
, &sbi
->flags
);
195 clear_bit(HFSPLUS_SB_NOBARRIER
, &sbi
->flags
);
198 set_bit(HFSPLUS_SB_NOBARRIER
, &sbi
->flags
);
201 set_bit(HFSPLUS_SB_FORCE
, &sbi
->flags
);
210 /* try utf8 first, as this is the old default behaviour */
211 sbi
->nls
= load_nls("utf8");
213 sbi
->nls
= load_nls_default();
221 int hfsplus_show_options(struct seq_file
*seq
, struct dentry
*root
)
223 struct hfsplus_sb_info
*sbi
= HFSPLUS_SB(root
->d_sb
);
225 if (sbi
->creator
!= HFSPLUS_DEF_CR_TYPE
)
226 seq_show_option_n(seq
, "creator", (char *)&sbi
->creator
, 4);
227 if (sbi
->type
!= HFSPLUS_DEF_CR_TYPE
)
228 seq_show_option_n(seq
, "type", (char *)&sbi
->type
, 4);
229 seq_printf(seq
, ",umask=%o,uid=%u,gid=%u", sbi
->umask
,
230 from_kuid_munged(&init_user_ns
, sbi
->uid
),
231 from_kgid_munged(&init_user_ns
, sbi
->gid
));
233 seq_printf(seq
, ",part=%u", sbi
->part
);
234 if (sbi
->session
>= 0)
235 seq_printf(seq
, ",session=%u", sbi
->session
);
237 seq_printf(seq
, ",nls=%s", sbi
->nls
->charset
);
238 if (test_bit(HFSPLUS_SB_NODECOMPOSE
, &sbi
->flags
))
239 seq_puts(seq
, ",nodecompose");
240 if (test_bit(HFSPLUS_SB_NOBARRIER
, &sbi
->flags
))
241 seq_puts(seq
, ",nobarrier");