| .. | .. | 
|---|
 | 1 | +// SPDX-License-Identifier: GPL-2.0-only  | 
|---|
| 1 | 2 |  /* | 
|---|
| 2 | 3 |   * This file is part of UBIFS. | 
|---|
| 3 | 4 |   * | 
|---|
| 4 | 5 |   * Copyright (C) 2006-2008 Nokia Corporation. | 
|---|
| 5 |  | - *  | 
|---|
| 6 |  | - * This program is free software; you can redistribute it and/or modify it  | 
|---|
| 7 |  | - * under the terms of the GNU General Public License version 2 as published by  | 
|---|
| 8 |  | - * the Free Software Foundation.  | 
|---|
| 9 |  | - *  | 
|---|
| 10 |  | - * This program is distributed in the hope that it will be useful, but WITHOUT  | 
|---|
| 11 |  | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or  | 
|---|
| 12 |  | - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for  | 
|---|
| 13 |  | - * more details.  | 
|---|
| 14 |  | - *  | 
|---|
| 15 |  | - * You should have received a copy of the GNU General Public License along with  | 
|---|
| 16 |  | - * this program; if not, write to the Free Software Foundation, Inc., 51  | 
|---|
| 17 |  | - * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA  | 
|---|
| 18 | 6 |   * | 
|---|
| 19 | 7 |   * Authors: Adrian Hunter | 
|---|
| 20 | 8 |   *          Artem Bityutskiy (Битюцкий Артём) | 
|---|
| .. | .. | 
|---|
| 35 | 23 |  #include "ubifs.h" | 
|---|
| 36 | 24 |   | 
|---|
| 37 | 25 |  static int try_read_node(const struct ubifs_info *c, void *buf, int type, | 
|---|
| 38 |  | -			 int len, int lnum, int offs);  | 
|---|
 | 26 | +			 struct ubifs_zbranch *zbr);  | 
|---|
| 39 | 27 |  static int fallible_read_node(struct ubifs_info *c, const union ubifs_key *key, | 
|---|
| 40 | 28 |  			      struct ubifs_zbranch *zbr, void *node); | 
|---|
| 41 | 29 |   | 
|---|
| .. | .. | 
|---|
| 55 | 43 |  	NAME_GREATER = 2, | 
|---|
| 56 | 44 |  	NOT_ON_MEDIA = 3, | 
|---|
| 57 | 45 |  }; | 
|---|
 | 46 | +  | 
|---|
 | 47 | +static void do_insert_old_idx(struct ubifs_info *c,  | 
|---|
 | 48 | +			      struct ubifs_old_idx *old_idx)  | 
|---|
 | 49 | +{  | 
|---|
 | 50 | +	struct ubifs_old_idx *o;  | 
|---|
 | 51 | +	struct rb_node **p, *parent = NULL;  | 
|---|
 | 52 | +  | 
|---|
 | 53 | +	p = &c->old_idx.rb_node;  | 
|---|
 | 54 | +	while (*p) {  | 
|---|
 | 55 | +		parent = *p;  | 
|---|
 | 56 | +		o = rb_entry(parent, struct ubifs_old_idx, rb);  | 
|---|
 | 57 | +		if (old_idx->lnum < o->lnum)  | 
|---|
 | 58 | +			p = &(*p)->rb_left;  | 
|---|
 | 59 | +		else if (old_idx->lnum > o->lnum)  | 
|---|
 | 60 | +			p = &(*p)->rb_right;  | 
|---|
 | 61 | +		else if (old_idx->offs < o->offs)  | 
|---|
 | 62 | +			p = &(*p)->rb_left;  | 
|---|
 | 63 | +		else if (old_idx->offs > o->offs)  | 
|---|
 | 64 | +			p = &(*p)->rb_right;  | 
|---|
 | 65 | +		else {  | 
|---|
 | 66 | +			ubifs_err(c, "old idx added twice!");  | 
|---|
 | 67 | +			kfree(old_idx);  | 
|---|
 | 68 | +		}  | 
|---|
 | 69 | +	}  | 
|---|
 | 70 | +	rb_link_node(&old_idx->rb, parent, p);  | 
|---|
 | 71 | +	rb_insert_color(&old_idx->rb, &c->old_idx);  | 
|---|
 | 72 | +}  | 
|---|
| 58 | 73 |   | 
|---|
| 59 | 74 |  /** | 
|---|
| 60 | 75 |   * insert_old_idx - record an index node obsoleted since the last commit start. | 
|---|
| .. | .. | 
|---|
| 81 | 96 |   */ | 
|---|
| 82 | 97 |  static int insert_old_idx(struct ubifs_info *c, int lnum, int offs) | 
|---|
| 83 | 98 |  { | 
|---|
| 84 |  | -	struct ubifs_old_idx *old_idx, *o;  | 
|---|
| 85 |  | -	struct rb_node **p, *parent = NULL;  | 
|---|
 | 99 | +	struct ubifs_old_idx *old_idx;  | 
|---|
| 86 | 100 |   | 
|---|
| 87 | 101 |  	old_idx = kmalloc(sizeof(struct ubifs_old_idx), GFP_NOFS); | 
|---|
| 88 | 102 |  	if (unlikely(!old_idx)) | 
|---|
| 89 | 103 |  		return -ENOMEM; | 
|---|
| 90 | 104 |  	old_idx->lnum = lnum; | 
|---|
| 91 | 105 |  	old_idx->offs = offs; | 
|---|
 | 106 | +	do_insert_old_idx(c, old_idx);  | 
|---|
| 92 | 107 |   | 
|---|
| 93 |  | -	p = &c->old_idx.rb_node;  | 
|---|
| 94 |  | -	while (*p) {  | 
|---|
| 95 |  | -		parent = *p;  | 
|---|
| 96 |  | -		o = rb_entry(parent, struct ubifs_old_idx, rb);  | 
|---|
| 97 |  | -		if (lnum < o->lnum)  | 
|---|
| 98 |  | -			p = &(*p)->rb_left;  | 
|---|
| 99 |  | -		else if (lnum > o->lnum)  | 
|---|
| 100 |  | -			p = &(*p)->rb_right;  | 
|---|
| 101 |  | -		else if (offs < o->offs)  | 
|---|
| 102 |  | -			p = &(*p)->rb_left;  | 
|---|
| 103 |  | -		else if (offs > o->offs)  | 
|---|
| 104 |  | -			p = &(*p)->rb_right;  | 
|---|
| 105 |  | -		else {  | 
|---|
| 106 |  | -			ubifs_err(c, "old idx added twice!");  | 
|---|
| 107 |  | -			kfree(old_idx);  | 
|---|
| 108 |  | -			return 0;  | 
|---|
| 109 |  | -		}  | 
|---|
| 110 |  | -	}  | 
|---|
| 111 |  | -	rb_link_node(&old_idx->rb, parent, p);  | 
|---|
| 112 |  | -	rb_insert_color(&old_idx->rb, &c->old_idx);  | 
|---|
| 113 | 108 |  	return 0; | 
|---|
| 114 | 109 |  } | 
|---|
| 115 | 110 |   | 
|---|
| .. | .. | 
|---|
| 211 | 206 |  	__set_bit(DIRTY_ZNODE, &zn->flags); | 
|---|
| 212 | 207 |  	__clear_bit(COW_ZNODE, &zn->flags); | 
|---|
| 213 | 208 |   | 
|---|
| 214 |  | -	ubifs_assert(c, !ubifs_zn_obsolete(znode));  | 
|---|
| 215 |  | -	__set_bit(OBSOLETE_ZNODE, &znode->flags);  | 
|---|
| 216 |  | -  | 
|---|
| 217 |  | -	if (znode->level != 0) {  | 
|---|
| 218 |  | -		int i;  | 
|---|
| 219 |  | -		const int n = zn->child_cnt;  | 
|---|
| 220 |  | -  | 
|---|
| 221 |  | -		/* The children now have new parent */  | 
|---|
| 222 |  | -		for (i = 0; i < n; i++) {  | 
|---|
| 223 |  | -			struct ubifs_zbranch *zbr = &zn->zbranch[i];  | 
|---|
| 224 |  | -  | 
|---|
| 225 |  | -			if (zbr->znode)  | 
|---|
| 226 |  | -				zbr->znode->parent = zn;  | 
|---|
| 227 |  | -		}  | 
|---|
| 228 |  | -	}  | 
|---|
| 229 |  | -  | 
|---|
| 230 |  | -	atomic_long_inc(&c->dirty_zn_cnt);  | 
|---|
| 231 | 209 |  	return zn; | 
|---|
| 232 | 210 |  } | 
|---|
| 233 | 211 |   | 
|---|
| .. | .. | 
|---|
| 243 | 221 |  { | 
|---|
| 244 | 222 |  	c->calc_idx_sz -= ALIGN(dirt, 8); | 
|---|
| 245 | 223 |  	return ubifs_add_dirt(c, lnum, dirt); | 
|---|
 | 224 | +}  | 
