Ignore:
File:
1 edited

Legend:

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

    r922427a8 r5e801dc  
    6464static bool ext4_is_dots(const uint8_t *, size_t);
    6565static errno_t ext4_instance_get(service_id_t, ext4_instance_t **);
    66 static errno_t handle_sparse_or_unallocated_fblock(ext4_filesystem_t *,
    67     ext4_inode_ref_t *, uint32_t, uint32_t, uint32_t *, int *, bool *);
    6866
    6967/* Forward declarations of ext4 libfs operations. */
     
    115113}
    116114
    117 static bool open_nodes_key_equal(const void *key_arg, size_t hash, const ht_link_t *item)
     115static bool open_nodes_key_equal(const void *key_arg, const ht_link_t *item)
    118116{
    119117        const node_key_t *key = key_arg;
     
    124122}
    125123
    126 static const hash_table_ops_t open_nodes_ops = {
     124static hash_table_ops_t open_nodes_ops = {
    127125        .hash = open_nodes_hash,
    128126        .key_hash = open_nodes_key_hash,
     
    160158}
    161159
     160/*
     161 * Ext4 libfs operations.
     162 */
     163
    162164/** Get instance from internal table by service_id.
    163165 *
     
    168170 *
    169171 */
    170 static errno_t ext4_instance_get(service_id_t service_id, ext4_instance_t **inst)
     172errno_t ext4_instance_get(service_id_t service_id, ext4_instance_t **inst)
    171173{
    172174        fibril_mutex_lock(&instance_list_mutex);
     
    188190        return EINVAL;
    189191}
    190 
    191 /*
    192  * Ext4 libfs operations.
    193  */
    194192
    195193/** Get root node of filesystem specified by service_id.
     
    812810}
    813811
    814 /** Get service ID for a service-special file.
     812/** Extract device identifier from node.
    815813 *
    816814 * @param node Node to extract id from
    817815 *
    818  * @return Service ID for a service-special file, zero for a regular file.
     816 * @return id of device, where is the filesystem
    819817 *
    820818 */
    821819service_id_t ext4_service_get(fs_node_t *fn)
    822820{
    823         return 0;
     821        ext4_node_t *enode = EXT4_NODE(fn);
     822        return enode->instance->service_id;
    824823}
    825824
     
    12861285    size_t *wbytes, aoff64_t *nsize)
    12871286{
    1288         fs_node_t *fn = NULL;
     1287        fs_node_t *fn;
    12891288        errno_t rc2;
    1290         bool fblock_allocated = false;
    1291         ext4_inode_ref_t *inode_ref = NULL;
    1292 
    12931289        errno_t rc = ext4_node_get(&fn, service_id, index);
    12941290        if (rc != EOK)
     
    13191315
    13201316        /* Load inode */
    1321         inode_ref = enode->inode_ref;
     1317        ext4_inode_ref_t *inode_ref = enode->inode_ref;
    13221318        rc = ext4_filesystem_get_inode_data_block_index(inode_ref, iblock,
    13231319            &fblock);
     
    13271323        }
    13281324
    1329         /* Handle sparse or unallocated block */
     1325        /* Check for sparse file */
    13301326        if (fblock == 0) {
    1331                 rc = handle_sparse_or_unallocated_fblock(fs, inode_ref,
    1332                     block_size, iblock, &fblock, &flags, &fblock_allocated);
    1333                 if (rc != EOK) {
    1334                         async_answer_0(&call, rc);
    1335                         goto exit;
     1327                if ((ext4_superblock_has_feature_incompatible(fs->superblock,
     1328                    EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
     1329                    (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
     1330                        uint32_t last_iblock =
     1331                            ext4_inode_get_size(fs->superblock, inode_ref->inode) /
     1332                            block_size;
     1333
     1334                        while (last_iblock < iblock) {
     1335                                rc = ext4_extent_append_block(inode_ref, &last_iblock,
     1336                                    &fblock, true);
     1337                                if (rc != EOK) {
     1338                                        async_answer_0(&call, rc);
     1339                                        goto exit;
     1340                                }
     1341                        }
     1342
     1343                        rc = ext4_extent_append_block(inode_ref, &last_iblock,
     1344                            &fblock, false);
     1345                        if (rc != EOK) {
     1346                                async_answer_0(&call, rc);
     1347                                goto exit;
     1348                        }
     1349                } else {
     1350                        rc = ext4_balloc_alloc_block(inode_ref, &fblock);
     1351                        if (rc != EOK) {
     1352                                async_answer_0(&call, rc);
     1353                                goto exit;
     1354                        }
     1355
     1356                        rc = ext4_filesystem_set_inode_data_block_index(inode_ref,
     1357                            iblock, fblock);
     1358                        if (rc != EOK) {
     1359                                ext4_balloc_free_block(inode_ref, fblock);
     1360                                async_answer_0(&call, rc);
     1361                                goto exit;
     1362                        }
    13361363                }
     1364
     1365                flags = BLOCK_FLAGS_NOREAD;
     1366                inode_ref->dirty = true;
    13371367        }
    13381368
     
    13731403
    13741404exit:
    1375         if (rc != EOK && fblock_allocated)
    1376                 ext4_balloc_free_block(inode_ref, fblock);
    1377 
    13781405        rc2 = ext4_node_put(fn);
    13791406        return rc == EOK ? rc2 : rc;
    1380 }
    1381 
    1382 /** Handle sparse or unallocated block.
    1383  *
    1384  * @param fs            Filesystem handle
    1385  * @param inode_ref     I-node reference
    1386  * @param block_size    Filesystem block size
    1387  * @param iblock        Logical block
    1388  * @param fblock        Place to store allocated block address
    1389  * @param flags         BLOCK_FLAGS to update
    1390  * @param allocated     Place to store whether new block was allocated
    1391  *
    1392  * @return Error code
    1393  *
    1394  */
    1395 static errno_t handle_sparse_or_unallocated_fblock(ext4_filesystem_t *fs,
    1396     ext4_inode_ref_t *inode_ref, uint32_t block_size, uint32_t iblock,
    1397     uint32_t *fblock, int *flags, bool *allocated)
    1398 {
    1399         errno_t rc;
    1400 
    1401         /* Check for sparse file */
    1402         if ((ext4_superblock_has_feature_incompatible(fs->superblock,
    1403             EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
    1404             (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
    1405                 uint32_t last_iblock =
    1406                     ext4_inode_get_size(fs->superblock, inode_ref->inode) /
    1407                     block_size;
    1408 
    1409                 while (last_iblock < iblock) {
    1410                         rc = ext4_extent_append_block(inode_ref, &last_iblock,
    1411                             fblock, true);
    1412                         if (rc != EOK)
    1413                                 return rc;
    1414                 }
    1415 
    1416                 rc = ext4_extent_append_block(inode_ref, &last_iblock, fblock,
    1417                     false);
    1418                 if (rc != EOK)
    1419                         return rc;
    1420 
    1421                 *allocated = false;
    1422         } else { /* Allocate new block */
    1423                 rc = ext4_balloc_alloc_block(inode_ref, fblock);
    1424                 if (rc != EOK)
    1425                         return rc;
    1426 
    1427                 rc = ext4_filesystem_set_inode_data_block_index(inode_ref,
    1428                     iblock, *fblock);
    1429                 if (rc != EOK) {
    1430                         ext4_balloc_free_block(inode_ref, *fblock);
    1431                         return rc;
    1432                 }
    1433 
    1434                 *allocated = true;
    1435         }
    1436 
    1437         *flags = BLOCK_FLAGS_NOREAD;
    1438         inode_ref->dirty = true;
    1439 
    1440         return EOK;
    14411407}
    14421408
Note: See TracChangeset for help on using the changeset viewer.