inode.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /* inode.c: /proc/openprom handling routines
  3. *
  4. * Copyright (C) 1996-1999 Jakub Jelinek (jakub@redhat.com)
  5. * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
  6. */
  7. #include <linux/module.h>
  8. #include <linux/types.h>
  9. #include <linux/string.h>
  10. #include <linux/fs.h>
  11. #include <linux/fs_context.h>
  12. #include <linux/init.h>
  13. #include <linux/slab.h>
  14. #include <linux/seq_file.h>
  15. #include <linux/magic.h>
  16. #include <asm/openprom.h>
  17. #include <asm/oplib.h>
  18. #include <asm/prom.h>
  19. #include <linux/uaccess.h>
  20. static DEFINE_MUTEX(op_mutex);
  21. #define OPENPROM_ROOT_INO 0
  22. enum op_inode_type {
  23. op_inode_node,
  24. op_inode_prop,
  25. };
  26. union op_inode_data {
  27. struct device_node *node;
  28. struct property *prop;
  29. };
  30. struct op_inode_info {
  31. struct inode vfs_inode;
  32. enum op_inode_type type;
  33. union op_inode_data u;
  34. };
  35. static struct inode *openprom_iget(struct super_block *sb, ino_t ino);
  36. static inline struct op_inode_info *OP_I(struct inode *inode)
  37. {
  38. return container_of(inode, struct op_inode_info, vfs_inode);
  39. }
  40. static int is_string(unsigned char *p, int len)
  41. {
  42. int i;
  43. for (i = 0; i < len; i++) {
  44. unsigned char val = p[i];
  45. if ((i && !val) ||
  46. (val >= ' ' && val <= '~'))
  47. continue;
  48. return 0;
  49. }
  50. return 1;
  51. }
  52. static int property_show(struct seq_file *f, void *v)
  53. {
  54. struct property *prop = f->private;
  55. void *pval;
  56. int len;
  57. len = prop->length;
  58. pval = prop->value;
  59. if (is_string(pval, len)) {
  60. while (len > 0) {
  61. int n = strlen(pval);
  62. seq_printf(f, "%s", (char *) pval);
  63. /* Skip over the NULL byte too. */
  64. pval += n + 1;
  65. len -= n + 1;
  66. if (len > 0)
  67. seq_printf(f, " + ");
  68. }
  69. } else {
  70. if (len & 3) {
  71. while (len) {
  72. len--;
  73. if (len)
  74. seq_printf(f, "%02x.",
  75. *(unsigned char *) pval);
  76. else
  77. seq_printf(f, "%02x",
  78. *(unsigned char *) pval);
  79. pval++;
  80. }
  81. } else {
  82. while (len >= 4) {
  83. len -= 4;
  84. if (len)
  85. seq_printf(f, "%08x.",
  86. *(unsigned int *) pval);
  87. else
  88. seq_printf(f, "%08x",
  89. *(unsigned int *) pval);
  90. pval += 4;
  91. }
  92. }
  93. }
  94. seq_printf(f, "\n");
  95. return 0;
  96. }
  97. static void *property_start(struct seq_file *f, loff_t *pos)
  98. {
  99. if (*pos == 0)
  100. return pos;
  101. return NULL;
  102. }
  103. static void *property_next(struct seq_file *f, void *v, loff_t *pos)
  104. {
  105. (*pos)++;
  106. return NULL;
  107. }
  108. static void property_stop(struct seq_file *f, void *v)
  109. {
  110. /* Nothing to do */
  111. }
  112. static const struct seq_operations property_op = {
  113. .start = property_start,
  114. .next = property_next,
  115. .stop = property_stop,
  116. .show = property_show
  117. };
  118. static int property_open(struct inode *inode, struct file *file)
  119. {
  120. struct op_inode_info *oi = OP_I(inode);
  121. int ret;
  122. BUG_ON(oi->type != op_inode_prop);
  123. ret = seq_open(file, &property_op);
  124. if (!ret) {
  125. struct seq_file *m = file->private_data;
  126. m->private = oi->u.prop;
  127. }
  128. return ret;
  129. }
  130. static const struct file_operations openpromfs_prop_ops = {
  131. .open = property_open,
  132. .read = seq_read,
  133. .llseek = seq_lseek,
  134. .release = seq_release,
  135. };
  136. static int openpromfs_readdir(struct file *, struct dir_context *);
  137. static const struct file_operations openprom_operations = {
  138. .read = generic_read_dir,
  139. .iterate_shared = openpromfs_readdir,
  140. .llseek = generic_file_llseek,
  141. };
  142. static struct dentry *openpromfs_lookup(struct inode *, struct dentry *, unsigned int);
  143. static const struct inode_operations openprom_inode_operations = {
  144. .lookup = openpromfs_lookup,
  145. };
  146. static struct dentry *openpromfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
  147. {
  148. struct op_inode_info *ent_oi, *oi = OP_I(dir);
  149. struct device_node *dp, *child;
  150. struct property *prop;
  151. enum op_inode_type ent_type;
  152. union op_inode_data ent_data;
  153. const char *name;
  154. struct inode *inode;
  155. unsigned int ino;
  156. int len;
  157. BUG_ON(oi->type != op_inode_node);
  158. dp = oi->u.node;
  159. name = dentry->d_name.name;
  160. len = dentry->d_name.len;
  161. mutex_lock(&op_mutex);
  162. child = dp->child;
  163. while (child) {
  164. const char *node_name = kbasename(child->full_name);
  165. int n = strlen(node_name);
  166. if (len == n &&
  167. !strncmp(node_name, name, len)) {
  168. ent_type = op_inode_node;
  169. ent_data.node = child;
  170. ino = child->unique_id;
  171. goto found;
  172. }
  173. child = child->sibling;
  174. }
  175. prop = dp->properties;
  176. while (prop) {
  177. int n = strlen(prop->name);
  178. if (len == n && !strncmp(prop->name, name, len)) {
  179. ent_type = op_inode_prop;
  180. ent_data.prop = prop;
  181. ino = prop->unique_id;
  182. goto found;
  183. }
  184. prop = prop->next;
  185. }
  186. mutex_unlock(&op_mutex);
  187. return ERR_PTR(-ENOENT);
  188. found:
  189. inode = openprom_iget(dir->i_sb, ino);
  190. mutex_unlock(&op_mutex);
  191. if (IS_ERR(inode))
  192. return ERR_CAST(inode);
  193. ent_oi = OP_I(inode);
  194. ent_oi->type = ent_type;
  195. ent_oi->u = ent_data;
  196. switch (ent_type) {
  197. case op_inode_node:
  198. inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
  199. inode->i_op = &openprom_inode_operations;
  200. inode->i_fop = &openprom_operations;
  201. set_nlink(inode, 2);
  202. break;
  203. case op_inode_prop:
  204. if (of_node_name_eq(dp, "options") && (len == 17) &&
  205. !strncmp (name, "security-password", 17))
  206. inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR;
  207. else
  208. inode->i_mode = S_IFREG | S_IRUGO;
  209. inode->i_fop = &openpromfs_prop_ops;
  210. set_nlink(inode, 1);
  211. inode->i_size = ent_oi->u.prop->length;
  212. break;
  213. }
  214. return d_splice_alias(inode, dentry);
  215. }
  216. static int openpromfs_readdir(struct file *file, struct dir_context *ctx)
  217. {
  218. struct inode *inode = file_inode(file);
  219. struct op_inode_info *oi = OP_I(inode);
  220. struct device_node *dp = oi->u.node;
  221. struct device_node *child;
  222. struct property *prop;
  223. int i;
  224. mutex_lock(&op_mutex);
  225. if (ctx->pos == 0) {
  226. if (!dir_emit(ctx, ".", 1, inode->i_ino, DT_DIR))
  227. goto out;
  228. ctx->pos = 1;
  229. }
  230. if (ctx->pos == 1) {
  231. if (!dir_emit(ctx, "..", 2,
  232. (dp->parent == NULL ?
  233. OPENPROM_ROOT_INO :
  234. dp->parent->unique_id), DT_DIR))
  235. goto out;
  236. ctx->pos = 2;
  237. }
  238. i = ctx->pos - 2;
  239. /* First, the children nodes as directories. */
  240. child = dp->child;
  241. while (i && child) {
  242. child = child->sibling;
  243. i--;
  244. }
  245. while (child) {
  246. if (!dir_emit(ctx,
  247. kbasename(child->full_name),
  248. strlen(kbasename(child->full_name)),
  249. child->unique_id, DT_DIR))
  250. goto out;
  251. ctx->pos++;
  252. child = child->sibling;
  253. }
  254. /* Next, the properties as files. */
  255. prop = dp->properties;
  256. while (i && prop) {
  257. prop = prop->next;
  258. i--;
  259. }
  260. while (prop) {
  261. if (!dir_emit(ctx, prop->name, strlen(prop->name),
  262. prop->unique_id, DT_REG))
  263. goto out;
  264. ctx->pos++;
  265. prop = prop->next;
  266. }
  267. out:
  268. mutex_unlock(&op_mutex);
  269. return 0;
  270. }
  271. static struct kmem_cache *op_inode_cachep;
  272. static struct inode *openprom_alloc_inode(struct super_block *sb)
  273. {
  274. struct op_inode_info *oi;
  275. oi = kmem_cache_alloc(op_inode_cachep, GFP_KERNEL);
  276. if (!oi)
  277. return NULL;
  278. return &oi->vfs_inode;
  279. }
  280. static void openprom_free_inode(struct inode *inode)
  281. {
  282. kmem_cache_free(op_inode_cachep, OP_I(inode));
  283. }
  284. static struct inode *openprom_iget(struct super_block *sb, ino_t ino)
  285. {
  286. struct inode *inode;
  287. inode = iget_locked(sb, ino);
  288. if (!inode)
  289. return ERR_PTR(-ENOMEM);
  290. if (inode->i_state & I_NEW) {
  291. inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
  292. if (inode->i_ino == OPENPROM_ROOT_INO) {
  293. inode->i_op = &openprom_inode_operations;
  294. inode->i_fop = &openprom_operations;
  295. inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
  296. }
  297. unlock_new_inode(inode);
  298. }
  299. return inode;
  300. }
  301. static int openprom_remount(struct super_block *sb, int *flags, char *data)
  302. {
  303. sync_filesystem(sb);
  304. *flags |= SB_NOATIME;
  305. return 0;
  306. }
  307. static const struct super_operations openprom_sops = {
  308. .alloc_inode = openprom_alloc_inode,
  309. .free_inode = openprom_free_inode,
  310. .statfs = simple_statfs,
  311. .remount_fs = openprom_remount,
  312. };
  313. static int openprom_fill_super(struct super_block *s, struct fs_context *fc)
  314. {
  315. struct inode *root_inode;
  316. struct op_inode_info *oi;
  317. int ret;
  318. s->s_flags |= SB_NOATIME;
  319. s->s_blocksize = 1024;
  320. s->s_blocksize_bits = 10;
  321. s->s_magic = OPENPROM_SUPER_MAGIC;
  322. s->s_op = &openprom_sops;
  323. s->s_time_gran = 1;
  324. root_inode = openprom_iget(s, OPENPROM_ROOT_INO);
  325. if (IS_ERR(root_inode)) {
  326. ret = PTR_ERR(root_inode);
  327. goto out_no_root;
  328. }
  329. oi = OP_I(root_inode);
  330. oi->type = op_inode_node;
  331. oi->u.node = of_find_node_by_path("/");
  332. s->s_root = d_make_root(root_inode);
  333. if (!s->s_root)
  334. goto out_no_root_dentry;
  335. return 0;
  336. out_no_root_dentry:
  337. ret = -ENOMEM;
  338. out_no_root:
  339. printk("openprom_fill_super: get root inode failed\n");
  340. return ret;
  341. }
  342. static int openpromfs_get_tree(struct fs_context *fc)
  343. {
  344. return get_tree_single(fc, openprom_fill_super);
  345. }
  346. static const struct fs_context_operations openpromfs_context_ops = {
  347. .get_tree = openpromfs_get_tree,
  348. };
  349. static int openpromfs_init_fs_context(struct fs_context *fc)
  350. {
  351. fc->ops = &openpromfs_context_ops;
  352. return 0;
  353. }
  354. static struct file_system_type openprom_fs_type = {
  355. .owner = THIS_MODULE,
  356. .name = "openpromfs",
  357. .init_fs_context = openpromfs_init_fs_context,
  358. .kill_sb = kill_anon_super,
  359. };
  360. MODULE_ALIAS_FS("openpromfs");
  361. static void op_inode_init_once(void *data)
  362. {
  363. struct op_inode_info *oi = (struct op_inode_info *) data;
  364. inode_init_once(&oi->vfs_inode);
  365. }
  366. static int __init init_openprom_fs(void)
  367. {
  368. int err;
  369. op_inode_cachep = kmem_cache_create("op_inode_cache",
  370. sizeof(struct op_inode_info),
  371. 0,
  372. (SLAB_RECLAIM_ACCOUNT |
  373. SLAB_MEM_SPREAD | SLAB_ACCOUNT),
  374. op_inode_init_once);
  375. if (!op_inode_cachep)
  376. return -ENOMEM;
  377. err = register_filesystem(&openprom_fs_type);
  378. if (err)
  379. kmem_cache_destroy(op_inode_cachep);
  380. return err;
  381. }
  382. static void __exit exit_openprom_fs(void)
  383. {
  384. unregister_filesystem(&openprom_fs_type);
  385. /*
  386. * Make sure all delayed rcu free inodes are flushed before we
  387. * destroy cache.
  388. */
  389. rcu_barrier();
  390. kmem_cache_destroy(op_inode_cachep);
  391. }
  392. module_init(init_openprom_fs)
  393. module_exit(exit_openprom_fs)
  394. MODULE_LICENSE("GPL");