|---|
 | 225 | +  | 
|---|
 | 226 | +/**  | 
|---|
 | 227 | + * replace_znode - replace old znode with new znode.  | 
|---|
 | 228 | + * @c: UBIFS file-system description object  | 
|---|
 | 229 | + * @new_zn: new znode  | 
|---|
 | 230 | + * @old_zn: old znode  | 
|---|
 | 231 | + * @zbr: the branch of parent znode  | 
|---|
 | 232 | + *  | 
|---|
 | 233 | + * Replace old znode with new znode in TNC.  | 
|---|
 | 234 | + */  | 
|---|
 | 235 | +static void replace_znode(struct ubifs_info *c, struct ubifs_znode *new_zn,  | 
|---|
 | 236 | +			  struct ubifs_znode *old_zn, struct ubifs_zbranch *zbr)  | 
|---|
 | 237 | +{  | 
|---|
 | 238 | +	ubifs_assert(c, !ubifs_zn_obsolete(old_zn));  | 
|---|
 | 239 | +	__set_bit(OBSOLETE_ZNODE, &old_zn->flags);  | 
|---|
 | 240 | +  | 
|---|
 | 241 | +	if (old_zn->level != 0) {  | 
|---|
 | 242 | +		int i;  | 
|---|
 | 243 | +		const int n = new_zn->child_cnt;  | 
|---|
 | 244 | +  | 
|---|
 | 245 | +		/* The children now have new parent */  | 
|---|
 | 246 | +		for (i = 0; i < n; i++) {  | 
|---|
 | 247 | +			struct ubifs_zbranch *child = &new_zn->zbranch[i];  | 
|---|
 | 248 | +  | 
|---|
 | 249 | +			if (child->znode)  | 
|---|
 | 250 | +				child->znode->parent = new_zn;  | 
|---|
 | 251 | +		}  | 
|---|
 | 252 | +	}  | 
|---|
 | 253 | +  | 
|---|
 | 254 | +	zbr->znode = new_zn;  | 
|---|
 | 255 | +	zbr->lnum = 0;  | 
|---|
 | 256 | +	zbr->offs = 0;  | 
|---|
 | 257 | +	zbr->len = 0;  | 
|---|
 | 258 | +  | 
|---|
 | 259 | +	atomic_long_inc(&c->dirty_zn_cnt);  | 
|---|
| 246 | 260 |  } | 
|---|
| 247 | 261 |   | 
|---|
| 248 | 262 |  /** | 
|---|
| .. | .. | 
|---|
| 277 | 291 |  		return zn; | 
|---|
| 278 | 292 |   | 
|---|
| 279 | 293 |  	if (zbr->len) { | 
|---|
| 280 |  | -		err = insert_old_idx(c, zbr->lnum, zbr->offs);  | 
|---|
| 281 |  | -		if (unlikely(err))  | 
|---|
| 282 |  | -			return ERR_PTR(err);  | 
|---|
 | 294 | +		struct ubifs_old_idx *old_idx;  | 
|---|
 | 295 | +  | 
|---|
 | 296 | +		old_idx = kmalloc(sizeof(struct ubifs_old_idx), GFP_NOFS);  | 
|---|
 | 297 | +		if (unlikely(!old_idx)) {  | 
|---|
 | 298 | +			err = -ENOMEM;  | 
|---|
 | 299 | +			goto out;  | 
|---|
 | 300 | +		}  | 
|---|
 | 301 | +		old_idx->lnum = zbr->lnum;  | 
|---|
 | 302 | +		old_idx->offs = zbr->offs;  | 
|---|
 | 303 | +  | 
|---|
| 283 | 304 |  		err = add_idx_dirt(c, zbr->lnum, zbr->len); | 
|---|
| 284 |  | -	} else  | 
|---|
| 285 |  | -		err = 0;  | 
|---|
 | 305 | +		if (err) {  | 
|---|
 | 306 | +			kfree(old_idx);  | 
|---|
 | 307 | +			goto out;  | 
|---|
 | 308 | +		}  | 
|---|
| 286 | 309 |   | 
|---|
| 287 |  | -	zbr->znode = zn;  | 
|---|
| 288 |  | -	zbr->lnum = 0;  | 
|---|
| 289 |  | -	zbr->offs = 0;  | 
|---|
| 290 |  | -	zbr->len = 0;  | 
|---|
 | 310 | +		do_insert_old_idx(c, old_idx);  | 
|---|
 | 311 | +	}  | 
|---|
| 291 | 312 |   | 
|---|
| 292 |  | -	if (unlikely(err))  | 
|---|
| 293 |  | -		return ERR_PTR(err);  | 
|---|
 | 313 | +	replace_znode(c, zn, znode, zbr);  | 
|---|
 | 314 | +  | 
|---|
| 294 | 315 |  	return zn; | 
|---|
 | 316 | +  | 
|---|
 | 317 | +out:  | 
|---|
 | 318 | +	kfree(zn);  | 
|---|
 | 319 | +	return ERR_PTR(err);  | 
|---|
| 295 | 320 |  } | 
|---|
| 296 | 321 |   | 
|---|
| 297 | 322 |  /** | 
|---|
| .. | .. | 
|---|
| 372 | 397 |  /** | 
|---|
| 373 | 398 |   * lnc_free - remove a leaf node from the leaf node cache. | 
|---|
| 374 | 399 |   * @zbr: zbranch of leaf node | 
|---|
| 375 |  | - * @node: leaf node  | 
|---|
| 376 | 400 |   */ | 
|---|
| 377 | 401 |  static void lnc_free(struct ubifs_zbranch *zbr) | 
|---|
| 378 | 402 |  { | 
|---|
| .. | .. | 
|---|
| 433 | 457 |   * @c: UBIFS file-system description object | 
|---|
| 434 | 458 |   * @buf: buffer to read to | 
|---|
| 435 | 459 |   * @type: node type | 
|---|
| 436 |  | - * @len: node length (not aligned)  | 
|---|
| 437 |  | - * @lnum: LEB number of node to read  | 
|---|
| 438 |  | - * @offs: offset of node to read  | 
|---|
 | 460 | + * @zbr: the zbranch describing the node to read  | 
|---|
| 439 | 461 |   * | 
|---|
| 440 | 462 |   * This function tries to read a node of known type and length, checks it and | 
|---|
| 441 | 463 |   * stores it in @buf. This function returns %1 if a node is present and %0 if | 
|---|
| .. | .. | 
|---|
| 453 | 475 |   * journal nodes may potentially be corrupted, so checking is required. | 
|---|
| 454 | 476 |   */ | 
|---|
| 455 | 477 |  static int try_read_node(const struct ubifs_info *c, void *buf, int type, | 
|---|
| 456 |  | -			 int len, int lnum, int offs)  | 
|---|
 | 478 | +			 struct ubifs_zbranch *zbr)  | 
