File Index
Files and directories
Sign in
FILE

options.c

File preview with syntax highlighting.

linux-6.19.14/fs/hfsplus/options.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 *  linux/fs/hfsplus/options.c
  4 *
  5 * Copyright (C) 2001
  6 * Brad Boyer (flar@allandria.com)
  7 * (C) 2003 Ardis Technologies <roman@ardistech.com>
  8 *
  9 * Option parsing
 10 */
 11
 12#include <linux/string.h>
 13#include <linux/kernel.h>
 14#include <linux/sched.h>
 15#include <linux/fs_struct.h>
 16#include <linux/fs_context.h>
 17#include <linux/fs_parser.h>
 18#include <linux/nls.h>
 19#include <linux/mount.h>
 20#include <linux/seq_file.h>
 21#include <linux/slab.h>
 22#include "hfsplus_fs.h"
 23
 24enum {
 25	opt_creator, opt_type,
 26	opt_umask, opt_uid, opt_gid,
 27	opt_part, opt_session, opt_nls,
 28	opt_decompose, opt_barrier,
 29	opt_force,
 30};
 31
 32static const struct fs_parameter_spec hfs_param_spec[] = {
 33	fsparam_string	("creator",	opt_creator),
 34	fsparam_string	("type",	opt_type),
 35	fsparam_u32oct	("umask",	opt_umask),
 36	fsparam_u32	("uid",		opt_uid),
 37	fsparam_u32	("gid",		opt_gid),
 38	fsparam_u32	("part",	opt_part),
 39	fsparam_u32	("session",	opt_session),
 40	fsparam_string	("nls",		opt_nls),
 41	fsparam_flag_no	("decompose",	opt_decompose),
 42	fsparam_flag_no	("barrier",	opt_barrier),
 43	fsparam_flag	("force",	opt_force),
 44	{}
 45};
 46
 47/* Initialize an options object to reasonable defaults */
 48void hfsplus_fill_defaults(struct hfsplus_sb_info *opts)
 49{
 50	if (!opts)
 51		return;
 52
 53	opts->creator = HFSPLUS_DEF_CR_TYPE;
 54	opts->type = HFSPLUS_DEF_CR_TYPE;
 55	opts->umask = current_umask();
 56	opts->uid = current_uid();
 57	opts->gid = current_gid();
 58	opts->part = -1;
 59	opts->session = -1;
 60}
 61
 62/* Parse options from mount. Returns nonzero errno on failure */
 63int hfsplus_parse_param(struct fs_context *fc, struct fs_parameter *param)
 64{
 65	struct hfsplus_sb_info *sbi = fc->s_fs_info;
 66	struct fs_parse_result result;
 67	int opt;
 68
 69	/*
 70	 * Only the force option is examined during remount, all others
 71	 * are ignored.
 72	 */
 73	if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE &&
 74	    strncmp(param->key, "force", 5))
 75		return 0;
 76
 77	opt = fs_parse(fc, hfs_param_spec, param, &result);
 78	if (opt < 0)
 79		return opt;
 80
 81	switch (opt) {
 82	case opt_creator:
 83		if (strlen(param->string) != 4) {
 84			pr_err("creator requires a 4 character value\n");
 85			return -EINVAL;
 86		}
 87		memcpy(&sbi->creator, param->string, 4);
 88		break;
 89	case opt_type:
 90		if (strlen(param->string) != 4) {
 91			pr_err("type requires a 4 character value\n");
 92			return -EINVAL;
 93		}
 94		memcpy(&sbi->type, param->string, 4);
 95		break;
 96	case opt_umask:
 97		sbi->umask = (umode_t)result.uint_32;
 98		break;
 99	case opt_uid:
100		sbi->uid = result.uid;
101		set_bit(HFSPLUS_SB_UID, &sbi->flags);
102		break;
103	case opt_gid:
104		sbi->gid = result.gid;
105		set_bit(HFSPLUS_SB_GID, &sbi->flags);
106		break;
107	case opt_part:
108		sbi->part = result.uint_32;
109		break;
110	case opt_session:
111		sbi->session = result.uint_32;
112		break;
113	case opt_nls:
114		if (sbi->nls) {
115			pr_err("unable to change nls mapping\n");
116			return -EINVAL;
117		}
118		sbi->nls = load_nls(param->string);
119		if (!sbi->nls) {
120			pr_err("unable to load nls mapping \"%s\"\n",
121			       param->string);
122			return -EINVAL;
123		}
124		break;
125	case opt_decompose:
126		if (result.negated)
127			set_bit(HFSPLUS_SB_NODECOMPOSE, &sbi->flags);
128		else
129			clear_bit(HFSPLUS_SB_NODECOMPOSE, &sbi->flags);
130		break;
131	case opt_barrier:
132		if (result.negated)
133			set_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags);
134		else
135			clear_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags);
136		break;
137	case opt_force:
138		set_bit(HFSPLUS_SB_FORCE, &sbi->flags);
139		break;
140	default:
141		return -EINVAL;
142	}
143
144	return 0;
145}
146
147int hfsplus_show_options(struct seq_file *seq, struct dentry *root)
148{
149	struct hfsplus_sb_info *sbi = HFSPLUS_SB(root->d_sb);
150
151	if (sbi->creator != HFSPLUS_DEF_CR_TYPE)
152		seq_show_option_n(seq, "creator", (char *)&sbi->creator, 4);
153	if (sbi->type != HFSPLUS_DEF_CR_TYPE)
154		seq_show_option_n(seq, "type", (char *)&sbi->type, 4);
155	seq_printf(seq, ",umask=%o,uid=%u,gid=%u", sbi->umask,
156			from_kuid_munged(&init_user_ns, sbi->uid),
157			from_kgid_munged(&init_user_ns, sbi->gid));
158	if (sbi->part >= 0)
159		seq_printf(seq, ",part=%u", sbi->part);
160	if (sbi->session >= 0)
161		seq_printf(seq, ",session=%u", sbi->session);
162	if (sbi->nls)
163		seq_printf(seq, ",nls=%s", sbi->nls->charset);
164	if (test_bit(HFSPLUS_SB_NODECOMPOSE, &sbi->flags))
165		seq_puts(seq, ",nodecompose");
166	if (test_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags))
167		seq_puts(seq, ",nobarrier");
168	return 0;
169}
~/ Read-only file preview.