17 #include <linux/module.h>
23 #include <linux/slab.h>
25 #include <linux/hash.h>
31 #define to_sysfs_dirent(X) rb_entry((X), struct sysfs_dirent, s_rb);
43 static unsigned int sysfs_name_hash(
const void *
ns,
const char *
name)
48 hash = partial_name_hash(*name++, hash);
49 hash = ( end_name_hash(hash) ^ hash_ptr( (
void *)ns, 31 ) );
59 static int sysfs_name_compare(
unsigned int hash,
const void *ns,
103 result = sysfs_sd_compare(sd, pos);
105 node = &pos->
s_rb.rb_left;
107 node = &pos->
s_rb.rb_right;
112 rb_link_node(&sd->
s_rb, parent, node);
127 static void sysfs_unlink_sibling(
struct sysfs_dirent *sd)
135 #ifdef CONFIG_DEBUG_LOCK_ALLOC
141 sd->
s_attr.attr->ignore_lockdep;
146 static inline bool ignore_lockdep(
struct sysfs_dirent *sd)
184 if (
likely(!ignore_lockdep(sd)))
203 if (
likely(!ignore_lockdep(sd)))
248 static int sysfs_alloc_ino(
unsigned int *
pino)
253 spin_lock(&sysfs_ino_lock);
255 spin_unlock(&sysfs_ino_lock);
267 static void sysfs_free_ino(
unsigned int ino)
269 spin_lock(&sysfs_ino_lock);
271 spin_unlock(&sysfs_ino_lock);
292 sysfs_free_ino(sd->
s_ino);
300 static int sysfs_dentry_delete(
const struct dentry *
dentry)
368 static void sysfs_dentry_release(
struct dentry *dentry)
374 .d_revalidate = sysfs_dentry_revalidate,
375 .d_delete = sysfs_dentry_delete,
376 .d_release = sysfs_dentry_release,
381 char *dup_name =
NULL;
394 if (sysfs_alloc_ino(&sd->
s_ino))
430 memset(acxt, 0,
sizeof(*acxt));
463 sysfs_ns_type(acxt->
parent_sd)?
"required":
"invalid",
471 ret = sysfs_link_sibling(sd);
531 "sysfs: cannot create duplicate filename '%s'\n",
533 : (sysfs_pathname(acxt->
parent_sd, path),
564 sysfs_unlink_sibling(sd);
600 sysfs_deactivate(sd);
621 const unsigned char *name)
623 struct rb_node *node = parent_sd->
s_dir.children.rb_node;
626 if (!!sysfs_ns_type(parent_sd) != !!ns) {
628 sysfs_ns_type(parent_sd)?
"required":
"invalid",
633 hash = sysfs_name_hash(ns, name);
639 result = sysfs_name_compare(hash, ns, name, sd);
666 const unsigned char *name)
680 enum kobj_ns_type type,
const void *ns,
const char *name,
695 sd->
s_dir.kobj = kobj;
713 return create_dir(kobj, kobj->
sd,
750 const void *ns =
NULL;
756 parent_sd = kobj->
parent->sd;
763 if (sysfs_ns_type(parent_sd))
764 ns = kobj->
ktype->namespace(kobj);
765 type = sysfs_read_ns_type(kobj);
767 error = create_dir(kobj, parent_sd, type, ns, kobject_name(kobj), &sd);
773 static struct dentry * sysfs_lookup(
struct inode *dir,
struct dentry *dentry,
777 struct dentry *parent = dentry->
d_parent;
786 type = sysfs_ns_type(parent_sd);
813 .lookup = sysfs_lookup,
835 static void __sysfs_remove_dir(
struct sysfs_dirent *dir_sd)
874 __sysfs_remove_dir(sd);
879 const char *new_name)
886 if ((sd->
s_parent == new_parent_sd) && (sd->
s_ns == new_ns) &&
906 sysfs_unlink_sibling(sd);
912 sysfs_link_sibling(sd);
923 const void *new_ns =
NULL;
925 if (sysfs_ns_type(parent_sd))
926 new_ns = kobj->
ktype->namespace(kobj);
935 const void *new_ns =
NULL;
939 new_ns = kobj->
ktype->namespace(kobj);
940 new_parent_sd = new_parent_kobj && new_parent_kobj->
sd ?
947 static inline unsigned char dt_type(
struct sysfs_dirent *sd)
949 return (sd->
s_mode >> 12) & 15;
952 static int sysfs_dir_release(
struct inode *inode,
struct file *filp)
958 static struct sysfs_dirent *sysfs_dir_pos(
const void *ns,
969 if (!pos && (hash > 1) && (hash <
INT_MAX)) {
970 struct rb_node *node = parent_sd->
s_dir.children.rb_node;
974 if (hash < pos->s_hash)
976 else if (hash > pos->
s_hash)
983 while (pos && pos->
s_ns != ns) {
993 static struct sysfs_dirent *sysfs_dir_next_pos(
const void *ns,
996 pos = sysfs_dir_pos(ns, parent_sd, ino, pos);
1003 }
while (pos && pos->
s_ns != ns);
1009 struct dentry *dentry = filp->
f_path.dentry;
1016 type = sysfs_ns_type(parent_sd);
1019 if (filp->
f_pos == 0) {
1020 ino = parent_sd->
s_ino;
1021 if (filldir(dirent,
".", 1, filp->
f_pos, ino,
DT_DIR) == 0)
1024 if (filp->
f_pos == 1) {
1028 ino = parent_sd->
s_ino;
1029 if (filldir(dirent,
"..", 2, filp->
f_pos, ino,
DT_DIR) == 0)
1033 for (pos = sysfs_dir_pos(ns, parent_sd, filp->
f_pos, pos);
1035 pos = sysfs_dir_next_pos(ns, parent_sd, filp->
f_pos, pos)) {
1043 type = dt_type(pos);
1048 ret = filldir(dirent, name, len, filp->
f_pos, ino, type);
1054 if ((filp->
f_pos > 1) && !pos) {
1064 .readdir = sysfs_readdir,
1065 .release = sysfs_dir_release,