Changeset 9104bb5 in mainline for uspace/lib/ext4/libext4_extent.c
- Timestamp:
- 2012-03-20T20:22:19Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a4419e7
- Parents:
- cd581120
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ext4/libext4_extent.c
rcd581120 r9104bb5 149 149 } 150 150 151 static void ext4_extent_binsearch_idx(ext4_extent_path_t *path, uint32_t iblock) 152 { 153 ext4_extent_header_t *header = path->header; 154 ext4_extent_index_t *r, *l, *m; 155 156 uint16_t entries_count = ext4_extent_header_get_entries_count(header); 157 l = EXT4_EXTENT_FIRST_INDEX(header) + 1; 158 r = l + entries_count - 1; 159 160 while (l <= r) { 161 m = l + (r - l) / 2; 162 uint32_t block = ext4_extent_index_get_first_block(m); 163 if (iblock < block) { 164 r = m - 1; 165 } else { 166 l = m + 1; 151 //static void ext4_extent_binsearch_idx(ext4_extent_path_t *path, uint32_t iblock) 152 //{ 153 // ext4_extent_header_t *header = path->header; 154 // ext4_extent_index_t *r, *l, *m; 155 // 156 // uint16_t entries_count = ext4_extent_header_get_entries_count(header); 157 // l = EXT4_EXTENT_FIRST_INDEX(header) + 1; 158 // r = l + entries_count - 1; 159 // 160 // while (l <= r) { 161 // m = l + (r - l) / 2; 162 // uint32_t block = ext4_extent_index_get_first_block(m); 163 // if (iblock < block) { 164 // r = m - 1; 165 // } else { 166 // l = m + 1; 167 // } 168 // } 169 // 170 // path->index = l - 1; 171 //} 172 // 173 //static void ext4_extent_binsearch(ext4_extent_path_t *path, uint32_t iblock) 174 //{ 175 // ext4_extent_header_t *header = path->header; 176 // ext4_extent_t *r, *l, *m; 177 // 178 // uint16_t entries_count = ext4_extent_header_get_entries_count(header); 179 // 180 // if (entries_count == 0) { 181 // // this leaf is empty 182 // return; 183 // } 184 // 185 // l = EXT4_EXTENT_FIRST(header) + 1; 186 // r = l + entries_count - 1; 187 // 188 // while (l <= r) { 189 // m = l + (r - l) / 2; 190 // uint32_t block = ext4_extent_get_first_block(m); 191 // if (iblock < block) { 192 // r = m - 1; 193 // } else { 194 // l = m + 1; 195 // } 196 // } 197 // 198 // path->extent = l - 1; 199 // 200 //} 201 202 static int ext4_extent_find_extent(ext4_filesystem_t *fs, ext4_inode_ref_t *inode_ref, uint32_t iblock, ext4_extent_t **ret_extent) 203 { 204 int rc; 205 206 block_t* block = NULL; 207 208 ext4_extent_header_t *header = ext4_inode_get_extent_header(inode_ref->inode); 209 while (ext4_extent_header_get_depth(header) != 0) { 210 211 ext4_extent_index_t *extent_index = EXT4_EXTENT_FIRST_INDEX(header); 212 213 for (uint16_t i = 0; i < ext4_extent_header_get_entries_count(header); ++i) { 214 if (iblock >= ext4_extent_index_get_first_block(extent_index)) { 215 216 uint64_t child = ext4_extent_index_get_leaf(extent_index); 217 218 if (block != NULL) { 219 block_put(block); 220 } 221 222 rc = block_get(&block, fs->device, child, BLOCK_FLAGS_NONE); 223 if (rc != EOK) { 224 return rc; 225 } 226 227 header = (ext4_extent_header_t *)block->data; 228 break; 229 } 167 230 } 168 231 } 169 232 170 path->index = l - 1;171 } 172 173 static void ext4_extent_binsearch(ext4_extent_path_t *path, uint32_t iblock) 174 { 175 ext4_extent_header_t *header = path->header;176 ext4_extent_t *r, *l, *m;177 178 uint16_t entries_count = ext4_extent_header_get_entries_count(header);179 180 if (entries_count == 0) {181 // this leaf is empty182 return;233 ext4_extent_t *extent = EXT4_EXTENT_FIRST(header); 234 // uint64_t phys_block = 0; 235 236 for (uint16_t i = 0; i < ext4_extent_header_get_entries_count(header); ++i) { 237 238 uint32_t first_block = ext4_extent_get_first_block(extent); 239 uint16_t block_count = ext4_extent_get_block_count(extent); 240 241 if ((iblock >= first_block) && (iblock < first_block + block_count)) { 242 break; 243 } 244 // Go to the next extent 245 ++extent; 183 246 } 184 247 185 l = EXT4_EXTENT_FIRST(header) + 1; 186 r = l + entries_count - 1; 187 188 while (l <= r) { 189 m = l + (r - l) / 2; 190 uint32_t block = ext4_extent_get_first_block(m); 191 if (iblock < block) { 192 r = m - 1; 193 } else { 194 l = m + 1; 195 } 248 *ret_extent = extent; 249 250 return EOK; 251 } 252 253 int ext4_extent_find_block(ext4_filesystem_t *fs, 254 ext4_inode_ref_t *inode_ref, uint32_t iblock, uint32_t *fblock) 255 { 256 int rc; 257 258 ext4_extent_t *extent = NULL; 259 rc = ext4_extent_find_extent(fs, inode_ref, iblock, &extent); 260 if (rc != EOK) { 261 return rc; 196 262 } 197 263 198 path->extent = l - 1; 199 200 } 201 202 int ext4_extent_find_block(ext4_filesystem_t *fs, ext4_extent_path_t **path, 203 ext4_extent_header_t *header, uint32_t iblock) 204 { 205 int rc; 206 207 uint16_t depth = ext4_extent_header_get_depth(header); 208 209 ext4_extent_header_t *eh = header; 210 211 ext4_extent_path_t *tmp_path; 212 213 // Added 2 for possible tree growing 214 tmp_path = malloc(sizeof(ext4_extent_path_t) * (depth + 2)); 215 if (tmp_path == NULL) { 216 *path = NULL; 217 return ENOMEM; 218 } 219 220 tmp_path[0].block = NULL; 221 tmp_path[0].header = eh; 222 223 uint16_t pos = 0, idx = depth; 224 while (idx > 0) { 225 226 ext4_extent_binsearch_idx(tmp_path + pos, iblock); 227 228 tmp_path[pos].depth = idx; 229 tmp_path[pos].extent = NULL; 230 231 uint64_t fblock = ext4_extent_index_get_leaf(tmp_path[pos].index); 232 block_t *block; 233 rc = block_get(&block, fs->device, fblock, BLOCK_FLAGS_NONE); 234 if (rc != EOK) { 235 // TODO cleanup 236 } 237 238 eh = (ext4_extent_header_t *)tmp_path[pos].block->data; 239 pos++; 240 241 tmp_path[pos].block = block; 242 tmp_path[pos].header = eh; 243 244 idx--; 245 246 } 247 248 tmp_path[pos].depth = idx; 249 tmp_path[pos].extent = NULL; 250 tmp_path[pos].index = NULL; 251 252 /* find extent */ 253 ext4_extent_binsearch(tmp_path + pos, iblock); 254 255 /* if not an empty leaf */ 256 if (tmp_path[pos].extent) { 257 uint64_t fblock = ext4_extent_get_start(tmp_path[pos].extent); 258 block_t *block; 259 rc = block_get(&block, fs->device, fblock, BLOCK_FLAGS_NONE); 260 if (rc != EOK) { 261 // TODO cleanup 262 } 263 tmp_path[pos].block = block; 264 } 264 uint32_t phys_block; 265 phys_block = ext4_extent_get_start(extent) + iblock; 266 phys_block -= ext4_extent_get_first_block(extent); 267 268 269 *fblock = phys_block; 265 270 266 271 return EOK; 272 273 274 // ext4_extent_header_t *eh = 275 // ext4_inode_get_extent_header(inode_ref->inode); 276 // 277 // uint16_t depth = ext4_extent_header_get_depth(eh); 278 // 279 // ext4_extent_path_t *tmp_path; 280 // 281 // // Added 2 for possible tree growing 282 // tmp_path = malloc(sizeof(ext4_extent_path_t) * (depth + 2)); 283 // if (tmp_path == NULL) { 284 // *path = NULL; 285 // return ENOMEM; 286 // } 287 // 288 // tmp_path[0].block = inode_ref->block; 289 // tmp_path[0].header = eh; 290 // 291 // uint16_t pos = 0; 292 // while (ext4_extent_header_get_depth(eh) != 0) { 293 // 294 // EXT4FS_DBG("count == \%u", ext4_extent_header_get_entries_count(eh)); 295 // 296 // ext4_extent_binsearch_idx(tmp_path + pos, iblock); 297 // 298 // uint32_t offset = (void *)tmp_path[pos].index - (void *)EXT4_EXTENT_FIRST_INDEX(eh); 299 // 300 // EXT4FS_DBG("offset = \%u", offset); 301 // 302 // EXT4FS_DBG("first block = \%u, leaf = \%u", 303 // ext4_extent_index_get_first_block(tmp_path[pos].index), 304 // (uint32_t)ext4_extent_index_get_leaf(tmp_path[pos].index)); 305 // 306 // tmp_path[pos].depth = depth; 307 // tmp_path[pos].extent = NULL; 308 // 309 // assert(tmp_path[pos].index != NULL); 310 // 311 // uint64_t fblock = ext4_extent_index_get_leaf(tmp_path[pos].index); 312 // 313 // EXT4FS_DBG("fblock = \%u", (uint32_t)fblock); 314 // 315 // block_t *block; 316 // rc = block_get(&block, fs->device, fblock, BLOCK_FLAGS_NONE); 317 // if (rc != EOK) { 318 // // TODO cleanup 319 // EXT4FS_DBG("ERRRR"); 320 // return rc; 321 // } 322 // 323 // EXT4FS_DBG("block loaded"); 324 // 325 // pos++; 326 // 327 // eh = (ext4_extent_header_t *)block->data; 328 // tmp_path[pos].block = block; 329 // tmp_path[pos].header = eh; 330 // 331 // } 332 // 333 // tmp_path[pos].depth = 0; 334 // tmp_path[pos].extent = NULL; 335 // tmp_path[pos].index = NULL; 336 // 337 // EXT4FS_DBG("pos = \%u", pos); 338 // 339 // /* find extent */ 340 // ext4_extent_binsearch(tmp_path + pos, iblock); 341 // 342 // EXT4FS_DBG("after binsearch in extent"); 343 // 344 // /* if not an empty leaf */ 345 // if (tmp_path[pos].extent) { 346 // EXT4FS_DBG("nonempty leaf"); 347 // 348 //// uint64_t fblock = ext4_extent_get_start(tmp_path[pos].extent); 349 //// block_t *block; 350 //// rc = block_get(&block, fs->device, fblock, BLOCK_FLAGS_NONE); 351 //// if (rc != EOK) { 352 //// // TODO cleanup 353 //// } 354 //// tmp_path[pos].block = block; 355 // } 356 // 357 // *path = tmp_path; 358 // 359 // return EOK; 267 360 } 268 361
Note:
See TracChangeset
for help on using the changeset viewer.