Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit da093a9b authored by J. Bruce Fields's avatar J. Bruce Fields Committed by Al Viro
Browse files

dcache: d_splice_alias should ignore DCACHE_DISCONNECTED



Any IS_ROOT() alias should be safe to use; there's nothing special about
DCACHE_DISCONNECTED dentries.

Note that this is in fact useful for filesystems such as btrfs which can
legimately encounter a directory with a preexisting IS_ROOT alias on a
lookup that crosses into a subvolume.  (Those aliases are currently
marked DCACHE_DISCONNECTED--but not really for any good reason, and
we'll change that soon.)

Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 908790fa
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -2649,9 +2649,9 @@ static void __d_materialise_dentry(struct dentry *dentry, struct dentry *anon)
 * @inode:  the inode which may have a disconnected dentry
 * @dentry: a negative dentry which we want to point to the inode.
 *
 * If inode is a directory and has a 'disconnected' dentry (i.e. IS_ROOT and
 * DCACHE_DISCONNECTED), then d_move that in place of the given dentry
 * and return it, else simply d_add the inode to the dentry and return NULL.
 * If inode is a directory and has an IS_ROOT alias, then d_move that in
 * place of the given dentry and return it, else simply d_add the inode
 * to the dentry and return NULL.
 *
 * If a non-IS_ROOT directory is found, the filesystem is corrupt, and
 * we should error out: directories can't have multiple aliases.
@@ -2678,7 +2678,7 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
		spin_lock(&inode->i_lock);
		new = __d_find_any_alias(inode);
		if (new) {
			if (!IS_ROOT(new) || !(new->d_flags & DCACHE_DISCONNECTED)) {
			if (!IS_ROOT(new)) {
				spin_unlock(&inode->i_lock);
				dput(new);
				return ERR_PTR(-EIO);