Changeset 052e82d in mainline for uspace/lib/ext4/libext4_filesystem.c


Ignore:
Timestamp:
2011-11-07T11:50:31Z (14 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
12b4a7f
Parents:
5664cf64
Message:

partially functional truncate operation

File:
1 edited

Legend:

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

    r5664cf64 r052e82d  
    251251         */
    252252        newref->index = index+1;
     253        newref->dirty = false;
    253254
    254255        *ref = newref;
     
    261262{
    262263        int rc;
     264
     265        if (ref->dirty) {
     266                ref->block->dirty = true;
     267        }
    263268
    264269        rc = block_put(ref->block);
     
    355360
    356361
    357 int ext4_filesystem_release_inode_block(ext4_filesystem_t *fs, ext4_inode_t *inode, uint32_t iblock)
     362int ext4_filesystem_release_inode_block(ext4_filesystem_t *fs,
     363                ext4_inode_ref_t *inode_ref, uint32_t iblock)
    358364{
    359365        int rc;
    360366        uint32_t fblock;
    361 
    362         // TODO handle with extents
    363 
    364         rc = ext4_filesystem_get_inode_data_block_index(fs, inode, iblock, &fblock);
    365         if (rc != EOK) {
    366                 // TODO error
    367                 return rc;
    368         }
    369 
    370         // Sparse file
    371         if (fblock == 0) {
    372 
    373                 //
    374                 return EOK;
    375         }
    376 
    377 
    378         // TODO vyhledat policko s ukazatelem a nastavit nulu
    379 
    380 
    381         // TODO uvolnit blok v bitmape
    382 
    383         // TODO return
    384 
    385 
    386         return EOK;
     367        int i;
     368        int level;
     369        aoff64_t block_offset_in_level;
     370        uint32_t current_block;
     371        uint32_t offset_in_block;
     372        block_t *block;
     373        ext4_inode_t *inode = inode_ref->inode;
     374
     375        /* TODO handle extents */
     376
     377        /* Handle simple case when we are dealing with direct reference */
     378        if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) {
     379                EXT4FS_DBG("direct block");
     380                fblock = ext4_inode_get_direct_block(inode, (uint32_t)iblock);
     381                // Sparse file
     382                if (fblock == 0) {
     383                        return EOK;
     384                }
     385
     386                ext4_inode_set_direct_block(inode, iblock, 0);
     387                return ext4_bitmap_free_block(fs, fblock);
     388        } else {
     389
     390                /* Determine the indirection level needed to get the desired block */
     391                level = -1;
     392                for (i = 1; i < 4; i++) {
     393                        if (iblock < fs->inode_block_limits[i]) {
     394                                level = i;
     395                                break;
     396                        }
     397                }
     398
     399                if (level == -1) {
     400                        return EIO;
     401                }
     402
     403                /* Compute offsets for the topmost level */
     404                block_offset_in_level = iblock - fs->inode_block_limits[level-1];
     405                current_block = ext4_inode_get_indirect_block(inode, level-1);
     406                offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1];
     407
     408                /* Navigate through other levels, until we find the block number
     409                 * or find null reference meaning we are dealing with sparse file
     410                 */
     411                while (level > 0) {
     412                        rc = block_get(&block, fs->device, current_block, 0);
     413                        if (rc != EOK) {
     414                                return rc;
     415                        }
     416
     417                        current_block = uint32_t_le2host(((uint32_t*)block->data)[offset_in_block]);
     418
     419                        // Set zero
     420                        if (level == 1) {
     421                                ((uint32_t*)block->data)[offset_in_block] = host2uint32_t_le(0);
     422                                block->dirty = true;
     423                        }
     424
     425                        rc = block_put(block);
     426                        if (rc != EOK) {
     427                                return rc;
     428                        }
     429
     430                        level -= 1;
     431
     432                        /* If we are on the last level, break here as
     433                         * there is no next level to visit
     434                         */
     435                        if (level == 0) {
     436                                break;
     437                        }
     438
     439                        /* Visit the next level */
     440                        block_offset_in_level %= fs->inode_blocks_per_level[level];
     441                        offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1];
     442                }
     443
     444                fblock = current_block;
     445
     446                if (fblock == 0) {
     447                        return EOK;
     448                }
     449        }
     450
     451        return ext4_bitmap_free_block(fs, fblock);
     452
    387453}
    388454
Note: See TracChangeset for help on using the changeset viewer.