diff options
Diffstat (limited to 'fs/ubifs/lprops.c')
-rw-r--r-- | fs/ubifs/lprops.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/fs/ubifs/lprops.c b/fs/ubifs/lprops.c index 4d4ca388889b..c7b25e2f7764 100644 --- a/fs/ubifs/lprops.c +++ b/fs/ubifs/lprops.c | |||
@@ -1035,7 +1035,8 @@ static int scan_check_cb(struct ubifs_info *c, | |||
1035 | struct ubifs_scan_leb *sleb; | 1035 | struct ubifs_scan_leb *sleb; |
1036 | struct ubifs_scan_node *snod; | 1036 | struct ubifs_scan_node *snod; |
1037 | struct ubifs_lp_stats *lst = &data->lst; | 1037 | struct ubifs_lp_stats *lst = &data->lst; |
1038 | int cat, lnum = lp->lnum, is_idx = 0, used = 0, free, dirty; | 1038 | int cat, lnum = lp->lnum, is_idx = 0, used = 0, free, dirty, ret; |
1039 | void *buf = NULL; | ||
1039 | 1040 | ||
1040 | cat = lp->flags & LPROPS_CAT_MASK; | 1041 | cat = lp->flags & LPROPS_CAT_MASK; |
1041 | if (cat != LPROPS_UNCAT) { | 1042 | if (cat != LPROPS_UNCAT) { |
@@ -1093,7 +1094,13 @@ static int scan_check_cb(struct ubifs_info *c, | |||
1093 | } | 1094 | } |
1094 | } | 1095 | } |
1095 | 1096 | ||
1096 | sleb = ubifs_scan(c, lnum, 0, c->dbg->buf, 0); | 1097 | buf = __vmalloc(c->leb_size, GFP_KERNEL | GFP_NOFS, PAGE_KERNEL); |
1098 | if (!buf) { | ||
1099 | ubifs_err("cannot allocate memory to scan LEB %d", lnum); | ||
1100 | goto out; | ||
1101 | } | ||
1102 | |||
1103 | sleb = ubifs_scan(c, lnum, 0, buf, 0); | ||
1097 | if (IS_ERR(sleb)) { | 1104 | if (IS_ERR(sleb)) { |
1098 | /* | 1105 | /* |
1099 | * After an unclean unmount, empty and freeable LEBs | 1106 | * After an unclean unmount, empty and freeable LEBs |
@@ -1105,7 +1112,8 @@ static int scan_check_cb(struct ubifs_info *c, | |||
1105 | lst->empty_lebs += 1; | 1112 | lst->empty_lebs += 1; |
1106 | lst->total_free += c->leb_size; | 1113 | lst->total_free += c->leb_size; |
1107 | lst->total_dark += ubifs_calc_dark(c, c->leb_size); | 1114 | lst->total_dark += ubifs_calc_dark(c, c->leb_size); |
1108 | return LPT_SCAN_CONTINUE; | 1115 | ret = LPT_SCAN_CONTINUE; |
1116 | goto exit; | ||
1109 | } | 1117 | } |
1110 | 1118 | ||
1111 | if (lp->free + lp->dirty == c->leb_size && | 1119 | if (lp->free + lp->dirty == c->leb_size && |
@@ -1115,10 +1123,12 @@ static int scan_check_cb(struct ubifs_info *c, | |||
1115 | lst->total_free += lp->free; | 1123 | lst->total_free += lp->free; |
1116 | lst->total_dirty += lp->dirty; | 1124 | lst->total_dirty += lp->dirty; |
1117 | lst->total_dark += ubifs_calc_dark(c, c->leb_size); | 1125 | lst->total_dark += ubifs_calc_dark(c, c->leb_size); |
1118 | return LPT_SCAN_CONTINUE; | 1126 | ret = LPT_SCAN_CONTINUE; |
1127 | goto exit; | ||
1119 | } | 1128 | } |
1120 | data->err = PTR_ERR(sleb); | 1129 | data->err = PTR_ERR(sleb); |
1121 | return LPT_SCAN_STOP; | 1130 | ret = LPT_SCAN_STOP; |
1131 | goto exit; | ||
1122 | } | 1132 | } |
1123 | 1133 | ||
1124 | is_idx = -1; | 1134 | is_idx = -1; |
@@ -1236,7 +1246,10 @@ static int scan_check_cb(struct ubifs_info *c, | |||
1236 | } | 1246 | } |
1237 | 1247 | ||
1238 | ubifs_scan_destroy(sleb); | 1248 | ubifs_scan_destroy(sleb); |
1239 | return LPT_SCAN_CONTINUE; | 1249 | ret = LPT_SCAN_CONTINUE; |
1250 | exit: | ||
1251 | vfree(buf); | ||
1252 | return ret; | ||
1240 | 1253 | ||
1241 | out_print: | 1254 | out_print: |
1242 | ubifs_err("bad accounting of LEB %d: free %d, dirty %d flags %#x, " | 1255 | ubifs_err("bad accounting of LEB %d: free %d, dirty %d flags %#x, " |
@@ -1246,6 +1259,7 @@ out_print: | |||
1246 | out_destroy: | 1259 | out_destroy: |
1247 | ubifs_scan_destroy(sleb); | 1260 | ubifs_scan_destroy(sleb); |
1248 | out: | 1261 | out: |
1262 | vfree(buf); | ||
1249 | data->err = -EINVAL; | 1263 | data->err = -EINVAL; |
1250 | return LPT_SCAN_STOP; | 1264 | return LPT_SCAN_STOP; |
1251 | } | 1265 | } |