aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/sysfs/dir.c4
-rw-r--r--fs/sysfs/inode.c1
-rw-r--r--include/linux/sysfs.h1
3 files changed, 5 insertions, 1 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index eb9bc0a8717b..f2ea00683ec9 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -171,7 +171,7 @@ void sysfs_deactivate(struct sysfs_dirent *sd)
171 DECLARE_COMPLETION_ONSTACK(wait); 171 DECLARE_COMPLETION_ONSTACK(wait);
172 int v; 172 int v;
173 173
174 BUG_ON(sd->s_sibling); 174 BUG_ON(sd->s_sibling || !(sd->s_flags & SYSFS_FLAG_REMOVED));
175 sd->s_sibling = (void *)&wait; 175 sd->s_sibling = (void *)&wait;
176 176
177 /* atomic_add_return() is a mb(), put_active() will always see 177 /* atomic_add_return() is a mb(), put_active() will always see
@@ -506,6 +506,7 @@ static void remove_dir(struct dentry * d)
506 mutex_lock(&parent->d_inode->i_mutex); 506 mutex_lock(&parent->d_inode->i_mutex);
507 507
508 sysfs_unlink_sibling(sd); 508 sysfs_unlink_sibling(sd);
509 sd->s_flags |= SYSFS_FLAG_REMOVED;
509 510
510 pr_debug(" o %s removing done (%d)\n",d->d_name.name, 511 pr_debug(" o %s removing done (%d)\n",d->d_name.name,
511 atomic_read(&d->d_count)); 512 atomic_read(&d->d_count));
@@ -540,6 +541,7 @@ static void __sysfs_remove_dir(struct dentry *dentry)
540 struct sysfs_dirent *sd = *pos; 541 struct sysfs_dirent *sd = *pos;
541 542
542 if (sysfs_type(sd) && (sysfs_type(sd) & SYSFS_NOT_PINNED)) { 543 if (sysfs_type(sd) && (sysfs_type(sd) & SYSFS_NOT_PINNED)) {
544 sd->s_flags |= SYSFS_FLAG_REMOVED;
543 *pos = sd->s_sibling; 545 *pos = sd->s_sibling;
544 sd->s_sibling = removed; 546 sd->s_sibling = removed;
545 removed = sd; 547 removed = sd;
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index ee3a5d957051..e2f6ef138d20 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -296,6 +296,7 @@ int sysfs_hash_and_remove(struct dentry * dir, const char * name)
296 if (!sysfs_type(sd)) 296 if (!sysfs_type(sd))
297 continue; 297 continue;
298 if (!strcmp(sd->s_name, name)) { 298 if (!strcmp(sd->s_name, name)) {
299 sd->s_flags |= SYSFS_FLAG_REMOVED;
299 *pos = sd->s_sibling; 300 *pos = sd->s_sibling;
300 sd->s_sibling = NULL; 301 sd->s_sibling = NULL;
301 found = 1; 302 found = 1;
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 58135509023e..2a6df6444e69 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -84,6 +84,7 @@ struct sysfs_ops {
84#define SYSFS_COPY_NAME (SYSFS_DIR | SYSFS_KOBJ_LINK) 84#define SYSFS_COPY_NAME (SYSFS_DIR | SYSFS_KOBJ_LINK)
85 85
86#define SYSFS_FLAG_MASK ~SYSFS_TYPE_MASK 86#define SYSFS_FLAG_MASK ~SYSFS_TYPE_MASK
87#define SYSFS_FLAG_REMOVED 0x0100
87 88
88#ifdef CONFIG_SYSFS 89#ifdef CONFIG_SYSFS
89 90