mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-10-31 18:09:19 +00:00
vfs: switch i_dentry/d_alias to hlist
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
9f713878f2
commit
b3d9b7a3c7
13 changed files with 36 additions and 28 deletions
|
@ -125,8 +125,9 @@ static void
|
||||||
affs_fix_dcache(struct inode *inode, u32 entry_ino)
|
affs_fix_dcache(struct inode *inode, u32 entry_ino)
|
||||||
{
|
{
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
|
struct hlist_node *p;
|
||||||
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) {
|
||||||
if (entry_ino == (u32)(long)dentry->d_fsdata) {
|
if (entry_ino == (u32)(long)dentry->d_fsdata) {
|
||||||
dentry->d_fsdata = (void *)inode->i_ino;
|
dentry->d_fsdata = (void *)inode->i_ino;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -6987,7 +6987,7 @@ void btrfs_destroy_inode(struct inode *inode)
|
||||||
struct btrfs_ordered_extent *ordered;
|
struct btrfs_ordered_extent *ordered;
|
||||||
struct btrfs_root *root = BTRFS_I(inode)->root;
|
struct btrfs_root *root = BTRFS_I(inode)->root;
|
||||||
|
|
||||||
WARN_ON(!list_empty(&inode->i_dentry));
|
WARN_ON(!hlist_empty(&inode->i_dentry));
|
||||||
WARN_ON(inode->i_data.nrpages);
|
WARN_ON(inode->i_data.nrpages);
|
||||||
WARN_ON(BTRFS_I(inode)->outstanding_extents);
|
WARN_ON(BTRFS_I(inode)->outstanding_extents);
|
||||||
WARN_ON(BTRFS_I(inode)->reserved_extents);
|
WARN_ON(BTRFS_I(inode)->reserved_extents);
|
||||||
|
|
|
@ -800,7 +800,7 @@ cifs_find_inode(struct inode *inode, void *opaque)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* if it's not a directory or has no dentries, then flag it */
|
/* if it's not a directory or has no dentries, then flag it */
|
||||||
if (S_ISDIR(inode->i_mode) && !list_empty(&inode->i_dentry))
|
if (S_ISDIR(inode->i_mode) && !hlist_empty(&inode->i_dentry))
|
||||||
fattr->cf_flags |= CIFS_FATTR_INO_COLLISION;
|
fattr->cf_flags |= CIFS_FATTR_INO_COLLISION;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -825,9 +825,10 @@ static bool
|
||||||
inode_has_hashed_dentries(struct inode *inode)
|
inode_has_hashed_dentries(struct inode *inode)
|
||||||
{
|
{
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
|
struct hlist_node *p;
|
||||||
|
|
||||||
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) {
|
||||||
if (!d_unhashed(dentry) || IS_ROOT(dentry)) {
|
if (!d_unhashed(dentry) || IS_ROOT(dentry)) {
|
||||||
spin_unlock(&inode->i_lock);
|
spin_unlock(&inode->i_lock);
|
||||||
return true;
|
return true;
|
||||||
|
|
33
fs/dcache.c
33
fs/dcache.c
|
@ -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);
|
||||||
|
|
|
@ -44,13 +44,14 @@ find_acceptable_alias(struct dentry *result,
|
||||||
{
|
{
|
||||||
struct dentry *dentry, *toput = NULL;
|
struct dentry *dentry, *toput = NULL;
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
|
struct hlist_node *p;
|
||||||
|
|
||||||
if (acceptable(context, result))
|
if (acceptable(context, result))
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
inode = result->d_inode;
|
inode = result->d_inode;
|
||||||
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) {
|
||||||
dget(dentry);
|
dget(dentry);
|
||||||
spin_unlock(&inode->i_lock);
|
spin_unlock(&inode->i_lock);
|
||||||
if (toput)
|
if (toput)
|
||||||
|
|
|
@ -225,7 +225,7 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
|
||||||
|
|
||||||
if (!journal) {
|
if (!journal) {
|
||||||
ret = __sync_inode(inode, datasync);
|
ret = __sync_inode(inode, datasync);
|
||||||
if (!ret && !list_empty(&inode->i_dentry))
|
if (!ret && !hlist_empty(&inode->i_dentry))
|
||||||
ret = ext4_sync_parent(inode);
|
ret = ext4_sync_parent(inode);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -249,7 +249,7 @@ static struct dentry *fuse_d_add_directory(struct dentry *entry,
|
||||||
/* This tries to shrink the subtree below alias */
|
/* This tries to shrink the subtree below alias */
|
||||||
fuse_invalidate_entry(alias);
|
fuse_invalidate_entry(alias);
|
||||||
dput(alias);
|
dput(alias);
|
||||||
if (!list_empty(&inode->i_dentry))
|
if (!hlist_empty(&inode->i_dentry))
|
||||||
return ERR_PTR(-EBUSY);
|
return ERR_PTR(-EBUSY);
|
||||||
} else {
|
} else {
|
||||||
dput(alias);
|
dput(alias);
|
||||||
|
|
|
@ -182,7 +182,7 @@ int inode_init_always(struct super_block *sb, struct inode *inode)
|
||||||
}
|
}
|
||||||
inode->i_private = NULL;
|
inode->i_private = NULL;
|
||||||
inode->i_mapping = mapping;
|
inode->i_mapping = mapping;
|
||||||
INIT_LIST_HEAD(&inode->i_dentry); /* buggered by rcu freeing */
|
INIT_HLIST_HEAD(&inode->i_dentry); /* buggered by rcu freeing */
|
||||||
#ifdef CONFIG_FS_POSIX_ACL
|
#ifdef CONFIG_FS_POSIX_ACL
|
||||||
inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED;
|
inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -62,7 +62,7 @@ static int nfs_superblock_set_dummy_root(struct super_block *sb, struct inode *i
|
||||||
*/
|
*/
|
||||||
spin_lock(&sb->s_root->d_inode->i_lock);
|
spin_lock(&sb->s_root->d_inode->i_lock);
|
||||||
spin_lock(&sb->s_root->d_lock);
|
spin_lock(&sb->s_root->d_lock);
|
||||||
list_del_init(&sb->s_root->d_alias);
|
hlist_del_init(&sb->s_root->d_alias);
|
||||||
spin_unlock(&sb->s_root->d_lock);
|
spin_unlock(&sb->s_root->d_lock);
|
||||||
spin_unlock(&sb->s_root->d_inode->i_lock);
|
spin_unlock(&sb->s_root->d_inode->i_lock);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@ void __fsnotify_vfsmount_delete(struct vfsmount *mnt)
|
||||||
void __fsnotify_update_child_dentry_flags(struct inode *inode)
|
void __fsnotify_update_child_dentry_flags(struct inode *inode)
|
||||||
{
|
{
|
||||||
struct dentry *alias;
|
struct dentry *alias;
|
||||||
|
struct hlist_node *p;
|
||||||
int watched;
|
int watched;
|
||||||
|
|
||||||
if (!S_ISDIR(inode->i_mode))
|
if (!S_ISDIR(inode->i_mode))
|
||||||
|
@ -63,7 +64,7 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode)
|
||||||
spin_lock(&inode->i_lock);
|
spin_lock(&inode->i_lock);
|
||||||
/* run all of the dentries associated with this inode. Since this is a
|
/* run all of the dentries associated with this inode. Since this is a
|
||||||
* directory, there damn well better only be one item on this list */
|
* directory, there damn well better only be one item on this list */
|
||||||
list_for_each_entry(alias, &inode->i_dentry, d_alias) {
|
hlist_for_each_entry(alias, p, &inode->i_dentry, d_alias) {
|
||||||
struct dentry *child;
|
struct dentry *child;
|
||||||
|
|
||||||
/* run all of the children of the original inode and fix their
|
/* run all of the children of the original inode and fix their
|
||||||
|
|
|
@ -170,10 +170,11 @@ struct dentry *ocfs2_find_local_alias(struct inode *inode,
|
||||||
u64 parent_blkno,
|
u64 parent_blkno,
|
||||||
int skip_unhashed)
|
int skip_unhashed)
|
||||||
{
|
{
|
||||||
|
struct hlist_node *p;
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
|
|
||||||
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 (ocfs2_match_dentry(dentry, parent_blkno, skip_unhashed)) {
|
if (ocfs2_match_dentry(dentry, parent_blkno, skip_unhashed)) {
|
||||||
trace_ocfs2_find_local_alias(dentry->d_name.len,
|
trace_ocfs2_find_local_alias(dentry->d_name.len,
|
||||||
|
|
|
@ -128,7 +128,7 @@ struct dentry {
|
||||||
struct rcu_head d_rcu;
|
struct rcu_head d_rcu;
|
||||||
} d_u;
|
} d_u;
|
||||||
struct list_head d_subdirs; /* our children */
|
struct list_head d_subdirs; /* our children */
|
||||||
struct list_head d_alias; /* inode alias list */
|
struct hlist_node d_alias; /* inode alias list */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -826,7 +826,7 @@ struct inode {
|
||||||
struct list_head i_lru; /* inode LRU list */
|
struct list_head i_lru; /* inode LRU list */
|
||||||
struct list_head i_sb_list;
|
struct list_head i_sb_list;
|
||||||
union {
|
union {
|
||||||
struct list_head i_dentry;
|
struct hlist_head i_dentry;
|
||||||
struct rcu_head i_rcu;
|
struct rcu_head i_rcu;
|
||||||
};
|
};
|
||||||
u64 i_version;
|
u64 i_version;
|
||||||
|
|
Loading…
Reference in a new issue