Loading fs/dcache.c +36 −26 Original line number Diff line number Diff line Loading @@ -441,36 +441,12 @@ void d_drop(struct dentry *dentry) } EXPORT_SYMBOL(d_drop); /* * Finish off a dentry we've decided to kill. * dentry->d_lock must be held, returns with it unlocked. * If ref is non-zero, then decrement the refcount too. * Returns dentry requiring refcount drop, or NULL if we're done. */ static struct dentry * dentry_kill(struct dentry *dentry, int unlock_on_failure) __releases(dentry->d_lock) static void __dentry_kill(struct dentry *dentry) { struct inode *inode; struct dentry *parent = NULL; bool can_free = true; inode = dentry->d_inode; if (inode && !spin_trylock(&inode->i_lock)) { relock: if (unlock_on_failure) { spin_unlock(&dentry->d_lock); cpu_relax(); } return dentry; /* try again with same dentry */ } if (!IS_ROOT(dentry)) parent = dentry->d_parent; if (parent && !spin_trylock(&parent->d_lock)) { if (inode) spin_unlock(&inode->i_lock); goto relock; } /* * The dentry is now unrecoverably dead to the world. Loading Loading @@ -514,10 +490,44 @@ relock: can_free = false; } spin_unlock(&dentry->d_lock); out: if (likely(can_free)) dentry_free(dentry); } /* * Finish off a dentry we've decided to kill. * dentry->d_lock must be held, returns with it unlocked. * If ref is non-zero, then decrement the refcount too. * Returns dentry requiring refcount drop, or NULL if we're done. */ static struct dentry * dentry_kill(struct dentry *dentry, int unlock_on_failure) __releases(dentry->d_lock) { struct inode *inode = dentry->d_inode; struct dentry *parent = NULL; if (inode && unlikely(!spin_trylock(&inode->i_lock))) goto failed; if (!IS_ROOT(dentry)) { parent = dentry->d_parent; if (unlikely(!spin_trylock(&parent->d_lock))) { if (inode) spin_unlock(&inode->i_lock); goto failed; } } __dentry_kill(dentry); return parent; failed: if (unlock_on_failure) { spin_unlock(&dentry->d_lock); cpu_relax(); } return dentry; /* try again with same dentry */ } /* Loading Loading
fs/dcache.c +36 −26 Original line number Diff line number Diff line Loading @@ -441,36 +441,12 @@ void d_drop(struct dentry *dentry) } EXPORT_SYMBOL(d_drop); /* * Finish off a dentry we've decided to kill. * dentry->d_lock must be held, returns with it unlocked. * If ref is non-zero, then decrement the refcount too. * Returns dentry requiring refcount drop, or NULL if we're done. */ static struct dentry * dentry_kill(struct dentry *dentry, int unlock_on_failure) __releases(dentry->d_lock) static void __dentry_kill(struct dentry *dentry) { struct inode *inode; struct dentry *parent = NULL; bool can_free = true; inode = dentry->d_inode; if (inode && !spin_trylock(&inode->i_lock)) { relock: if (unlock_on_failure) { spin_unlock(&dentry->d_lock); cpu_relax(); } return dentry; /* try again with same dentry */ } if (!IS_ROOT(dentry)) parent = dentry->d_parent; if (parent && !spin_trylock(&parent->d_lock)) { if (inode) spin_unlock(&inode->i_lock); goto relock; } /* * The dentry is now unrecoverably dead to the world. Loading Loading @@ -514,10 +490,44 @@ relock: can_free = false; } spin_unlock(&dentry->d_lock); out: if (likely(can_free)) dentry_free(dentry); } /* * Finish off a dentry we've decided to kill. * dentry->d_lock must be held, returns with it unlocked. * If ref is non-zero, then decrement the refcount too. * Returns dentry requiring refcount drop, or NULL if we're done. */ static struct dentry * dentry_kill(struct dentry *dentry, int unlock_on_failure) __releases(dentry->d_lock) { struct inode *inode = dentry->d_inode; struct dentry *parent = NULL; if (inode && unlikely(!spin_trylock(&inode->i_lock))) goto failed; if (!IS_ROOT(dentry)) { parent = dentry->d_parent; if (unlikely(!spin_trylock(&parent->d_lock))) { if (inode) spin_unlock(&inode->i_lock); goto failed; } } __dentry_kill(dentry); return parent; failed: if (unlock_on_failure) { spin_unlock(&dentry->d_lock); cpu_relax(); } return dentry; /* try again with same dentry */ } /* Loading