|---|
| 457 | 479 |  { | 
|---|
 | 480 | +	int len = zbr->len;  | 
|---|
 | 481 | +	int lnum = zbr->lnum;  | 
|---|
 | 482 | +	int offs = zbr->offs;  | 
|---|
| 458 | 483 |  	int err, node_len; | 
|---|
| 459 | 484 |  	struct ubifs_ch *ch = buf; | 
|---|
| 460 | 485 |  	uint32_t crc, node_crc; | 
|---|
| .. | .. | 
|---|
| 478 | 503 |  	if (node_len != len) | 
|---|
| 479 | 504 |  		return 0; | 
|---|
| 480 | 505 |   | 
|---|
| 481 |  | -	if (type == UBIFS_DATA_NODE && c->no_chk_data_crc && !c->mounting &&  | 
|---|
| 482 |  | -	    !c->remounting_rw)  | 
|---|
| 483 |  | -		return 1;  | 
|---|
 | 506 | +	if (type != UBIFS_DATA_NODE || !c->no_chk_data_crc || c->mounting ||  | 
|---|
 | 507 | +	    c->remounting_rw) {  | 
|---|
 | 508 | +		crc = crc32(UBIFS_CRC32_INIT, buf + 8, node_len - 8);  | 
|---|
 | 509 | +		node_crc = le32_to_cpu(ch->crc);  | 
|---|
 | 510 | +		if (crc != node_crc)  | 
|---|
 | 511 | +			return 0;  | 
|---|
 | 512 | +	}  | 
|---|
| 484 | 513 |   | 
|---|
| 485 |  | -	crc = crc32(UBIFS_CRC32_INIT, buf + 8, node_len - 8);  | 
|---|
| 486 |  | -	node_crc = le32_to_cpu(ch->crc);  | 
|---|
| 487 |  | -	if (crc != node_crc)  | 
|---|
 | 514 | +	err = ubifs_node_check_hash(c, buf, zbr->hash);  | 
|---|
 | 515 | +	if (err) {  | 
|---|
 | 516 | +		ubifs_bad_hash(c, buf, zbr->hash, lnum, offs);  | 
|---|
| 488 | 517 |  		return 0; | 
|---|
 | 518 | +	}  | 
|---|
| 489 | 519 |   | 
|---|
| 490 | 520 |  	return 1; | 
|---|
| 491 | 521 |  } | 
|---|
| .. | .. | 
|---|
| 507 | 537 |   | 
|---|
| 508 | 538 |  	dbg_tnck(key, "LEB %d:%d, key ", zbr->lnum, zbr->offs); | 
|---|
| 509 | 539 |   | 
|---|
| 510 |  | -	ret = try_read_node(c, node, key_type(c, key), zbr->len, zbr->lnum,  | 
|---|
| 511 |  | -			    zbr->offs);  | 
|---|
 | 540 | +	ret = try_read_node(c, node, key_type(c, key), zbr);  | 
