diff options
Diffstat (limited to 'ubifs-utils/libubifs')
| -rw-r--r-- | ubifs-utils/libubifs/io.c | 4 | ||||
| -rw-r--r-- | ubifs-utils/libubifs/lpt.c | 66 | ||||
| -rw-r--r-- | ubifs-utils/libubifs/lpt_commit.c | 5 | ||||
| -rw-r--r-- | ubifs-utils/libubifs/master.c | 18 | ||||
| -rw-r--r-- | ubifs-utils/libubifs/orphan.c | 4 | ||||
| -rw-r--r-- | ubifs-utils/libubifs/recovery.c | 4 | ||||
| -rw-r--r-- | ubifs-utils/libubifs/replay.c | 1 | ||||
| -rw-r--r-- | ubifs-utils/libubifs/sb.c | 2 | ||||
| -rw-r--r-- | ubifs-utils/libubifs/scan.c | 1 | ||||
| -rw-r--r-- | ubifs-utils/libubifs/tnc_misc.c | 4 | ||||
| -rw-r--r-- | ubifs-utils/libubifs/ubifs.h | 98 | 
11 files changed, 187 insertions, 20 deletions
| diff --git a/ubifs-utils/libubifs/io.c b/ubifs-utils/libubifs/io.c index 6f17017..b6fb331 100644 --- a/ubifs-utils/libubifs/io.c +++ b/ubifs-utils/libubifs/io.c @@ -964,6 +964,7 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len,  	err = ubifs_check_node(c, buf, len, lnum, offs, 0, 0);  	if (err) { +		set_failure_reason_callback(c, FR_DATA_CORRUPTED);  		ubifs_err(c, "expected node type %d", type);  		return err;  	} @@ -977,6 +978,7 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len,  	return 0;  out: +	set_failure_reason_callback(c, FR_DATA_CORRUPTED);  	ubifs_err(c, "bad node at LEB %d:%d", lnum, offs);  	ubifs_dump_node(c, buf, len);  	dump_stack(); @@ -1020,6 +1022,7 @@ int ubifs_read_node(const struct ubifs_info *c, void *buf, int type, int len,  	err = ubifs_check_node(c, buf, len, lnum, offs, 0, 0);  	if (err) { +		set_failure_reason_callback(c, FR_DATA_CORRUPTED);  		ubifs_err(c, "expected node type %d", type);  		return err;  	} @@ -1033,6 +1036,7 @@ int ubifs_read_node(const struct ubifs_info *c, void *buf, int type, int len,  	return 0;  out: +	set_failure_reason_callback(c, FR_DATA_CORRUPTED);  	ubifs_err(c, "bad node at LEB %d:%d, LEB mapping status %d", lnum,  		  offs, ubi_is_mapped(c->dev_fd, lnum));  	ubifs_dump_node(c, buf, len); diff --git a/ubifs-utils/libubifs/lpt.c b/ubifs-utils/libubifs/lpt.c index 92b3fec..c0df7c7 100644 --- a/ubifs-utils/libubifs/lpt.c +++ b/ubifs-utils/libubifs/lpt.c @@ -983,6 +983,7 @@ static int check_lpt_crc(const struct ubifs_info *c, void *buf, int len)  	calc_crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,  			 len - UBIFS_LPT_CRC_BYTES);  	if (crc != calc_crc) { +		set_failure_reason_callback(c, FR_LPT_CORRUPTED);  		ubifs_err(c, "invalid crc in LPT node: crc %hx calc %hx",  			  crc, calc_crc);  		dump_stack(); @@ -1007,6 +1008,7 @@ static int check_lpt_type(const struct ubifs_info *c, uint8_t **addr,  	node_type = ubifs_unpack_bits(c, addr, pos, UBIFS_LPT_TYPE_BITS);  	if (node_type != type) { +		set_failure_reason_callback(c, FR_LPT_CORRUPTED);  		ubifs_err(c, "invalid type (%d) in LPT node type %d",  			  node_type, type);  		dump_stack(); @@ -1106,8 +1108,10 @@ static int unpack_ltab(const struct ubifs_info *c, void *buf)  		int dirty = ubifs_unpack_bits(c, &addr, &pos, c->lpt_spc_bits);  		if (free < 0 || free > c->leb_size || dirty < 0 || -		    dirty > c->leb_size || free + dirty > c->leb_size) +		    dirty > c->leb_size || free + dirty > c->leb_size) { +			set_failure_reason_callback(c, FR_LPT_CORRUPTED);  			return -EINVAL; +		}  		c->ltab[i].free = free;  		c->ltab[i].dirty = dirty; @@ -1136,8 +1140,10 @@ static int unpack_lsave(const struct ubifs_info *c, void *buf)  	for (i = 0; i < c->lsave_cnt; i++) {  		int lnum = ubifs_unpack_bits(c, &addr, &pos, c->lnum_bits); -		if (lnum < c->main_first || lnum >= c->leb_cnt) +		if (lnum < c->main_first || lnum >= c->leb_cnt) { +			set_failure_reason_callback(c, FR_LPT_CORRUPTED);  			return -EINVAL; +		}  		c->lsave[i] = lnum;  	}  	err = check_lpt_crc(c, buf, c->lsave_sz); @@ -1162,11 +1168,11 @@ static int validate_nnode(const struct ubifs_info *c, struct ubifs_nnode *nnode,  		int num = calc_nnode_num_from_parent(c, parent, iip);  		if (nnode->num != num) -			return -EINVAL; +			goto out_invalid;  	}  	lvl = parent ? parent->level - 1 : c->lpt_hght;  	if (lvl < 1) -		return -EINVAL; +		goto out_invalid;  	if (lvl == 1)  		max_offs = c->leb_size - c->pnode_sz;  	else @@ -1177,15 +1183,19 @@ static int validate_nnode(const struct ubifs_info *c, struct ubifs_nnode *nnode,  		if (lnum == 0) {  			if (offs != 0) -				return -EINVAL; +				goto out_invalid;  			continue;  		}  		if (lnum < c->lpt_first || lnum > c->lpt_last) -			return -EINVAL; +			goto out_invalid;  		if (offs < 0 || offs > max_offs) -			return -EINVAL; +			goto out_invalid;  	}  	return 0; + +out_invalid: +	set_failure_reason_callback(c, FR_LPT_CORRUPTED); +	return -EINVAL;  }  /** @@ -1206,7 +1216,7 @@ static int validate_pnode(const struct ubifs_info *c, struct ubifs_pnode *pnode,  		int num = calc_pnode_num_from_parent(c, parent, iip);  		if (pnode->num != num) -			return -EINVAL; +			goto out_invalid;  	}  	for (i = 0; i < UBIFS_LPT_FANOUT; i++) {  		int free = pnode->lprops[i].free; @@ -1214,13 +1224,17 @@ static int validate_pnode(const struct ubifs_info *c, struct ubifs_pnode *pnode,  		if (free < 0 || free > c->leb_size || free % c->min_io_size ||  		    (free & 7)) -			return -EINVAL; +			goto out_invalid;  		if (dirty < 0 || dirty > c->leb_size || (dirty & 7)) -			return -EINVAL; +			goto out_invalid;  		if (dirty + free > c->leb_size) -			return -EINVAL; +			goto out_invalid;  	}  	return 0; + +out_invalid: +	set_failure_reason_callback(c, FR_LPT_CORRUPTED); +	return -EINVAL;  }  /** @@ -1283,8 +1297,11 @@ int ubifs_read_nnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip)  			nnode->num = calc_nnode_num_from_parent(c, parent, iip);  	} else {  		err = ubifs_leb_read(c, lnum, buf, offs, c->nnode_sz, 1); -		if (err) +		if (err) { +			if (err == -EBADMSG) +				set_failure_reason_callback(c, FR_LPT_CORRUPTED);  			goto out; +		}  		err = ubifs_unpack_nnode(c, buf, nnode);  		if (err)  			goto out; @@ -1352,8 +1369,11 @@ static int read_pnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip)  		}  	} else {  		err = ubifs_leb_read(c, lnum, buf, offs, c->pnode_sz, 1); -		if (err) +		if (err) { +			if (err == -EBADMSG) +				set_failure_reason_callback(c, FR_LPT_CORRUPTED);  			goto out; +		}  		err = unpack_pnode(c, buf, pnode);  		if (err)  			goto out; @@ -1394,8 +1414,11 @@ static int read_ltab(struct ubifs_info *c)  	if (!buf)  		return -ENOMEM;  	err = ubifs_leb_read(c, c->ltab_lnum, buf, c->ltab_offs, c->ltab_sz, 1); -	if (err) +	if (err) { +		if (err == -EBADMSG) +			set_failure_reason_callback(c, FR_LPT_CORRUPTED);  		goto out; +	}  	err = unpack_ltab(c, buf);  out:  	vfree(buf); @@ -1418,8 +1441,11 @@ static int read_lsave(struct ubifs_info *c)  		return -ENOMEM;  	err = ubifs_leb_read(c, c->lsave_lnum, buf, c->lsave_offs,  			     c->lsave_sz, 1); -	if (err) +	if (err) { +		if (err == -EBADMSG) +			set_failure_reason_callback(c, FR_LPT_CORRUPTED);  		goto out; +	}  	err = unpack_lsave(c, buf);  	if (err)  		goto out; @@ -2031,8 +2057,11 @@ static struct ubifs_nnode *scan_get_nnode(struct ubifs_info *c,  	} else {  		err = ubifs_leb_read(c, branch->lnum, buf, branch->offs,  				     c->nnode_sz, 1); -		if (err) +		if (err) { +			if (err == -EBADMSG) +				set_failure_reason_callback(c, FR_LPT_CORRUPTED);  			return ERR_PTR(err); +		}  		err = ubifs_unpack_nnode(c, buf, nnode);  		if (err)  			return ERR_PTR(err); @@ -2100,8 +2129,11 @@ static struct ubifs_pnode *scan_get_pnode(struct ubifs_info *c,  		ubifs_assert(c, branch->offs >= 0 && branch->offs < c->leb_size);  		err = ubifs_leb_read(c, branch->lnum, buf, branch->offs,  				     c->pnode_sz, 1); -		if (err) +		if (err) { +			if (err == -EBADMSG) +				set_failure_reason_callback(c, FR_LPT_CORRUPTED);  			return ERR_PTR(err); +		}  		err = unpack_pnode(c, buf, pnode);  		if (err)  			return ERR_PTR(err); diff --git a/ubifs-utils/libubifs/lpt_commit.c b/ubifs-utils/libubifs/lpt_commit.c index b00f75f..43eb7a6 100644 --- a/ubifs-utils/libubifs/lpt_commit.c +++ b/ubifs-utils/libubifs/lpt_commit.c @@ -1607,8 +1607,11 @@ static int dbg_check_ltab_lnum(struct ubifs_info *c, int lnum)  	dbg_lp("LEB %d", lnum);  	err = ubifs_leb_read(c, lnum, buf, 0, c->leb_size, 1); -	if (err) +	if (err) { +		if (err == -EBADMSG) +			set_failure_reason_callback(c, FR_LPT_CORRUPTED);  		goto out; +	}  	while (1) {  		if (!is_a_node(c, p, len)) { diff --git a/ubifs-utils/libubifs/master.c b/ubifs-utils/libubifs/master.c index cce1a41..61ff4ce 100644 --- a/ubifs-utils/libubifs/master.c +++ b/ubifs-utils/libubifs/master.c @@ -146,10 +146,12 @@ static int scan_for_master(struct ubifs_info *c)  	return 0;  out: +	set_failure_reason_callback(c, FR_DATA_CORRUPTED);  	ubifs_scan_destroy(sleb);  	return -EUCLEAN;  out_dump: +	set_failure_reason_callback(c, FR_DATA_CORRUPTED);  	ubifs_err(c, "unexpected node type %d master LEB %d:%d",  		  snod->type, lnum, snod->offs);  	ubifs_scan_destroy(sleb); @@ -165,6 +167,7 @@ out_dump:   */  static int validate_master(const struct ubifs_info *c)  { +	unsigned int reason = FR_DATA_CORRUPTED;  	long long main_sz;  	int err; @@ -254,39 +257,46 @@ static int validate_master(const struct ubifs_info *c)  	}  	if (c->lst.empty_lebs < 0 || c->lst.empty_lebs > c->main_lebs - 2) { +		reason = FR_LPT_INCORRECT;  		err = 15;  		goto out;  	}  	if (c->lst.idx_lebs < 0 || c->lst.idx_lebs > c->main_lebs - 1) { +		reason = FR_LPT_INCORRECT;  		err = 16;  		goto out;  	}  	if (c->lst.total_free < 0 || c->lst.total_free > main_sz ||  	    c->lst.total_free & 7) { +		reason = FR_LPT_INCORRECT;  		err = 17;  		goto out;  	}  	if (c->lst.total_dirty < 0 || (c->lst.total_dirty & 7)) { +		reason = FR_LPT_INCORRECT;  		err = 18;  		goto out;  	}  	if (c->lst.total_used < 0 || (c->lst.total_used & 7)) { +		reason = FR_LPT_INCORRECT;  		err = 19;  		goto out;  	}  	if (c->lst.total_free + c->lst.total_dirty +  	    c->lst.total_used > main_sz) { +		reason = FR_LPT_INCORRECT;  		err = 20;  		goto out;  	}  	if (c->lst.total_dead + c->lst.total_dark +  	    c->lst.total_used + c->bi.old_idx_sz > main_sz) { +		reason = FR_LPT_INCORRECT;  		err = 21;  		goto out;  	} @@ -294,6 +304,7 @@ static int validate_master(const struct ubifs_info *c)  	if (c->lst.total_dead < 0 ||  	    c->lst.total_dead > c->lst.total_free + c->lst.total_dirty ||  	    c->lst.total_dead & 7) { +		reason = FR_LPT_INCORRECT;  		err = 22;  		goto out;  	} @@ -301,6 +312,7 @@ static int validate_master(const struct ubifs_info *c)  	if (c->lst.total_dark < 0 ||  	    c->lst.total_dark > c->lst.total_free + c->lst.total_dirty ||  	    c->lst.total_dark & 7) { +		reason = FR_LPT_INCORRECT;  		err = 23;  		goto out;  	} @@ -308,6 +320,7 @@ static int validate_master(const struct ubifs_info *c)  	return 0;  out: +	set_failure_reason_callback(c, reason);  	ubifs_err(c, "bad master node at offset %d error %d", c->mst_offs, err);  	ubifs_dump_node(c, c->mst_node, c->mst_node_alsz);  	return -EINVAL; @@ -331,8 +344,10 @@ int ubifs_read_master(struct ubifs_info *c)  	err = scan_for_master(c);  	if (err) { -		if (err == -EUCLEAN) +		if (err == -EUCLEAN) { +			clear_failure_reason_callback(c);  			err = ubifs_recover_master_node(c); +		}  		if (err)  			/*  			 * Note, we do not free 'c->mst_node' here because the @@ -386,6 +401,7 @@ int ubifs_read_master(struct ubifs_info *c)  		if (c->leb_cnt < old_leb_cnt ||  		    c->leb_cnt < UBIFS_MIN_LEB_CNT) { +			set_failure_reason_callback(c, FR_DATA_CORRUPTED);  			ubifs_err(c, "bad leb_cnt on master node");  			ubifs_dump_node(c, c->mst_node, c->mst_node_alsz);  			return -EINVAL; diff --git a/ubifs-utils/libubifs/orphan.c b/ubifs-utils/libubifs/orphan.c index 2f31874..26668cb 100644 --- a/ubifs-utils/libubifs/orphan.c +++ b/ubifs-utils/libubifs/orphan.c @@ -547,9 +547,11 @@ static int kill_orphans(struct ubifs_info *c)  		dbg_rcvry("LEB %d", lnum);  		sleb = ubifs_scan(c, lnum, 0, c->sbuf, 1);  		if (IS_ERR(sleb)) { -			if (PTR_ERR(sleb) == -EUCLEAN) +			if (PTR_ERR(sleb) == -EUCLEAN) { +				clear_failure_reason_callback(c);  				sleb = ubifs_recover_leb(c, lnum, 0,  							 c->sbuf, -1); +			}  			if (IS_ERR(sleb)) {  				err = PTR_ERR(sleb);  				break; diff --git a/ubifs-utils/libubifs/recovery.c b/ubifs-utils/libubifs/recovery.c index 910414c..9115b17 100644 --- a/ubifs-utils/libubifs/recovery.c +++ b/ubifs-utils/libubifs/recovery.c @@ -182,6 +182,7 @@ static int get_master_node(const struct ubifs_info *c, int lnum, void **pbuf,  	return 0;  out_err: +	set_failure_reason_callback(c, FR_DATA_CORRUPTED);  	err = -EINVAL;  out_free:  	vfree(sbuf); @@ -355,6 +356,7 @@ int ubifs_recover_master_node(struct ubifs_info *c)  	return 0;  out_err: +	set_failure_reason_callback(c, FR_DATA_CORRUPTED);  	err = -EINVAL;  out_free:  	ubifs_err(c, "failed to recover master node"); @@ -762,6 +764,7 @@ corrupted_rescan:  	ubifs_err(c, "corruption %d", ret);  	ubifs_scan_a_node(c, buf, len, lnum, offs, 0);  corrupted: +	set_failure_reason_callback(c, FR_DATA_CORRUPTED);  	ubifs_scanned_corruption(c, lnum, offs, buf);  	err = -EUCLEAN;  error: @@ -817,6 +820,7 @@ static int get_cs_sqnum(struct ubifs_info *c, int lnum, int offs,  out_err:  	err = -EINVAL; +	set_failure_reason_callback(c, FR_DATA_CORRUPTED);  out_free:  	ubifs_err(c, "failed to get CS sqnum");  	kfree(cs_node); diff --git a/ubifs-utils/libubifs/replay.c b/ubifs-utils/libubifs/replay.c index b1d0164..30ed282 100644 --- a/ubifs-utils/libubifs/replay.c +++ b/ubifs-utils/libubifs/replay.c @@ -928,6 +928,7 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf)  	if (IS_ERR(sleb)) {  		if (PTR_ERR(sleb) != -EUCLEAN || !c->need_recovery)  			return PTR_ERR(sleb); +		clear_failure_reason_callback(c);  		/*  		 * Note, the below function will recover this log LEB only if  		 * it is the last, because unclean reboots can possibly corrupt diff --git a/ubifs-utils/libubifs/sb.c b/ubifs-utils/libubifs/sb.c index 312661d..2147280 100644 --- a/ubifs-utils/libubifs/sb.c +++ b/ubifs-utils/libubifs/sb.c @@ -360,6 +360,8 @@ int ubifs_read_superblock(struct ubifs_info *c)  	err = validate_sb(c, sup);  out: +	if (err) +		set_failure_reason_callback(c, FR_DATA_CORRUPTED);  	return err;  } diff --git a/ubifs-utils/libubifs/scan.c b/ubifs-utils/libubifs/scan.c index 74509fd..e9581a6 100644 --- a/ubifs-utils/libubifs/scan.c +++ b/ubifs-utils/libubifs/scan.c @@ -344,6 +344,7 @@ corrupted:  	}  	err = -EUCLEAN;  	ubifs_scan_destroy(sleb); +	set_failure_reason_callback(c, FR_DATA_CORRUPTED);  	return ERR_PTR(err);  error: diff --git a/ubifs-utils/libubifs/tnc_misc.c b/ubifs-utils/libubifs/tnc_misc.c index 8c38f15..0ffb434 100644 --- a/ubifs-utils/libubifs/tnc_misc.c +++ b/ubifs-utils/libubifs/tnc_misc.c @@ -222,6 +222,8 @@ static int read_znode(struct ubifs_info *c, struct ubifs_zbranch *zzbr,  	err = ubifs_read_node(c, idx, UBIFS_IDX_NODE, len, lnum, offs);  	if (err < 0) { +		if (test_and_clear_failure_reason_callback(c, FR_DATA_CORRUPTED)) +			set_failure_reason_callback(c, FR_TNC_CORRUPTED);  		kfree(idx);  		return err;  	} @@ -335,6 +337,7 @@ static int read_znode(struct ubifs_info *c, struct ubifs_zbranch *zzbr,  	return 0;  out_dump: +	set_failure_reason_callback(c, FR_TNC_CORRUPTED);  	ubifs_err(c, "bad indexing node at LEB %d:%d, error %d", lnum, offs, err);  	ubifs_dump_node(c, idx, c->max_idx_node_sz);  	kfree(idx); @@ -430,6 +433,7 @@ int ubifs_tnc_read_node(struct ubifs_info *c, struct ubifs_zbranch *zbr,  	/* Make sure the key of the read node is correct */  	key_read(c, node + UBIFS_KEY_OFFSET, &key1);  	if (!keys_eq(c, key, &key1)) { +		set_failure_reason_callback(c, FR_DATA_CORRUPTED);  		ubifs_err(c, "bad key in node at LEB %d:%d",  			  zbr->lnum, zbr->offs);  		dbg_tnck(key, "looked for key "); diff --git a/ubifs-utils/libubifs/ubifs.h b/ubifs-utils/libubifs/ubifs.h index babaae8..21b0ce0 100644 --- a/ubifs-utils/libubifs/ubifs.h +++ b/ubifs-utils/libubifs/ubifs.h @@ -1029,6 +1029,20 @@ struct ubifs_budg_info {   *   * @private: private information related to specific situation, eg. fsck.   * @assert_failed_cb: callback function to handle assertion failure + * @set_failure_reason_cb: record reasons while certain failure happens + * @get_failure_reason_cb: get failure reasons + * @clear_failure_reason_cb: callback function to clear the error which is + *			     caused by reading corrupted data or invalid lpt + * @test_and_clear_failure_reason_cb: callback function to check and clear the + *				      error which is caused by reading corrupted + *				      data or invalid lpt + * @set_lpt_invalid_cb: callback function to set the invalid lpt status + * @test_lpt_valid_cb: callback function to check whether lpt is corrupted or + *		       incorrect, should be called before updating lpt + * @can_ignore_failure_cb: callback function to decide whether the failure + *			   can be ignored + * @handle_failure_cb: callback function to decide whether the failure can be + *		       handled   */  struct ubifs_info {  	struct ubifs_sb_node *sup_node; @@ -1254,6 +1268,21 @@ struct ubifs_info {  	void *private;  	void (*assert_failed_cb)(const struct ubifs_info *c); +	void (*set_failure_reason_cb)(const struct ubifs_info *c, +				      unsigned int reason); +	unsigned int (*get_failure_reason_cb)(const struct ubifs_info *c); +	void (*clear_failure_reason_cb)(const struct ubifs_info *c); +	bool (*test_and_clear_failure_reason_cb)(const struct ubifs_info *c, +						 unsigned int reason); +	void (*set_lpt_invalid_cb)(const struct ubifs_info *c, +				   unsigned int reason); +	bool (*test_lpt_valid_cb)(const struct ubifs_info *c, int lnum, +				  int old_free, int old_dirty, +				  int free, int dirty); +	bool (*can_ignore_failure_cb)(const struct ubifs_info *c, +				      unsigned int reason); +	bool (*handle_failure_cb)(const struct ubifs_info *c, +				  unsigned int reason);  };  extern atomic_long_t ubifs_clean_zn_cnt; @@ -1502,6 +1531,75 @@ int ubifs_add_snod(const struct ubifs_info *c, struct ubifs_scan_leb *sleb,  void ubifs_scanned_corruption(const struct ubifs_info *c, int lnum, int offs,  			      void *buf); +/* Failure reasons which are checked by fsck. */ +enum { +	FR_DATA_CORRUPTED = 1,	/* Data is corrupted(master/log/orphan/main) */ +	FR_TNC_CORRUPTED = 2,	/* TNC is corrupted */ +	FR_LPT_CORRUPTED = 4,	/* LPT is corrupted */ +	FR_LPT_INCORRECT = 8	/* Space statistics are wrong */ +}; +/* Callback functions for failure(which can be handled by fsck) happens. */ +static inline void set_failure_reason_callback(const struct ubifs_info *c, +					       unsigned int reason) +{ +	if (c->set_failure_reason_cb) +		c->set_failure_reason_cb(c, reason); +} +static inline unsigned int get_failure_reason_callback( +						const struct ubifs_info *c) +{ +	if (c->get_failure_reason_cb) +		return c->get_failure_reason_cb(c); + +	return 0; +} +static inline void clear_failure_reason_callback(const struct ubifs_info *c) +{ +	if (c->clear_failure_reason_cb) +		c->clear_failure_reason_cb(c); +} +static inline bool test_and_clear_failure_reason_callback( +						const struct ubifs_info *c, +						unsigned int reason) +{ +	if (c->test_and_clear_failure_reason_cb) +		return c->test_and_clear_failure_reason_cb(c, reason); + +	return false; +} +static inline void set_lpt_invalid_callback(const struct ubifs_info *c, +					    unsigned int reason) +{ +	if (c->set_lpt_invalid_cb) +		c->set_lpt_invalid_cb(c, reason); +} +static inline bool test_lpt_valid_callback(const struct ubifs_info *c, int lnum, +					   int old_free, int old_dirty, +					   int free, int dirty) +{ +	if (c->test_lpt_valid_cb) +		return c->test_lpt_valid_cb(c, lnum, +					    old_free, old_dirty, free, dirty); + +	return false; +} +static inline bool can_ignore_failure_callback(const struct ubifs_info *c, +					       unsigned int reason) +{ +	if (c->can_ignore_failure_cb) +		return c->can_ignore_failure_cb(c, reason); + +	return false; +} +static inline bool handle_failure_callback(const struct ubifs_info *c, +					   unsigned int reason) +{ +	if (c->handle_failure_cb) +		return c->handle_failure_cb(c, reason); + +	return false; +} +  /* log.c */  void ubifs_add_bud(struct ubifs_info *c, struct ubifs_bud *bud);  void ubifs_create_buds_lists(struct ubifs_info *c); | 
