aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysfs
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2011-10-12 18:02:43 -0400
committerDavid S. Miller <davem@davemloft.net>2011-10-19 19:24:16 -0400
commit903e21e2eea036f6947f523f732e28b33a63ed0f (patch)
treee63059c0acbfde6eca66cd9c293a984e64d6cab8 /fs/sysfs
parent23396180a9770df2c6a694bbb689c12bdf792f94 (diff)
sysfs: Reject with a warning invalid uses of tagged directories.
sysfs is a core piece of ifrastructure that many people use and few people have all of the rules in their head on how to use it correctly. Add warnings for people using tagged directories improperly to that any misuses can be caught and diagnosed quickly. A single inexpensive test in sysfs_find_dirent is almost sufficient to catch all possible misuses. An additional warning is needed in sysfs_add_dirent so that we actually fail when attempting to add an untagged dirent in a tagged directory. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Acked-by: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'fs/sysfs')
-rw-r--r--fs/sysfs/dir.c14
-rw-r--r--fs/sysfs/file.c3
2 files changed, 14 insertions, 3 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 352d26d98c0a..26f370a9b5ce 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -384,6 +384,13 @@ int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
384{ 384{
385 struct sysfs_inode_attrs *ps_iattr; 385 struct sysfs_inode_attrs *ps_iattr;
386 386
387 if (!!sysfs_ns_type(acxt->parent_sd) != !!sd->s_ns) {
388 WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n",
389 sysfs_ns_type(acxt->parent_sd)? "required": "invalid",
390 acxt->parent_sd->s_name, sd->s_name);
391 return -EINVAL;
392 }
393
387 if (sysfs_find_dirent(acxt->parent_sd, sd->s_ns, sd->s_name)) 394 if (sysfs_find_dirent(acxt->parent_sd, sd->s_ns, sd->s_name))
388 return -EEXIST; 395 return -EEXIST;
389 396
@@ -542,6 +549,13 @@ struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
542{ 549{
543 struct sysfs_dirent *sd; 550 struct sysfs_dirent *sd;
544 551
552 if (!!sysfs_ns_type(parent_sd) != !!ns) {
553 WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n",
554 sysfs_ns_type(parent_sd)? "required": "invalid",
555 parent_sd->s_name, name);
556 return NULL;
557 }
558
545 for (sd = parent_sd->s_dir.children; sd; sd = sd->s_sibling) { 559 for (sd = parent_sd->s_dir.children; sd; sd = sd->s_sibling) {
546 if (sd->s_ns != ns) 560 if (sd->s_ns != ns)
547 continue; 561 continue;
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 07c1b4ec00df..d4e6080b4b20 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -466,9 +466,6 @@ void sysfs_notify(struct kobject *k, const char *dir, const char *attr)
466 mutex_lock(&sysfs_mutex); 466 mutex_lock(&sysfs_mutex);
467 467
468 if (sd && dir) 468 if (sd && dir)
469 /* Only directories are tagged, so no need to pass
470 * a tag explicitly.
471 */
472 sd = sysfs_find_dirent(sd, NULL, dir); 469 sd = sysfs_find_dirent(sd, NULL, dir);
473 if (sd && attr) 470 if (sd && attr)
474 sd = sysfs_find_dirent(sd, NULL, attr); 471 sd = sysfs_find_dirent(sd, NULL, attr);