[OpenAFS-devel] Re: OpenAFS client crashes on RHEL 5.10 and RHEL 6.5
Andrew Deason
adeason@sinenomine.net
Tue, 18 Mar 2014 14:16:12 -0500
On Tue, 18 Mar 2014 14:04:12 -0500
Andrew Deason <adeason@sinenomine.net> wrote:
> Due to the various bug reports filed about this issue, Red Hat has
> indicated that they are considering this issue a regression in Red Hat
> Enterprise Linux and will be providing a fix in at least RHEL 6.6 and an
> RHEL 6.5 update. Red Hat has not yet indicated that a fix will be
> available for RHEL 5, though they will probably be investigating a fix
> for that version.
The following is a fix from Red Hat that I was testing against. Red Hat
is okay with sharing this, but they want it to be clear that running
with this is _not_ supported, and the actual fix that makes it into 6.6
et al may be different.
Anyway, I wanted to share this so others can confirm my thoughts and to
see what's probably going to happen:
---------------------
diff --git a/fs/dcache.c b/fs/dcache.c
index 81aa7ba..59a0ae3 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1220,6 +1220,19 @@ struct dentry *d_obtain_alias(struct inode *inode)
}
EXPORT_SYMBOL(d_obtain_alias);
+static struct dentry *__find_moveable_alias(struct inode *inode,
+ struct dentry *parent)
+{
+ struct dentry *alias;
+
+ if (list_empty(&inode->i_dentry))
+ return NULL;
+ alias = list_first_entry(&inode->i_dentry, struct dentry, d_alias);
+ if (alias->d_parent == parent || IS_ROOT(alias))
+ return __dget_locked(alias);
+ return NULL;
+}
+
/**
* d_splice_alias - splice a disconnected dentry into the tree if one exists
* @inode: the inode which may have a disconnected dentry
@@ -1242,20 +1255,14 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
if (inode && S_ISDIR(inode->i_mode)) {
spin_lock(&dcache_lock);
- new = __d_find_any_alias(inode);
+ new = __find_moveable_alias(inode, dentry->d_parent);
if (new) {
- if (new->d_parent != dentry->d_parent &&
- !IS_ROOT(new->d_parent)) {
- WARN_ON_ONCE(1);
- goto add_duplicate_alias;
- }
spin_unlock(&dcache_lock);
security_d_instantiate(new, inode);
d_rehash(dentry);
d_move(new, dentry);
iput(inode);
} else {
-add_duplicate_alias:
/* already taking dcache_lock, so d_add() by hand */
__d_instantiate(dentry, inode);
spin_unlock(&dcache_lock);
------------------
That seems like it gets rid of any problems. Now 'new' will be NULL if
it finds a "non-moveable alias", so we still get to use our aliased
dentry. If the duplicate mount point is in the same parent dir, it may
be a little strange since we may ping-pong d_move'ing back and forth
between the entries, but I can't find any actual problems with that
happening.
--
Andrew Deason
adeason@sinenomine.net