aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSotirios-Efstathios Maneas <smaneas@cs.toronto.edu>2018-10-11 18:21:35 -0400
committerJaegeuk Kim <jaegeuk@kernel.org>2019-03-27 07:02:45 -0700
commita5805b87e345af0f017b81c45cc7a01501af6566 (patch)
tree078f28aa57cb4cf057c91ca0be7c242b6fcd92b9
parent503117796fc6701d08b7892529b1a011a975865d (diff)
downloadf2fs-tools-a5805b87e345af0f017b81c45cc7a01501af6566.tar.gz
fsck/mount: Gracefully terminate the mount procedure in case the program runs out of memory.
Added the necessary statements so that the mount procedure gracefully terminates in case the program runs out of memory. Signed-off-by: Sotirios-Efstathios Maneas <smaneas@cs.toronto.edu> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r--fsck/mount.c78
1 files changed, 58 insertions, 20 deletions
diff --git a/fsck/mount.c b/fsck/mount.c
index 29e0405..aa64e93 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -1323,20 +1323,26 @@ int build_sit_info(struct f2fs_sb_info *sbi)
unsigned int bitmap_size;
sit_i = malloc(sizeof(struct sit_info));
- if (!sit_i)
+ if (!sit_i) {
+ MSG(1, "\tError: Malloc failed for build_sit_info!\n");
return -ENOMEM;
+ }
SM_I(sbi)->sit_info = sit_i;
sit_i->sentries = calloc(TOTAL_SEGS(sbi) * sizeof(struct seg_entry), 1);
- if (!sit_i->sentries)
- return -ENOMEM;
+ if (!sit_i->sentries) {
+ MSG(1, "\tError: Calloc failed for build_sit_info!\n");
+ goto free_sit_info;
+ }
for (start = 0; start < TOTAL_SEGS(sbi); start++) {
sit_i->sentries[start].cur_valid_map
= calloc(SIT_VBLOCK_MAP_SIZE, 1);
- if (!sit_i->sentries[start].cur_valid_map)
- return -ENOMEM;
+ if (!sit_i->sentries[start].cur_valid_map) {
+ MSG(1, "\tError: Calloc failed for build_sit_info!!\n");
+ goto free_validity_maps;
+ }
}
sit_segs = get_sb(segment_count_sit) >> 1;
@@ -1344,8 +1350,10 @@ int build_sit_info(struct f2fs_sb_info *sbi)
src_bitmap = __bitmap_ptr(sbi, SIT_BITMAP);
dst_bitmap = malloc(bitmap_size);
- if (!dst_bitmap)
- return -ENOMEM;
+ if (!dst_bitmap) {
+ MSG(1, "\tError: Malloc failed for build_sit_info!!\n");
+ goto free_validity_maps;
+ }
memcpy(dst_bitmap, src_bitmap, bitmap_size);
@@ -1358,6 +1366,16 @@ int build_sit_info(struct f2fs_sb_info *sbi)
sit_i->sents_per_block = SIT_ENTRY_PER_BLOCK;
sit_i->elapsed_time = get_cp(elapsed_time);
return 0;
+
+free_validity_maps:
+ for (--start ; start >= 0; --start)
+ free(sit_i->sentries[start].cur_valid_map);
+ free(sit_i->sentries);
+
+free_sit_info:
+ free(sit_i);
+
+ return -ENOMEM;
}
void reset_curseg(struct f2fs_sb_info *sbi, int type)
@@ -1535,7 +1553,7 @@ static void restore_curseg_summaries(struct f2fs_sb_info *sbi)
read_normal_summaries(sbi, type);
}
-static void build_curseg(struct f2fs_sb_info *sbi)
+static int build_curseg(struct f2fs_sb_info *sbi)
{
struct f2fs_checkpoint *cp = F2FS_CKPT(sbi);
struct curseg_info *array;
@@ -1544,13 +1562,20 @@ static void build_curseg(struct f2fs_sb_info *sbi)
int i;
array = malloc(sizeof(*array) * NR_CURSEG_TYPE);
- ASSERT(array);
+ if (!array) {
+ MSG(1, "\tError: Malloc failed for build_curseg!\n");
+ return -ENOMEM;
+ }
SM_I(sbi)->curseg_array = array;
for (i = 0; i < NR_CURSEG_TYPE; i++) {
array[i].sum_blk = malloc(PAGE_CACHE_SIZE);
- ASSERT(array[i].sum_blk);
+ if (!array[i].sum_blk) {
+ MSG(1, "\tError: Malloc failed for build_curseg!!\n");
+ goto seg_cleanup;
+ }
+
if (i <= CURSEG_COLD_DATA) {
blk_off = get_cp(cur_data_blkoff[i]);
segno = get_cp(cur_data_segno[i]);
@@ -1569,6 +1594,14 @@ static void build_curseg(struct f2fs_sb_info *sbi)
array[i].alloc_type = cp->alloc_type[i];
}
restore_curseg_summaries(sbi);
+ return 0;
+
+seg_cleanup:
+ for(--i ; i >=0; --i)
+ free(array[i].sum_blk);
+ free(array);
+
+ return -ENOMEM;
}
static inline void check_seg_range(struct f2fs_sb_info *sbi, unsigned int segno)
@@ -1854,7 +1887,7 @@ void get_node_info(struct f2fs_sb_info *sbi, nid_t nid, struct node_info *ni)
node_info_from_raw_nat(ni, &raw_nat);
}
-void build_sit_entries(struct f2fs_sb_info *sbi)
+static int build_sit_entries(struct f2fs_sb_info *sbi)
{
struct sit_info *sit_i = SIT_I(sbi);
struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_COLD_DATA);
@@ -1865,7 +1898,11 @@ void build_sit_entries(struct f2fs_sb_info *sbi)
unsigned int i, segno;
sit_blk = calloc(BLOCK_SZ, 1);
- ASSERT(sit_blk);
+ if (!sit_blk) {
+ MSG(1, "\tError: Calloc failed for build_sit_entries!\n");
+ return -ENOMEM;
+ }
+
for (segno = 0; segno < TOTAL_SEGS(sbi); segno++) {
se = &sit_i->sentries[segno];
@@ -1885,18 +1922,20 @@ void build_sit_entries(struct f2fs_sb_info *sbi)
check_block_count(sbi, segno, &sit);
seg_info_from_raw_sit(se, &sit);
}
-
+ return 0;
}
-int build_segment_manager(struct f2fs_sb_info *sbi)
+static int build_segment_manager(struct f2fs_sb_info *sbi)
{
struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
struct f2fs_checkpoint *cp = F2FS_CKPT(sbi);
struct f2fs_sm_info *sm_info;
sm_info = malloc(sizeof(struct f2fs_sm_info));
- if (!sm_info)
+ if (!sm_info) {
+ MSG(1, "\tError: Malloc failed for build_segment_manager!\n");
return -ENOMEM;
+ }
/* init sm info */
sbi->sm_info = sm_info;
@@ -1908,11 +1947,10 @@ int build_segment_manager(struct f2fs_sb_info *sbi)
sm_info->main_segments = get_sb(segment_count_main);
sm_info->ssa_blkaddr = get_sb(ssa_blkaddr);
- build_sit_info(sbi);
-
- build_curseg(sbi);
-
- build_sit_entries(sbi);
+ if (build_sit_info(sbi) || build_curseg(sbi) || build_sit_entries(sbi)) {
+ free(sm_info);
+ return -ENOMEM;
+ }
return 0;
}