*
* This function does a scan of a LEB, but caters for errors that might have
* been caused by the unclean unmount from which we are attempting to recover.
- *
- * This function returns %0 on success and a negative error code on failure.
+ * Returns %0 in case of success, %-EUCLEAN if an unrecoverable corruption is
+ * found, and a negative error code in case of failure.
*/
struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
int offs, void *sbuf, int grouped)
goto corrupted;
default:
dbg_err("unknown");
- goto corrupted;
+ err = -EINVAL;
+ goto error;
}
}
dbg_mnt("replay log LEB %d:%d", lnum, offs);
sleb = ubifs_scan(c, lnum, offs, sbuf);
- if (IS_ERR(sleb)) {
- if (c->need_recovery)
- sleb = ubifs_recover_log_leb(c, lnum, offs, sbuf);
+ if (IS_ERR(sleb) ) {
+ if (PTR_ERR(sleb) != -EUCLEAN || !c->need_recovery)
+ return PTR_ERR(sleb);
+ sleb = ubifs_recover_log_leb(c, lnum, offs, sbuf);
if (IS_ERR(sleb))
return PTR_ERR(sleb);
}
* @sbuf: scan buffer (must be c->leb_size)
*
* This function scans LEB number @lnum and returns complete information about
- * its contents. Returns an error code in case of failure.
+ * its contents. Returns the scaned information in case of success and,
+ * %-EUCLEAN if the LEB neads recovery, and other negative error codes in case
+ * of failure.
*/
struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum,
int offs, void *sbuf)
cond_resched();
ret = ubifs_scan_a_node(c, buf, len, lnum, offs, 0);
-
if (ret > 0) {
/* Padding bytes or a valid padding node */
offs += ret;
goto corrupted;
default:
dbg_err("unknown");
- goto corrupted;
+ err = -EINVAL;
+ goto error;
}
err = ubifs_add_snod(c, sleb, buf, offs);
len -= node_len;
}
- if (offs % c->min_io_size)
- goto corrupted;
+ if (offs % c->min_io_size) {
+ ubifs_err("empty space starts at non-aligned offset %d", offs);
+ goto corrupted;;
+ }
ubifs_end_scan(c, sleb, lnum, offs);