···25752575 * Note: If ever the locking in lock_rename() changes, then please25762576 * remember to update this too...25772577 */25782578-static struct dentry *__d_unalias(struct inode *inode,25782578+static int __d_unalias(struct inode *inode,25792579 struct dentry *dentry, struct dentry *alias)25802580{25812581 struct mutex *m1 = NULL, *m2 = NULL;25822582- struct dentry *ret = ERR_PTR(-EBUSY);25822582+ int ret = -EBUSY;2583258325842584 /* If alias and dentry share a parent, then no extra locks required */25852585 if (alias->d_parent == dentry->d_parent)···25942594 m2 = &alias->d_parent->d_inode->i_mutex;25952595out_unalias:25962596 __d_move(alias, dentry, false);25972597- ret = alias;25972597+ ret = 0;25982598out_err:25992599 spin_unlock(&inode->i_lock);26002600 if (m2)···26292629 */26302630struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)26312631{26322632- struct dentry *new = NULL;26332633-26342632 if (IS_ERR(inode))26352633 return ERR_CAST(inode);26362636-26372637- if (inode && S_ISDIR(inode->i_mode)) {26382638- spin_lock(&inode->i_lock);26392639- new = __d_find_any_alias(inode);26402640- if (new) {26412641- if (!IS_ROOT(new)) {26422642- spin_unlock(&inode->i_lock);26432643- dput(new);26442644- iput(inode);26452645- return ERR_PTR(-EIO);26462646- }26472647- if (d_ancestor(new, dentry)) {26482648- spin_unlock(&inode->i_lock);26492649- dput(new);26502650- iput(inode);26512651- return ERR_PTR(-EIO);26522652- }26532653- write_seqlock(&rename_lock);26542654- __d_move(new, dentry, false);26552655- write_sequnlock(&rename_lock);26562656- spin_unlock(&inode->i_lock);26572657- security_d_instantiate(new, inode);26582658- iput(inode);26592659- } else {26602660- /* already taking inode->i_lock, so d_add() by hand */26612661- __d_instantiate(dentry, inode);26622662- spin_unlock(&inode->i_lock);26632663- security_d_instantiate(dentry, inode);26642664- d_rehash(dentry);26652665- }26662666- } else {26672667- d_instantiate(dentry, inode);26682668- if (d_unhashed(dentry))26692669- d_rehash(dentry);26702670- }26712671- return new;26722672-}26732673-EXPORT_SYMBOL(d_splice_alias);26742674-26752675-/**26762676- * d_materialise_unique - introduce an inode into the tree26772677- * @dentry: candidate dentry26782678- * @inode: inode to bind to the dentry, to which aliases may be attached26792679- *26802680- * Introduces an dentry into the tree, substituting an extant disconnected26812681- * root directory alias in its place if there is one. Caller must hold the26822682- * i_mutex of the parent directory.26832683- */26842684-struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)26852685-{26862686- struct dentry *actual;2687263426882635 BUG_ON(!d_unhashed(dentry));2689263626902637 if (!inode) {26912691- actual = dentry;26922638 __d_instantiate(dentry, NULL);26932693- d_rehash(actual);26942694- goto out_nolock;26392639+ goto out;26952640 }26962696-26972641 spin_lock(&inode->i_lock);26982698-26992642 if (S_ISDIR(inode->i_mode)) {27002700- struct dentry *alias;27012701-27022702- /* Does an aliased dentry already exist? */27032703- alias = __d_find_alias(inode);27042704- if (alias) {27052705- actual = alias;26432643+ struct dentry *new = __d_find_any_alias(inode);26442644+ if (unlikely(new)) {27062645 write_seqlock(&rename_lock);27072707-27082708- if (d_ancestor(alias, dentry)) {27092709- /* Check for loops */27102710- actual = ERR_PTR(-ELOOP);27112711- spin_unlock(&inode->i_lock);27122712- } else if (IS_ROOT(alias)) {27132713- /* Is this an anonymous mountpoint that we27142714- * could splice into our tree? */27152715- __d_move(alias, dentry, false);26462646+ if (unlikely(d_ancestor(new, dentry))) {27162647 write_sequnlock(&rename_lock);27172717- goto found;26482648+ spin_unlock(&inode->i_lock);26492649+ dput(new);26502650+ new = ERR_PTR(-ELOOP);26512651+ pr_warn_ratelimited(26522652+ "VFS: Lookup of '%s' in %s %s"26532653+ " would have caused loop\n",26542654+ dentry->d_name.name,26552655+ inode->i_sb->s_type->name,26562656+ inode->i_sb->s_id);26572657+ } else if (!IS_ROOT(new)) {26582658+ int err = __d_unalias(inode, dentry, new);26592659+ write_sequnlock(&rename_lock);26602660+ if (err) {26612661+ dput(new);26622662+ new = ERR_PTR(err);26632663+ }27182664 } else {27192719- /* Nope, but we must(!) avoid directory27202720- * aliasing. This drops inode->i_lock */27212721- actual = __d_unalias(inode, dentry, alias);26652665+ __d_move(new, dentry, false);26662666+ write_sequnlock(&rename_lock);26672667+ spin_unlock(&inode->i_lock);26682668+ security_d_instantiate(new, inode);27222669 }27232723- write_sequnlock(&rename_lock);27242724- if (IS_ERR(actual)) {27252725- if (PTR_ERR(actual) == -ELOOP)27262726- pr_warn_ratelimited(27272727- "VFS: Lookup of '%s' in %s %s"27282728- " would have caused loop\n",27292729- dentry->d_name.name,27302730- inode->i_sb->s_type->name,27312731- inode->i_sb->s_id);27322732- dput(alias);27332733- }27342734- goto out_nolock;26702670+ iput(inode);26712671+ return new;27352672 }27362673 }27372737-27382738- /* Add a unique reference */27392739- actual = __d_instantiate_unique(dentry, inode);27402740- if (!actual)27412741- actual = dentry;27422742-27432743- d_rehash(actual);27442744-found:26742674+ /* already taking inode->i_lock, so d_add() by hand */26752675+ __d_instantiate(dentry, inode);27452676 spin_unlock(&inode->i_lock);27462746-out_nolock:27472747- if (actual == dentry) {27482748- security_d_instantiate(dentry, inode);27492749- return NULL;27502750- }27512751-27522752- iput(inode);27532753- return actual;26772677+out:26782678+ security_d_instantiate(dentry, inode);26792679+ d_rehash(dentry);26802680+ return NULL;27542681}27552755-EXPORT_SYMBOL_GPL(d_materialise_unique);26822682+EXPORT_SYMBOL(d_splice_alias);2756268327572684static int prepend(char **buffer, int *buflen, const char *str, int namelen)27582685{