Changeset f62c901 in mainline
- Timestamp:
- 2025-05-23T21:37:48Z (6 days ago)
- 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)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ext4/src/ops.c
r61f28c4 rf62c901 64 64 static bool ext4_is_dots(const uint8_t *, size_t); 65 65 static 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 *); 66 68 67 69 /* Forward declarations of ext4 libfs operations. */ … … 158 160 } 159 161 160 /*161 * Ext4 libfs operations.162 */163 164 162 /** Get instance from internal table by service_id. 165 163 * … … 170 168 * 171 169 */ 172 errno_t ext4_instance_get(service_id_t service_id, ext4_instance_t **inst)170 static errno_t ext4_instance_get(service_id_t service_id, ext4_instance_t **inst) 173 171 { 174 172 fibril_mutex_lock(&instance_list_mutex); … … 190 188 return EINVAL; 191 189 } 190 191 /* 192 * Ext4 libfs operations. 193 */ 192 194 193 195 /** Get root node of filesystem specified by service_id. … … 1322 1324 } 1323 1325 1324 /* Check for sparse file*/1326 /* Handle sparse or unallocated block */ 1325 1327 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; 1362 1333 } 1363 1364 flags = BLOCK_FLAGS_NOREAD;1365 inode_ref->dirty = true;1366 1334 } 1367 1335 … … 1404 1372 rc2 = ext4_node_put(fn); 1405 1373 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 */ 1388 static 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; 1406 1430 } 1407 1431
Note:
See TracChangeset
for help on using the changeset viewer.