|---|
| 512 | 541 |  	if (ret == 1) { | 
|---|
| 513 | 542 |  		union ubifs_key node_key; | 
|---|
| 514 | 543 |  		struct ubifs_dent_node *dent = node; | 
|---|
| .. | .. | 
|---|
| 899 | 928 |  				      int adding) | 
|---|
| 900 | 929 |  { | 
|---|
| 901 | 930 |  	struct ubifs_znode *o_znode = NULL, *znode = *zn; | 
|---|
| 902 |  | -	int uninitialized_var(o_n), err, cmp, unsure = 0, nn = *n;  | 
|---|
 | 931 | +	int o_n, err, cmp, unsure = 0, nn = *n;  | 
|---|
| 903 | 932 |   | 
|---|
| 904 | 933 |  	cmp = fallible_matches_name(c, &znode->zbranch[nn], nm); | 
|---|
| 905 | 934 |  	if (unlikely(cmp < 0)) | 
|---|
| .. | .. | 
|---|
| 1521 | 1550 |   */ | 
|---|
| 1522 | 1551 |  int ubifs_tnc_get_bu_keys(struct ubifs_info *c, struct bu_info *bu) | 
|---|
| 1523 | 1552 |  { | 
|---|
| 1524 |  | -	int n, err = 0, lnum = -1, uninitialized_var(offs);  | 
|---|
| 1525 |  | -	int uninitialized_var(len);  | 
|---|
 | 1553 | +	int n, err = 0, lnum = -1, offs;  | 
|---|
 | 1554 | +	int len;  | 
|---|
| 1526 | 1555 |  	unsigned int block = key_block(c, &bu->key); | 
|---|
| 1527 | 1556 |  	struct ubifs_znode *znode; | 
|---|
| 1528 | 1557 |   | 
|---|
| .. | .. | 
|---|
| 1711 | 1740 |  	if (err) { | 
|---|
| 1712 | 1741 |  		ubifs_err(c, "expected node type %d", UBIFS_DATA_NODE); | 
|---|
| 1713 | 1742 |  		goto out; | 
|---|
 | 1743 | +	}  | 
|---|
 | 1744 | +  | 
|---|
 | 1745 | +	err = ubifs_node_check_hash(c, buf, zbr->hash);  | 
|---|
 | 1746 | +	if (err) {  | 
|---|
 | 1747 | +		ubifs_bad_hash(c, buf, zbr->hash, zbr->lnum, zbr->offs);  | 
|---|
 | 1748 | +		return err;  | 
|---|
| 1714 | 1749 |  	} | 
|---|
| 1715 | 1750 |   | 
|---|
| 1716 | 1751 |  	len = le32_to_cpu(ch->len); | 
|---|
| .. | .. | 
|---|
| 2266 | 2301 |   * @lnum: LEB number of node | 
|---|
| 2267 | 2302 |   * @offs: node offset | 
|---|
| 2268 | 2303 |   * @len: node length | 
|---|
 | 2304 | + * @hash: The hash over the node  | 
|---|
| 2269 | 2305 |   * | 
|---|
| 2270 | 2306 |   * This function adds a node with key @key to TNC. The node may be new or it may | 
|---|
| 2271 | 2307 |   * obsolete some existing one. Returns %0 on success or negative error code on | 
|---|
| 2272 | 2308 |   * failure. | 
|---|
| 2273 | 2309 |   */ | 
|---|
| 2274 | 2310 |  int ubifs_tnc_add(struct ubifs_info *c, const union ubifs_key *key, int lnum, | 
|---|
| 2275 |  | -		  int offs, int len)  | 
|---|
 | 2311 | +		  int offs, int len, const u8 *hash)  | 
|---|
| 2276 | 2312 |  { | 
|---|
| 2277 | 2313 |  	int found, n, err = 0; | 
|---|
| 2278 | 2314 |  	struct ubifs_znode *znode; | 
|---|
| .. | .. | 
|---|
| 2287 | 2323 |  		zbr.lnum = lnum; | 
|---|
| 2288 | 2324 |  		zbr.offs = offs; | 
|---|
| 2289 | 2325 |  		zbr.len = len; | 
|---|
 | 2326 | +		ubifs_copy_hash(c, hash, zbr.hash);  | 
|---|
| 2290 | 2327 |  		key_copy(c, key, &zbr.key); | 
|---|
| 2291 | 2328 |  		err = tnc_insert(c, znode, &zbr, n + 1); | 
|---|
| 2292 | 2329 |  	} else if (found == 1) { | 
|---|
| .. | .. | 
|---|
| 2297 | 2334 |  		zbr->lnum = lnum; | 
|---|
| 2298 | 2335 |  		zbr->offs = offs; | 
|---|
| 2299 | 2336 |  		zbr->len = len; | 
|---|
 | 2337 | +		ubifs_copy_hash(c, hash, zbr->hash);  | 
|---|
| 2300 | 2338 |  	} else | 
|---|
| 2301 | 2339 |  		err = found; | 
|---|
| 2302 | 2340 |  	if (!err) | 
|---|
| .. | .. | 
|---|
| 2398 | 2436 |   * @lnum: LEB number of node | 
|---|
| 2399 | 2437 |   * @offs: node offset | 
|---|
| 2400 | 2438 |   * @len: node length | 
|---|
 | 2439 | + * @hash: The hash over the node  | 
|---|
| 2401 | 2440 |   * @nm: node name | 
|---|
| 2402 | 2441 |   * | 
|---|
| 2403 | 2442 |   * This is the same as 'ubifs_tnc_add()' but it should be used with keys which | 
|---|
| 2404 | 2443 |   * may have collisions, like directory entry keys. | 
|---|
| 2405 | 2444 |   */ | 
|---|
| 2406 | 2445 |  int ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key, | 
|---|
| 2407 |  | -		     int lnum, int offs, int len,  | 
|---|
 | 2446 | +		     int lnum, int offs, int len, const u8 *hash,  | 
|---|
| 2408 | 2447 |  		     const struct fscrypt_name *nm) | 
|---|
| 2409 | 2448 |  { | 
|---|
| 2410 | 2449 |  	int found, n, err = 0; | 
|---|
| .. | .. | 
|---|
| 2447 | 2486 |  			zbr->lnum = lnum; | 
|---|
| 2448 | 2487 |  			zbr->offs = offs; | 
|---|
| 2449 | 2488 |  			zbr->len = len; | 
|---|
 | 2489 | +			ubifs_copy_hash(c, hash, zbr->hash);  | 
|---|
| 2450 | 2490 |  			goto out_unlock; | 
|---|
| 2451 | 2491 |  		} | 
|---|
| 2452 | 2492 |  	} | 
|---|
| .. | .. | 
|---|
| 2458 | 2498 |  		zbr.lnum = lnum; | 
|---|
| 2459 | 2499 |  		zbr.offs = offs; | 
|---|
| 2460 | 2500 |  		zbr.len = len; | 
|---|
 | 2501 | +		ubifs_copy_hash(c, hash, zbr.hash);  | 
