|
@@ -1853,58 +1853,6 @@ struct dentry *d_obtain_alias(struct inode *inode)
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(d_obtain_alias);
|
|
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
|
|
* d_add_ci - lookup or allocate new dentry with case-exact name
|
|
* @inode: the inode case-insensitive lookup has found
|
|
* @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 */
|
|
/* 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
|
|
* d_materialise_unique - introduce an inode into the tree
|
|
* @dentry: candidate dentry
|
|
* @dentry: candidate dentry
|