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);
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);
}
}
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);
- }
-}