On Thu, Feb 06, 2025 at 04:42:42PM +1100, NeilBrown wrote: > @@ -1700,6 +1702,15 @@ struct dentry *lookup_one_qstr(const struct qstr *name, > if ((flags & LOOKUP_INTENT_FLAGS) == 0) > /* ->lookup must have given final answer */ > d_lookup_done(dentry); > +found: > + if (d_is_negative(dentry) && !(flags & LOOKUP_CREATE)) { > + dput(dentry); > + return ERR_PTR(-ENOENT); > + } > + if (d_is_positive(dentry) && (flags & LOOKUP_EXCL)) { > + dput(dentry); > + return ERR_PTR(-EEXIST); > + } Final dput() on an in-lookup dentry would blow up. What happens if we get there without LOOKUP_CREATE, but with something else from LOOKUP_INTENT_FLAGS? That, BTW, is another lovely example of the reasons why making state (in-lookup in this case, locking elsewhere) transitions dependent upon the function arguments is a bad idea.