diff options
author | Phillip Lougher <phillip@squashfs.org.uk> | 2014-03-02 03:33:56 +0000 |
---|---|---|
committer | Phillip Lougher <phillip@squashfs.org.uk> | 2014-03-02 03:37:18 +0000 |
commit | 5172991022b8985dc81a95700e5260a49223128a (patch) | |
tree | 50935b6c473fde926e1a68f302419c9a1b876736 | |
parent | d97595caecd17c7922cf137bb5f015df16340e7a (diff) | |
download | squashfs-tools-5172991022b8985dc81a95700e5260a49223128a.tar.gz |
mksquashfs: write_file_blocks_dup(), bring into line with write_file_frag_dup()
Write_file_frag() does pre duplicate checking, and calls
write_file_frag_dup().
Make the behaviour of write_file_blocks() the same.
Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
-rw-r--r-- | squashfs-tools/mksquashfs.c | 173 |
1 files changed, 87 insertions, 86 deletions
diff --git a/squashfs-tools/mksquashfs.c b/squashfs-tools/mksquashfs.c index ecaa3cf..e3ecc95 100644 --- a/squashfs-tools/mksquashfs.c +++ b/squashfs-tools/mksquashfs.c @@ -2542,42 +2542,58 @@ read_err: } -int write_file_blocks(squashfs_inode *inode, struct dir_ent *dir_ent, +int write_file_blocks_dup(squashfs_inode *inode, struct dir_ent *dir_ent, struct file_buffer *read_buffer, int *duplicate_file) { + int block, thresh; long long read_size = read_buffer->file_size; - long long file_bytes, start; + long long file_bytes, dup_start, start; struct fragment *fragment; - unsigned int *block_list; - int block, status; + struct file_info *dupl_ptr; int blocks = (read_size + block_size - 1) >> block_log; + unsigned int *block_list, *block_listp; + struct file_buffer **buffer_list; + int status, num_locked_fragments; long long sparse = 0; struct file_buffer *fragment_buffer = NULL; - *duplicate_file = FALSE; - block_list = malloc(blocks * sizeof(unsigned int)); if(block_list == NULL) MEM_ERROR(); + block_listp = block_list; - lock_fragments(); + buffer_list = malloc(blocks * sizeof(struct file_buffer *)); + if(buffer_list == NULL) + MEM_ERROR(); + + num_locked_fragments = lock_fragments(); file_bytes = 0; - start = bytes; + start = dup_start = bytes; + thresh = blocks > (writer_buffer_size - num_locked_fragments) ? + blocks - (writer_buffer_size - num_locked_fragments): 0; + for(block = 0; block < blocks;) { if(read_buffer->fragment) { block_list[block] = 0; + buffer_list[block] = NULL; fragment_buffer = read_buffer; blocks = read_size >> block_log; } else { block_list[block] = read_buffer->c_byte; + if(read_buffer->c_byte) { read_buffer->block = bytes; bytes += read_buffer->size; - cache_hash(read_buffer, read_buffer->block); file_bytes += read_buffer->size; - queue_put(to_writer, read_buffer); + cache_hash(read_buffer, read_buffer->block); + if(block < thresh) { + buffer_list[block] = NULL; + queue_put(to_writer, read_buffer); + } else + buffer_list[block] = read_buffer; } else { + buffer_list[block] = NULL; sparse += read_buffer->size; cache_block_put(read_buffer); } @@ -2591,13 +2607,37 @@ int write_file_blocks(squashfs_inode *inode, struct dir_ent *dir_ent, } } + dupl_ptr = duplicate(read_size, file_bytes, &block_listp, &dup_start, + &fragment, fragment_buffer, blocks, 0, 0, FALSE); + + if(dupl_ptr) { + *duplicate_file = FALSE; + for(block = thresh; block < blocks; block ++) + if(buffer_list[block]) + queue_put(to_writer, buffer_list[block]); + fragment = get_and_fill_fragment(fragment_buffer, dir_ent); + dupl_ptr->fragment = fragment; + } else { + *duplicate_file = TRUE; + for(block = thresh; block < blocks; block ++) + cache_block_put(buffer_list[block]); + bytes = start; + if(thresh && !block_device) { + int res; + + queue_put(to_writer, NULL); + if(queue_get(from_writer) != 0) + EXIT_MKSQUASHFS(); + res = ftruncate(fd, bytes); + if(res != 0) + BAD_ERROR("Failed to truncate dest file because" + " %s\n", strerror(errno)); + } + } + unlock_fragments(); - fragment = get_and_fill_fragment(fragment_buffer, dir_ent); cache_block_put(fragment_buffer); - - if(duplicate_checking) - add_non_dup(read_size, file_bytes, block_list, start, fragment, - 0, 0, FALSE); + free(buffer_list); file_count ++; total_bytes += read_size; @@ -2612,13 +2652,11 @@ int write_file_blocks(squashfs_inode *inode, struct dir_ent *dir_ent, if(sparse && (dir_ent->inode->buf.st_blocks << 9) >= read_size) sparse = 0; - create_inode(inode, NULL, dir_ent, SQUASHFS_FILE_TYPE, read_size, start, - blocks, block_list, fragment, NULL, sparse); + create_inode(inode, NULL, dir_ent, SQUASHFS_FILE_TYPE, read_size, + dup_start, blocks, block_listp, fragment, NULL, sparse); - if(duplicate_checking == FALSE) { + if(*duplicate_file == TRUE) free(block_list); - free_fragment(fragment); - } return 0; @@ -2626,7 +2664,7 @@ read_err: dec_progress_bar(block); status = read_buffer->error; bytes = start; - if(!block_device) { + if(thresh && !block_device) { int res; queue_put(to_writer, NULL); @@ -2638,64 +2676,54 @@ read_err: strerror(errno)); } unlock_fragments(); + for(blocks = thresh; blocks < block; blocks ++) + cache_block_put(buffer_list[blocks]); + free(buffer_list); free(block_list); cache_block_put(read_buffer); return status; } -int write_file_blocks_dup(squashfs_inode *inode, struct dir_ent *dir_ent, - struct file_buffer *read_buffer, int *duplicate_file) +int write_file_blocks(squashfs_inode *inode, struct dir_ent *dir_ent, + struct file_buffer *read_buffer, int *dup) { - int block, thresh; long long read_size = read_buffer->file_size; - long long file_bytes, dup_start, start; + long long file_bytes, start; struct fragment *fragment; - struct file_info *dupl_ptr; + unsigned int *block_list; + int block, status; int blocks = (read_size + block_size - 1) >> block_log; - unsigned int *block_list, *block_listp; - struct file_buffer **buffer_list; - int status, num_locked_fragments; long long sparse = 0; struct file_buffer *fragment_buffer = NULL; + if(pre_duplicate(read_size)) + return write_file_blocks_dup(inode, dir_ent, read_buffer, dup); + + *dup = FALSE; + block_list = malloc(blocks * sizeof(unsigned int)); if(block_list == NULL) MEM_ERROR(); - block_listp = block_list; - - buffer_list = malloc(blocks * sizeof(struct file_buffer *)); - if(buffer_list == NULL) - MEM_ERROR(); - num_locked_fragments = lock_fragments(); + lock_fragments(); file_bytes = 0; - start = dup_start = bytes; - thresh = blocks > (writer_buffer_size - num_locked_fragments) ? - blocks - (writer_buffer_size - num_locked_fragments): 0; - + start = bytes; for(block = 0; block < blocks;) { if(read_buffer->fragment) { block_list[block] = 0; - buffer_list[block] = NULL; fragment_buffer = read_buffer; blocks = read_size >> block_log; } else { block_list[block] = read_buffer->c_byte; - if(read_buffer->c_byte) { read_buffer->block = bytes; bytes += read_buffer->size; - file_bytes += read_buffer->size; cache_hash(read_buffer, read_buffer->block); - if(block < thresh) { - buffer_list[block] = NULL; - queue_put(to_writer, read_buffer); - } else - buffer_list[block] = read_buffer; + file_bytes += read_buffer->size; + queue_put(to_writer, read_buffer); } else { - buffer_list[block] = NULL; sparse += read_buffer->size; cache_block_put(read_buffer); } @@ -2709,37 +2737,13 @@ int write_file_blocks_dup(squashfs_inode *inode, struct dir_ent *dir_ent, } } - dupl_ptr = duplicate(read_size, file_bytes, &block_listp, &dup_start, - &fragment, fragment_buffer, blocks, 0, 0, FALSE); - - if(dupl_ptr) { - *duplicate_file = FALSE; - for(block = thresh; block < blocks; block ++) - if(buffer_list[block]) - queue_put(to_writer, buffer_list[block]); - fragment = get_and_fill_fragment(fragment_buffer, dir_ent); - dupl_ptr->fragment = fragment; - } else { - *duplicate_file = TRUE; - for(block = thresh; block < blocks; block ++) - cache_block_put(buffer_list[block]); - bytes = start; - if(thresh && !block_device) { - int res; - - queue_put(to_writer, NULL); - if(queue_get(from_writer) != 0) - EXIT_MKSQUASHFS(); - res = ftruncate(fd, bytes); - if(res != 0) - BAD_ERROR("Failed to truncate dest file because" - " %s\n", strerror(errno)); - } - } - unlock_fragments(); + fragment = get_and_fill_fragment(fragment_buffer, dir_ent); cache_block_put(fragment_buffer); - free(buffer_list); + + if(duplicate_checking) + add_non_dup(read_size, file_bytes, block_list, start, fragment, + 0, 0, FALSE); file_count ++; total_bytes += read_size; @@ -2754,11 +2758,13 @@ int write_file_blocks_dup(squashfs_inode *inode, struct dir_ent *dir_ent, if(sparse && (dir_ent->inode->buf.st_blocks << 9) >= read_size) sparse = 0; - create_inode(inode, NULL, dir_ent, SQUASHFS_FILE_TYPE, read_size, - dup_start, blocks, block_listp, fragment, NULL, sparse); + create_inode(inode, NULL, dir_ent, SQUASHFS_FILE_TYPE, read_size, start, + blocks, block_list, fragment, NULL, sparse); - if(*duplicate_file == TRUE) + if(duplicate_checking == FALSE) { free(block_list); + free_fragment(fragment); + } return 0; @@ -2766,7 +2772,7 @@ read_err: dec_progress_bar(block); status = read_buffer->error; bytes = start; - if(thresh && !block_device) { + if(!block_device) { int res; queue_put(to_writer, NULL); @@ -2778,9 +2784,6 @@ read_err: strerror(errno)); } unlock_fragments(); - for(blocks = thresh; blocks < block; blocks ++) - cache_block_put(buffer_list[blocks]); - free(buffer_list); free(block_list); cache_block_put(read_buffer); return status; @@ -2804,8 +2807,6 @@ again: write_file_empty(inode, dir, read_buffer, dup); else if(read_buffer->fragment && read_buffer->c_byte) write_file_frag(inode, dir, read_buffer, dup); - else if(pre_duplicate(read_buffer->file_size)) - status = write_file_blocks_dup(inode, dir, read_buffer, dup); else status = write_file_blocks(inode, dir, read_buffer, dup); |