Lines Matching +full:serial +full:- +full:dir

1 // SPDX-License-Identifier: GPL-2.0-only
3 * proc/fs/generic.c --- generic routines for the proc-fs
5 * This file contains generic proc-fs routines for handling
39 if (S_ISLNK(pde->mode)) in pde_free()
40 kfree(pde->data); in pde_free()
41 if (pde->name != pde->inline_name) in pde_free()
42 kfree(pde->name); in pde_free()
48 if (len < de->namelen) in proc_match()
49 return -1; in proc_match()
50 if (len > de->namelen) in proc_match()
53 return memcmp(name, de->name, len); in proc_match()
56 static struct proc_dir_entry *pde_subdir_first(struct proc_dir_entry *dir) in pde_subdir_first() argument
58 return rb_entry_safe(rb_first(&dir->subdir), struct proc_dir_entry, in pde_subdir_first()
62 static struct proc_dir_entry *pde_subdir_next(struct proc_dir_entry *dir) in pde_subdir_next() argument
64 return rb_entry_safe(rb_next(&dir->subdir_node), struct proc_dir_entry, in pde_subdir_next()
68 static struct proc_dir_entry *pde_subdir_find(struct proc_dir_entry *dir, in pde_subdir_find() argument
72 struct rb_node *node = dir->subdir.rb_node; in pde_subdir_find()
81 node = node->rb_left; in pde_subdir_find()
83 node = node->rb_right; in pde_subdir_find()
90 static bool pde_subdir_insert(struct proc_dir_entry *dir, in pde_subdir_insert() argument
93 struct rb_root *root = &dir->subdir; in pde_subdir_insert()
94 struct rb_node **new = &root->rb_node, *parent = NULL; in pde_subdir_insert()
101 int result = proc_match(de->name, this, de->namelen); in pde_subdir_insert()
105 new = &(*new)->rb_left; in pde_subdir_insert()
107 new = &(*new)->rb_right; in pde_subdir_insert()
113 rb_link_node(&de->subdir_node, parent, new); in pde_subdir_insert()
114 rb_insert_color(&de->subdir_node, root); in pde_subdir_insert()
132 proc_set_user(de, inode->i_uid, inode->i_gid); in proc_notify_change()
133 de->mode = inode->i_mode; in proc_notify_change()
141 struct inode *inode = d_inode(path->dentry); in proc_getattr()
144 nlink_t nlink = READ_ONCE(de->nlink); in proc_getattr()
159 * This function parses a name such as "tty/driver/serial", and
161 * returns "serial" in residual.
171 de = pde_subdir_find(de, cp, next - cp); in __xlate_proc_name()
174 return -ENOENT; in __xlate_proc_name()
206 i = ida_simple_get(&proc_inum_ida, 0, UINT_MAX - PROC_DYNAMIC_FIRST + 1, in proc_alloc_inum()
217 ida_simple_remove(&proc_inum_ida, inum - PROC_DYNAMIC_FIRST); in proc_free_inum()
223 return -ECHILD; in proc_misc_d_revalidate()
225 if (atomic_read(&PDE(d_inode(dentry))->in_use) < 0) in proc_misc_d_revalidate()
232 return atomic_read(&PDE(d_inode(dentry))->in_use) < 0; in proc_misc_d_delete()
241 * Don't create negative dentries here, return -ENOENT by hand
244 struct dentry *proc_lookup_de(struct inode *dir, struct dentry *dentry, in proc_lookup_de() argument
250 de = pde_subdir_find(de, dentry->d_name.name, dentry->d_name.len); in proc_lookup_de()
254 inode = proc_get_inode(dir->i_sb, de); in proc_lookup_de()
256 return ERR_PTR(-ENOMEM); in proc_lookup_de()
257 d_set_d_op(dentry, de->proc_dops); in proc_lookup_de()
261 return ERR_PTR(-ENOENT); in proc_lookup_de()
264 struct dentry *proc_lookup(struct inode *dir, struct dentry *dentry, in proc_lookup() argument
267 struct proc_fs_info *fs_info = proc_sb_info(dir->i_sb); in proc_lookup()
269 if (fs_info->pidonly == PROC_PIDONLY_ON) in proc_lookup()
270 return ERR_PTR(-ENOENT); in proc_lookup()
272 return proc_lookup_de(dir, dentry, PDE(dir)); in proc_lookup()
276 * This returns non-zero if at EOF, so that the /proc
280 * Note that the VFS-layer doesn't care about the return
281 * value of the readdir() call, as long as it's non-negative
292 i = ctx->pos - 2; in proc_readdir_de()
303 i--; in proc_readdir_de()
310 if (!dir_emit(ctx, de->name, de->namelen, in proc_readdir_de()
311 de->low_ino, de->mode >> 12)) { in proc_readdir_de()
315 ctx->pos++; in proc_readdir_de()
328 struct proc_fs_info *fs_info = proc_sb_info(inode->i_sb); in proc_readdir()
330 if (fs_info->pidonly == PROC_PIDONLY_ON) in proc_readdir()
338 * use the in-memory "struct proc_dir_entry" tree to parse
367 struct proc_dir_entry *proc_register(struct proc_dir_entry *dir, in proc_register() argument
370 if (proc_alloc_inum(&dp->low_ino)) in proc_register()
374 dp->parent = dir; in proc_register()
375 if (pde_subdir_insert(dir, dp) == false) { in proc_register()
377 dir->name, dp->name); in proc_register()
381 dir->nlink++; in proc_register()
386 proc_free_inum(dp->low_ino); in proc_register()
431 ent->name = ent->inline_name; in __proc_create()
433 ent->name = kmalloc(qstr.len + 1, GFP_KERNEL); in __proc_create()
434 if (!ent->name) { in __proc_create()
440 memcpy(ent->name, fn, qstr.len + 1); in __proc_create()
441 ent->namelen = qstr.len; in __proc_create()
442 ent->mode = mode; in __proc_create()
443 ent->nlink = nlink; in __proc_create()
444 ent->subdir = RB_ROOT; in __proc_create()
445 refcount_set(&ent->refcnt, 1); in __proc_create()
446 spin_lock_init(&ent->pde_unload_lock); in __proc_create()
447 INIT_LIST_HEAD(&ent->pde_openers); in __proc_create()
448 proc_set_user(ent, (*parent)->uid, (*parent)->gid); in __proc_create()
450 ent->proc_dops = &proc_misc_dentry_ops; in __proc_create()
452 if ((*parent)->proc_dops == &proc_net_dentry_ops) in __proc_create()
468 ent->data = kmalloc((ent->size=strlen(dest))+1, GFP_KERNEL); in proc_symlink()
469 if (ent->data) { in proc_symlink()
470 strcpy((char*)ent->data,dest); in proc_symlink()
471 ent->proc_iops = &proc_link_inode_operations; in proc_symlink()
492 ent->data = data; in _proc_mkdir()
493 ent->proc_dir_ops = &proc_dir_operations; in _proc_mkdir()
494 ent->proc_iops = &proc_dir_inode_operations; in _proc_mkdir()
532 ent->data = NULL; in proc_create_mount_point()
533 ent->proc_dir_ops = NULL; in proc_create_mount_point()
534 ent->proc_iops = NULL; in proc_create_mount_point()
555 p->proc_iops = &proc_file_inode_operations; in proc_create_reg()
556 p->data = data; in proc_create_reg()
563 if (pde->proc_ops->proc_flags & PROC_ENTRY_PERMANENT) in pde_set_flags()
564 pde->flags |= PROC_ENTRY_PERMANENT; in pde_set_flags()
576 p->proc_ops = proc_ops; in proc_create_data()
594 if (de->state_size) in proc_seq_open()
595 return seq_open_private(file, de->seq_ops, de->state_size); in proc_seq_open()
596 return seq_open(file, de->seq_ops); in proc_seq_open()
603 if (de->state_size) in proc_seq_release()
609 /* not permanent -- can call into arbitrary seq_operations */
625 p->proc_ops = &proc_seq_ops; in proc_create_seq_private()
626 p->seq_ops = ops; in proc_create_seq_private()
627 p->state_size = state_size; in proc_create_seq_private()
636 return single_open(file, de->single_show, de->data); in proc_single_open()
640 /* not permanent -- can call into arbitrary ->single_show */
656 p->proc_ops = &proc_single_ops; in proc_create_single_data()
657 p->single_show = show; in proc_create_single_data()
664 de->size = size; in proc_set_size()
670 de->uid = uid; in proc_set_user()
671 de->gid = gid; in proc_set_user()
677 if (refcount_dec_and_test(&pde->refcnt)) { in pde_put()
678 proc_free_inum(pde->low_ino); in pde_put()
702 WARN(1, "removing permanent /proc entry '%s'", de->name); in remove_proc_entry()
705 rb_erase(&de->subdir_node, &parent->subdir); in remove_proc_entry()
706 if (S_ISDIR(de->mode)) in remove_proc_entry()
707 parent->nlink--; in remove_proc_entry()
719 "%s: removing non-empty directory '%s/%s', leaking at least '%s'\n", in remove_proc_entry()
720 __func__, de->parent->name, de->name, pde_subdir_first(de)->name); in remove_proc_entry()
734 return -ENOENT; in remove_proc_subtree()
741 return -ENOENT; in remove_proc_subtree()
746 root->parent->name, root->name); in remove_proc_subtree()
747 return -EINVAL; in remove_proc_subtree()
749 rb_erase(&root->subdir_node, &parent->subdir); in remove_proc_subtree()
758 next->parent->name, next->name); in remove_proc_subtree()
759 return -EINVAL; in remove_proc_subtree()
761 rb_erase(&next->subdir_node, &de->subdir); in remove_proc_subtree()
765 next = de->parent; in remove_proc_subtree()
766 if (S_ISDIR(de->mode)) in remove_proc_subtree()
767 next->nlink--; in remove_proc_subtree()
786 return de->parent->data; in proc_get_parent_data()
793 remove_proc_subtree(de->name, de->parent); in proc_remove()
799 * one is supplied. The ->write() method is permitted to modify the
800 * kernel-side buffer.
809 if (!pde->write) in proc_simple_write()
810 return -EACCES; in proc_simple_write()
811 if (size == 0 || size > PAGE_SIZE - 1) in proc_simple_write()
812 return -EINVAL; in proc_simple_write()
816 ret = pde->write(f, buf, size); in proc_simple_write()