1ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* 2ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * Copyright (C) 2010 The Android Open Source Project 3ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * 4ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * Licensed under the Apache License, Version 2.0 (the "License"); 5ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * you may not use this file except in compliance with the License. 6ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * You may obtain a copy of the License at 7ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * 89579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash * http://www.apache.org/licenses/LICENSE-2.0 9ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * 10ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * Unless required by applicable law or agreed to in writing, software 11ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * distributed under the License is distributed on an "AS IS" BASIS, 12ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * See the License for the specific language governing permissions and 14ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * limitations under the License. 15ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross */ 16ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 17ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross#include "ext4_utils.h" 18ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross#include "extent.h" 19ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 20dc5abeee1e6fc4827ee0d5ece12aaed2dd56f4c7Colin Cross#include <sparse/sparse.h> 21dc5abeee1e6fc4827ee0d5ece12aaed2dd56f4c7Colin Cross 22af0723439af552c170425416ee8e35f4f20bbe67Colin Cross#include <inttypes.h> 2333f96c66e9a1f2e266a75e5e84c091dffa6ef118Colin Cross#include <stdlib.h> 2433f96c66e9a1f2e266a75e5e84c091dffa6ef118Colin Cross#include <stdio.h> 2533f96c66e9a1f2e266a75e5e84c091dffa6ef118Colin Cross 2633f96c66e9a1f2e266a75e5e84c091dffa6ef118Colin Cross 27ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Creates data buffers for the first backing_len bytes of a block allocation 28ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross and queues them to be written */ 29ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic u8 *extent_create_backing(struct block_allocation *alloc, 308aef66d2125af8de7672a12895276802fcc1948fColin Cross u64 backing_len) 31ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{ 32ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross u8 *data = calloc(backing_len, 1); 33ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross if (!data) 34ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross critical_error_errno("calloc"); 35ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 36ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross u8 *ptr = data; 37ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross for (; alloc != NULL && backing_len > 0; get_next_region(alloc)) { 38ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross u32 region_block; 39ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross u32 region_len; 40ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross u32 len; 41ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross get_region(alloc, ®ion_block, ®ion_len); 42ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 43ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross len = min(region_len * info.block_size, backing_len); 44ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 45782879ab61fe825835a9c6a701f91aa7d305acefColin Cross sparse_file_add_data(ext4_sparse_file, ptr, len, region_block); 46ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross ptr += len; 47ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross backing_len -= len; 48ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross } 49ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 50ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross return data; 51ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross} 52ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 53ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Queues each chunk of a file to be written to contiguous data block 54ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross regions */ 55ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic void extent_create_backing_file(struct block_allocation *alloc, 568aef66d2125af8de7672a12895276802fcc1948fColin Cross u64 backing_len, const char *filename) 57ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{ 5833f96c66e9a1f2e266a75e5e84c091dffa6ef118Colin Cross off64_t offset = 0; 59ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross for (; alloc != NULL && backing_len > 0; get_next_region(alloc)) { 60ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross u32 region_block; 61ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross u32 region_len; 62ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross u32 len; 63ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross get_region(alloc, ®ion_block, ®ion_len); 64ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 65ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross len = min(region_len * info.block_size, backing_len); 66ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 67782879ab61fe825835a9c6a701f91aa7d305acefColin Cross sparse_file_add_file(ext4_sparse_file, filename, offset, len, 68f0ee37ffded79afdb03e15ae3a69969d2b7e6079Colin Cross region_block); 69ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross offset += len; 70ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross backing_len -= len; 71ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross } 72ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross} 73ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 74ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic struct block_allocation *do_inode_allocate_extents( 759579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash struct ext4_inode *inode, u64 len, struct block_allocation *prealloc) 76ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{ 779579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash u32 block_len = DIV_ROUND_UP(len, info.block_size), prealloc_block_len; 789579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash struct block_allocation *alloc; 79ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross u32 extent_block = 0; 80ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross u32 file_block = 0; 81ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross struct ext4_extent *extent; 82ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross u64 blocks; 83ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 849579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash if (!prealloc) { 859579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash alloc = allocate_blocks(block_len + 1); 869579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash if (alloc == NULL) { 879579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash error("Failed to allocate %d blocks\n", block_len + 1); 889579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash return NULL; 899579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash } 909579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash } else { 919579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash prealloc_block_len = block_allocation_len(prealloc); 929579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash if (block_len + 1 > prealloc_block_len) { 939579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash alloc = allocate_blocks(block_len + 1 - prealloc_block_len); 949579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash if (alloc == NULL) { 959579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash error("Failed to allocate %d blocks\n", 969579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash block_len + 1 - prealloc_block_len); 979579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash return NULL; 989579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash } 99f7124d6c955c0453361b0ff47c5c94619e68087fMohamad Ayyash region_list_merge(&prealloc->list, &alloc->list); 1009579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash free(alloc); 1019579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash } 1029579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash alloc = prealloc; 103ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross } 104ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 105ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross int allocation_len = block_allocation_num_regions(alloc); 106ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross if (allocation_len <= 3) { 107ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross reduce_allocation(alloc, 1); 1089579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash // IMPORTANT: reduce_allocation may have changed allocation 1099579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash // length, otherwise file corruption happens when fs thinks 1109579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash // a block is missing from extent header. 1119579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash allocation_len = block_allocation_num_regions(alloc); 112ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross } else { 113ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross reserve_oob_blocks(alloc, 1); 114ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross extent_block = get_oob_block(alloc, 0); 115ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross } 116ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 117ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross if (!extent_block) { 118ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross struct ext4_extent_header *hdr = 1198aef66d2125af8de7672a12895276802fcc1948fColin Cross (struct ext4_extent_header *)&inode->i_block[0]; 120ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross hdr->eh_magic = EXT4_EXT_MAGIC; 121ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross hdr->eh_entries = allocation_len; 122ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross hdr->eh_max = 3; 123ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross hdr->eh_generation = 0; 124ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross hdr->eh_depth = 0; 125ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 126ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross extent = (struct ext4_extent *)&inode->i_block[3]; 127ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross } else { 128ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross struct ext4_extent_header *hdr = 1298aef66d2125af8de7672a12895276802fcc1948fColin Cross (struct ext4_extent_header *)&inode->i_block[0]; 130ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross hdr->eh_magic = EXT4_EXT_MAGIC; 131ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross hdr->eh_entries = 1; 132ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross hdr->eh_max = 3; 133ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross hdr->eh_generation = 0; 134ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross hdr->eh_depth = 1; 135ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 136ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross struct ext4_extent_idx *idx = 1378aef66d2125af8de7672a12895276802fcc1948fColin Cross (struct ext4_extent_idx *)&inode->i_block[3]; 138ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross idx->ei_block = 0; 139ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross idx->ei_leaf_lo = extent_block; 140ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross idx->ei_leaf_hi = 0; 141ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross idx->ei_unused = 0; 142ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 143ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross u8 *data = calloc(info.block_size, 1); 144ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross if (!data) 145ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross critical_error_errno("calloc"); 146ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 147782879ab61fe825835a9c6a701f91aa7d305acefColin Cross sparse_file_add_data(ext4_sparse_file, data, info.block_size, 148f0ee37ffded79afdb03e15ae3a69969d2b7e6079Colin Cross extent_block); 149ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 150ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross if (((int)(info.block_size - sizeof(struct ext4_extent_header) / 151ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross sizeof(struct ext4_extent))) < allocation_len) { 152af0723439af552c170425416ee8e35f4f20bbe67Colin Cross error("File size %"PRIu64" is too big to fit in a single extent block\n", 153ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross len); 154ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross return NULL; 155ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross } 156ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 157ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross hdr = (struct ext4_extent_header *)data; 158ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross hdr->eh_magic = EXT4_EXT_MAGIC; 159ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross hdr->eh_entries = allocation_len; 1608aef66d2125af8de7672a12895276802fcc1948fColin Cross hdr->eh_max = (info.block_size - sizeof(struct ext4_extent_header)) / 1618aef66d2125af8de7672a12895276802fcc1948fColin Cross sizeof(struct ext4_extent); 162ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross hdr->eh_generation = 0; 163ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross hdr->eh_depth = 0; 164ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 1658aef66d2125af8de7672a12895276802fcc1948fColin Cross extent = (struct ext4_extent *)(data + 1668aef66d2125af8de7672a12895276802fcc1948fColin Cross sizeof(struct ext4_extent_header)); 167ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross } 168ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 169ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross for (; !last_region(alloc); extent++, get_next_region(alloc)) { 170ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross u32 region_block; 171ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross u32 region_len; 172ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 173ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross get_region(alloc, ®ion_block, ®ion_len); 174ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross extent->ee_block = file_block; 175ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross extent->ee_len = region_len; 176ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross extent->ee_start_hi = 0; 177ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross extent->ee_start_lo = region_block; 178ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross file_block += region_len; 179ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross } 180ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 181ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross if (extent_block) 182ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross block_len += 1; 183ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 184ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross blocks = (u64)block_len * info.block_size / 512; 185ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 186ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross inode->i_flags |= EXT4_EXTENTS_FL; 187ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross inode->i_size_lo = len; 188ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross inode->i_size_high = len >> 32; 189ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross inode->i_blocks_lo = blocks; 190ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross inode->osd2.linux2.l_i_blocks_high = blocks >> 32; 191ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 192ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross rewind_alloc(alloc); 193ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 194ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross return alloc; 195ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross} 196ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 197ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Allocates enough blocks to hold len bytes, with backing_len bytes in a data 198ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross buffer, and connects them to an inode. Returns a pointer to the data 199ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross buffer. */ 200ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossu8 *inode_allocate_data_extents(struct ext4_inode *inode, u64 len, 2018aef66d2125af8de7672a12895276802fcc1948fColin Cross u64 backing_len) 202ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{ 203ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross struct block_allocation *alloc; 204ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross u8 *data = NULL; 205ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 2069579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash alloc = do_inode_allocate_extents(inode, len, NULL); 207ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross if (alloc == NULL) { 208af0723439af552c170425416ee8e35f4f20bbe67Colin Cross error("failed to allocate extents for %"PRIu64" bytes", len); 209ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross return NULL; 210ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross } 211ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 212ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross if (backing_len) { 213ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross data = extent_create_backing(alloc, backing_len); 214ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross if (!data) 215af0723439af552c170425416ee8e35f4f20bbe67Colin Cross error("failed to create backing for %"PRIu64" bytes", backing_len); 216ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross } 217ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 218ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross free_alloc(alloc); 219ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 220ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross return data; 221ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross} 222ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 223ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Allocates enough blocks to hold len bytes, queues them to be written 224ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross from a file, and connects them to an inode. */ 225bec598e982301bf2714d37b14e312c9845c7cc0cDoug Zongkerstruct block_allocation* inode_allocate_file_extents(struct ext4_inode *inode, u64 len, 2268aef66d2125af8de7672a12895276802fcc1948fColin Cross const char *filename) 227ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{ 2289579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash struct block_allocation *alloc, *prealloc = base_fs_allocations, *prev_prealloc = NULL; 2299579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash // TODO(mkayyash): base_fs_allocations is sorted by filename, consider 2309579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash // storing it in an array and then binary searching for a filename match instead 2319579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash while (prealloc && prealloc->filename != NULL) { 2329579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash if (!strcmp(filename, prealloc->filename)) { 2339579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash break; 2349579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash } 2359579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash prev_prealloc = prealloc; 2369579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash prealloc = prealloc->next; 2379579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash } 2389579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash if (prealloc) { 2399579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash if (!prev_prealloc) { 2409579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash base_fs_allocations = base_fs_allocations->next; 2419579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash } else { 2429579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash prev_prealloc->next = prealloc->next; 2439579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash } 2449579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash prealloc->next = NULL; 2459579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash } 246ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 2479579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash alloc = do_inode_allocate_extents(inode, len, prealloc); 248ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross if (alloc == NULL) { 249af0723439af552c170425416ee8e35f4f20bbe67Colin Cross error("failed to allocate extents for %"PRIu64" bytes", len); 2509922135de65b717267d8173f61e360fbb9cf1ebdDoug Zongker return NULL; 251ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross } 252ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 253ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross extent_create_backing_file(alloc, len, filename); 2549922135de65b717267d8173f61e360fbb9cf1ebdDoug Zongker return alloc; 255ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross} 256ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 257ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Allocates enough blocks to hold len bytes and connects them to an inode */ 258ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossvoid inode_allocate_extents(struct ext4_inode *inode, u64 len) 259ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{ 260ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross struct block_allocation *alloc; 261ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 2629579198cd7d5b88b3508f1b00ddd77bd8da60682Mohamad Ayyash alloc = do_inode_allocate_extents(inode, len, NULL); 263ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross if (alloc == NULL) { 264af0723439af552c170425416ee8e35f4f20bbe67Colin Cross error("failed to allocate extents for %"PRIu64" bytes", len); 265ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross return; 266ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross } 267ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross 268ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross free_alloc(alloc); 269ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross} 270