2 * linux/fs/hfsplus/options.c
5 * Brad Boyer (flar@allandria.com)
6 * (C) 2003 Ardis Technologies <roman@ardistech.com>
11 #include <linux/string.h>
12 #include <linux/kernel.h>
13 #include <linux/sched.h>
14 #include <linux/parser.h>
15 #include <linux/nls.h>
16 #include <linux/mount.h>
17 #include <linux/seq_file.h>
18 #include "hfsplus_fs.h"
21 opt_creator
, opt_type
,
22 opt_umask
, opt_uid
, opt_gid
,
23 opt_part
, opt_session
, opt_nls
,
24 opt_nodecompose
, opt_decompose
,
28 static const match_table_t tokens
= {
29 { opt_creator
, "creator=%s" },
30 { opt_type
, "type=%s" },
31 { opt_umask
, "umask=%o" },
32 { opt_uid
, "uid=%u" },
33 { opt_gid
, "gid=%u" },
34 { opt_part
, "part=%u" },
35 { opt_session
, "session=%u" },
36 { opt_nls
, "nls=%s" },
37 { opt_decompose
, "decompose" },
38 { opt_nodecompose
, "nodecompose" },
39 { opt_force
, "force" },
43 /* Initialize an options object to reasonable defaults */
44 void hfsplus_fill_defaults(struct hfsplus_sb_info
*opts
)
49 opts
->creator
= HFSPLUS_DEF_CR_TYPE
;
50 opts
->type
= HFSPLUS_DEF_CR_TYPE
;
51 opts
->umask
= current
->fs
->umask
;
52 opts
->uid
= current
->uid
;
53 opts
->gid
= current
->gid
;
58 /* convert a "four byte character" to a 32 bit int with error checks */
59 static inline int match_fourchar(substring_t
*arg
, u32
*result
)
61 if (arg
->to
- arg
->from
!= 4)
63 memcpy(result
, arg
->from
, 4);
67 /* Parse options from mount. Returns 0 on failure */
68 /* input is the options passed to mount() as a string */
69 int hfsplus_parse_options(char *input
, struct hfsplus_sb_info
*sbi
)
72 substring_t args
[MAX_OPT_ARGS
];
78 while ((p
= strsep(&input
, ",")) != NULL
) {
82 token
= match_token(p
, tokens
, args
);
85 if (match_fourchar(&args
[0], &sbi
->creator
)) {
86 printk(KERN_ERR
"hfs: creator requires a 4 character value\n");
91 if (match_fourchar(&args
[0], &sbi
->type
)) {
92 printk(KERN_ERR
"hfs: type requires a 4 character value\n");
97 if (match_octal(&args
[0], &tmp
)) {
98 printk(KERN_ERR
"hfs: umask requires a value\n");
101 sbi
->umask
= (umode_t
)tmp
;
104 if (match_int(&args
[0], &tmp
)) {
105 printk(KERN_ERR
"hfs: uid requires an argument\n");
108 sbi
->uid
= (uid_t
)tmp
;
111 if (match_int(&args
[0], &tmp
)) {
112 printk(KERN_ERR
"hfs: gid requires an argument\n");
115 sbi
->gid
= (gid_t
)tmp
;
118 if (match_int(&args
[0], &sbi
->part
)) {
119 printk(KERN_ERR
"hfs: part requires an argument\n");
124 if (match_int(&args
[0], &sbi
->session
)) {
125 printk(KERN_ERR
"hfs: session requires an argument\n");
131 printk(KERN_ERR
"hfs: unable to change nls mapping\n");
134 p
= match_strdup(&args
[0]);
136 sbi
->nls
= load_nls(p
);
138 printk(KERN_ERR
"hfs: unable to load nls mapping \"%s\"\n", p
);
145 sbi
->flags
&= ~HFSPLUS_SB_NODECOMPOSE
;
147 case opt_nodecompose
:
148 sbi
->flags
|= HFSPLUS_SB_NODECOMPOSE
;
151 sbi
->flags
|= HFSPLUS_SB_FORCE
;
160 /* try utf8 first, as this is the old default behaviour */
161 sbi
->nls
= load_nls("utf8");
163 sbi
->nls
= load_nls_default();
171 int hfsplus_show_options(struct seq_file
*seq
, struct vfsmount
*mnt
)
173 struct hfsplus_sb_info
*sbi
= &HFSPLUS_SB(mnt
->mnt_sb
);
175 if (sbi
->creator
!= HFSPLUS_DEF_CR_TYPE
)
176 seq_printf(seq
, ",creator=%.4s", (char *)&sbi
->creator
);
177 if (sbi
->type
!= HFSPLUS_DEF_CR_TYPE
)
178 seq_printf(seq
, ",type=%.4s", (char *)&sbi
->type
);
179 seq_printf(seq
, ",umask=%o,uid=%u,gid=%u", sbi
->umask
, sbi
->uid
, sbi
->gid
);
181 seq_printf(seq
, ",part=%u", sbi
->part
);
182 if (sbi
->session
>= 0)
183 seq_printf(seq
, ",session=%u", sbi
->session
);
185 seq_printf(seq
, ",nls=%s", sbi
->nls
->charset
);
186 if (sbi
->flags
& HFSPLUS_SB_NODECOMPOSE
)
187 seq_printf(seq
, ",nodecompose");