diff options
author | J. Bruce Fields <bfields@redhat.com> | 2014-02-17 18:03:57 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2014-08-07 14:40:10 -0400 |
commit | da093a9b76efca0a7a217af538929e1ecb204466 (patch) | |
tree | 2ba563181c06bbcbd68fe4144f98e6a31d813d81 /fs/dcache.c | |
parent | 908790fa3b779d37365e6b28e3aa0f6e833020c3 (diff) |
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: J. Bruce Fields <bfields@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index a191eebf1d63..3ed095363997 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -2649,9 +2649,9 @@ static void __d_materialise_dentry(struct dentry *dentry, struct dentry *anon) | |||
2649 | * @inode: the inode which may have a disconnected dentry | 2649 | * @inode: the inode which may have a disconnected dentry |
2650 | * @dentry: a negative dentry which we want to point to the inode. | 2650 | * @dentry: a negative dentry which we want to point to the inode. |
2651 | * | 2651 | * |
2652 | * If inode is a directory and has a 'disconnected' dentry (i.e. IS_ROOT and | 2652 | * If inode is a directory and has an IS_ROOT alias, then d_move that in |
2653 | * DCACHE_DISCONNECTED), then d_move that in place of the given dentry | 2653 | * place of the given dentry and return it, else simply d_add the inode |
2654 | * and return it, else simply d_add the inode to the dentry and return NULL. | 2654 | * to the dentry and return NULL. |
2655 | * | 2655 | * |
2656 | * If a non-IS_ROOT directory is found, the filesystem is corrupt, and | 2656 | * If a non-IS_ROOT directory is found, the filesystem is corrupt, and |
2657 | * we should error out: directories can't have multiple aliases. | 2657 | * 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) | |||
2678 | spin_lock(&inode->i_lock); | 2678 | spin_lock(&inode->i_lock); |
2679 | new = __d_find_any_alias(inode); | 2679 | new = __d_find_any_alias(inode); |
2680 | if (new) { | 2680 | if (new) { |
2681 | if (!IS_ROOT(new) || !(new->d_flags & DCACHE_DISCONNECTED)) { | 2681 | if (!IS_ROOT(new)) { |
2682 | spin_unlock(&inode->i_lock); | 2682 | spin_unlock(&inode->i_lock); |
2683 | dput(new); | 2683 | dput(new); |
2684 | return ERR_PTR(-EIO); | 2684 | return ERR_PTR(-EIO); |