main.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. /*
  2. * fs/sdcardfs/main.c
  3. *
  4. * Copyright (c) 2013 Samsung Electronics Co. Ltd
  5. * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun,
  6. * Sunghwan Yun, Sungjong Seo
  7. *
  8. * This program has been developed as a stackable file system based on
  9. * the WrapFS which written by
  10. *
  11. * Copyright (c) 1998-2011 Erez Zadok
  12. * Copyright (c) 2009 Shrikar Archak
  13. * Copyright (c) 2003-2011 Stony Brook University
  14. * Copyright (c) 2003-2011 The Research Foundation of SUNY
  15. *
  16. * This file is dual licensed. It may be redistributed and/or modified
  17. * under the terms of the Apache 2.0 License OR version 2 of the GNU
  18. * General Public License.
  19. */
  20. #include "sdcardfs.h"
  21. #include <linux/module.h>
  22. #include <linux/types.h>
  23. #include <linux/parser.h>
  24. enum {
  25. Opt_fsuid,
  26. Opt_fsgid,
  27. Opt_gid,
  28. Opt_debug,
  29. Opt_mask,
  30. Opt_multiuser,
  31. Opt_userid,
  32. Opt_reserved_mb,
  33. Opt_gid_derivation,
  34. Opt_default_normal,
  35. Opt_unshared_obb,
  36. Opt_nocache,
  37. Opt_err,
  38. };
  39. static const match_table_t sdcardfs_tokens = {
  40. {Opt_fsuid, "fsuid=%u"},
  41. {Opt_fsgid, "fsgid=%u"},
  42. {Opt_gid, "gid=%u"},
  43. {Opt_debug, "debug"},
  44. {Opt_mask, "mask=%u"},
  45. {Opt_userid, "userid=%d"},
  46. {Opt_multiuser, "multiuser"},
  47. {Opt_gid_derivation, "derive_gid"},
  48. {Opt_default_normal, "default_normal"},
  49. {Opt_unshared_obb, "unshared_obb"},
  50. {Opt_reserved_mb, "reserved_mb=%u"},
  51. {Opt_nocache, "nocache"},
  52. {Opt_err, NULL}
  53. };
  54. static int parse_options(struct super_block *sb, char *options, int silent,
  55. int *debug, struct sdcardfs_vfsmount_options *vfsopts,
  56. struct sdcardfs_mount_options *opts)
  57. {
  58. char *p;
  59. substring_t args[MAX_OPT_ARGS];
  60. int option;
  61. /* by default, we use AID_MEDIA_RW as uid, gid */
  62. opts->fs_low_uid = AID_MEDIA_RW;
  63. opts->fs_low_gid = AID_MEDIA_RW;
  64. vfsopts->mask = 0;
  65. opts->multiuser = false;
  66. opts->fs_user_id = 0;
  67. vfsopts->gid = 0;
  68. /* by default, 0MB is reserved */
  69. opts->reserved_mb = 0;
  70. /* by default, gid derivation is off */
  71. opts->gid_derivation = false;
  72. opts->default_normal = false;
  73. opts->nocache = false;
  74. *debug = 0;
  75. if (!options)
  76. return 0;
  77. while ((p = strsep(&options, ",")) != NULL) {
  78. int token;
  79. if (!*p)
  80. continue;
  81. token = match_token(p, sdcardfs_tokens, args);
  82. switch (token) {
  83. case Opt_debug:
  84. *debug = 1;
  85. break;
  86. case Opt_fsuid:
  87. if (match_int(&args[0], &option))
  88. return 0;
  89. opts->fs_low_uid = option;
  90. break;
  91. case Opt_fsgid:
  92. if (match_int(&args[0], &option))
  93. return 0;
  94. opts->fs_low_gid = option;
  95. break;
  96. case Opt_gid:
  97. if (match_int(&args[0], &option))
  98. return 0;
  99. vfsopts->gid = option;
  100. break;
  101. case Opt_userid:
  102. if (match_int(&args[0], &option))
  103. return 0;
  104. opts->fs_user_id = option;
  105. break;
  106. case Opt_mask:
  107. if (match_int(&args[0], &option))
  108. return 0;
  109. vfsopts->mask = option;
  110. break;
  111. case Opt_multiuser:
  112. opts->multiuser = true;
  113. break;
  114. case Opt_reserved_mb:
  115. if (match_int(&args[0], &option))
  116. return 0;
  117. opts->reserved_mb = option;
  118. break;
  119. case Opt_gid_derivation:
  120. opts->gid_derivation = true;
  121. break;
  122. case Opt_default_normal:
  123. opts->default_normal = true;
  124. break;
  125. case Opt_unshared_obb:
  126. opts->unshared_obb = true;
  127. break;
  128. case Opt_nocache:
  129. opts->nocache = true;
  130. break;
  131. /* unknown option */
  132. default:
  133. if (!silent)
  134. pr_err("Unrecognized mount option \"%s\" or missing value", p);
  135. return -EINVAL;
  136. }
  137. }
  138. if (*debug) {
  139. pr_info("sdcardfs : options - debug:%d\n", *debug);
  140. pr_info("sdcardfs : options - uid:%d\n",
  141. opts->fs_low_uid);
  142. pr_info("sdcardfs : options - gid:%d\n",
  143. opts->fs_low_gid);
  144. }
  145. return 0;
  146. }
  147. int parse_options_remount(struct super_block *sb, char *options, int silent,
  148. struct sdcardfs_vfsmount_options *vfsopts)
  149. {
  150. char *p;
  151. substring_t args[MAX_OPT_ARGS];
  152. int option;
  153. int debug;
  154. if (!options)
  155. return 0;
  156. while ((p = strsep(&options, ",")) != NULL) {
  157. int token;
  158. if (!*p)
  159. continue;
  160. token = match_token(p, sdcardfs_tokens, args);
  161. switch (token) {
  162. case Opt_debug:
  163. debug = 1;
  164. break;
  165. case Opt_gid:
  166. if (match_int(&args[0], &option))
  167. return 0;
  168. vfsopts->gid = option;
  169. break;
  170. case Opt_mask:
  171. if (match_int(&args[0], &option))
  172. return 0;
  173. vfsopts->mask = option;
  174. break;
  175. case Opt_unshared_obb:
  176. case Opt_default_normal:
  177. case Opt_multiuser:
  178. case Opt_userid:
  179. case Opt_fsuid:
  180. case Opt_fsgid:
  181. case Opt_reserved_mb:
  182. case Opt_gid_derivation:
  183. if (!silent)
  184. pr_warn("Option \"%s\" can't be changed during remount\n", p);
  185. break;
  186. /* unknown option */
  187. default:
  188. if (!silent)
  189. pr_err("Unrecognized mount option \"%s\" or missing value", p);
  190. return -EINVAL;
  191. }
  192. }
  193. if (debug) {
  194. pr_info("sdcardfs : options - debug:%d\n", debug);
  195. pr_info("sdcardfs : options - gid:%d\n", vfsopts->gid);
  196. pr_info("sdcardfs : options - mask:%d\n", vfsopts->mask);
  197. }
  198. return 0;
  199. }
  200. #if 0
  201. /*
  202. * our custom d_alloc_root work-alike
  203. *
  204. * we can't use d_alloc_root if we want to use our own interpose function
  205. * unchanged, so we simply call our own "fake" d_alloc_root
  206. */
  207. static struct dentry *sdcardfs_d_alloc_root(struct super_block *sb)
  208. {
  209. struct dentry *ret = NULL;
  210. if (sb) {
  211. static const struct qstr name = QSTR_INIT("/", 1);
  212. ret = d_alloc(NULL, &name);
  213. if (ret) {
  214. d_set_d_op(ret, &sdcardfs_ci_dops);
  215. ret->d_sb = sb;
  216. ret->d_parent = ret;
  217. }
  218. }
  219. return ret;
  220. }
  221. #endif
  222. DEFINE_MUTEX(sdcardfs_super_list_lock);
  223. EXPORT_SYMBOL_GPL(sdcardfs_super_list_lock);
  224. LIST_HEAD(sdcardfs_super_list);
  225. EXPORT_SYMBOL_GPL(sdcardfs_super_list);
  226. /*
  227. * There is no need to lock the sdcardfs_super_info's rwsem as there is no
  228. * way anyone can have a reference to the superblock at this point in time.
  229. */
  230. static int sdcardfs_read_super(struct vfsmount *mnt, struct super_block *sb,
  231. const char *dev_name, void *raw_data, int silent)
  232. {
  233. int err = 0;
  234. int debug;
  235. struct super_block *lower_sb;
  236. struct path lower_path;
  237. struct sdcardfs_sb_info *sb_info;
  238. struct sdcardfs_vfsmount_options *mnt_opt = mnt->data;
  239. struct inode *inode;
  240. pr_info("sdcardfs version 2.0\n");
  241. if (!dev_name) {
  242. pr_err("sdcardfs: read_super: missing dev_name argument\n");
  243. err = -EINVAL;
  244. goto out;
  245. }
  246. pr_info("sdcardfs: dev_name -> %s\n", dev_name);
  247. pr_info("sdcardfs: options -> %s\n", (char *)raw_data);
  248. pr_info("sdcardfs: mnt -> %p\n", mnt);
  249. /* parse lower path */
  250. err = kern_path(dev_name, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
  251. &lower_path);
  252. if (err) {
  253. pr_err("sdcardfs: error accessing lower directory '%s'\n", dev_name);
  254. goto out;
  255. }
  256. /* allocate superblock private data */
  257. sb->s_fs_info = kzalloc(sizeof(struct sdcardfs_sb_info), GFP_KERNEL);
  258. if (!SDCARDFS_SB(sb)) {
  259. pr_crit("sdcardfs: read_super: out of memory\n");
  260. err = -ENOMEM;
  261. goto out_free;
  262. }
  263. sb_info = sb->s_fs_info;
  264. /* parse options */
  265. err = parse_options(sb, raw_data, silent, &debug, mnt_opt, &sb_info->options);
  266. if (err) {
  267. pr_err("sdcardfs: invalid options\n");
  268. goto out_freesbi;
  269. }
  270. /* set the lower superblock field of upper superblock */
  271. lower_sb = lower_path.dentry->d_sb;
  272. atomic_inc(&lower_sb->s_active);
  273. sdcardfs_set_lower_super(sb, lower_sb);
  274. sb->s_stack_depth = lower_sb->s_stack_depth + 1;
  275. if (sb->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) {
  276. pr_err("sdcardfs: maximum fs stacking depth exceeded\n");
  277. err = -EINVAL;
  278. goto out_sput;
  279. }
  280. /* inherit maxbytes from lower file system */
  281. sb->s_maxbytes = lower_sb->s_maxbytes;
  282. /*
  283. * Our c/m/atime granularity is 1 ns because we may stack on file
  284. * systems whose granularity is as good.
  285. */
  286. sb->s_time_gran = 1;
  287. sb->s_magic = SDCARDFS_SUPER_MAGIC;
  288. sb->s_op = &sdcardfs_sops;
  289. /* get a new inode and allocate our root dentry */
  290. inode = sdcardfs_iget(sb, lower_path.dentry->d_inode, 0);
  291. if (IS_ERR(inode)) {
  292. err = PTR_ERR(inode);
  293. goto out_sput;
  294. }
  295. sb->s_root = d_make_root(inode);
  296. if (!sb->s_root) {
  297. err = -ENOMEM;
  298. goto out_sput;
  299. }
  300. d_set_d_op(sb->s_root, &sdcardfs_ci_dops);
  301. /* link the upper and lower dentries */
  302. sb->s_root->d_fsdata = NULL;
  303. err = new_dentry_private_data(sb->s_root);
  304. if (err)
  305. goto out_freeroot;
  306. /* set the lower dentries for s_root */
  307. sdcardfs_set_lower_path(sb->s_root, &lower_path);
  308. /*
  309. * No need to call interpose because we already have a positive
  310. * dentry, which was instantiated by d_make_root. Just need to
  311. * d_rehash it.
  312. */
  313. d_rehash(sb->s_root);
  314. /* setup permission policy */
  315. sb_info->obbpath_s = kzalloc(PATH_MAX, GFP_KERNEL);
  316. mutex_lock(&sdcardfs_super_list_lock);
  317. if (sb_info->options.multiuser) {
  318. setup_derived_state(sb->s_root->d_inode, PERM_PRE_ROOT,
  319. sb_info->options.fs_user_id, AID_ROOT);
  320. snprintf(sb_info->obbpath_s, PATH_MAX, "%s/obb", dev_name);
  321. } else {
  322. setup_derived_state(sb->s_root->d_inode, PERM_ROOT,
  323. sb_info->options.fs_user_id, AID_ROOT);
  324. snprintf(sb_info->obbpath_s, PATH_MAX, "%s/Android/obb", dev_name);
  325. }
  326. fixup_tmp_permissions(sb->s_root->d_inode);
  327. sb_info->sb = sb;
  328. list_add(&sb_info->list, &sdcardfs_super_list);
  329. mutex_unlock(&sdcardfs_super_list_lock);
  330. if (!silent)
  331. pr_info("sdcardfs: mounted on top of %s type %s\n",
  332. dev_name, lower_sb->s_type->name);
  333. goto out; /* all is well */
  334. /* no longer needed: free_dentry_private_data(sb->s_root); */
  335. out_freeroot:
  336. dput(sb->s_root);
  337. sb->s_root = NULL;
  338. out_sput:
  339. /* drop refs we took earlier */
  340. atomic_dec(&lower_sb->s_active);
  341. out_freesbi:
  342. kfree(SDCARDFS_SB(sb));
  343. sb->s_fs_info = NULL;
  344. out_free:
  345. path_put(&lower_path);
  346. out:
  347. return err;
  348. }
  349. struct sdcardfs_mount_private {
  350. struct vfsmount *mnt;
  351. const char *dev_name;
  352. void *raw_data;
  353. };
  354. static int __sdcardfs_fill_super(
  355. struct super_block *sb,
  356. void *_priv, int silent)
  357. {
  358. struct sdcardfs_mount_private *priv = _priv;
  359. return sdcardfs_read_super(priv->mnt,
  360. sb, priv->dev_name, priv->raw_data, silent);
  361. }
  362. static struct dentry *sdcardfs_mount(struct vfsmount *mnt,
  363. struct file_system_type *fs_type, int flags,
  364. const char *dev_name, void *raw_data)
  365. {
  366. struct sdcardfs_mount_private priv = {
  367. .mnt = mnt,
  368. .dev_name = dev_name,
  369. .raw_data = raw_data
  370. };
  371. return mount_nodev(fs_type, flags,
  372. &priv, __sdcardfs_fill_super);
  373. }
  374. static struct dentry *sdcardfs_mount_wrn(struct file_system_type *fs_type,
  375. int flags, const char *dev_name, void *raw_data)
  376. {
  377. WARN(1, "sdcardfs does not support mount. Use mount2.\n");
  378. return ERR_PTR(-EINVAL);
  379. }
  380. void *sdcardfs_alloc_mnt_data(void)
  381. {
  382. return kmalloc(sizeof(struct sdcardfs_vfsmount_options), GFP_KERNEL);
  383. }
  384. void sdcardfs_kill_sb(struct super_block *sb)
  385. {
  386. struct sdcardfs_sb_info *sbi;
  387. if (sb->s_magic == SDCARDFS_SUPER_MAGIC && sb->s_fs_info) {
  388. sbi = SDCARDFS_SB(sb);
  389. mutex_lock(&sdcardfs_super_list_lock);
  390. list_del(&sbi->list);
  391. mutex_unlock(&sdcardfs_super_list_lock);
  392. }
  393. kill_anon_super(sb);
  394. }
  395. static struct file_system_type sdcardfs_fs_type = {
  396. .owner = THIS_MODULE,
  397. .name = SDCARDFS_NAME,
  398. .mount = sdcardfs_mount_wrn,
  399. .mount2 = sdcardfs_mount,
  400. .alloc_mnt_data = sdcardfs_alloc_mnt_data,
  401. .kill_sb = sdcardfs_kill_sb,
  402. .fs_flags = 0,
  403. };
  404. MODULE_ALIAS_FS(SDCARDFS_NAME);
  405. static int __init init_sdcardfs_fs(void)
  406. {
  407. int err;
  408. pr_info("Registering sdcardfs " SDCARDFS_VERSION "\n");
  409. err = sdcardfs_init_inode_cache();
  410. if (err)
  411. goto out;
  412. err = sdcardfs_init_dentry_cache();
  413. if (err)
  414. goto out;
  415. err = packagelist_init();
  416. if (err)
  417. goto out;
  418. err = register_filesystem(&sdcardfs_fs_type);
  419. out:
  420. if (err) {
  421. sdcardfs_destroy_inode_cache();
  422. sdcardfs_destroy_dentry_cache();
  423. packagelist_exit();
  424. }
  425. return err;
  426. }
  427. static void __exit exit_sdcardfs_fs(void)
  428. {
  429. sdcardfs_destroy_inode_cache();
  430. sdcardfs_destroy_dentry_cache();
  431. packagelist_exit();
  432. unregister_filesystem(&sdcardfs_fs_type);
  433. pr_info("Completed sdcardfs module unload\n");
  434. }
  435. /* Original wrapfs authors */
  436. MODULE_AUTHOR("Erez Zadok, Filesystems and Storage Lab, Stony Brook University (http://www.fsl.cs.sunysb.edu/)");
  437. /* Original sdcardfs authors */
  438. MODULE_AUTHOR("Woojoong Lee, Daeho Jeong, Kitae Lee, Yeongjin Gil System Memory Lab., Samsung Electronics");
  439. /* Current maintainer */
  440. MODULE_AUTHOR("Daniel Rosenberg, Google");
  441. MODULE_DESCRIPTION("Sdcardfs " SDCARDFS_VERSION);
  442. MODULE_LICENSE("GPL");
  443. module_init(init_sdcardfs_fs);
  444. module_exit(exit_sdcardfs_fs);