Merge pull request #80 from FreddieChopin/fix-memory-leaks

Fix memory leaks
This commit is contained in:
Christopher Haster 2018-07-19 17:30:48 -05:00 committed by GitHub
commit 84adead98b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

76
lfs.c
View File

@ -2016,6 +2016,21 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
/// Filesystem operations /// /// Filesystem operations ///
static void lfs_deinit(lfs_t *lfs) {
// free allocated memory
if (!lfs->cfg->read_buffer) {
lfs_free(lfs->rcache.buffer);
}
if (!lfs->cfg->prog_buffer) {
lfs_free(lfs->pcache.buffer);
}
if (!lfs->cfg->lookahead_buffer) {
lfs_free(lfs->free.buffer);
}
}
static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) { static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
lfs->cfg = cfg; lfs->cfg = cfg;
@ -2025,7 +2040,7 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
} else { } else {
lfs->rcache.buffer = lfs_malloc(lfs->cfg->read_size); lfs->rcache.buffer = lfs_malloc(lfs->cfg->read_size);
if (!lfs->rcache.buffer) { if (!lfs->rcache.buffer) {
return LFS_ERR_NOMEM; goto cleanup;
} }
} }
@ -2035,7 +2050,7 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
} else { } else {
lfs->pcache.buffer = lfs_malloc(lfs->cfg->prog_size); lfs->pcache.buffer = lfs_malloc(lfs->cfg->prog_size);
if (!lfs->pcache.buffer) { if (!lfs->pcache.buffer) {
return LFS_ERR_NOMEM; goto cleanup;
} }
} }
@ -2051,7 +2066,7 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
} else { } else {
lfs->free.buffer = lfs_malloc(lfs->cfg->lookahead/8); lfs->free.buffer = lfs_malloc(lfs->cfg->lookahead/8);
if (!lfs->free.buffer) { if (!lfs->free.buffer) {
return LFS_ERR_NOMEM; goto cleanup;
} }
} }
@ -2071,23 +2086,10 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
lfs->deorphaned = false; lfs->deorphaned = false;
return 0; return 0;
}
static int lfs_deinit(lfs_t *lfs) { cleanup:
// free allocated memory lfs_deinit(lfs);
if (!lfs->cfg->read_buffer) { return LFS_ERR_NOMEM;
lfs_free(lfs->rcache.buffer);
}
if (!lfs->cfg->prog_buffer) {
lfs_free(lfs->pcache.buffer);
}
if (!lfs->cfg->lookahead_buffer) {
lfs_free(lfs->free.buffer);
}
return 0;
} }
int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) { int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
@ -2107,19 +2109,19 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
lfs_dir_t superdir; lfs_dir_t superdir;
err = lfs_dir_alloc(lfs, &superdir); err = lfs_dir_alloc(lfs, &superdir);
if (err) { if (err) {
return err; goto cleanup;
} }
// write root directory // write root directory
lfs_dir_t root; lfs_dir_t root;
err = lfs_dir_alloc(lfs, &root); err = lfs_dir_alloc(lfs, &root);
if (err) { if (err) {
return err; goto cleanup;
} }
err = lfs_dir_commit(lfs, &root, NULL, 0); err = lfs_dir_commit(lfs, &root, NULL, 0);
if (err) { if (err) {
return err; goto cleanup;
} }
lfs->root[0] = root.pair[0]; lfs->root[0] = root.pair[0];
@ -2150,24 +2152,28 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
&superblock.d, sizeof(superblock.d)} &superblock.d, sizeof(superblock.d)}
}, 1); }, 1);
if (err && err != LFS_ERR_CORRUPT) { if (err && err != LFS_ERR_CORRUPT) {
return err; goto cleanup;
} }
valid = valid || !err; valid = valid || !err;
} }
if (!valid) { if (!valid) {
return LFS_ERR_CORRUPT; err = LFS_ERR_CORRUPT;
goto cleanup;
} }
// sanity check that fetch works // sanity check that fetch works
err = lfs_dir_fetch(lfs, &superdir, (const lfs_block_t[2]){0, 1}); err = lfs_dir_fetch(lfs, &superdir, (const lfs_block_t[2]){0, 1});
if (err) { if (err) {
return err; goto cleanup;
} }
lfs_alloc_ack(lfs); lfs_alloc_ack(lfs);
return lfs_deinit(lfs);
cleanup:
lfs_deinit(lfs);
return err;
} }
int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) { int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
@ -2187,7 +2193,7 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
lfs_superblock_t superblock; lfs_superblock_t superblock;
err = lfs_dir_fetch(lfs, &dir, (const lfs_block_t[2]){0, 1}); err = lfs_dir_fetch(lfs, &dir, (const lfs_block_t[2]){0, 1});
if (err && err != LFS_ERR_CORRUPT) { if (err && err != LFS_ERR_CORRUPT) {
return err; goto cleanup;
} }
if (!err) { if (!err) {
@ -2195,7 +2201,7 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
&superblock.d, sizeof(superblock.d)); &superblock.d, sizeof(superblock.d));
lfs_superblock_fromle32(&superblock.d); lfs_superblock_fromle32(&superblock.d);
if (err) { if (err) {
return err; goto cleanup;
} }
lfs->root[0] = superblock.d.root[0]; lfs->root[0] = superblock.d.root[0];
@ -2204,7 +2210,8 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
if (err || memcmp(superblock.d.magic, "littlefs", 8) != 0) { if (err || memcmp(superblock.d.magic, "littlefs", 8) != 0) {
LFS_ERROR("Invalid superblock at %d %d", 0, 1); LFS_ERROR("Invalid superblock at %d %d", 0, 1);
return LFS_ERR_CORRUPT; err = LFS_ERR_CORRUPT;
goto cleanup;
} }
uint16_t major_version = (0xffff & (superblock.d.version >> 16)); uint16_t major_version = (0xffff & (superblock.d.version >> 16));
@ -2212,14 +2219,21 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
if ((major_version != LFS_DISK_VERSION_MAJOR || if ((major_version != LFS_DISK_VERSION_MAJOR ||
minor_version > LFS_DISK_VERSION_MINOR)) { minor_version > LFS_DISK_VERSION_MINOR)) {
LFS_ERROR("Invalid version %d.%d", major_version, minor_version); LFS_ERROR("Invalid version %d.%d", major_version, minor_version);
return LFS_ERR_INVAL; err = LFS_ERR_INVAL;
goto cleanup;
} }
return 0; return 0;
cleanup:
lfs_deinit(lfs);
return err;
} }
int lfs_unmount(lfs_t *lfs) { int lfs_unmount(lfs_t *lfs) {
return lfs_deinit(lfs); lfs_deinit(lfs);
return 0;
} }