summaryrefslogtreecommitdiff
path: root/fs/aufs/vdir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/aufs/vdir.c')
-rw-r--r--fs/aufs/vdir.c39
1 files changed, 25 insertions, 14 deletions
diff --git a/fs/aufs/vdir.c b/fs/aufs/vdir.c
index feddcc204..e6e3a1eaa 100644
--- a/fs/aufs/vdir.c
+++ b/fs/aufs/vdir.c
@@ -97,7 +97,7 @@ static void au_nhash_wh_do_free(struct hlist_head *head)
struct hlist_node *node;
hlist_for_each_entry_safe(pos, node, head, wh_hash)
- kfree(pos);
+ au_delayed_kfree(pos);
}
static void au_nhash_de_do_free(struct hlist_head *head)
@@ -106,7 +106,7 @@ static void au_nhash_de_do_free(struct hlist_head *head)
struct hlist_node *node;
hlist_for_each_entry_safe(pos, node, head, hash)
- au_cache_free_vdir_dehstr(pos);
+ au_cache_dfree_vdir_dehstr(pos);
}
static void au_nhash_do_free(struct au_nhash *nhash,
@@ -124,7 +124,7 @@ static void au_nhash_do_free(struct au_nhash *nhash,
nhash_count(head);
free(head++);
}
- kfree(nhash->nh_head);
+ au_delayed_kfree(nhash->nh_head);
}
void au_nhash_wh_free(struct au_nhash *whlist)
@@ -167,6 +167,8 @@ static struct hlist_head *au_name_hash(struct au_nhash *nhash,
AuDebugOn(!nhash->nh_num || !nhash->nh_head);
v = 0;
+ if (len > 8)
+ len = 8;
while (len--)
v += *name++;
/* v = hash_long(v, magic_bit); */
@@ -335,15 +337,23 @@ out:
/* ---------------------------------------------------------------------- */
-void au_vdir_free(struct au_vdir *vdir)
+void au_vdir_free(struct au_vdir *vdir, int atonce)
{
unsigned char **deblk;
deblk = vdir->vd_deblk;
- while (vdir->vd_nblk--)
- kfree(*deblk++);
- kfree(vdir->vd_deblk);
- au_cache_free_vdir(vdir);
+ if (!atonce) {
+ while (vdir->vd_nblk--)
+ au_delayed_kfree(*deblk++);
+ au_delayed_kfree(vdir->vd_deblk);
+ au_cache_dfree_vdir(vdir);
+ } else {
+ /* not delayed */
+ while (vdir->vd_nblk--)
+ kfree(*deblk++);
+ kfree(vdir->vd_deblk);
+ au_cache_free_vdir(vdir);
+ }
}
static struct au_vdir *alloc_vdir(struct file *file)
@@ -377,10 +387,10 @@ static struct au_vdir *alloc_vdir(struct file *file)
if (!err)
return vdir; /* success */
- kfree(vdir->vd_deblk);
+ au_delayed_kfree(vdir->vd_deblk);
out_free:
- au_cache_free_vdir(vdir);
+ au_cache_dfree_vdir(vdir);
out:
vdir = ERR_PTR(err);
return vdir;
@@ -392,7 +402,7 @@ static int reinit_vdir(struct au_vdir *vdir)
union au_vdir_deblk_p p, deblk_end;
while (vdir->vd_nblk > 1) {
- kfree(vdir->vd_deblk[vdir->vd_nblk - 1]);
+ au_delayed_kfree(vdir->vd_deblk[vdir->vd_nblk - 1]);
/* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */
vdir->vd_nblk--;
}
@@ -523,7 +533,7 @@ static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir,
}
}
- free_page((unsigned long)o);
+ au_delayed_free_page((unsigned long)o);
out:
AuTraceErr(err);
@@ -624,6 +634,7 @@ static int read_vdir(struct file *file, int may_read)
err = 0;
inode = file_inode(file);
IMustLock(inode);
+ IiMustWriteLock(inode);
SiMustAnyLock(inode->i_sb);
allocated = NULL;
@@ -661,7 +672,7 @@ static int read_vdir(struct file *file, int may_read)
if (allocated)
au_set_ivdir(inode, allocated);
} else if (allocated)
- au_vdir_free(allocated);
+ au_vdir_free(allocated, /*atonce*/0);
out:
return err;
@@ -755,7 +766,7 @@ int au_vdir_init(struct file *file)
if (allocated)
au_set_fvdir_cache(file, allocated);
} else if (allocated)
- au_vdir_free(allocated);
+ au_vdir_free(allocated, /*atonce*/0);
out:
return err;