]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/sysfs/dir.c
Merge remote-tracking branch 'userns/for-next'
[karo-tx-linux.git] / fs / sysfs / dir.c
index 0cdfd8128d3e5199eaf37e7dd7f2c54030100b68..11837b73abbfac18fdc733b41808dac2800d6af9 100644 (file)
@@ -144,24 +144,6 @@ static void sysfs_unlink_sibling(struct sysfs_dirent *sd)
                sd->s_parent->s_flags &= ~SYSFS_FLAG_HAS_NS;
 }
 
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
-
-/* Test for attributes that want to ignore lockdep for read-locking */
-static bool ignore_lockdep(struct sysfs_dirent *sd)
-{
-       return sysfs_type(sd) == SYSFS_KOBJ_ATTR &&
-                       sd->s_attr.attr->ignore_lockdep;
-}
-
-#else
-
-static inline bool ignore_lockdep(struct sysfs_dirent *sd)
-{
-       return true;
-}
-
-#endif
-
 /**
  *     sysfs_get_active - get an active reference to sysfs_dirent
  *     @sd: sysfs_dirent to get an active reference to
@@ -180,7 +162,7 @@ struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd)
        if (!atomic_inc_unless_negative(&sd->s_active))
                return NULL;
 
-       if (likely(!ignore_lockdep(sd)))
+       if (likely(!sysfs_ignore_lockdep(sd)))
                rwsem_acquire_read(&sd->dep_map, 0, 1, _RET_IP_);
        return sd;
 }
@@ -199,7 +181,7 @@ void sysfs_put_active(struct sysfs_dirent *sd)
        if (unlikely(!sd))
                return;
 
-       if (likely(!ignore_lockdep(sd)))
+       if (likely(!sysfs_ignore_lockdep(sd)))
                rwsem_release(&sd->dep_map, 1, _RET_IP_);
        v = atomic_dec_return(&sd->s_active);
        if (likely(v != SD_DEACTIVATED_BIAS))
@@ -333,7 +315,6 @@ static int sysfs_dentry_revalidate(struct dentry *dentry, unsigned int flags)
                goto out_bad;
 
        mutex_unlock(&sysfs_mutex);
-out_valid:
        return 1;
 out_bad:
        /* Remove the dentry from the dcache hashes.
@@ -347,13 +328,7 @@ out_bad:
         * to the dcache hashes.
         */
        mutex_unlock(&sysfs_mutex);
-
-       /* If we have submounts we must allow the vfs caches
-        * to lie about the state of the filesystem to prevent
-        * leaks and other nasty things.
-        */
-       if (check_submounts_and_drop(dentry) != 0)
-               goto out_valid;
+       shrink_submounts_and_drop(dentry);
 
        return 0;
 }
@@ -545,7 +520,8 @@ int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd,
  *     LOCKING:
  *     Determined by sysfs_addrm_start().
  */
-void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
+static void sysfs_remove_one(struct sysfs_addrm_cxt *acxt,
+                            struct sysfs_dirent *sd)
 {
        struct sysfs_inode_attrs *ps_iattr;
 
@@ -594,7 +570,7 @@ void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
                acxt->removed = sd->u.removed_list;
 
                sysfs_deactivate(sd);
-               unmap_bin_file(sd);
+               sysfs_unmap_bin_file(sd);
                sysfs_put(sd);
        }
 }
@@ -775,20 +751,6 @@ const struct inode_operations sysfs_dir_inode_operations = {
        .setxattr       = sysfs_setxattr,
 };
 
-static void remove_dir(struct sysfs_dirent *sd)
-{
-       struct sysfs_addrm_cxt acxt;
-
-       sysfs_addrm_start(&acxt);
-       sysfs_remove_one(&acxt, sd);
-       sysfs_addrm_finish(&acxt);
-}
-
-void sysfs_remove_subdir(struct sysfs_dirent *sd)
-{
-       remove_dir(sd);
-}
-
 static struct sysfs_dirent *sysfs_leftmost_descendant(struct sysfs_dirent *pos)
 {
        struct sysfs_dirent *last;
@@ -844,25 +806,36 @@ static struct sysfs_dirent *sysfs_next_descendant_post(struct sysfs_dirent *pos,
        return pos->s_parent;
 }
 
-static void __sysfs_remove_dir(struct sysfs_dirent *dir_sd)
+void __sysfs_remove(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
 {
-       struct sysfs_addrm_cxt acxt;
        struct sysfs_dirent *pos, *next;
 
-       if (!dir_sd)
+       if (!sd)
                return;
 
-       pr_debug("sysfs %s: removing dir\n", dir_sd->s_name);
-       sysfs_addrm_start(&acxt);
+       pr_debug("sysfs %s: removing\n", sd->s_name);
 
        next = NULL;
        do {
                pos = next;
-               next = sysfs_next_descendant_post(pos, dir_sd);
+               next = sysfs_next_descendant_post(pos, sd);
                if (pos)
-                       sysfs_remove_one(&acxt, pos);
+                       sysfs_remove_one(acxt, pos);
        } while (next);
+}
 
+/**
+ * sysfs_remove - remove a sysfs_dirent recursively
+ * @sd: the sysfs_dirent to remove
+ *
+ * Remove @sd along with all its subdirectories and files.
+ */
+void sysfs_remove(struct sysfs_dirent *sd)
+{
+       struct sysfs_addrm_cxt acxt;
+
+       sysfs_addrm_start(&acxt);
+       __sysfs_remove(&acxt, sd);
        sysfs_addrm_finish(&acxt);
 }
 
@@ -882,7 +855,10 @@ void sysfs_remove_dir(struct kobject *kobj)
        kobj->sd = NULL;
        spin_unlock(&sysfs_assoc_lock);
 
-       __sysfs_remove_dir(sd);
+       if (sd) {
+               WARN_ON_ONCE(sysfs_type(sd) != SYSFS_DIR);
+               sysfs_remove(sd);
+       }
 }
 
 int sysfs_rename(struct sysfs_dirent *sd, struct sysfs_dirent *new_parent_sd,