1 // SPDX-License-Identifier: GPL-2.0-only
2 /* inode.c: /proc/openprom handling routines
4 * Copyright (C) 1996-1999 Jakub Jelinek (jakub@redhat.com)
5 * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
8 #include <linux/module.h>
9 #include <linux/types.h>
10 #include <linux/string.h>
12 #include <linux/fs_context.h>
13 #include <linux/init.h>
14 #include <linux/slab.h>
15 #include <linux/seq_file.h>
16 #include <linux/magic.h>
18 #include <asm/openprom.h>
19 #include <asm/oplib.h>
21 #include <linux/uaccess.h>
23 static DEFINE_MUTEX(op_mutex
);
25 #define OPENPROM_ROOT_INO 0
33 struct device_node
*node
;
34 struct property
*prop
;
37 struct op_inode_info
{
38 struct inode vfs_inode
;
39 enum op_inode_type type
;
40 union op_inode_data u
;
43 static struct inode
*openprom_iget(struct super_block
*sb
, ino_t ino
);
45 static inline struct op_inode_info
*OP_I(struct inode
*inode
)
47 return container_of(inode
, struct op_inode_info
, vfs_inode
);
50 static int is_string(unsigned char *p
, int len
)
54 for (i
= 0; i
< len
; i
++) {
55 unsigned char val
= p
[i
];
58 (val
>= ' ' && val
<= '~'))
67 static int property_show(struct seq_file
*f
, void *v
)
69 struct property
*prop
= f
->private;
76 if (is_string(pval
, len
)) {
80 seq_printf(f
, "%s", (char *) pval
);
82 /* Skip over the NULL byte too. */
94 seq_printf(f
, "%02x.",
95 *(unsigned char *) pval
);
98 *(unsigned char *) pval
);
106 seq_printf(f
, "%08x.",
107 *(unsigned int *) pval
);
109 seq_printf(f
, "%08x",
110 *(unsigned int *) pval
);
120 static void *property_start(struct seq_file
*f
, loff_t
*pos
)
127 static void *property_next(struct seq_file
*f
, void *v
, loff_t
*pos
)
133 static void property_stop(struct seq_file
*f
, void *v
)
138 static const struct seq_operations property_op
= {
139 .start
= property_start
,
140 .next
= property_next
,
141 .stop
= property_stop
,
142 .show
= property_show
145 static int property_open(struct inode
*inode
, struct file
*file
)
147 struct op_inode_info
*oi
= OP_I(inode
);
150 BUG_ON(oi
->type
!= op_inode_prop
);
152 ret
= seq_open(file
, &property_op
);
154 struct seq_file
*m
= file
->private_data
;
155 m
->private = oi
->u
.prop
;
160 static const struct file_operations openpromfs_prop_ops
= {
161 .open
= property_open
,
164 .release
= seq_release
,
167 static int openpromfs_readdir(struct file
*, struct dir_context
*);
169 static const struct file_operations openprom_operations
= {
170 .read
= generic_read_dir
,
171 .iterate_shared
= openpromfs_readdir
,
172 .llseek
= generic_file_llseek
,
175 static struct dentry
*openpromfs_lookup(struct inode
*, struct dentry
*, unsigned int);
177 static const struct inode_operations openprom_inode_operations
= {
178 .lookup
= openpromfs_lookup
,
181 static struct dentry
*openpromfs_lookup(struct inode
*dir
, struct dentry
*dentry
, unsigned int flags
)
183 struct op_inode_info
*ent_oi
, *oi
= OP_I(dir
);
184 struct device_node
*dp
, *child
;
185 struct property
*prop
;
186 enum op_inode_type ent_type
;
187 union op_inode_data ent_data
;
193 BUG_ON(oi
->type
!= op_inode_node
);
197 name
= dentry
->d_name
.name
;
198 len
= dentry
->d_name
.len
;
200 mutex_lock(&op_mutex
);
204 const char *node_name
= kbasename(child
->full_name
);
205 int n
= strlen(node_name
);
208 !strncmp(node_name
, name
, len
)) {
209 ent_type
= op_inode_node
;
210 ent_data
.node
= child
;
211 ino
= child
->unique_id
;
214 child
= child
->sibling
;
217 prop
= dp
->properties
;
219 int n
= strlen(prop
->name
);
221 if (len
== n
&& !strncmp(prop
->name
, name
, len
)) {
222 ent_type
= op_inode_prop
;
223 ent_data
.prop
= prop
;
224 ino
= prop
->unique_id
;
231 mutex_unlock(&op_mutex
);
232 return ERR_PTR(-ENOENT
);
235 inode
= openprom_iget(dir
->i_sb
, ino
);
236 mutex_unlock(&op_mutex
);
238 return ERR_CAST(inode
);
239 ent_oi
= OP_I(inode
);
240 ent_oi
->type
= ent_type
;
241 ent_oi
->u
= ent_data
;
245 inode
->i_mode
= S_IFDIR
| S_IRUGO
| S_IXUGO
;
246 inode
->i_op
= &openprom_inode_operations
;
247 inode
->i_fop
= &openprom_operations
;
251 if (of_node_name_eq(dp
, "options") && (len
== 17) &&
252 !strncmp (name
, "security-password", 17))
253 inode
->i_mode
= S_IFREG
| S_IRUSR
| S_IWUSR
;
255 inode
->i_mode
= S_IFREG
| S_IRUGO
;
256 inode
->i_fop
= &openpromfs_prop_ops
;
258 inode
->i_size
= ent_oi
->u
.prop
->length
;
262 return d_splice_alias(inode
, dentry
);
265 static int openpromfs_readdir(struct file
*file
, struct dir_context
*ctx
)
267 struct inode
*inode
= file_inode(file
);
268 struct op_inode_info
*oi
= OP_I(inode
);
269 struct device_node
*dp
= oi
->u
.node
;
270 struct device_node
*child
;
271 struct property
*prop
;
274 mutex_lock(&op_mutex
);
277 if (!dir_emit(ctx
, ".", 1, inode
->i_ino
, DT_DIR
))
282 if (!dir_emit(ctx
, "..", 2,
283 (dp
->parent
== NULL
?
285 dp
->parent
->unique_id
), DT_DIR
))
291 /* First, the children nodes as directories. */
294 child
= child
->sibling
;
299 kbasename(child
->full_name
),
300 strlen(kbasename(child
->full_name
)),
301 child
->unique_id
, DT_DIR
))
305 child
= child
->sibling
;
308 /* Next, the properties as files. */
309 prop
= dp
->properties
;
315 if (!dir_emit(ctx
, prop
->name
, strlen(prop
->name
),
316 prop
->unique_id
, DT_REG
))
324 mutex_unlock(&op_mutex
);
328 static struct kmem_cache
*op_inode_cachep
;
330 static struct inode
*openprom_alloc_inode(struct super_block
*sb
)
332 struct op_inode_info
*oi
;
334 oi
= kmem_cache_alloc(op_inode_cachep
, GFP_KERNEL
);
338 return &oi
->vfs_inode
;
341 static void openprom_free_inode(struct inode
*inode
)
343 kmem_cache_free(op_inode_cachep
, OP_I(inode
));
346 static struct inode
*openprom_iget(struct super_block
*sb
, ino_t ino
)
350 inode
= iget_locked(sb
, ino
);
352 return ERR_PTR(-ENOMEM
);
353 if (inode
->i_state
& I_NEW
) {
354 inode
->i_mtime
= inode
->i_atime
= inode
->i_ctime
= current_time(inode
);
355 if (inode
->i_ino
== OPENPROM_ROOT_INO
) {
356 inode
->i_op
= &openprom_inode_operations
;
357 inode
->i_fop
= &openprom_operations
;
358 inode
->i_mode
= S_IFDIR
| S_IRUGO
| S_IXUGO
;
360 unlock_new_inode(inode
);
365 static int openprom_remount(struct super_block
*sb
, int *flags
, char *data
)
368 *flags
|= SB_NOATIME
;
372 static const struct super_operations openprom_sops
= {
373 .alloc_inode
= openprom_alloc_inode
,
374 .free_inode
= openprom_free_inode
,
375 .statfs
= simple_statfs
,
376 .remount_fs
= openprom_remount
,
379 static int openprom_fill_super(struct super_block
*s
, struct fs_context
*fc
)
381 struct inode
*root_inode
;
382 struct op_inode_info
*oi
;
385 s
->s_flags
|= SB_NOATIME
;
386 s
->s_blocksize
= 1024;
387 s
->s_blocksize_bits
= 10;
388 s
->s_magic
= OPENPROM_SUPER_MAGIC
;
389 s
->s_op
= &openprom_sops
;
391 root_inode
= openprom_iget(s
, OPENPROM_ROOT_INO
);
392 if (IS_ERR(root_inode
)) {
393 ret
= PTR_ERR(root_inode
);
397 oi
= OP_I(root_inode
);
398 oi
->type
= op_inode_node
;
399 oi
->u
.node
= of_find_node_by_path("/");
401 s
->s_root
= d_make_root(root_inode
);
403 goto out_no_root_dentry
;
409 printk("openprom_fill_super: get root inode failed\n");
413 static int openpromfs_get_tree(struct fs_context
*fc
)
415 return get_tree_single(fc
, openprom_fill_super
);
418 static const struct fs_context_operations openpromfs_context_ops
= {
419 .get_tree
= openpromfs_get_tree
,
422 static int openpromfs_init_fs_context(struct fs_context
*fc
)
424 fc
->ops
= &openpromfs_context_ops
;
428 static struct file_system_type openprom_fs_type
= {
429 .owner
= THIS_MODULE
,
430 .name
= "openpromfs",
431 .init_fs_context
= openpromfs_init_fs_context
,
432 .kill_sb
= kill_anon_super
,
434 MODULE_ALIAS_FS("openpromfs");
436 static void op_inode_init_once(void *data
)
438 struct op_inode_info
*oi
= (struct op_inode_info
*) data
;
440 inode_init_once(&oi
->vfs_inode
);
443 static int __init
init_openprom_fs(void)
447 op_inode_cachep
= kmem_cache_create("op_inode_cache",
448 sizeof(struct op_inode_info
),
450 (SLAB_RECLAIM_ACCOUNT
|
451 SLAB_MEM_SPREAD
| SLAB_ACCOUNT
),
453 if (!op_inode_cachep
)
456 err
= register_filesystem(&openprom_fs_type
);
458 kmem_cache_destroy(op_inode_cachep
);
463 static void __exit
exit_openprom_fs(void)
465 unregister_filesystem(&openprom_fs_type
);
467 * Make sure all delayed rcu free inodes are flushed before we
471 kmem_cache_destroy(op_inode_cachep
);
474 module_init(init_openprom_fs
)
475 module_exit(exit_openprom_fs
)
476 MODULE_LICENSE("GPL");