[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20140115151749.GF23999@fieldses.org>
Date: Wed, 15 Jan 2014 10:17:49 -0500
From: "J. Bruce Fields" <bfields@...ldses.org>
To: Al Viro <viro@...iv.linux.org.uk>
Cc: linux-fsdevel@...r.kernel.org, linux-kernel@...r.kernel.org,
linux-nfs@...r.kernel.org, Miklos Szeredi <mszeredi@...e.cz>
Subject: [PATCH] dcache: fix d_splice_alias handling of aliases
From: "J. Bruce Fields" <bfields@...hat.com>
d_splice_alias can create duplicate directory aliases (in the !new
case), or (in the new case) d_move without holding appropriate locks.
d_materialise_unique deals with both of these problems. (The latter
seems to be dealt by trylocks (see __d_unalias), which look like they
could cause spurious lookup failures--but that's at least better than
corrupting the dcache.)
Signed-off-by: J. Bruce Fields <bfields@...hat.com>
---
fs/dcache.c | 25 +------------------------
1 file changed, 1 insertion(+), 24 deletions(-)
Only lightly tested.... If this is right, then we can also just ditch
d_splice_alias completely, and clean up the various d_find_alias's.
I think the only reason we have both d_splice_alias and
d_materialise_unique is that the former was written for exportable
filesystems and the latter for distributed filesystems.
But we have at least one exportable filesystem (fuse) using
d_materialise_unique. And I doubt d_splice_alias was ever completely
correct even for on-disk filesystems.
Am I missing some subtlety?
--b.
diff --git a/fs/dcache.c b/fs/dcache.c
index 4bdb300..da82fa9 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1926,33 +1926,10 @@ EXPORT_SYMBOL(d_obtain_alias);
*/
struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
{
- struct dentry *new = NULL;
-
if (IS_ERR(inode))
return ERR_CAST(inode);
- if (inode && S_ISDIR(inode->i_mode)) {
- spin_lock(&inode->i_lock);
- new = __d_find_alias(inode, 1);
- if (new) {
- BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED));
- spin_unlock(&inode->i_lock);
- security_d_instantiate(new, inode);
- d_move(new, dentry);
- iput(inode);
- } else {
- /* already taking inode->i_lock, so d_add() by hand */
- __d_instantiate(dentry, inode);
- spin_unlock(&inode->i_lock);
- security_d_instantiate(dentry, inode);
- d_rehash(dentry);
- }
- } else {
- d_instantiate(dentry, inode);
- if (d_unhashed(dentry))
- d_rehash(dentry);
- }
- return new;
+ return d_materialise_unique(dentry, inode);
}
EXPORT_SYMBOL(d_splice_alias);
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists