summaryrefslogtreecommitdiff
path: root/fs/sysfs/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/sysfs/dir.c')
-rw-r--r--fs/sysfs/dir.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index eab59de47556..486238d06021 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -813,7 +813,8 @@ static struct sysfs_dirent *sysfs_next_descendant_post(struct sysfs_dirent *pos,
return pos->s_parent;
}
-void __sysfs_remove(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
+static void __sysfs_remove(struct sysfs_addrm_cxt *acxt,
+ struct sysfs_dirent *sd)
{
struct sysfs_dirent *pos, *next;
@@ -847,6 +848,41 @@ void sysfs_remove(struct sysfs_dirent *sd)
}
/**
+ * sysfs_hash_and_remove - find a sysfs_dirent by name and remove it
+ * @dir_sd: parent of the target
+ * @name: name of the sysfs_dirent to remove
+ * @ns: namespace tag of the sysfs_dirent to remove
+ *
+ * Look for the sysfs_dirent with @name and @ns under @dir_sd and remove
+ * it. Returns 0 on success, -ENOENT if such entry doesn't exist.
+ */
+int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name,
+ const void *ns)
+{
+ struct sysfs_addrm_cxt acxt;
+ struct sysfs_dirent *sd;
+
+ if (!dir_sd) {
+ WARN(1, KERN_WARNING "sysfs: can not remove '%s', no directory\n",
+ name);
+ return -ENOENT;
+ }
+
+ sysfs_addrm_start(&acxt);
+
+ sd = sysfs_find_dirent(dir_sd, name, ns);
+ if (sd)
+ __sysfs_remove(&acxt, sd);
+
+ sysfs_addrm_finish(&acxt);
+
+ if (sd)
+ return 0;
+ else
+ return -ENOENT;
+}
+
+/**
* sysfs_remove_dir - remove an object's directory.
* @kobj: object.
*