|
@@ -218,7 +218,7 @@ static void __d_free(struct rcu_head *head)
|
|
{
|
|
{
|
|
struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu);
|
|
struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu);
|
|
|
|
|
|
- WARN_ON(!list_empty(&dentry->d_alias));
|
|
|
|
|
|
+ WARN_ON(!hlist_unhashed(&dentry->d_alias));
|
|
if (dname_external(dentry))
|
|
if (dname_external(dentry))
|
|
kfree(dentry->d_name.name);
|
|
kfree(dentry->d_name.name);
|
|
kmem_cache_free(dentry_cache, dentry);
|
|
kmem_cache_free(dentry_cache, dentry);
|
|
@@ -267,7 +267,7 @@ static void dentry_iput(struct dentry * dentry)
|
|
struct inode *inode = dentry->d_inode;
|
|
struct inode *inode = dentry->d_inode;
|
|
if (inode) {
|
|
if (inode) {
|
|
dentry->d_inode = NULL;
|
|
dentry->d_inode = NULL;
|
|
- list_del_init(&dentry->d_alias);
|
|
|
|
|
|
+ hlist_del_init(&dentry->d_alias);
|
|
spin_unlock(&dentry->d_lock);
|
|
spin_unlock(&dentry->d_lock);
|
|
spin_unlock(&inode->i_lock);
|
|
spin_unlock(&inode->i_lock);
|
|
if (!inode->i_nlink)
|
|
if (!inode->i_nlink)
|
|
@@ -291,7 +291,7 @@ static void dentry_unlink_inode(struct dentry * dentry)
|
|
{
|
|
{
|
|
struct inode *inode = dentry->d_inode;
|
|
struct inode *inode = dentry->d_inode;
|
|
dentry->d_inode = NULL;
|
|
dentry->d_inode = NULL;
|
|
- list_del_init(&dentry->d_alias);
|
|
|
|
|
|
+ hlist_del_init(&dentry->d_alias);
|
|
dentry_rcuwalk_barrier(dentry);
|
|
dentry_rcuwalk_barrier(dentry);
|
|
spin_unlock(&dentry->d_lock);
|
|
spin_unlock(&dentry->d_lock);
|
|
spin_unlock(&inode->i_lock);
|
|
spin_unlock(&inode->i_lock);
|
|
@@ -699,10 +699,11 @@ EXPORT_SYMBOL(dget_parent);
|
|
static struct dentry *__d_find_alias(struct inode *inode, int want_discon)
|
|
static struct dentry *__d_find_alias(struct inode *inode, int want_discon)
|
|
{
|
|
{
|
|
struct dentry *alias, *discon_alias;
|
|
struct dentry *alias, *discon_alias;
|
|
|
|
+ struct hlist_node *p;
|
|
|
|
|
|
again:
|
|
again:
|
|
discon_alias = NULL;
|
|
discon_alias = NULL;
|
|
- list_for_each_entry(alias, &inode->i_dentry, d_alias) {
|
|
|
|
|
|
+ hlist_for_each_entry(alias, p, &inode->i_dentry, d_alias) {
|
|
spin_lock(&alias->d_lock);
|
|
spin_lock(&alias->d_lock);
|
|
if (S_ISDIR(inode->i_mode) || !d_unhashed(alias)) {
|
|
if (S_ISDIR(inode->i_mode) || !d_unhashed(alias)) {
|
|
if (IS_ROOT(alias) &&
|
|
if (IS_ROOT(alias) &&
|
|
@@ -737,7 +738,7 @@ struct dentry *d_find_alias(struct inode *inode)
|
|
{
|
|
{
|
|
struct dentry *de = NULL;
|
|
struct dentry *de = NULL;
|
|
|
|
|
|
- if (!list_empty(&inode->i_dentry)) {
|
|
|
|
|
|
+ if (!hlist_empty(&inode->i_dentry)) {
|
|
spin_lock(&inode->i_lock);
|
|
spin_lock(&inode->i_lock);
|
|
de = __d_find_alias(inode, 0);
|
|
de = __d_find_alias(inode, 0);
|
|
spin_unlock(&inode->i_lock);
|
|
spin_unlock(&inode->i_lock);
|
|
@@ -753,9 +754,10 @@ EXPORT_SYMBOL(d_find_alias);
|
|
void d_prune_aliases(struct inode *inode)
|
|
void d_prune_aliases(struct inode *inode)
|
|
{
|
|
{
|
|
struct dentry *dentry;
|
|
struct dentry *dentry;
|
|
|
|
+ struct hlist_node *p;
|
|
restart:
|
|
restart:
|
|
spin_lock(&inode->i_lock);
|
|
spin_lock(&inode->i_lock);
|
|
- list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
|
|
|
|
|
|
+ hlist_for_each_entry(dentry, p, &inode->i_dentry, d_alias) {
|
|
spin_lock(&dentry->d_lock);
|
|
spin_lock(&dentry->d_lock);
|
|
if (!dentry->d_count) {
|
|
if (!dentry->d_count) {
|
|
__dget_dlock(dentry);
|
|
__dget_dlock(dentry);
|
|
@@ -977,7 +979,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
|
|
inode = dentry->d_inode;
|
|
inode = dentry->d_inode;
|
|
if (inode) {
|
|
if (inode) {
|
|
dentry->d_inode = NULL;
|
|
dentry->d_inode = NULL;
|
|
- list_del_init(&dentry->d_alias);
|
|
|
|
|
|
+ hlist_del_init(&dentry->d_alias);
|
|
if (dentry->d_op && dentry->d_op->d_iput)
|
|
if (dentry->d_op && dentry->d_op->d_iput)
|
|
dentry->d_op->d_iput(dentry, inode);
|
|
dentry->d_op->d_iput(dentry, inode);
|
|
else
|
|
else
|
|
@@ -1312,7 +1314,7 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name)
|
|
INIT_HLIST_BL_NODE(&dentry->d_hash);
|
|
INIT_HLIST_BL_NODE(&dentry->d_hash);
|
|
INIT_LIST_HEAD(&dentry->d_lru);
|
|
INIT_LIST_HEAD(&dentry->d_lru);
|
|
INIT_LIST_HEAD(&dentry->d_subdirs);
|
|
INIT_LIST_HEAD(&dentry->d_subdirs);
|
|
- INIT_LIST_HEAD(&dentry->d_alias);
|
|
|
|
|
|
+ INIT_HLIST_NODE(&dentry->d_alias);
|
|
INIT_LIST_HEAD(&dentry->d_u.d_child);
|
|
INIT_LIST_HEAD(&dentry->d_u.d_child);
|
|
d_set_d_op(dentry, dentry->d_sb->s_d_op);
|
|
d_set_d_op(dentry, dentry->d_sb->s_d_op);
|
|
|
|
|
|
@@ -1400,7 +1402,7 @@ static void __d_instantiate(struct dentry *dentry, struct inode *inode)
|
|
if (inode) {
|
|
if (inode) {
|
|
if (unlikely(IS_AUTOMOUNT(inode)))
|
|
if (unlikely(IS_AUTOMOUNT(inode)))
|
|
dentry->d_flags |= DCACHE_NEED_AUTOMOUNT;
|
|
dentry->d_flags |= DCACHE_NEED_AUTOMOUNT;
|
|
- list_add(&dentry->d_alias, &inode->i_dentry);
|
|
|
|
|
|
+ hlist_add_head(&dentry->d_alias, &inode->i_dentry);
|
|
}
|
|
}
|
|
dentry->d_inode = inode;
|
|
dentry->d_inode = inode;
|
|
dentry_rcuwalk_barrier(dentry);
|
|
dentry_rcuwalk_barrier(dentry);
|
|
@@ -1425,7 +1427,7 @@ static void __d_instantiate(struct dentry *dentry, struct inode *inode)
|
|
|
|
|
|
void d_instantiate(struct dentry *entry, struct inode * inode)
|
|
void d_instantiate(struct dentry *entry, struct inode * inode)
|
|
{
|
|
{
|
|
- BUG_ON(!list_empty(&entry->d_alias));
|
|
|
|
|
|
+ BUG_ON(!hlist_unhashed(&entry->d_alias));
|
|
if (inode)
|
|
if (inode)
|
|
spin_lock(&inode->i_lock);
|
|
spin_lock(&inode->i_lock);
|
|
__d_instantiate(entry, inode);
|
|
__d_instantiate(entry, inode);
|
|
@@ -1458,13 +1460,14 @@ static struct dentry *__d_instantiate_unique(struct dentry *entry,
|
|
int len = entry->d_name.len;
|
|
int len = entry->d_name.len;
|
|
const char *name = entry->d_name.name;
|
|
const char *name = entry->d_name.name;
|
|
unsigned int hash = entry->d_name.hash;
|
|
unsigned int hash = entry->d_name.hash;
|
|
|
|
+ struct hlist_node *p;
|
|
|
|
|
|
if (!inode) {
|
|
if (!inode) {
|
|
__d_instantiate(entry, NULL);
|
|
__d_instantiate(entry, NULL);
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
- list_for_each_entry(alias, &inode->i_dentry, d_alias) {
|
|
|
|
|
|
+ hlist_for_each_entry(alias, p, &inode->i_dentry, d_alias) {
|
|
/*
|
|
/*
|
|
* Don't need alias->d_lock here, because aliases with
|
|
* Don't need alias->d_lock here, because aliases with
|
|
* d_parent == entry->d_parent are not subject to name or
|
|
* d_parent == entry->d_parent are not subject to name or
|
|
@@ -1490,7 +1493,7 @@ struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode)
|
|
{
|
|
{
|
|
struct dentry *result;
|
|
struct dentry *result;
|
|
|
|
|
|
- BUG_ON(!list_empty(&entry->d_alias));
|
|
|
|
|
|
+ BUG_ON(!hlist_unhashed(&entry->d_alias));
|
|
|
|
|
|
if (inode)
|
|
if (inode)
|
|
spin_lock(&inode->i_lock);
|
|
spin_lock(&inode->i_lock);
|
|
@@ -1531,9 +1534,9 @@ static struct dentry * __d_find_any_alias(struct inode *inode)
|
|
{
|
|
{
|
|
struct dentry *alias;
|
|
struct dentry *alias;
|
|
|
|
|
|
- if (list_empty(&inode->i_dentry))
|
|
|
|
|
|
+ if (hlist_empty(&inode->i_dentry))
|
|
return NULL;
|
|
return NULL;
|
|
- alias = list_first_entry(&inode->i_dentry, struct dentry, d_alias);
|
|
|
|
|
|
+ alias = hlist_entry(inode->i_dentry.first, struct dentry, d_alias);
|
|
__dget(alias);
|
|
__dget(alias);
|
|
return alias;
|
|
return alias;
|
|
}
|
|
}
|
|
@@ -1607,7 +1610,7 @@ struct dentry *d_obtain_alias(struct inode *inode)
|
|
spin_lock(&tmp->d_lock);
|
|
spin_lock(&tmp->d_lock);
|
|
tmp->d_inode = inode;
|
|
tmp->d_inode = inode;
|
|
tmp->d_flags |= DCACHE_DISCONNECTED;
|
|
tmp->d_flags |= DCACHE_DISCONNECTED;
|
|
- list_add(&tmp->d_alias, &inode->i_dentry);
|
|
|
|
|
|
+ hlist_add_head(&tmp->d_alias, &inode->i_dentry);
|
|
hlist_bl_lock(&tmp->d_sb->s_anon);
|
|
hlist_bl_lock(&tmp->d_sb->s_anon);
|
|
hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon);
|
|
hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon);
|
|
hlist_bl_unlock(&tmp->d_sb->s_anon);
|
|
hlist_bl_unlock(&tmp->d_sb->s_anon);
|