mirror of https://gitee.com/openkylin/linux.git
dcache: move d_splice_alias
Just a trivial move to locate it near (similar) d_materialise_unique code and save some forward references in a following patch. Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: J. Bruce Fields <bfields@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
d03b29a271
commit
3f70bd51cb
104
fs/dcache.c
104
fs/dcache.c
|
@ -1853,58 +1853,6 @@ struct dentry *d_obtain_alias(struct inode *inode)
|
|||
}
|
||||
EXPORT_SYMBOL(d_obtain_alias);
|
||||
|
||||
/**
|
||||
* d_splice_alias - splice a disconnected dentry into the tree if one exists
|
||||
* @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.
|
||||
*
|
||||
* 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
|
||||
* is returned. This matches the expected return value of ->lookup.
|
||||
*
|
||||
* Cluster filesystems may call this function with a negative, hashed dentry.
|
||||
* In that case, we know that the inode will be a regular file, and also this
|
||||
* will only occur during atomic_open. So we need to check for the dentry
|
||||
* being already hashed only in the final case.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
EXPORT_SYMBOL(d_splice_alias);
|
||||
|
||||
/**
|
||||
* d_add_ci - lookup or allocate new dentry with case-exact name
|
||||
* @inode: the inode case-insensitive lookup has found
|
||||
|
@ -2696,6 +2644,58 @@ static void __d_materialise_dentry(struct dentry *dentry, struct dentry *anon)
|
|||
/* anon->d_lock still locked, returns locked */
|
||||
}
|
||||
|
||||
/**
|
||||
* d_splice_alias - splice a disconnected dentry into the tree if one exists
|
||||
* @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.
|
||||
*
|
||||
* 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
|
||||
* is returned. This matches the expected return value of ->lookup.
|
||||
*
|
||||
* Cluster filesystems may call this function with a negative, hashed dentry.
|
||||
* In that case, we know that the inode will be a regular file, and also this
|
||||
* will only occur during atomic_open. So we need to check for the dentry
|
||||
* being already hashed only in the final case.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
EXPORT_SYMBOL(d_splice_alias);
|
||||
|
||||
/**
|
||||
* d_materialise_unique - introduce an inode into the tree
|
||||
* @dentry: candidate dentry
|
||||
|
|
Loading…
Reference in New Issue