^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * fs/sysfs/dir.c - sysfs core and dir operation implementation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2001-3 Patrick Mochel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 2007 SUSE Linux Products GmbH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (c) 2007 Tejun Heo <teheo@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Please see Documentation/filesystems/sysfs.rst for more information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define pr_fmt(fmt) "sysfs: " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/kobject.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "sysfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) DEFINE_SPINLOCK(sysfs_symlink_target_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) void sysfs_warn_dup(struct kernfs_node *parent, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) buf = kzalloc(PATH_MAX, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) if (buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) kernfs_path(parent, buf, PATH_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) pr_warn("cannot create duplicate filename '%s/%s'\n", buf, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) dump_stack();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * sysfs_create_dir_ns - create a directory for an object with a namespace tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * @kobj: object we're creating directory for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * @ns: the namespace tag to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) int sysfs_create_dir_ns(struct kobject *kobj, const void *ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct kernfs_node *parent, *kn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) kuid_t uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) kgid_t gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) if (WARN_ON(!kobj))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (kobj->parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) parent = kobj->parent->sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) parent = sysfs_root_kn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if (!parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) kobject_get_ownership(kobj, &uid, &gid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) kn = kernfs_create_dir_ns(parent, kobject_name(kobj),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) S_IRWXU | S_IRUGO | S_IXUGO, uid, gid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) kobj, ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (IS_ERR(kn)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (PTR_ERR(kn) == -EEXIST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) sysfs_warn_dup(parent, kobject_name(kobj));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return PTR_ERR(kn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) kobj->sd = kn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * sysfs_remove_dir - remove an object's directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * @kobj: object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * The only thing special about this is that we remove any files in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * the directory before we remove the directory, and we've inlined
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * what used to be sysfs_rmdir() below, instead of calling separately.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) void sysfs_remove_dir(struct kobject *kobj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct kernfs_node *kn = kobj->sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * In general, kboject owner is responsible for ensuring removal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * doesn't race with other operations and sysfs doesn't provide any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * protection; however, when @kobj is used as a symlink target, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * symlinking entity usually doesn't own @kobj and thus has no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * control over removal. @kobj->sd may be removed anytime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * and symlink code may end up dereferencing an already freed node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * sysfs_symlink_target_lock synchronizes @kobj->sd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * disassociation against symlink operations so that symlink code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * can safely dereference @kobj->sd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) spin_lock(&sysfs_symlink_target_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) kobj->sd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) spin_unlock(&sysfs_symlink_target_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (kn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) WARN_ON_ONCE(kernfs_type(kn) != KERNFS_DIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) kernfs_remove(kn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) int sysfs_rename_dir_ns(struct kobject *kobj, const char *new_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) const void *new_ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct kernfs_node *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) parent = kernfs_get_parent(kobj->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) ret = kernfs_rename_ns(kobj->sd, parent, new_name, new_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) kernfs_put(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) int sysfs_move_dir_ns(struct kobject *kobj, struct kobject *new_parent_kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) const void *new_ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct kernfs_node *kn = kobj->sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct kernfs_node *new_parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) new_parent = new_parent_kobj && new_parent_kobj->sd ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) new_parent_kobj->sd : sysfs_root_kn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return kernfs_rename_ns(kn, new_parent, kn->name, new_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * sysfs_create_mount_point - create an always empty directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * @parent_kobj: kobject that will contain this always empty directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * @name: The name of the always empty directory to add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) int sysfs_create_mount_point(struct kobject *parent_kobj, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct kernfs_node *kn, *parent = parent_kobj->sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) kn = kernfs_create_empty_dir(parent, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (IS_ERR(kn)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (PTR_ERR(kn) == -EEXIST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) sysfs_warn_dup(parent, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return PTR_ERR(kn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) EXPORT_SYMBOL_GPL(sysfs_create_mount_point);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * sysfs_remove_mount_point - remove an always empty directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * @parent_kobj: kobject that will contain this always empty directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * @name: The name of the always empty directory to remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) void sysfs_remove_mount_point(struct kobject *parent_kobj, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct kernfs_node *parent = parent_kobj->sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) kernfs_remove_by_name_ns(parent, name, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) EXPORT_SYMBOL_GPL(sysfs_remove_mount_point);