瀏覽代碼

sysfs: Add support for tagged directories with untagged members.

I had hopped to avoid this but the bonding driver adds a file
to /sys/class/net/  and the easiest way to handle that file is
to make it untagged and to register it only once.

So relax the rules on tagged directories, and make bonding work.

Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Eric W. Biederman 15 年之前
父節點
當前提交
af10ec77b4
共有 2 個文件被更改,包括 5 次插入9 次删除
  1. 3 9
      fs/sysfs/dir.c
  2. 2 0
      fs/sysfs/inode.c

+ 3 - 9
fs/sysfs/dir.c

@@ -383,12 +383,6 @@ int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
 	if (sysfs_find_dirent(acxt->parent_sd, sd->s_ns, sd->s_name))
 	if (sysfs_find_dirent(acxt->parent_sd, sd->s_ns, sd->s_name))
 		return -EEXIST;
 		return -EEXIST;
 
 
-	if (sysfs_ns_type(acxt->parent_sd) && !sd->s_ns) {
-		WARN(1, KERN_WARNING "sysfs: ns required in '%s' for '%s'\n",
-			acxt->parent_sd->s_name, sd->s_name);
-		return -EINVAL;
-	}
-
 	sd->s_parent = sysfs_get(acxt->parent_sd);
 	sd->s_parent = sysfs_get(acxt->parent_sd);
 
 
 	sysfs_link_sibling(sd);
 	sysfs_link_sibling(sd);
@@ -545,7 +539,7 @@ struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
 	struct sysfs_dirent *sd;
 	struct sysfs_dirent *sd;
 
 
 	for (sd = parent_sd->s_dir.children; sd; sd = sd->s_sibling) {
 	for (sd = parent_sd->s_dir.children; sd; sd = sd->s_sibling) {
-		if (sd->s_ns != ns)
+		if (ns && sd->s_ns && (sd->s_ns != ns))
 			continue;
 			continue;
 		if (!strcmp(sd->s_name, name))
 		if (!strcmp(sd->s_name, name))
 			return sd;
 			return sd;
@@ -879,7 +873,7 @@ static struct sysfs_dirent *sysfs_dir_pos(const void *ns,
 		while (pos && (ino > pos->s_ino))
 		while (pos && (ino > pos->s_ino))
 			pos = pos->s_sibling;
 			pos = pos->s_sibling;
 	}
 	}
-	while (pos && pos->s_ns != ns)
+	while (pos && pos->s_ns && pos->s_ns != ns)
 		pos = pos->s_sibling;
 		pos = pos->s_sibling;
 	return pos;
 	return pos;
 }
 }
@@ -890,7 +884,7 @@ static struct sysfs_dirent *sysfs_dir_next_pos(const void *ns,
 	pos = sysfs_dir_pos(ns, parent_sd, ino, pos);
 	pos = sysfs_dir_pos(ns, parent_sd, ino, pos);
 	if (pos)
 	if (pos)
 		pos = pos->s_sibling;
 		pos = pos->s_sibling;
-	while (pos && pos->s_ns != ns)
+	while (pos && pos->s_ns && pos->s_ns != ns)
 		pos = pos->s_sibling;
 		pos = pos->s_sibling;
 	return pos;
 	return pos;
 }
 }

+ 2 - 0
fs/sysfs/inode.c

@@ -335,6 +335,8 @@ int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns, const cha
 	sysfs_addrm_start(&acxt, dir_sd);
 	sysfs_addrm_start(&acxt, dir_sd);
 
 
 	sd = sysfs_find_dirent(dir_sd, ns, name);
 	sd = sysfs_find_dirent(dir_sd, ns, name);
+	if (sd && (sd->s_ns != ns))
+		sd = NULL;
 	if (sd)
 	if (sd)
 		sysfs_remove_one(&acxt, sd);
 		sysfs_remove_one(&acxt, sd);