]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
kill configfs_drop_dentry()
authorAl Viro <viro@zeniv.linux.org.uk>
Tue, 12 May 2026 16:53:35 +0000 (12:53 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Mon, 8 Jun 2026 18:53:14 +0000 (14:53 -0400)
Fold into the only remaining user, don't bother with the timestamps
of parent - we are going to rmdir it shortly anyway, which will
override those.

Fix the locking of inode, while we are at it - updating the link
count and timestamps ought to be done with the inode locked.

Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/configfs/configfs_internal.h
fs/configfs/dir.c
fs/configfs/inode.c

index 0b969d0eb8ff987b86c8e9f0af3e05dea2d19989..acdeea8e2d69ac9d621e1a42b039719811c31757 100644 (file)
@@ -76,7 +76,6 @@ extern int configfs_make_dirent(struct configfs_dirent *, struct dentry *,
 extern int configfs_dirent_is_ready(struct configfs_dirent *);
 
 extern const unsigned char * configfs_get_name(struct configfs_dirent *sd);
-extern void configfs_drop_dentry(struct configfs_dirent *sd, struct dentry *parent);
 extern int configfs_setattr(struct mnt_idmap *idmap,
                            struct dentry *dentry, struct iattr *iattr);
 
index 479d37b8d806a5ce6993bf94a170368c689f5deb..4a4bad1741cfe93a986ff7a6bd9f467479324b45 100644 (file)
@@ -581,12 +581,34 @@ static void detach_attrs(struct dentry *dentry)
 
        spin_lock(&configfs_dirent_lock);
        for (sd = next_dirent(parent_sd, NULL); sd; sd = next) {
+               struct dentry *child;
+
                next = next_dirent(parent_sd, sd);
                if (!(sd->s_type & CONFIGFS_NOT_PINNED))
                        continue;
                list_del_init(&sd->s_sibling);
+               child = sd->s_dentry;
+               if (child) {
+                       spin_lock(&child->d_lock);
+                       if (simple_positive(child)) {
+                               dget_dlock(child);
+                               __d_drop(child);
+                               spin_unlock(&child->d_lock);
+                       } else {
+                               spin_unlock(&child->d_lock);
+                               child = NULL;
+                       }
+               }
                spin_unlock(&configfs_dirent_lock);
-               configfs_drop_dentry(sd, dentry);
+               if (child) {
+                       struct inode *inode = child->d_inode;
+
+                       inode_lock_nested(inode, I_MUTEX_NONDIR2);
+                       inode_set_ctime_current(inode);
+                       drop_nlink(inode);
+                       inode_unlock(inode);
+                       dput(child);
+               }
                configfs_put(sd);
                spin_lock(&configfs_dirent_lock);
        }
index bc507b720a01d6e40eda515de88965f61bf5342e..3c26b6c443be9a4972e95b74fd93afc6d7e79424 100644 (file)
@@ -195,25 +195,3 @@ const unsigned char * configfs_get_name(struct configfs_dirent *sd)
        }
        return NULL;
 }
-
-
-/*
- * Unhashes the dentry corresponding to given configfs_dirent
- * Called with parent inode's i_mutex held.
- */
-void configfs_drop_dentry(struct configfs_dirent * sd, struct dentry * parent)
-{
-       struct dentry * dentry = sd->s_dentry;
-
-       if (dentry) {
-               spin_lock(&dentry->d_lock);
-               if (simple_positive(dentry)) {
-                       dget_dlock(dentry);
-                       __d_drop(dentry);
-                       spin_unlock(&dentry->d_lock);
-                       __simple_unlink(d_inode(parent), dentry);
-                       dput(dentry);
-               } else
-                       spin_unlock(&dentry->d_lock);
-       }
-}