dect
/
linux-2.6
Archived
13
0
Fork 0

UBIFS: clean up LEB recovery function

This patch cleans up 'ubifs_recover_leb()' function and makes it more readable.
Move things which are done only once out of the loop and kill unneeded 'switch'
statement.

Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
This commit is contained in:
Artem Bityutskiy 2011-05-16 13:41:55 +03:00
parent 9d510db423
commit 6179920695
1 changed files with 28 additions and 56 deletions

View File

@ -609,8 +609,8 @@ static int drop_incomplete_group(struct ubifs_scan_leb *sleb, int *offs)
struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
int offs, void *sbuf, int grouped)
{
int err, len = c->leb_size - offs, need_clean = 0, quiet = 1;
int empty_chkd = 0, start = offs;
int ret = 0, err, len = c->leb_size - offs, need_clean = 0;
int start = offs;
struct ubifs_scan_leb *sleb;
void *buf = sbuf + offs;
@ -624,8 +624,6 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
need_clean = 1;
while (len >= 8) {
int ret;
dbg_scan("look at LEB %d:%d (%d bytes left)",
lnum, offs, len);
@ -635,8 +633,7 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
* Scan quietly until there is an error from which we cannot
* recover
*/
ret = ubifs_scan_a_node(c, buf, len, lnum, offs, quiet);
ret = ubifs_scan_a_node(c, buf, len, lnum, offs, 0);
if (ret == SCANNED_A_NODE) {
/* A valid node, and not a padding node */
struct ubifs_ch *ch = buf;
@ -649,66 +646,37 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
offs += node_len;
buf += node_len;
len -= node_len;
continue;
}
if (ret > 0) {
} else if (ret > 0) {
/* Padding bytes or a valid padding node */
offs += ret;
buf += ret;
len -= ret;
continue;
}
if (ret == SCANNED_EMPTY_SPACE) {
if (!is_empty(buf, len)) {
if (!is_last_write(c, buf, offs))
break;
clean_buf(c, &buf, lnum, &offs, &len);
need_clean = 1;
}
empty_chkd = 1;
} else if (ret == SCANNED_EMPTY_SPACE ||
ret == SCANNED_GARBAGE ||
ret == SCANNED_A_BAD_PAD_NODE ||
ret == SCANNED_A_CORRUPT_NODE) {
dbg_rcvry("found corruption - %d", ret);
break;
}
if (ret == SCANNED_GARBAGE || ret == SCANNED_A_BAD_PAD_NODE)
if (is_last_write(c, buf, offs)) {
clean_buf(c, &buf, lnum, &offs, &len);
need_clean = 1;
empty_chkd = 1;
break;
}
if (ret == SCANNED_A_CORRUPT_NODE)
if (no_more_nodes(c, buf, len, lnum, offs)) {
clean_buf(c, &buf, lnum, &offs, &len);
need_clean = 1;
empty_chkd = 1;
break;
}
if (quiet) {
/* Redo the last scan but noisily */
quiet = 0;
continue;
}
switch (ret) {
case SCANNED_GARBAGE:
dbg_err("garbage");
goto corrupted;
case SCANNED_A_CORRUPT_NODE:
case SCANNED_A_BAD_PAD_NODE:
dbg_err("bad node");
goto corrupted;
default:
dbg_err("unknown");
} else {
dbg_err("unexpected return value %d", ret);
err = -EINVAL;
goto error;
}
}
if (!empty_chkd && !is_empty(buf, len)) {
if (ret == SCANNED_GARBAGE || ret == SCANNED_A_BAD_PAD_NODE) {
if (is_last_write(c, buf, offs)) {
clean_buf(c, &buf, lnum, &offs, &len);
need_clean = 1;
} else
goto corrupted_rescan;
} else if (ret == SCANNED_A_CORRUPT_NODE) {
if (no_more_nodes(c, buf, len, lnum, offs)) {
clean_buf(c, &buf, lnum, &offs, &len);
need_clean = 1;
} else
goto corrupted_rescan;
} else if (!is_empty(buf, len)) {
if (is_last_write(c, buf, offs)) {
clean_buf(c, &buf, lnum, &offs, &len);
need_clean = 1;
@ -751,6 +719,10 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
return sleb;
corrupted_rescan:
/* Re-scan the corrupted data with verbose messages */
dbg_err("corruptio %d", ret);
ubifs_scan_a_node(c, buf, len, lnum, offs, 1);
corrupted:
ubifs_scanned_corruption(c, lnum, offs, buf);
err = -EUCLEAN;