options.c 4.1 KB

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