Commit bdf996cb authored by Richard Russon's avatar Richard Russon

Merge flatcap.org:/home/flatcap/backup/bk/ntfs-2.6

into flatcap.org:/home/flatcap/backup/bk/ntfs-2.6-devel
parents b5fbb17a 772a49b7
......@@ -288,12 +288,11 @@ struct dentry * dget_locked(struct dentry *dentry)
* any other hashed alias over that one.
*/
struct dentry * d_find_alias(struct inode *inode)
static struct dentry * __d_find_alias(struct inode *inode, int want_discon)
{
struct list_head *head, *next, *tmp;
struct dentry *alias, *discon_alias=NULL;
spin_lock(&dcache_lock);
head = &inode->i_dentry;
next = inode->i_dentry.next;
while (next != head) {
......@@ -304,19 +303,26 @@ struct dentry * d_find_alias(struct inode *inode)
if (!d_unhashed(alias)) {
if (alias->d_flags & DCACHE_DISCONNECTED)
discon_alias = alias;
else {
else if (!want_discon) {
__dget_locked(alias);
spin_unlock(&dcache_lock);
return alias;
}
}
}
if (discon_alias)
__dget_locked(discon_alias);
spin_unlock(&dcache_lock);
return discon_alias;
}
struct dentry * d_find_alias(struct inode *inode)
{
struct dentry *de;
spin_lock(&dcache_lock);
de = __d_find_alias(inode, 0);
spin_unlock(&dcache_lock);
return de;
}
/*
* Try to kill dentries associated with this inode.
* WARNING: you must own a reference to inode.
......@@ -835,33 +841,27 @@ struct dentry * d_alloc_anon(struct inode *inode)
tmp->d_parent = tmp; /* make sure dput doesn't croak */
spin_lock(&dcache_lock);
if (S_ISDIR(inode->i_mode) && !list_empty(&inode->i_dentry)) {
/* A directory can only have one dentry.
* This (now) has one, so use it.
*/
res = list_entry(inode->i_dentry.next, struct dentry, d_alias);
__dget_locked(res);
} else {
res = __d_find_alias(inode, 0);
if (!res) {
/* attach a disconnected dentry */
res = tmp;
tmp = NULL;
if (res) {
spin_lock(&res->d_lock);
res->d_sb = inode->i_sb;
res->d_parent = res;
res->d_inode = inode;
spin_lock(&res->d_lock);
res->d_sb = inode->i_sb;
res->d_parent = res;
res->d_inode = inode;
/*
* Set d_bucket to an "impossible" bucket address so
* that d_move() doesn't get a false positive
*/
res->d_bucket = NULL;
res->d_flags |= DCACHE_DISCONNECTED;
res->d_flags &= ~DCACHE_UNHASHED;
list_add(&res->d_alias, &inode->i_dentry);
hlist_add_head(&res->d_hash, &inode->i_sb->s_anon);
spin_unlock(&res->d_lock);
/*
* Set d_bucket to an "impossible" bucket address so
* that d_move() doesn't get a false positive
*/
res->d_bucket = NULL;
res->d_flags |= DCACHE_DISCONNECTED;
res->d_flags &= ~DCACHE_UNHASHED;
list_add(&res->d_alias, &inode->i_dentry);
hlist_add_head(&res->d_hash, &inode->i_sb->s_anon);
spin_unlock(&res->d_lock);
}
inode = NULL; /* don't drop reference */
}
spin_unlock(&dcache_lock);
......@@ -883,7 +883,7 @@ struct dentry * d_alloc_anon(struct inode *inode)
* 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.
*
* This is (will be) needed in the lookup routine of any filesystem that is exportable
* This is needed in the lookup routine of any filesystem that is exportable
* (via knfsd) so that we can build dcache paths to directories effectively.
*
* If a dentry was found and moved, then it is returned. Otherwise NULL
......@@ -894,11 +894,11 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
{
struct dentry *new = NULL;
if (inode && S_ISDIR(inode->i_mode)) {
if (inode) {
spin_lock(&dcache_lock);
if (!list_empty(&inode->i_dentry)) {
new = list_entry(inode->i_dentry.next, struct dentry, d_alias);
__dget_locked(new);
new = __d_find_alias(inode, 1);
if (new) {
BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED));
spin_unlock(&dcache_lock);
security_d_instantiate(new, inode);
d_rehash(dentry);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment