Changeset eb94d84 in mainline


Ignore:
Timestamp:
2015-04-05T15:56:38Z (9 years ago)
Author:
Maurizio Lombardi <m.lombardi85@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
749fe15b
Parents:
6efd162
Message:

libext4: fix memory leak, release the superblock structure if the mount operation fails

Location:
uspace/lib/ext4
Files:
3 edited

Legend:

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

    r6efd162 reb94d84  
    5353    enum cache_mode cmode)
    5454{
     55        ext4_superblock_t *temp_superblock = NULL;
     56
    5557        fs->device = service_id;
    56        
     58
    5759        /* Initialize block library (4096 is size of communication channel) */
    5860        int rc = block_init(EXCHANGE_SERIALIZE, fs->device, 4096);
    5961        if (rc != EOK)
    60                 return rc;
    61        
     62                goto err;
     63
    6264        /* Read superblock from device to memory */
    63         ext4_superblock_t *temp_superblock;
    6465        rc = ext4_superblock_read_direct(fs->device, &temp_superblock);
    65         if (rc != EOK) {
    66                 block_fini(fs->device);
    67                 return rc;
    68         }
    69        
     66        if (rc != EOK)
     67                goto err_1;
     68
    7069        /* Read block size from superblock and check */
    7170        uint32_t block_size = ext4_superblock_get_block_size(temp_superblock);
    7271        if (block_size > EXT4_MAX_BLOCK_SIZE) {
    73                 block_fini(fs->device);
    74                 return ENOTSUP;
    75         }
    76        
     72                rc = ENOTSUP;
     73                goto err_1;
     74        }
     75
    7776        /* Initialize block caching by libblock */
    7877        rc = block_cache_init(service_id, block_size, 0, cmode);
    79         if (rc != EOK) {
    80                 block_fini(fs->device);
    81                 return rc;
    82         }
    83        
     78        if (rc != EOK)
     79                goto err_1;
     80
    8481        /* Compute limits for indirect block levels */
    8582        uint32_t block_ids_per_block = block_size / sizeof(uint32_t);
     
    9289                    fs->inode_blocks_per_level[i];
    9390        }
    94        
     91
    9592        /* Return loaded superblock */
    9693        fs->superblock = temp_superblock;
    97        
     94
    9895        uint16_t state = ext4_superblock_get_state(fs->superblock);
    99        
     96
    10097        if (((state & EXT4_SUPERBLOCK_STATE_VALID_FS) !=
    10198            EXT4_SUPERBLOCK_STATE_VALID_FS) ||
    10299            ((state & EXT4_SUPERBLOCK_STATE_ERROR_FS) ==
    103100            EXT4_SUPERBLOCK_STATE_ERROR_FS)) {
    104                 block_cache_fini(fs->device);
    105                 block_fini(fs->device);
    106                 return ENOTSUP;
    107         }
    108        
     101                rc = ENOTSUP;
     102                goto err_2;
     103        }
     104
    109105        /* Mark system as mounted */
    110106        ext4_superblock_set_state(fs->superblock, EXT4_SUPERBLOCK_STATE_ERROR_FS);
    111107        rc = ext4_superblock_write_direct(fs->device, fs->superblock);
    112         if (rc != EOK) {
    113                 block_cache_fini(fs->device);
    114                 block_fini(fs->device);
    115                 return rc;
    116         }
    117        
     108        if (rc != EOK)
     109                goto err_2;
     110
    118111        uint16_t mnt_count = ext4_superblock_get_mount_count(fs->superblock);
    119112        ext4_superblock_set_mount_count(fs->superblock, mnt_count + 1);
    120        
     113
    121114        return EOK;
     115
     116err_2:
     117        block_cache_fini(fs->device);
     118err_1:
     119        block_fini(fs->device);
     120err:
     121        if (temp_superblock)
     122                ext4_superblock_release(temp_superblock);
     123        return rc;
    122124}
    123125
  • uspace/lib/ext4/libext4_superblock.c

    r6efd162 reb94d84  
    11781178}
    11791179
     1180/** Release the memory allocated for the superblock structure
     1181 *
     1182 * @param sb         Superblock to be freed
     1183 *
     1184 */
     1185void ext4_superblock_release(ext4_superblock_t *sb)
     1186{
     1187        free(sb);
     1188}
     1189
    11801190/** Check sanity of the superblock.
    11811191 *
  • uspace/lib/ext4/libext4_superblock.h

    r6efd162 reb94d84  
    145145extern int ext4_superblock_read_direct(service_id_t, ext4_superblock_t **);
    146146extern int ext4_superblock_write_direct(service_id_t, ext4_superblock_t *);
     147extern void ext4_superblock_release(ext4_superblock_t *);
    147148extern int ext4_superblock_check_sanity(ext4_superblock_t *);
    148149
Note: See TracChangeset for help on using the changeset viewer.