Changeset 0d4db0f in mainline for uspace/lib/ext4/libext4_extent.c


Ignore:
Timestamp:
2012-04-01T18:35:37Z (12 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
001307cf
Parents:
a2fa350
Message:

function for release data block (last) from extent, actually without releasing index blocks

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/ext4/libext4_extent.c

    ra2fa350 r0d4db0f  
    205205        r = l + entries_count - 1;
    206206
    207         while (l <= r) {
     207        while (l < r) {
    208208                m = l + (r - l) / 2;
    209209                uint32_t first_block = ext4_extent_get_first_block(m);
     
    246246
    247247
    248         ext4_extent_t* extent;
     248        ext4_extent_t* extent = NULL;
    249249        ext4_extent_binsearch(header, &extent, iblock);
    250250
     251        assert(extent != NULL);
    251252
    252253        uint32_t phys_block;
     
    264265}
    265266
    266 //static int ext4_extent_find_extent(ext4_filesystem_t *fs,
    267 //              ext4_inode_ref_t *inode_ref, uint32_t iblock, ext4_extent_path_t **ret_path)
    268 //{
    269 //      int rc;
    270 //
    271 //      ext4_extent_header_t *eh =
    272 //                      ext4_inode_get_extent_header(inode_ref->inode);
    273 //
    274 //      uint16_t depth = ext4_extent_header_get_depth(eh);
    275 //
    276 //      ext4_extent_path_t *tmp_path;
    277 //
    278 //      // Added 2 for possible tree growing
    279 //      tmp_path = malloc(sizeof(ext4_extent_path_t) * (depth + 2));
    280 //      if (tmp_path == NULL) {
    281 //              return ENOMEM;
    282 //      }
    283 //
    284 //      tmp_path[0].block = inode_ref->block;
    285 //      tmp_path[0].header = eh;
    286 //
    287 //      uint16_t pos = 0;
    288 //      while (ext4_extent_header_get_depth(eh) != 0) {
    289 //
    290 //              ext4_extent_binsearch_idx(tmp_path[pos].header, &tmp_path[pos].index, iblock);
    291 //
    292 //              tmp_path[pos].depth = depth;
    293 //              tmp_path[pos].extent = NULL;
    294 //
    295 //              assert(tmp_path[pos].index != NULL);
    296 //
    297 //              uint64_t fblock = ext4_extent_index_get_leaf(tmp_path[pos].index);
    298 //
    299 //              block_t *block;
    300 //              rc = block_get(&block, fs->device, fblock, BLOCK_FLAGS_NONE);
    301 //              if (rc != EOK) {
    302 //                      // TODO cleanup
    303 //                      EXT4FS_DBG("ERRRR");
    304 //                      return rc;
    305 //              }
    306 //
    307 //              pos++;
    308 //
    309 //              eh = (ext4_extent_header_t *)block->data;
    310 //              tmp_path[pos].block = block;
    311 //              tmp_path[pos].header = eh;
    312 //
    313 //      }
    314 //
    315 //      tmp_path[pos].depth = 0;
    316 //      tmp_path[pos].extent = NULL;
    317 //      tmp_path[pos].index = NULL;
    318 //
    319 //    /* find extent */
    320 //      ext4_extent_binsearch(tmp_path[pos].header, &tmp_path[pos].extent, iblock);
    321 //
    322 //      *ret_path = tmp_path;
    323 //
    324 //      return EOK;
    325 //}
    326 
    327 
    328 //int ext4_extent_find_block(ext4_filesystem_t *fs,
    329 //              ext4_inode_ref_t *inode_ref, uint32_t iblock, uint32_t *fblock)
    330 //{
    331 //      int rc;
    332 //
    333 //      ext4_extent_path_t *path;
    334 //      rc = ext4_extent_find_extent(fs, inode_ref, iblock, &path);
    335 //      if (rc != EOK) {
    336 //              return rc;
    337 //      }
    338 //
    339 //      uint16_t depth = path->depth;
    340 //
    341 //      ext4_extent_t *extent = path[depth].extent;
    342 //
    343 //      uint32_t phys_block;
    344 //      phys_block = ext4_extent_get_start(extent) + iblock;
    345 //      phys_block -= ext4_extent_get_first_block(extent);
    346 //
    347 //      *fblock = phys_block;
    348 //
    349 //      // Put loaded blocks
    350 //      // From 1 -> 0 is a block with inode data
    351 //      for (uint16_t i = 1; i < depth; ++i) {
    352 //              if (path[i].block) {
    353 //                      block_put(path[i].block);
    354 //              }
    355 //      }
    356 //
    357 //      // Destroy temporary data structure
    358 //      free(path);
    359 //
    360 //      return EOK;
    361 //
    362 //}
     267static int ext4_extent_find_extent(ext4_inode_ref_t *inode_ref,
     268                uint32_t iblock, ext4_extent_path_t **ret_path)
     269{
     270        int rc;
     271
     272        ext4_extent_header_t *eh =
     273                        ext4_inode_get_extent_header(inode_ref->inode);
     274
     275        uint16_t depth = ext4_extent_header_get_depth(eh);
     276
     277//      EXT4FS_DBG("depth = \%u", depth);
     278//      EXT4FS_DBG("header = \%u", (uint32_t)eh);
     279//      EXT4FS_DBG("entries_count = \%u", ext4_extent_header_get_entries_count(eh));
     280//      EXT4FS_DBG("max entries_count = \%u", ext4_extent_header_get_max_entries_count(eh));
     281
     282        ext4_extent_path_t *tmp_path;
     283
     284        // Added 2 for possible tree growing
     285        tmp_path = malloc(sizeof(ext4_extent_path_t) * (depth + 2));
     286        if (tmp_path == NULL) {
     287                return ENOMEM;
     288        }
     289
     290        tmp_path[0].block = inode_ref->block;
     291        tmp_path[0].header = eh;
     292
     293        uint16_t pos = 0;
     294        while (ext4_extent_header_get_depth(eh) != 0) {
     295
     296                ext4_extent_binsearch_idx(tmp_path[pos].header, &tmp_path[pos].index, iblock);
     297
     298                tmp_path[pos].depth = depth;
     299                tmp_path[pos].extent = NULL;
     300
     301                assert(tmp_path[pos].index != NULL);
     302
     303                uint64_t fblock = ext4_extent_index_get_leaf(tmp_path[pos].index);
     304
     305                block_t *block;
     306                rc = block_get(&block, inode_ref->fs->device, fblock, BLOCK_FLAGS_NONE);
     307                if (rc != EOK) {
     308                        // TODO cleanup
     309                        EXT4FS_DBG("ERRRR");
     310                        return rc;
     311                }
     312
     313                pos++;
     314
     315                eh = (ext4_extent_header_t *)block->data;
     316                tmp_path[pos].block = block;
     317                tmp_path[pos].header = eh;
     318
     319        }
     320
     321        tmp_path[pos].depth = 0;
     322        tmp_path[pos].extent = NULL;
     323        tmp_path[pos].index = NULL;
     324
     325    /* find extent */
     326        ext4_extent_binsearch(tmp_path[pos].header, &tmp_path[pos].extent, iblock);
     327
     328        EXT4FS_DBG("extent = \%u", (uint32_t)tmp_path[pos].extent);
     329
     330        *ret_path = tmp_path;
     331
     332        return EOK;
     333}
     334
     335int ext4_extent_release_block(ext4_inode_ref_t *inode_ref, uint32_t iblock)
     336{
     337        int rc;
     338
     339        ext4_extent_path_t *path;
     340        rc = ext4_extent_find_extent(inode_ref, iblock, &path);
     341        if (rc != EOK) {
     342                return rc;
     343        }
     344
     345        ext4_extent_path_t *path_ptr = path;
     346        while (path_ptr->depth != 0) {
     347                EXT4FS_DBG("depth = \%u", path_ptr->depth);
     348                path_ptr++;
     349        }
     350
     351        assert(path_ptr->extent != NULL);
     352
     353        uint32_t fblock;
     354        fblock = ext4_extent_get_start(path_ptr->extent) + iblock;
     355        fblock -= ext4_extent_get_first_block(path_ptr->extent);
     356
     357        uint16_t block_count = ext4_extent_get_block_count(path_ptr->extent);
     358
     359        assert((ext4_extent_get_first_block(path_ptr->extent) + block_count - 1) == iblock);
     360
     361        block_count--;
     362        ext4_extent_set_block_count(path_ptr->extent, block_count);
     363
     364        if (block_count == 0) {
     365                uint16_t entries = ext4_extent_header_get_entries_count(path_ptr->header);
     366                entries--;
     367                ext4_extent_header_set_entries_count(path_ptr->header, entries);
     368
     369                // TODO if empty leaf, release it
     370
     371        }
     372
     373        path_ptr->block->dirty = true;
     374
     375        rc = ext4_balloc_free_block(inode_ref, fblock);
     376        if (rc != EOK) {
     377                // TODO handle error
     378        }
     379
     380        uint16_t depth = path->depth;
     381
     382        // Put loaded blocks
     383        // From 1 -> 0 is a block with inode data
     384        for (uint16_t i = 1; i < depth; ++i) {
     385                if (path[i].block) {
     386                        block_put(path[i].block);
     387                }
     388        }
     389
     390        // Destroy temporary data structure
     391        free(path);
     392
     393
     394        return EOK;
     395}
    363396
    364397/**
Note: See TracChangeset for help on using the changeset viewer.