Changeset 12b4a7f in mainline for uspace/lib/ext4/libext4_filesystem.c


Ignore:
Timestamp:
2011-11-07T16:23:30Z (14 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
43a9968
Parents:
052e82d
Message:

functional truncate operation (only to lower size actually), except extent files

File:
1 edited

Legend:

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

    r052e82d r12b4a7f  
    152152        }
    153153
    154         //EXT4FS_DBG("desc size = \%u", (uint32_t)ext4_superblock_get_desc_size(fs->superblock));
    155 
    156154        descriptors_per_block = ext4_superblock_get_block_size(fs->superblock)
    157155            / ext4_superblock_get_desc_size(fs->superblock);
     
    171169
    172170        newref->block_group = newref->block->data + offset;
     171        newref->dirty = false;
    173172
    174173        *ref = newref;
     
    180179{
    181180        int rc;
     181
     182        if (ref->dirty) {
     183                ref->block->dirty = true;
     184        }
    182185
    183186        rc = block_put(ref->block);
     
    375378        /* TODO handle extents */
    376379
     380
    377381        /* Handle simple case when we are dealing with direct reference */
    378382        if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) {
    379                 EXT4FS_DBG("direct block");
    380                 fblock = ext4_inode_get_direct_block(inode, (uint32_t)iblock);
     383                fblock = ext4_inode_get_direct_block(inode, iblock);
    381384                // Sparse file
    382385                if (fblock == 0) {
     
    386389                ext4_inode_set_direct_block(inode, iblock, 0);
    387390                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);
     391        }
     392
     393
     394        /* Determine the indirection level needed to get the desired block */
     395        level = -1;
     396        for (i = 1; i < 4; i++) {
     397                if (iblock < fs->inode_block_limits[i]) {
     398                        level = i;
     399                        break;
     400                }
     401        }
     402
     403        if (level == -1) {
     404                return EIO;
     405        }
     406
     407        /* Compute offsets for the topmost level */
     408        block_offset_in_level = iblock - fs->inode_block_limits[level-1];
     409        current_block = ext4_inode_get_indirect_block(inode, level-1);
     410        offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1];
     411
     412        /* Navigate through other levels, until we find the block number
     413         * or find null reference meaning we are dealing with sparse file
     414         */
     415        while (level > 0) {
     416                rc = block_get(&block, fs->device, current_block, 0);
     417                if (rc != EOK) {
     418                        return rc;
     419                }
     420
     421                current_block = uint32_t_le2host(((uint32_t*)block->data)[offset_in_block]);
     422
     423                // Set zero
     424                if (level == 1) {
     425                        ((uint32_t*)block->data)[offset_in_block] = host2uint32_t_le(0);
     426                        block->dirty = true;
     427                }
     428
     429                rc = block_put(block);
     430                if (rc != EOK) {
     431                        return rc;
     432                }
     433
     434                level -= 1;
     435
     436                /* If we are on the last level, break here as
     437                 * there is no next level to visit
     438                 */
     439                if (level == 0) {
     440                        break;
     441                }
     442
     443                /* Visit the next level */
     444                block_offset_in_level %= fs->inode_blocks_per_level[level];
    406445                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                 }
     446        }
     447
     448        fblock = current_block;
     449
     450        if (fblock == 0) {
     451                return EOK;
    449452        }
    450453
Note: See TracChangeset for help on using the changeset viewer.