Changeset f62c901 in mainline


Ignore:
Timestamp:
2025-05-23T21:37:48Z (6 days ago)
Author:
Miroslav Cimerman <mc@…>
Children:
d91d076
Parents:
61f28c4
git-author:
Miroslav Cimerman <mc@…> (2025-05-23 21:34:00)
git-committer:
Miroslav Cimerman <mc@…> (2025-05-23 21:37:48)
Message:

ext4: write: sparse/unallocated block helper fcn

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/ext4/src/ops.c

    r61f28c4 rf62c901  
    6464static bool ext4_is_dots(const uint8_t *, size_t);
    6565static errno_t ext4_instance_get(service_id_t, ext4_instance_t **);
     66static errno_t handle_sparse_or_unallocated_fblock(ext4_filesystem_t *,
     67    ext4_inode_ref_t *, uint32_t, uint32_t, uint32_t *, int *);
    6668
    6769/* Forward declarations of ext4 libfs operations. */
     
    158160}
    159161
    160 /*
    161  * Ext4 libfs operations.
    162  */
    163 
    164162/** Get instance from internal table by service_id.
    165163 *
     
    170168 *
    171169 */
    172 errno_t ext4_instance_get(service_id_t service_id, ext4_instance_t **inst)
     170static errno_t ext4_instance_get(service_id_t service_id, ext4_instance_t **inst)
    173171{
    174172        fibril_mutex_lock(&instance_list_mutex);
     
    190188        return EINVAL;
    191189}
     190
     191/*
     192 * Ext4 libfs operations.
     193 */
    192194
    193195/** Get root node of filesystem specified by service_id.
     
    13221324        }
    13231325
    1324         /* Check for sparse file */
     1326        /* Handle sparse or unallocated block */
    13251327        if (fblock == 0) {
    1326                 if ((ext4_superblock_has_feature_incompatible(fs->superblock,
    1327                     EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
    1328                     (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
    1329                         uint32_t last_iblock =
    1330                             ext4_inode_get_size(fs->superblock, inode_ref->inode) /
    1331                             block_size;
    1332 
    1333                         while (last_iblock < iblock) {
    1334                                 rc = ext4_extent_append_block(inode_ref, &last_iblock,
    1335                                     &fblock, true);
    1336                                 if (rc != EOK) {
    1337                                         async_answer_0(&call, rc);
    1338                                         goto exit;
    1339                                 }
    1340                         }
    1341 
    1342                         rc = ext4_extent_append_block(inode_ref, &last_iblock,
    1343                             &fblock, false);
    1344                         if (rc != EOK) {
    1345                                 async_answer_0(&call, rc);
    1346                                 goto exit;
    1347                         }
    1348                 } else {
    1349                         rc = ext4_balloc_alloc_block(inode_ref, &fblock);
    1350                         if (rc != EOK) {
    1351                                 async_answer_0(&call, rc);
    1352                                 goto exit;
    1353                         }
    1354 
    1355                         rc = ext4_filesystem_set_inode_data_block_index(inode_ref,
    1356                             iblock, fblock);
    1357                         if (rc != EOK) {
    1358                                 ext4_balloc_free_block(inode_ref, fblock);
    1359                                 async_answer_0(&call, rc);
    1360                                 goto exit;
    1361                         }
     1328                rc = handle_sparse_or_unallocated_fblock(fs, inode_ref,
     1329                    block_size, iblock, &fblock, &flags);
     1330                if (rc != EOK) {
     1331                        async_answer_0(&call, rc);
     1332                        goto exit;
    13621333                }
    1363 
    1364                 flags = BLOCK_FLAGS_NOREAD;
    1365                 inode_ref->dirty = true;
    13661334        }
    13671335
     
    14041372        rc2 = ext4_node_put(fn);
    14051373        return rc == EOK ? rc2 : rc;
     1374}
     1375
     1376/** Handle sparse or unallocated block.
     1377 *
     1378 * @param fs            Filesystem handle
     1379 * @param inode_ref     I-node reference
     1380 * @param block_size    Filesystem block size
     1381 * @param iblock        Logical block
     1382 * @param fblock        Place to store allocated block address
     1383 * @param flags         BLOCK_FLAGS to update
     1384 *
     1385 * @return Error code
     1386 *
     1387 */
     1388static errno_t handle_sparse_or_unallocated_fblock(ext4_filesystem_t *fs,
     1389    ext4_inode_ref_t *inode_ref, uint32_t block_size, uint32_t iblock,
     1390    uint32_t *fblock, int *flags)
     1391{
     1392        errno_t rc;
     1393
     1394        /* Check for sparse file */
     1395        if ((ext4_superblock_has_feature_incompatible(fs->superblock,
     1396            EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
     1397            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
     1398                uint32_t last_iblock =
     1399                    ext4_inode_get_size(fs->superblock, inode_ref->inode) /
     1400                    block_size;
     1401
     1402                while (last_iblock < iblock) {
     1403                        rc = ext4_extent_append_block(inode_ref, &last_iblock,
     1404                            fblock, true);
     1405                        if (rc != EOK)
     1406                                return rc;
     1407                }
     1408
     1409                rc = ext4_extent_append_block(inode_ref, &last_iblock, fblock,
     1410                    false);
     1411                if (rc != EOK)
     1412                        return rc;
     1413        } else { /* Allocate new block */
     1414                rc = ext4_balloc_alloc_block(inode_ref, fblock);
     1415                if (rc != EOK)
     1416                        return rc;
     1417
     1418                rc = ext4_filesystem_set_inode_data_block_index(inode_ref,
     1419                    iblock, *fblock);
     1420                if (rc != EOK) {
     1421                        ext4_balloc_free_block(inode_ref, *fblock);
     1422                        return rc;
     1423                }
     1424        }
     1425
     1426        *flags = BLOCK_FLAGS_NOREAD;
     1427        inode_ref->dirty = true;
     1428
     1429        return EOK;
    14061430}
    14071431
Note: See TracChangeset for help on using the changeset viewer.