Skip to content

Commit d91d076

Browse files
committed
ext4: write: fix block leak
1 parent f62c901 commit d91d076

File tree

1 file changed

+11
-3
lines changed

1 file changed

+11
-3
lines changed

uspace/lib/ext4/src/ops.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ static errno_t ext4_read_file(ipc_call_t *, aoff64_t, size_t, ext4_instance_t *,
6464
static bool ext4_is_dots(const uint8_t *, size_t);
6565
static errno_t ext4_instance_get(service_id_t, ext4_instance_t **);
6666
static errno_t handle_sparse_or_unallocated_fblock(ext4_filesystem_t *,
67-
ext4_inode_ref_t *, uint32_t, uint32_t, uint32_t *, int *);
67+
ext4_inode_ref_t *, uint32_t, uint32_t, uint32_t *, int *, bool *);
6868

6969
/* Forward declarations of ext4 libfs operations. */
7070

@@ -1287,6 +1287,8 @@ static errno_t ext4_write(service_id_t service_id, fs_index_t index, aoff64_t po
12871287
{
12881288
fs_node_t *fn;
12891289
errno_t rc2;
1290+
bool fblock_allocated = false;
1291+
12901292
errno_t rc = ext4_node_get(&fn, service_id, index);
12911293
if (rc != EOK)
12921294
return rc;
@@ -1326,7 +1328,7 @@ static errno_t ext4_write(service_id_t service_id, fs_index_t index, aoff64_t po
13261328
/* Handle sparse or unallocated block */
13271329
if (fblock == 0) {
13281330
rc = handle_sparse_or_unallocated_fblock(fs, inode_ref,
1329-
block_size, iblock, &fblock, &flags);
1331+
block_size, iblock, &fblock, &flags, &fblock_allocated);
13301332
if (rc != EOK) {
13311333
async_answer_0(&call, rc);
13321334
goto exit;
@@ -1369,6 +1371,9 @@ static errno_t ext4_write(service_id_t service_id, fs_index_t index, aoff64_t po
13691371
*wbytes = bytes;
13701372

13711373
exit:
1374+
if (rc != EOK && fblock_allocated)
1375+
ext4_balloc_free_block(inode_ref, fblock);
1376+
13721377
rc2 = ext4_node_put(fn);
13731378
return rc == EOK ? rc2 : rc;
13741379
}
@@ -1381,13 +1386,14 @@ static errno_t ext4_write(service_id_t service_id, fs_index_t index, aoff64_t po
13811386
* @param iblock Logical block
13821387
* @param fblock Place to store allocated block address
13831388
* @param flags BLOCK_FLAGS to update
1389+
* @param allocated Place to store whether new block was allocated
13841390
*
13851391
* @return Error code
13861392
*
13871393
*/
13881394
static errno_t handle_sparse_or_unallocated_fblock(ext4_filesystem_t *fs,
13891395
ext4_inode_ref_t *inode_ref, uint32_t block_size, uint32_t iblock,
1390-
uint32_t *fblock, int *flags)
1396+
uint32_t *fblock, int *flags, bool *allocated)
13911397
{
13921398
errno_t rc;
13931399

@@ -1421,6 +1427,8 @@ static errno_t handle_sparse_or_unallocated_fblock(ext4_filesystem_t *fs,
14211427
ext4_balloc_free_block(inode_ref, *fblock);
14221428
return rc;
14231429
}
1430+
1431+
*allocated = true;
14241432
}
14251433

14261434
*flags = BLOCK_FLAGS_NOREAD;

0 commit comments

Comments
 (0)