The patch titled unionfs: fix slab abuses with krealloc has been added to the -mm tree. Its filename is unionfs-fix-slab-abuses-with-krealloc.patch *** Remember to use Documentation/SubmitChecklist when testing your code *** See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this ------------------------------------------------------ Subject: unionfs: fix slab abuses with krealloc From: Pekka Enberg <penberg@xxxxxxxxxxxxxx> This changes unionfs to use krealloc() for reallocating memory so that we don't need to play tricks with slab internals. Cc: Josef Sipek <jsipek@xxxxxxxxxxxxxxxxx> Signed-off-by: Pekka Enberg <penberg@xxxxxxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- fs/unionfs/copyup.c | 35 +++++++++++++---------------------- fs/unionfs/lookup.c | 33 +++++++++++++-------------------- 2 files changed, 26 insertions(+), 42 deletions(-) diff -puN fs/unionfs/copyup.c~unionfs-fix-slab-abuses-with-krealloc fs/unionfs/copyup.c --- a/fs/unionfs/copyup.c~unionfs-fix-slab-abuses-with-krealloc +++ a/fs/unionfs/copyup.c @@ -603,23 +603,16 @@ static struct dentry *create_parents_nam const char *childname; unsigned int childnamelen; - int old_kmalloc_size; - int kmalloc_size; - int num_dentry; + int nr_dentry; int count; int old_bstart; int old_bend; struct dentry **path = NULL; - struct dentry **tmp_path; struct super_block *sb; verify_locked(dentry); - /* There is no sense allocating any less than the minimum. */ - kmalloc_size = malloc_sizes[0].cs_size; - num_dentry = kmalloc_size / sizeof(struct dentry *); - if ((err = is_robranch_super(dir->i_sb, bindex))) { hidden_dentry = ERR_PTR(err); goto out; @@ -629,7 +622,10 @@ static struct dentry *create_parents_nam old_bend = dbend(dentry); hidden_dentry = ERR_PTR(-ENOMEM); - path = kzalloc(kmalloc_size, GFP_KERNEL); + + /* There is no sense allocating any less than the minimum. */ + nr_dentry = 1; + path = kmalloc(nr_dentry * sizeof(struct dentry *), GFP_KERNEL); if (!path) goto out; @@ -655,26 +651,21 @@ static struct dentry *create_parents_nam /* find out the hidden_parent_dentry in the given branch */ hidden_parent_dentry = unionfs_lower_dentry_idx(parent_dentry, bindex); - /* store the child dentry */ - path[count++] = child_dentry; - /* grow path table */ - if (count == num_dentry) { - old_kmalloc_size = kmalloc_size; - kmalloc_size *= 2; - num_dentry = kmalloc_size / sizeof(struct dentry *); + if (count == nr_dentry) { + void *p; - tmp_path = kzalloc(kmalloc_size, GFP_KERNEL); - if (!tmp_path) { + nr_dentry *= 2; + p = krealloc(path, nr_dentry * sizeof(struct dentry *), GFP_KERNEL); + if (!p) { hidden_dentry = ERR_PTR(-ENOMEM); goto out; } - memcpy(tmp_path, path, old_kmalloc_size); - kfree(path); - path = tmp_path; - tmp_path = NULL; + path = p; } + /* store the child dentry */ + path[count++] = child_dentry; } while (!hidden_parent_dentry); count--; diff -puN fs/unionfs/lookup.c~unionfs-fix-slab-abuses-with-krealloc fs/unionfs/lookup.c --- a/fs/unionfs/lookup.c~unionfs-fix-slab-abuses-with-krealloc +++ a/fs/unionfs/lookup.c @@ -428,9 +428,8 @@ void free_dentry_private_data(struct uni /* allocate new dentry private data, free old one if necessary */ int new_dentry_private_data(struct dentry *dentry) { - int newsize; - int oldsize = 0; struct unionfs_dentry_info *info = UNIONFS_D(dentry); + int new_size, size; spin_lock(&dentry->d_lock); if (!info) { @@ -445,8 +444,9 @@ int new_dentry_private_data(struct dentr mutex_lock(&info->lock); info->lower_paths = NULL; + size = 0; } else - oldsize = sizeof(struct path) * info->bcount; + size = sizeof(struct path) * info->bcount; info->bstart = -1; info->bend = -1; @@ -454,28 +454,21 @@ int new_dentry_private_data(struct dentr info->bcount = sbmax(dentry->d_sb); atomic_set(&info->generation, atomic_read(&UNIONFS_SB(dentry->d_sb)->generation)); - newsize = sizeof(struct path) * sbmax(dentry->d_sb); + + new_size = sizeof(struct path) * sbmax(dentry->d_sb); /* Don't reallocate when we already have enough space. */ - /* It would be ideal if we could actually use the slab macros to - * determine what our object sizes is, but those are not exported. - */ - if (oldsize) { - int minsize = malloc_sizes[0].cs_size; - - if (!newsize || ((oldsize < newsize) && (newsize > minsize))) { - kfree(info->lower_paths); - info->lower_paths = NULL; - } - } + if (new_size > size) { + void *p; - if (!info->lower_paths && newsize) { - info->lower_paths = kmalloc(newsize, GFP_ATOMIC); - if (!info->lower_paths) + p = krealloc(info->lower_paths, new_size, GFP_ATOMIC); + if (!p) goto out_free; - } - memset(info->lower_paths, 0, (oldsize > newsize ? oldsize : newsize)); + info->lower_paths = p; + size = new_size; + } + memset(info->lower_paths, 0, size); spin_unlock(&dentry->d_lock); return 0; _ Patches currently in -mm which might be from penberg@xxxxxxxxxxxxxx are slab-introduce-krealloc.patch unionfs-fix-slab-abuses-with-krealloc.patch slab-ensure-cache_alloc_refill-terminates.patch slab-remove-colouroff-from-struct-slab.patch module-use-krealloc.patch slab-use-cpu_lock_.patch slab-leaks3-default-y.patch - To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html