|---|
| 2461 | 2502 |  		key_copy(c, key, &zbr.key); | 
|---|
| 2462 | 2503 |  		err = tnc_insert(c, znode, &zbr, n + 1); | 
|---|
| 2463 | 2504 |  		if (err) | 
|---|
| .. | .. | 
|---|
| 2880 | 2921 |  			err = PTR_ERR(xent); | 
|---|
| 2881 | 2922 |  			if (err == -ENOENT) | 
|---|
| 2882 | 2923 |  				break; | 
|---|
 | 2924 | +			kfree(pxent);  | 
|---|
| 2883 | 2925 |  			return err; | 
|---|
| 2884 | 2926 |  		} | 
|---|
| 2885 | 2927 |   | 
|---|
| .. | .. | 
|---|
| 2893 | 2935 |  		fname_len(&nm) = le16_to_cpu(xent->nlen); | 
|---|
| 2894 | 2936 |  		err = ubifs_tnc_remove_nm(c, &key1, &nm); | 
|---|
| 2895 | 2937 |  		if (err) { | 
|---|
 | 2938 | +			kfree(pxent);  | 
|---|
| 2896 | 2939 |  			kfree(xent); | 
|---|
| 2897 | 2940 |  			return err; | 
|---|
| 2898 | 2941 |  		} | 
|---|
| .. | .. | 
|---|
| 2901 | 2944 |  		highest_ino_key(c, &key2, xattr_inum); | 
|---|
| 2902 | 2945 |  		err = ubifs_tnc_remove_range(c, &key1, &key2); | 
|---|
| 2903 | 2946 |  		if (err) { | 
|---|
 | 2947 | +			kfree(pxent);  | 
|---|
| 2904 | 2948 |  			kfree(xent); | 
|---|
| 2905 | 2949 |  			return err; | 
|---|
| 2906 | 2950 |  		} | 
|---|
| .. | .. | 
|---|
| 3046 | 3090 |  		cnext = cnext->cnext; | 
|---|
| 3047 | 3091 |  		if (ubifs_zn_obsolete(znode)) | 
|---|
| 3048 | 3092 |  			kfree(znode); | 
|---|
 | 3093 | +		else if (!ubifs_zn_cow(znode)) {  | 
|---|
 | 3094 | +			/*  | 
|---|
 | 3095 | +			 * Don't forget to update clean znode count after  | 
|---|
 | 3096 | +			 * committing failed, because ubifs will check this  | 
|---|
 | 3097 | +			 * count while closing tnc. Non-obsolete znode could  | 
|---|
 | 3098 | +			 * be re-dirtied during committing process, so dirty  | 
|---|
 | 3099 | +			 * flag is untrustable. The flag 'COW_ZNODE' is set  | 
|---|
 | 3100 | +			 * for each dirty znode before committing, and it is  | 
|---|
 | 3101 | +			 * cleared as long as the znode become clean, so we  | 
|---|
 | 3102 | +			 * can statistic clean znode count according to this  | 
|---|
 | 3103 | +			 * flag.  | 
|---|
 | 3104 | +			 */  | 
|---|
 | 3105 | +			atomic_long_inc(&c->clean_zn_cnt);  | 
|---|
 | 3106 | +			atomic_long_inc(&ubifs_clean_zn_cnt);  | 
|---|
 | 3107 | +		}  | 
|---|
| 3049 | 3108 |  	} while (cnext && cnext != c->cnext); | 
|---|
| 3050 | 3109 |  } | 
|---|
| 3051 | 3110 |   | 
|---|
| .. | .. | 
|---|
| 3461 | 3520 |  /** | 
|---|
| 3462 | 3521 |   * dbg_check_inode_size - check if inode size is correct. | 
|---|
| 3463 | 3522 |   * @c: UBIFS file-system description object | 
|---|
| 3464 |  | - * @inum: inode number  | 
|---|
 | 3523 | + * @inode: inode to check  | 
|---|
| 3465 | 3524 |   * @size: inode size | 
|---|
| 3466 | 3525 |   * | 
|---|
| 3467 | 3526 |   * This function makes sure that the inode size (@size) is correct and it does | 
|---|