On Tue, Sep 09, 2025 at 02:43:15PM +1000, NeilBrown wrote: > Note that instead of always getting an exclusive lock, ovl now only gets > a shared lock, and only sometimes. The exclusive lock was never needed. what it is the locking environment in callers and what stabilizes that list hanging off rdd, seeing that you now run through it without having dir held exclusive? > - int err; > + int err = 0; > struct dentry *dentry, *dir = path->dentry; > const struct cred *old_cred; > > old_cred = ovl_override_creds(rdd->dentry->d_sb); > > - err = down_write_killable(&dir->d_inode->i_rwsem); > - if (!err) { > - while (rdd->first_maybe_whiteout) { > - struct ovl_cache_entry *p = > - rdd->first_maybe_whiteout; > - rdd->first_maybe_whiteout = p->next_maybe_whiteout; > - dentry = lookup_one(mnt_idmap(path->mnt), > - &QSTR_LEN(p->name, p->len), dir); > - if (!IS_ERR(dentry)) { > - p->is_whiteout = ovl_is_whiteout(dentry); > - dput(dentry); > - } > + while (rdd->first_maybe_whiteout) { > + struct ovl_cache_entry *p = > + rdd->first_maybe_whiteout; > + rdd->first_maybe_whiteout = p->next_maybe_whiteout; > + dentry = lookup_one_positive_killable(mnt_idmap(path->mnt), > + &QSTR_LEN(p->name, p->len), > + dir); > + if (!IS_ERR(dentry)) { > + p->is_whiteout = ovl_is_whiteout(dentry); > + dput(dentry); > + } else if (PTR_ERR(dentry) == -EINTR) { > + err = -EINTR; > + break; > } > - inode_unlock(dir->d_inode); > } > ovl_revert_creds(old_cred); > > diff --git a/include/linux/namei.h b/include/linux/namei.h > index 5d085428e471..551a1a01e5e7 100644 > --- a/include/linux/namei.h > +++ b/include/linux/namei.h > @@ -80,6 +80,9 @@ struct dentry *lookup_one_unlocked(struct mnt_idmap *idmap, > struct dentry *lookup_one_positive_unlocked(struct mnt_idmap *idmap, > struct qstr *name, > struct dentry *base); > +struct dentry *lookup_one_positive_killable(struct mnt_idmap *idmap, > + struct qstr *name, > + struct dentry *base); > > extern int follow_down_one(struct path *); > extern int follow_down(struct path *path, unsigned int flags); > -- > 2.50.0.107.gf914562f5916.dirty >