Change the branch management code to use krealloc instead of playing tricks with kmalloc/memcpy/kfree. Signed-off-by: Josef 'Jeff' Sipek <jsipek@xxxxxxxxxxxxx> --- fs/unionfs/super.c | 56 +++++++++++++--------------------------------------- 1 files changed, 14 insertions(+), 42 deletions(-) diff --git a/fs/unionfs/super.c b/fs/unionfs/super.c index b7f0b45..3dee863 100644 --- a/fs/unionfs/super.c +++ b/fs/unionfs/super.c @@ -427,6 +427,7 @@ static int unionfs_remount_fs(struct super_block *sb, int *flags, struct unionfs_data *new_data = NULL, *tmp_data = NULL; struct path *new_lower_paths = NULL, *tmp_lower_paths = NULL; int new_high_branch_id; /* new high branch ID */ + int size; /* memory allocation size, temp var */ unionfs_write_lock(sb); @@ -634,49 +635,20 @@ out_no_change: * Also handle invalidating any pages that will have to be re-read. *******************************************************************/ - /* - * Allocate space for actual pointers, if needed. By the time we - * finish this block of code, new_branches and new_lower_paths will - * have the correct size. None of this code below would be needed - * if the kernel had a realloc() function, at least one capable of - * shrinking/truncating an allocation's size (hint, hint). - */ - if (new_branches < max_branches) { + /* (re)allocate space for new pointers to hidden dentry */ + size = new_branches * sizeof(struct unionfs_data); + new_data = krealloc(tmp_data, size, GFP_KERNEL); + if (!new_data) { + err = -ENOMEM; + goto out_release; + } - /* allocate space for new pointers to hidden dentry */ - new_data = kcalloc(new_branches, - sizeof(struct unionfs_data), GFP_KERNEL); - if (!new_data) { - err = -ENOMEM; - goto out_release; - } - /* allocate space for new pointers to lower paths */ - new_lower_paths = kcalloc(new_branches, - sizeof(struct path), GFP_KERNEL); - if (!new_lower_paths) { - err = -ENOMEM; - goto out_release; - } - /* - * copy current info into new placeholders, incrementing - * refcounts. - */ - memcpy(new_data, tmp_data, - new_branches * sizeof(struct unionfs_data)); - memcpy(new_lower_paths, tmp_lower_paths, - new_branches * sizeof(struct path)); - /* - * Since we already hold various refcnts on the objects, we - * don't need to redo it here. Just free the older memory - * and re-point the pointers. - */ - kfree(tmp_data); - kfree(tmp_lower_paths); - /* no need to nullify pointers here */ - } else { - /* number of branches didn't change, no need to re-alloc */ - new_data = tmp_data; - new_lower_paths = tmp_lower_paths; + /* allocate space for new pointers to lower paths */ + size = new_branches * sizeof(struct path); + new_lower_paths = krealloc(tmp_lower_paths, size, GFP_KERNEL); + if (!new_lower_paths) { + err = -ENOMEM; + goto out_release; } /* -- 1.5.2.rc1.165.gaf9b - To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html