| .. | .. | 
|---|
 | 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: Artem Bityutskiy (Битюцкий Артём) | 
|---|
| 20 | 8 |   *          Adrian Hunter | 
|---|
| .. | .. | 
|---|
| 88 | 76 |  static inline void zero_trun_node_unused(struct ubifs_trun_node *trun) | 
|---|
| 89 | 77 |  { | 
|---|
| 90 | 78 |  	memset(trun->padding, 0, 12); | 
|---|
 | 79 | +}  | 
|---|
 | 80 | +  | 
|---|
 | 81 | +static void ubifs_add_auth_dirt(struct ubifs_info *c, int lnum)  | 
|---|
 | 82 | +{  | 
|---|
 | 83 | +	if (ubifs_authenticated(c))  | 
|---|
 | 84 | +		ubifs_add_dirt(c, lnum, ubifs_auth_node_sz(c));  | 
|---|
| 91 | 85 |  } | 
|---|
| 92 | 86 |   | 
|---|
| 93 | 87 |  /** | 
|---|
| .. | .. | 
|---|
| 228 | 222 |  	return err; | 
|---|
| 229 | 223 |  } | 
|---|
| 230 | 224 |   | 
|---|
| 231 |  | -/**  | 
|---|
| 232 |  | - * write_node - write node to a journal head.  | 
|---|
| 233 |  | - * @c: UBIFS file-system description object  | 
|---|
| 234 |  | - * @jhead: journal head  | 
|---|
| 235 |  | - * @node: node to write  | 
|---|
| 236 |  | - * @len: node length  | 
|---|
| 237 |  | - * @lnum: LEB number written is returned here  | 
|---|
| 238 |  | - * @offs: offset written is returned here  | 
|---|
| 239 |  | - *  | 
|---|
| 240 |  | - * This function writes a node to reserved space of journal head @jhead.  | 
|---|
| 241 |  | - * Returns zero in case of success and a negative error code in case of  | 
|---|
| 242 |  | - * failure.  | 
|---|
| 243 |  | - */  | 
|---|
| 244 |  | -static int write_node(struct ubifs_info *c, int jhead, void *node, int len,  | 
|---|
| 245 |  | -		      int *lnum, int *offs)  | 
|---|
 | 225 | +static int ubifs_hash_nodes(struct ubifs_info *c, void *node,  | 
|---|
 | 226 | +			     int len, struct shash_desc *hash)  | 
|---|
| 246 | 227 |  { | 
|---|
| 247 |  | -	struct ubifs_wbuf *wbuf = &c->jheads[jhead].wbuf;  | 
|---|
 | 228 | +	int auth_node_size = ubifs_auth_node_sz(c);  | 
|---|
 | 229 | +	int err;  | 
|---|
| 248 | 230 |   | 
|---|
| 249 |  | -	ubifs_assert(c, jhead != GCHD);  | 
|---|
 | 231 | +	while (1) {  | 
|---|
 | 232 | +		const struct ubifs_ch *ch = node;  | 
|---|
 | 233 | +		int nodelen = le32_to_cpu(ch->len);  | 
|---|
| 250 | 234 |   | 
|---|
| 251 |  | -	*lnum = c->jheads[jhead].wbuf.lnum;  | 
|---|
| 252 |  | -	*offs = c->jheads[jhead].wbuf.offs + c->jheads[jhead].wbuf.used;  | 
|---|
 | 235 | +		ubifs_assert(c, len >= auth_node_size);  | 
|---|
| 253 | 236 |   | 
|---|
| 254 |  | -	dbg_jnl("jhead %s, LEB %d:%d, len %d",  | 
|---|
| 255 |  | -		dbg_jhead(jhead), *lnum, *offs, len);  | 
|---|
| 256 |  | -	ubifs_prepare_node(c, node, len, 0);  | 
|---|
 | 237 | +		if (len == auth_node_size)  | 
|---|
 | 238 | +			break;  | 
|---|
| 257 | 239 |   | 
|---|
| 258 |  | -	return ubifs_wbuf_write_nolock(wbuf, node, len);  | 
|---|
 | 240 | +		ubifs_assert(c, len > nodelen);  | 
|---|
 | 241 | +		ubifs_assert(c, ch->magic == cpu_to_le32(UBIFS_NODE_MAGIC));  | 
|---|
 | 242 | +  | 
|---|
 | 243 | +		err = ubifs_shash_update(c, hash, (void *)node, nodelen);  | 
|---|
 | 244 | +		if (err)  | 
|---|
 | 245 | +			return err;  | 
|---|
 | 246 | +  | 
|---|
 | 247 | +		node += ALIGN(nodelen, 8);  | 
|---|
 | 248 | +		len -= ALIGN(nodelen, 8);  | 
|---|
 | 249 | +	}  | 
|---|
 | 250 | +  | 
|---|
 | 251 | +	return ubifs_prepare_auth_node(c, node, hash);  | 
|---|
| 259 | 252 |  } | 
|---|
| 260 | 253 |   | 
|---|
| 261 | 254 |  /** | 
|---|
| .. | .. | 
|---|
| 268 | 261 |   * @offs: offset written is returned here | 
|---|
| 269 | 262 |   * @sync: non-zero if the write-buffer has to by synchronized | 
|---|
| 270 | 263 |   * | 
|---|
| 271 |  | - * This function is the same as 'write_node()' but it does not assume the  | 
|---|
| 272 |  | - * buffer it is writing is a node, so it does not prepare it (which means  | 
|---|
| 273 |  | - * initializing common header and calculating CRC).  | 
|---|
 | 264 | + * This function writes data to the reserved space of journal head @jhead.  | 
|---|
 | 265 | + * Returns zero in case of success and a negative error code in case of  | 
|---|
 | 266 | + * failure.  | 
|---|
| 274 | 267 |   */ | 
|---|
| 275 | 268 |  static int write_head(struct ubifs_info *c, int jhead, void *buf, int len, | 
|---|
| 276 | 269 |  		      int *lnum, int *offs, int sync) | 
|---|
| .. | .. | 
|---|
| 284 | 277 |  	*offs = c->jheads[jhead].wbuf.offs + c->jheads[jhead].wbuf.used; | 
|---|
| 285 | 278 |  	dbg_jnl("jhead %s, LEB %d:%d, len %d", | 
|---|
| 286 | 279 |  		dbg_jhead(jhead), *lnum, *offs, len); | 
|---|
 | 280 | +  | 
|---|
 | 281 | +	if (ubifs_authenticated(c)) {  | 
|---|
 | 282 | +		err = ubifs_hash_nodes(c, buf, len, c->jheads[jhead].log_hash);  | 
|---|
 | 283 | +		if (err)  | 
|---|
 | 284 | +			return err;  | 
|---|
 | 285 | +	}  | 
|---|
| 287 | 286 |   | 
|---|
| 288 | 287 |  	err = ubifs_wbuf_write_nolock(wbuf, buf, len); | 
|---|
| 289 | 288 |  	if (err) | 
|---|
| .. | .. | 
|---|
| 504 | 503 |  static void set_dent_cookie(struct ubifs_info *c, struct ubifs_dent_node *dent) | 
|---|
| 505 | 504 |  { | 
|---|
| 506 | 505 |  	if (c->double_hash) | 
|---|
| 507 |  | -		dent->cookie = prandom_u32();  | 
|---|
 | 506 | +		dent->cookie = (__force __le32) prandom_u32();  | 
|---|
| 508 | 507 |  	else | 
|---|
| 509 | 508 |  		dent->cookie = 0; | 
|---|
| 510 | 509 |  } | 
|---|
| .. | .. | 
|---|
| 540 | 539 |  		     const struct fscrypt_name *nm, const struct inode *inode, | 
|---|
| 541 | 540 |  		     int deletion, int xent) | 
|---|
| 542 | 541 |  { | 
|---|
| 543 |  | -	int err, dlen, ilen, len, lnum, ino_offs, dent_offs;  | 
|---|
 | 542 | +	int err, dlen, ilen, len, lnum, ino_offs, dent_offs, orphan_added = 0;  | 
|---|
| 544 | 543 |  	int aligned_dlen, aligned_ilen, sync = IS_DIRSYNC(dir); | 
|---|
| 545 | 544 |  	int last_reference = !!(deletion && inode->i_nlink == 0); | 
|---|
| 546 | 545 |  	struct ubifs_inode *ui = ubifs_inode(inode); | 
|---|
| .. | .. | 
|---|
| 548 | 547 |  	struct ubifs_dent_node *dent; | 
|---|
| 549 | 548 |  	struct ubifs_ino_node *ino; | 
|---|
| 550 | 549 |  	union ubifs_key dent_key, ino_key; | 
|---|
 | 550 | +	u8 hash_dent[UBIFS_HASH_ARR_SZ];  | 
|---|
 | 551 | +	u8 hash_ino[UBIFS_HASH_ARR_SZ];  | 
|---|
 | 552 | +	u8 hash_ino_host[UBIFS_HASH_ARR_SZ];  | 
|---|
| 551 | 553 |   | 
|---|
| 552 | 554 |  	ubifs_assert(c, mutex_is_locked(&host_ui->ui_mutex)); | 
|---|
| 553 | 555 |   | 
|---|
| .. | .. | 
|---|
| 570 | 572 |   | 
|---|
| 571 | 573 |  	len = aligned_dlen + aligned_ilen + UBIFS_INO_NODE_SZ; | 
|---|
| 572 | 574 |  	/* Make sure to also account for extended attributes */ | 
|---|
| 573 |  | -	len += host_ui->data_len;  | 
|---|
 | 575 | +	if (ubifs_authenticated(c))  | 
|---|
 | 576 | +		len += ALIGN(host_ui->data_len, 8) + ubifs_auth_node_sz(c);  | 
|---|
 | 577 | +	else  | 
|---|
 | 578 | +		len += host_ui->data_len;  | 
|---|
| 574 | 579 |   | 
|---|
| 575 | 580 |  	dent = kzalloc(len, GFP_NOFS); | 
|---|
| 576 | 581 |  	if (!dent) | 
|---|
| .. | .. | 
|---|
| 602 | 607 |   | 
|---|
| 603 | 608 |  	zero_dent_node_unused(dent); | 
|---|
| 604 | 609 |  	ubifs_prep_grp_node(c, dent, dlen, 0); | 
|---|
 | 610 | +	err = ubifs_node_calc_hash(c, dent, hash_dent);  | 
|---|
 | 611 | +	if (err)  | 
|---|
 | 612 | +		goto out_release;  | 
|---|
| 605 | 613 |   | 
|---|
| 606 | 614 |  	ino = (void *)dent + aligned_dlen; | 
|---|
| 607 | 615 |  	pack_inode(c, ino, inode, 0); | 
|---|
 | 616 | +	err = ubifs_node_calc_hash(c, ino, hash_ino);  | 
|---|
 | 617 | +	if (err)  | 
|---|
 | 618 | +		goto out_release;  | 
|---|
 | 619 | +  | 
|---|
| 608 | 620 |  	ino = (void *)ino + aligned_ilen; | 
|---|
| 609 | 621 |  	pack_inode(c, ino, dir, 1); | 
|---|
 | 622 | +	err = ubifs_node_calc_hash(c, ino, hash_ino_host);  | 
|---|
 | 623 | +	if (err)  | 
|---|
 | 624 | +		goto out_release;  | 
|---|
| 610 | 625 |   | 
|---|
| 611 | 626 |  	if (last_reference) { | 
|---|
| 612 | 627 |  		err = ubifs_add_orphan(c, inode->i_ino); | 
|---|
| .. | .. | 
|---|
| 615 | 630 |  			goto out_finish; | 
|---|
| 616 | 631 |  		} | 
|---|
| 617 | 632 |  		ui->del_cmtno = c->cmt_no; | 
|---|
 | 633 | +		orphan_added = 1;  | 
|---|
| 618 | 634 |  	} | 
|---|
| 619 | 635 |   | 
|---|
| 620 | 636 |  	err = write_head(c, BASEHD, dent, len, &lnum, &dent_offs, sync); | 
|---|
| .. | .. | 
|---|
| 628 | 644 |  	} | 
|---|
| 629 | 645 |  	release_head(c, BASEHD); | 
|---|
| 630 | 646 |  	kfree(dent); | 
|---|
 | 647 | +	ubifs_add_auth_dirt(c, lnum);  | 
|---|
| 631 | 648 |   | 
|---|
| 632 | 649 |  	if (deletion) { | 
|---|
| 633 | 650 |  		if (fname_name(nm) == NULL) | 
|---|
| .. | .. | 
|---|
| 638 | 655 |  			goto out_ro; | 
|---|
| 639 | 656 |  		err = ubifs_add_dirt(c, lnum, dlen); | 
|---|
| 640 | 657 |  	} else | 
|---|
| 641 |  | -		err = ubifs_tnc_add_nm(c, &dent_key, lnum, dent_offs, dlen, nm);  | 
|---|
 | 658 | +		err = ubifs_tnc_add_nm(c, &dent_key, lnum, dent_offs, dlen,  | 
|---|
 | 659 | +				       hash_dent, nm);  | 
|---|
| 642 | 660 |  	if (err) | 
|---|
| 643 | 661 |  		goto out_ro; | 
|---|
| 644 | 662 |   | 
|---|
| .. | .. | 
|---|
| 650 | 668 |  	 */ | 
|---|
| 651 | 669 |  	ino_key_init(c, &ino_key, inode->i_ino); | 
|---|
| 652 | 670 |  	ino_offs = dent_offs + aligned_dlen; | 
|---|
| 653 |  | -	err = ubifs_tnc_add(c, &ino_key, lnum, ino_offs, ilen);  | 
|---|
 | 671 | +	err = ubifs_tnc_add(c, &ino_key, lnum, ino_offs, ilen, hash_ino);  | 
|---|
| 654 | 672 |  	if (err) | 
|---|
| 655 | 673 |  		goto out_ro; | 
|---|
| 656 | 674 |   | 
|---|
| 657 | 675 |  	ino_key_init(c, &ino_key, dir->i_ino); | 
|---|
| 658 | 676 |  	ino_offs += aligned_ilen; | 
|---|
| 659 | 677 |  	err = ubifs_tnc_add(c, &ino_key, lnum, ino_offs, | 
|---|
| 660 |  | -			    UBIFS_INO_NODE_SZ + host_ui->data_len);  | 
|---|
 | 678 | +			    UBIFS_INO_NODE_SZ + host_ui->data_len, hash_ino_host);  | 
|---|
| 661 | 679 |  	if (err) | 
|---|
| 662 | 680 |  		goto out_ro; | 
|---|
| 663 | 681 |   | 
|---|
| .. | .. | 
|---|
| 685 | 703 |  	kfree(dent); | 
|---|
| 686 | 704 |  out_ro: | 
|---|
| 687 | 705 |  	ubifs_ro_mode(c, err); | 
|---|
| 688 |  | -	if (last_reference)  | 
|---|
 | 706 | +	if (orphan_added)  | 
|---|
| 689 | 707 |  		ubifs_delete_orphan(c, inode->i_ino); | 
|---|
| 690 | 708 |  	finish_reservation(c); | 
|---|
| 691 | 709 |  	return err; | 
|---|
| .. | .. | 
|---|
| 706 | 724 |  			 const union ubifs_key *key, const void *buf, int len) | 
|---|
| 707 | 725 |  { | 
|---|
| 708 | 726 |  	struct ubifs_data_node *data; | 
|---|
| 709 |  | -	int err, lnum, offs, compr_type, out_len, compr_len;  | 
|---|
 | 727 | +	int err, lnum, offs, compr_type, out_len, compr_len, auth_len;  | 
|---|
| 710 | 728 |  	int dlen = COMPRESSED_DATA_NODE_BUF_SZ, allocated = 1; | 
|---|
 | 729 | +	int write_len;  | 
|---|
| 711 | 730 |  	struct ubifs_inode *ui = ubifs_inode(inode); | 
|---|
| 712 |  | -	bool encrypted = ubifs_crypt_is_encrypted(inode);  | 
|---|
 | 731 | +	bool encrypted = IS_ENCRYPTED(inode);  | 
|---|
 | 732 | +	u8 hash[UBIFS_HASH_ARR_SZ];  | 
|---|
| 713 | 733 |   | 
|---|
| 714 | 734 |  	dbg_jnlk(key, "ino %lu, blk %u, len %d, key ", | 
|---|
| 715 | 735 |  		(unsigned long)key_inum(c, key), key_block(c, key), len); | 
|---|
| .. | .. | 
|---|
| 718 | 738 |  	if (encrypted) | 
|---|
| 719 | 739 |  		dlen += UBIFS_CIPHER_BLOCK_SIZE; | 
|---|
| 720 | 740 |   | 
|---|
| 721 |  | -	data = kmalloc(dlen, GFP_NOFS | __GFP_NOWARN);  | 
|---|
 | 741 | +	auth_len = ubifs_auth_node_sz(c);  | 
|---|
 | 742 | +  | 
|---|
 | 743 | +	data = kmalloc(dlen + auth_len, GFP_NOFS | __GFP_NOWARN);  | 
|---|
| 722 | 744 |  	if (!data) { | 
|---|
| 723 | 745 |  		/* | 
|---|
| 724 | 746 |  		 * Fall-back to the write reserve buffer. Note, we might be | 
|---|
| .. | .. | 
|---|
| 757 | 779 |  	} | 
|---|
| 758 | 780 |   | 
|---|
| 759 | 781 |  	dlen = UBIFS_DATA_NODE_SZ + out_len; | 
|---|
 | 782 | +	if (ubifs_authenticated(c))  | 
|---|
 | 783 | +		write_len = ALIGN(dlen, 8) + auth_len;  | 
|---|
 | 784 | +	else  | 
|---|
 | 785 | +		write_len = dlen;  | 
|---|
 | 786 | +  | 
|---|
| 760 | 787 |  	data->compr_type = cpu_to_le16(compr_type); | 
|---|
| 761 | 788 |   | 
|---|
| 762 | 789 |  	/* Make reservation before allocating sequence numbers */ | 
|---|
| 763 |  | -	err = make_reservation(c, DATAHD, dlen);  | 
|---|
 | 790 | +	err = make_reservation(c, DATAHD, write_len);  | 
|---|
| 764 | 791 |  	if (err) | 
|---|
| 765 | 792 |  		goto out_free; | 
|---|
| 766 | 793 |   | 
|---|
| 767 |  | -	err = write_node(c, DATAHD, data, dlen, &lnum, &offs);  | 
|---|
 | 794 | +	ubifs_prepare_node(c, data, dlen, 0);  | 
|---|
 | 795 | +	err = write_head(c, DATAHD, data, write_len, &lnum, &offs, 0);  | 
|---|
| 768 | 796 |  	if (err) | 
|---|
| 769 | 797 |  		goto out_release; | 
|---|
 | 798 | +  | 
|---|
 | 799 | +	err = ubifs_node_calc_hash(c, data, hash);  | 
|---|
 | 800 | +	if (err)  | 
|---|
 | 801 | +		goto out_release;  | 
|---|
 | 802 | +  | 
|---|
| 770 | 803 |  	ubifs_wbuf_add_ino_nolock(&c->jheads[DATAHD].wbuf, key_inum(c, key)); | 
|---|
| 771 | 804 |  	release_head(c, DATAHD); | 
|---|
| 772 | 805 |   | 
|---|
| 773 |  | -	err = ubifs_tnc_add(c, key, lnum, offs, dlen);  | 
|---|
 | 806 | +	ubifs_add_auth_dirt(c, lnum);  | 
|---|
 | 807 | +  | 
|---|
 | 808 | +	err = ubifs_tnc_add(c, key, lnum, offs, dlen, hash);  | 
|---|
| 774 | 809 |  	if (err) | 
|---|
| 775 | 810 |  		goto out_ro; | 
|---|
| 776 | 811 |   | 
|---|
| .. | .. | 
|---|
| 806 | 841 |  int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode) | 
|---|
| 807 | 842 |  { | 
|---|
| 808 | 843 |  	int err, lnum, offs; | 
|---|
| 809 |  | -	struct ubifs_ino_node *ino;  | 
|---|
 | 844 | +	struct ubifs_ino_node *ino, *ino_start;  | 
|---|
| 810 | 845 |  	struct ubifs_inode *ui = ubifs_inode(inode); | 
|---|
| 811 |  | -	int sync = 0, len = UBIFS_INO_NODE_SZ, last_reference = !inode->i_nlink;  | 
|---|
 | 846 | +	int sync = 0, write_len = 0, ilen = UBIFS_INO_NODE_SZ;  | 
|---|
 | 847 | +	int last_reference = !inode->i_nlink;  | 
|---|
 | 848 | +	int kill_xattrs = ui->xattr_cnt && last_reference;  | 
|---|
 | 849 | +	u8 hash[UBIFS_HASH_ARR_SZ];  | 
|---|
| 812 | 850 |   | 
|---|
| 813 | 851 |  	dbg_jnl("ino %lu, nlink %u", inode->i_ino, inode->i_nlink); | 
|---|
| 814 | 852 |   | 
|---|
| .. | .. | 
|---|
| 817 | 855 |  	 * need to synchronize the write-buffer either. | 
|---|
| 818 | 856 |  	 */ | 
|---|
| 819 | 857 |  	if (!last_reference) { | 
|---|
| 820 |  | -		len += ui->data_len;  | 
|---|
 | 858 | +		ilen += ui->data_len;  | 
|---|
| 821 | 859 |  		sync = IS_SYNC(inode); | 
|---|
 | 860 | +	} else if (kill_xattrs) {  | 
|---|
 | 861 | +		write_len += UBIFS_INO_NODE_SZ * ui->xattr_cnt;  | 
|---|
| 822 | 862 |  	} | 
|---|
| 823 |  | -	ino = kmalloc(len, GFP_NOFS);  | 
|---|
 | 863 | +  | 
|---|
 | 864 | +	if (ubifs_authenticated(c))  | 
|---|
 | 865 | +		write_len += ALIGN(ilen, 8) + ubifs_auth_node_sz(c);  | 
|---|
 | 866 | +	else  | 
|---|
 | 867 | +		write_len += ilen;  | 
|---|
 | 868 | +  | 
|---|
 | 869 | +	ino_start = ino = kmalloc(write_len, GFP_NOFS);  | 
|---|
| 824 | 870 |  	if (!ino) | 
|---|
| 825 | 871 |  		return -ENOMEM; | 
|---|
| 826 | 872 |   | 
|---|
| 827 | 873 |  	/* Make reservation before allocating sequence numbers */ | 
|---|
| 828 |  | -	err = make_reservation(c, BASEHD, len);  | 
|---|
 | 874 | +	err = make_reservation(c, BASEHD, write_len);  | 
|---|
| 829 | 875 |  	if (err) | 
|---|
| 830 | 876 |  		goto out_free; | 
|---|
| 831 | 877 |   | 
|---|
 | 878 | +	if (kill_xattrs) {  | 
|---|
 | 879 | +		union ubifs_key key;  | 
|---|
 | 880 | +		struct fscrypt_name nm = {0};  | 
|---|
 | 881 | +		struct inode *xino;  | 
|---|
 | 882 | +		struct ubifs_dent_node *xent, *pxent = NULL;  | 
|---|
 | 883 | +  | 
|---|
 | 884 | +		if (ui->xattr_cnt > ubifs_xattr_max_cnt(c)) {  | 
|---|
 | 885 | +			err = -EPERM;  | 
|---|
 | 886 | +			ubifs_err(c, "Cannot delete inode, it has too much xattrs!");  | 
|---|
 | 887 | +			goto out_release;  | 
|---|
 | 888 | +		}  | 
|---|
 | 889 | +  | 
|---|
 | 890 | +		lowest_xent_key(c, &key, inode->i_ino);  | 
|---|
 | 891 | +		while (1) {  | 
|---|
 | 892 | +			xent = ubifs_tnc_next_ent(c, &key, &nm);  | 
|---|
 | 893 | +			if (IS_ERR(xent)) {  | 
|---|
 | 894 | +				err = PTR_ERR(xent);  | 
|---|
 | 895 | +				if (err == -ENOENT)  | 
|---|
 | 896 | +					break;  | 
|---|
 | 897 | +  | 
|---|
 | 898 | +				kfree(pxent);  | 
|---|
 | 899 | +				goto out_release;  | 
|---|
 | 900 | +			}  | 
|---|
 | 901 | +  | 
|---|
 | 902 | +			fname_name(&nm) = xent->name;  | 
|---|
 | 903 | +			fname_len(&nm) = le16_to_cpu(xent->nlen);  | 
|---|
 | 904 | +  | 
|---|
 | 905 | +			xino = ubifs_iget(c->vfs_sb, le64_to_cpu(xent->inum));  | 
|---|
 | 906 | +			if (IS_ERR(xino)) {  | 
|---|
 | 907 | +				err = PTR_ERR(xino);  | 
|---|
 | 908 | +				ubifs_err(c, "dead directory entry '%s', error %d",  | 
|---|
 | 909 | +					  xent->name, err);  | 
|---|
 | 910 | +				ubifs_ro_mode(c, err);  | 
|---|
 | 911 | +				kfree(pxent);  | 
|---|
 | 912 | +				kfree(xent);  | 
|---|
 | 913 | +				goto out_release;  | 
|---|
 | 914 | +			}  | 
|---|
 | 915 | +			ubifs_assert(c, ubifs_inode(xino)->xattr);  | 
|---|
 | 916 | +  | 
|---|
 | 917 | +			clear_nlink(xino);  | 
|---|
 | 918 | +			pack_inode(c, ino, xino, 0);  | 
|---|
 | 919 | +			ino = (void *)ino + UBIFS_INO_NODE_SZ;  | 
|---|
 | 920 | +			iput(xino);  | 
|---|
 | 921 | +  | 
|---|
 | 922 | +			kfree(pxent);  | 
|---|
 | 923 | +			pxent = xent;  | 
|---|
 | 924 | +			key_read(c, &xent->key, &key);  | 
|---|
 | 925 | +		}  | 
|---|
 | 926 | +		kfree(pxent);  | 
|---|
 | 927 | +	}  | 
|---|
 | 928 | +  | 
|---|
| 832 | 929 |  	pack_inode(c, ino, inode, 1); | 
|---|
| 833 |  | -	err = write_head(c, BASEHD, ino, len, &lnum, &offs, sync);  | 
|---|
 | 930 | +	err = ubifs_node_calc_hash(c, ino, hash);  | 
|---|
 | 931 | +	if (err)  | 
|---|
 | 932 | +		goto out_release;  | 
|---|
 | 933 | +  | 
|---|
 | 934 | +	err = write_head(c, BASEHD, ino_start, write_len, &lnum, &offs, sync);  | 
|---|
| 834 | 935 |  	if (err) | 
|---|
| 835 | 936 |  		goto out_release; | 
|---|
| 836 | 937 |  	if (!sync) | 
|---|
| .. | .. | 
|---|
| 843 | 944 |  		if (err) | 
|---|
| 844 | 945 |  			goto out_ro; | 
|---|
| 845 | 946 |  		ubifs_delete_orphan(c, inode->i_ino); | 
|---|
| 846 |  | -		err = ubifs_add_dirt(c, lnum, len);  | 
|---|
 | 947 | +		err = ubifs_add_dirt(c, lnum, write_len);  | 
|---|
| 847 | 948 |  	} else { | 
|---|
| 848 | 949 |  		union ubifs_key key; | 
|---|
| 849 | 950 |   | 
|---|
 | 951 | +		ubifs_add_auth_dirt(c, lnum);  | 
|---|
 | 952 | +  | 
|---|
| 850 | 953 |  		ino_key_init(c, &key, inode->i_ino); | 
|---|
| 851 |  | -		err = ubifs_tnc_add(c, &key, lnum, offs, len);  | 
|---|
 | 954 | +		err = ubifs_tnc_add(c, &key, lnum, offs, ilen, hash);  | 
|---|
| 852 | 955 |  	} | 
|---|
| 853 | 956 |  	if (err) | 
|---|
| 854 | 957 |  		goto out_ro; | 
|---|
| .. | .. | 
|---|
| 857 | 960 |  	spin_lock(&ui->ui_lock); | 
|---|
| 858 | 961 |  	ui->synced_i_size = ui->ui_size; | 
|---|
| 859 | 962 |  	spin_unlock(&ui->ui_lock); | 
|---|
| 860 |  | -	kfree(ino);  | 
|---|
 | 963 | +	kfree(ino_start);  | 
|---|
| 861 | 964 |  	return 0; | 
|---|
| 862 | 965 |   | 
|---|
| 863 | 966 |  out_release: | 
|---|
| .. | .. | 
|---|
| 866 | 969 |  	ubifs_ro_mode(c, err); | 
|---|
| 867 | 970 |  	finish_reservation(c); | 
|---|
| 868 | 971 |  out_free: | 
|---|
| 869 |  | -	kfree(ino);  | 
|---|
 | 972 | +	kfree(ino_start);  | 
|---|
| 870 | 973 |  	return err; | 
|---|
| 871 | 974 |  } | 
|---|
| 872 | 975 |   | 
|---|
| .. | .. | 
|---|
| 906 | 1009 |   | 
|---|
| 907 | 1010 |  	ubifs_assert(c, inode->i_nlink == 0); | 
|---|
| 908 | 1011 |   | 
|---|
| 909 |  | -	if (ui->del_cmtno != c->cmt_no)  | 
|---|
| 910 |  | -		/* A commit happened for sure */  | 
|---|
 | 1012 | +	if (ui->xattr_cnt || ui->del_cmtno != c->cmt_no)  | 
|---|
 | 1013 | +		/* A commit happened for sure or inode hosts xattrs */  | 
|---|
| 911 | 1014 |  		return ubifs_jnl_write_inode(c, inode); | 
|---|
| 912 | 1015 |   | 
|---|
| 913 | 1016 |  	down_read(&c->commit_sem); | 
|---|
| .. | .. | 
|---|
| 958 | 1061 |  	int aligned_dlen1, aligned_dlen2; | 
|---|
| 959 | 1062 |  	int twoparents = (fst_dir != snd_dir); | 
|---|
| 960 | 1063 |  	void *p; | 
|---|
 | 1064 | +	u8 hash_dent1[UBIFS_HASH_ARR_SZ];  | 
|---|
 | 1065 | +	u8 hash_dent2[UBIFS_HASH_ARR_SZ];  | 
|---|
 | 1066 | +	u8 hash_p1[UBIFS_HASH_ARR_SZ];  | 
|---|
 | 1067 | +	u8 hash_p2[UBIFS_HASH_ARR_SZ];  | 
|---|
| 961 | 1068 |   | 
|---|
| 962 | 1069 |  	ubifs_assert(c, ubifs_inode(fst_dir)->data_len == 0); | 
|---|
| 963 | 1070 |  	ubifs_assert(c, ubifs_inode(snd_dir)->data_len == 0); | 
|---|
| .. | .. | 
|---|
| 972 | 1079 |  	len = aligned_dlen1 + aligned_dlen2 + ALIGN(plen, 8); | 
|---|
| 973 | 1080 |  	if (twoparents) | 
|---|
| 974 | 1081 |  		len += plen; | 
|---|
 | 1082 | +  | 
|---|
 | 1083 | +	len += ubifs_auth_node_sz(c);  | 
|---|
| 975 | 1084 |   | 
|---|
| 976 | 1085 |  	dent1 = kzalloc(len, GFP_NOFS); | 
|---|
| 977 | 1086 |  	if (!dent1) | 
|---|
| .. | .. | 
|---|
| 993 | 1102 |  	set_dent_cookie(c, dent1); | 
|---|
| 994 | 1103 |  	zero_dent_node_unused(dent1); | 
|---|
| 995 | 1104 |  	ubifs_prep_grp_node(c, dent1, dlen1, 0); | 
|---|
 | 1105 | +	err = ubifs_node_calc_hash(c, dent1, hash_dent1);  | 
|---|
 | 1106 | +	if (err)  | 
|---|
 | 1107 | +		goto out_release;  | 
|---|
| 996 | 1108 |   | 
|---|
| 997 | 1109 |  	/* Make new dent for 2nd entry */ | 
|---|
| 998 | 1110 |  	dent2 = (void *)dent1 + aligned_dlen1; | 
|---|
| .. | .. | 
|---|
| 1006 | 1118 |  	set_dent_cookie(c, dent2); | 
|---|
| 1007 | 1119 |  	zero_dent_node_unused(dent2); | 
|---|
| 1008 | 1120 |  	ubifs_prep_grp_node(c, dent2, dlen2, 0); | 
|---|
 | 1121 | +	err = ubifs_node_calc_hash(c, dent2, hash_dent2);  | 
|---|
 | 1122 | +	if (err)  | 
|---|
 | 1123 | +		goto out_release;  | 
|---|
| 1009 | 1124 |   | 
|---|
| 1010 | 1125 |  	p = (void *)dent2 + aligned_dlen2; | 
|---|
| 1011 |  | -	if (!twoparents)  | 
|---|
 | 1126 | +	if (!twoparents) {  | 
|---|
| 1012 | 1127 |  		pack_inode(c, p, fst_dir, 1); | 
|---|
| 1013 |  | -	else {  | 
|---|
 | 1128 | +		err = ubifs_node_calc_hash(c, p, hash_p1);  | 
|---|
 | 1129 | +		if (err)  | 
|---|
 | 1130 | +			goto out_release;  | 
|---|
 | 1131 | +	} else {  | 
|---|
| 1014 | 1132 |  		pack_inode(c, p, fst_dir, 0); | 
|---|
 | 1133 | +		err = ubifs_node_calc_hash(c, p, hash_p1);  | 
|---|
 | 1134 | +		if (err)  | 
|---|
 | 1135 | +			goto out_release;  | 
|---|
| 1015 | 1136 |  		p += ALIGN(plen, 8); | 
|---|
| 1016 | 1137 |  		pack_inode(c, p, snd_dir, 1); | 
|---|
 | 1138 | +		err = ubifs_node_calc_hash(c, p, hash_p2);  | 
|---|
 | 1139 | +		if (err)  | 
|---|
 | 1140 | +			goto out_release;  | 
|---|
| 1017 | 1141 |  	} | 
|---|
| 1018 | 1142 |   | 
|---|
| 1019 | 1143 |  	err = write_head(c, BASEHD, dent1, len, &lnum, &offs, sync); | 
|---|
| .. | .. | 
|---|
| 1027 | 1151 |  	} | 
|---|
| 1028 | 1152 |  	release_head(c, BASEHD); | 
|---|
| 1029 | 1153 |   | 
|---|
 | 1154 | +	ubifs_add_auth_dirt(c, lnum);  | 
|---|
 | 1155 | +  | 
|---|
| 1030 | 1156 |  	dent_key_init(c, &key, snd_dir->i_ino, snd_nm); | 
|---|
| 1031 |  | -	err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen1, snd_nm);  | 
|---|
 | 1157 | +	err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen1, hash_dent1, snd_nm);  | 
|---|
| 1032 | 1158 |  	if (err) | 
|---|
| 1033 | 1159 |  		goto out_ro; | 
|---|
| 1034 | 1160 |   | 
|---|
| 1035 | 1161 |  	offs += aligned_dlen1; | 
|---|
| 1036 | 1162 |  	dent_key_init(c, &key, fst_dir->i_ino, fst_nm); | 
|---|
| 1037 |  | -	err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen2, fst_nm);  | 
|---|
 | 1163 | +	err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen2, hash_dent2, fst_nm);  | 
|---|
| 1038 | 1164 |  	if (err) | 
|---|
| 1039 | 1165 |  		goto out_ro; | 
|---|
| 1040 | 1166 |   | 
|---|
| 1041 | 1167 |  	offs += aligned_dlen2; | 
|---|
| 1042 | 1168 |   | 
|---|
| 1043 | 1169 |  	ino_key_init(c, &key, fst_dir->i_ino); | 
|---|
| 1044 |  | -	err = ubifs_tnc_add(c, &key, lnum, offs, plen);  | 
|---|
 | 1170 | +	err = ubifs_tnc_add(c, &key, lnum, offs, plen, hash_p1);  | 
|---|
| 1045 | 1171 |  	if (err) | 
|---|
| 1046 | 1172 |  		goto out_ro; | 
|---|
| 1047 | 1173 |   | 
|---|
| 1048 | 1174 |  	if (twoparents) { | 
|---|
| 1049 | 1175 |  		offs += ALIGN(plen, 8); | 
|---|
| 1050 | 1176 |  		ino_key_init(c, &key, snd_dir->i_ino); | 
|---|
| 1051 |  | -		err = ubifs_tnc_add(c, &key, lnum, offs, plen);  | 
|---|
 | 1177 | +		err = ubifs_tnc_add(c, &key, lnum, offs, plen, hash_p2);  | 
|---|
| 1052 | 1178 |  		if (err) | 
|---|
| 1053 | 1179 |  			goto out_ro; | 
|---|
| 1054 | 1180 |  	} | 
|---|
| .. | .. | 
|---|
| 1096 | 1222 |  	void *p; | 
|---|
| 1097 | 1223 |  	union ubifs_key key; | 
|---|
| 1098 | 1224 |  	struct ubifs_dent_node *dent, *dent2; | 
|---|
| 1099 |  | -	int err, dlen1, dlen2, ilen, lnum, offs, len;  | 
|---|
 | 1225 | +	int err, dlen1, dlen2, ilen, lnum, offs, len, orphan_added = 0;  | 
|---|
| 1100 | 1226 |  	int aligned_dlen1, aligned_dlen2, plen = UBIFS_INO_NODE_SZ; | 
|---|
| 1101 | 1227 |  	int last_reference = !!(new_inode && new_inode->i_nlink == 0); | 
|---|
| 1102 | 1228 |  	int move = (old_dir != new_dir); | 
|---|
| 1103 |  | -	struct ubifs_inode *uninitialized_var(new_ui);  | 
|---|
 | 1229 | +	struct ubifs_inode *new_ui;  | 
|---|
 | 1230 | +	u8 hash_old_dir[UBIFS_HASH_ARR_SZ];  | 
|---|
 | 1231 | +	u8 hash_new_dir[UBIFS_HASH_ARR_SZ];  | 
|---|
 | 1232 | +	u8 hash_new_inode[UBIFS_HASH_ARR_SZ];  | 
|---|
 | 1233 | +	u8 hash_dent1[UBIFS_HASH_ARR_SZ];  | 
|---|
 | 1234 | +	u8 hash_dent2[UBIFS_HASH_ARR_SZ];  | 
|---|
| 1104 | 1235 |   | 
|---|
| 1105 | 1236 |  	ubifs_assert(c, ubifs_inode(old_dir)->data_len == 0); | 
|---|
| 1106 | 1237 |  	ubifs_assert(c, ubifs_inode(new_dir)->data_len == 0); | 
|---|
| .. | .. | 
|---|
| 1123 | 1254 |  	len = aligned_dlen1 + aligned_dlen2 + ALIGN(ilen, 8) + ALIGN(plen, 8); | 
|---|
| 1124 | 1255 |  	if (move) | 
|---|
| 1125 | 1256 |  		len += plen; | 
|---|
 | 1257 | +  | 
|---|
 | 1258 | +	len += ubifs_auth_node_sz(c);  | 
|---|
 | 1259 | +  | 
|---|
| 1126 | 1260 |  	dent = kzalloc(len, GFP_NOFS); | 
|---|
| 1127 | 1261 |  	if (!dent) | 
|---|
| 1128 | 1262 |  		return -ENOMEM; | 
|---|
| .. | .. | 
|---|
| 1143 | 1277 |  	set_dent_cookie(c, dent); | 
|---|
| 1144 | 1278 |  	zero_dent_node_unused(dent); | 
|---|
| 1145 | 1279 |  	ubifs_prep_grp_node(c, dent, dlen1, 0); | 
|---|
 | 1280 | +	err = ubifs_node_calc_hash(c, dent, hash_dent1);  | 
|---|
 | 1281 | +	if (err)  | 
|---|
 | 1282 | +		goto out_release;  | 
|---|
| 1146 | 1283 |   | 
|---|
| 1147 | 1284 |  	dent2 = (void *)dent + aligned_dlen1; | 
|---|
| 1148 | 1285 |  	dent2->ch.node_type = UBIFS_DENT_NODE; | 
|---|
| .. | .. | 
|---|
| 1162 | 1299 |  	set_dent_cookie(c, dent2); | 
|---|
| 1163 | 1300 |  	zero_dent_node_unused(dent2); | 
|---|
| 1164 | 1301 |  	ubifs_prep_grp_node(c, dent2, dlen2, 0); | 
|---|
 | 1302 | +	err = ubifs_node_calc_hash(c, dent2, hash_dent2);  | 
|---|
 | 1303 | +	if (err)  | 
|---|
 | 1304 | +		goto out_release;  | 
|---|
| 1165 | 1305 |   | 
|---|
| 1166 | 1306 |  	p = (void *)dent2 + aligned_dlen2; | 
|---|
| 1167 | 1307 |  	if (new_inode) { | 
|---|
| 1168 | 1308 |  		pack_inode(c, p, new_inode, 0); | 
|---|
 | 1309 | +		err = ubifs_node_calc_hash(c, p, hash_new_inode);  | 
|---|
 | 1310 | +		if (err)  | 
|---|
 | 1311 | +			goto out_release;  | 
|---|
 | 1312 | +  | 
|---|
| 1169 | 1313 |  		p += ALIGN(ilen, 8); | 
|---|
| 1170 | 1314 |  	} | 
|---|
| 1171 | 1315 |   | 
|---|
| 1172 |  | -	if (!move)  | 
|---|
 | 1316 | +	if (!move) {  | 
|---|
| 1173 | 1317 |  		pack_inode(c, p, old_dir, 1); | 
|---|
| 1174 |  | -	else {  | 
|---|
 | 1318 | +		err = ubifs_node_calc_hash(c, p, hash_old_dir);  | 
|---|
 | 1319 | +		if (err)  | 
|---|
 | 1320 | +			goto out_release;  | 
|---|
 | 1321 | +	} else {  | 
|---|
| 1175 | 1322 |  		pack_inode(c, p, old_dir, 0); | 
|---|
 | 1323 | +		err = ubifs_node_calc_hash(c, p, hash_old_dir);  | 
|---|
 | 1324 | +		if (err)  | 
|---|
 | 1325 | +			goto out_release;  | 
|---|
 | 1326 | +  | 
|---|
| 1176 | 1327 |  		p += ALIGN(plen, 8); | 
|---|
| 1177 | 1328 |  		pack_inode(c, p, new_dir, 1); | 
|---|
 | 1329 | +		err = ubifs_node_calc_hash(c, p, hash_new_dir);  | 
|---|
 | 1330 | +		if (err)  | 
|---|
 | 1331 | +			goto out_release;  | 
|---|
| 1178 | 1332 |  	} | 
|---|
| 1179 | 1333 |   | 
|---|
| 1180 | 1334 |  	if (last_reference) { | 
|---|
| .. | .. | 
|---|
| 1184 | 1338 |  			goto out_finish; | 
|---|
| 1185 | 1339 |  		} | 
|---|
| 1186 | 1340 |  		new_ui->del_cmtno = c->cmt_no; | 
|---|
 | 1341 | +		orphan_added = 1;  | 
|---|
| 1187 | 1342 |  	} | 
|---|
| 1188 | 1343 |   | 
|---|
| 1189 | 1344 |  	err = write_head(c, BASEHD, dent, len, &lnum, &offs, sync); | 
|---|
| .. | .. | 
|---|
| 1200 | 1355 |  	} | 
|---|
| 1201 | 1356 |  	release_head(c, BASEHD); | 
|---|
| 1202 | 1357 |   | 
|---|
 | 1358 | +	ubifs_add_auth_dirt(c, lnum);  | 
|---|
 | 1359 | +  | 
|---|
| 1203 | 1360 |  	dent_key_init(c, &key, new_dir->i_ino, new_nm); | 
|---|
| 1204 |  | -	err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen1, new_nm);  | 
|---|
 | 1361 | +	err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen1, hash_dent1, new_nm);  | 
|---|
| 1205 | 1362 |  	if (err) | 
|---|
| 1206 | 1363 |  		goto out_ro; | 
|---|
| 1207 | 1364 |   | 
|---|
| 1208 | 1365 |  	offs += aligned_dlen1; | 
|---|
| 1209 | 1366 |  	if (whiteout) { | 
|---|
| 1210 | 1367 |  		dent_key_init(c, &key, old_dir->i_ino, old_nm); | 
|---|
| 1211 |  | -		err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen2, old_nm);  | 
|---|
 | 1368 | +		err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen2, hash_dent2, old_nm);  | 
|---|
| 1212 | 1369 |  		if (err) | 
|---|
| 1213 | 1370 |  			goto out_ro; | 
|---|
| 1214 | 1371 |   | 
|---|
| .. | .. | 
|---|
| 1227 | 1384 |  	offs += aligned_dlen2; | 
|---|
| 1228 | 1385 |  	if (new_inode) { | 
|---|
| 1229 | 1386 |  		ino_key_init(c, &key, new_inode->i_ino); | 
|---|
| 1230 |  | -		err = ubifs_tnc_add(c, &key, lnum, offs, ilen);  | 
|---|
 | 1387 | +		err = ubifs_tnc_add(c, &key, lnum, offs, ilen, hash_new_inode);  | 
|---|
| 1231 | 1388 |  		if (err) | 
|---|
| 1232 | 1389 |  			goto out_ro; | 
|---|
| 1233 | 1390 |  		offs += ALIGN(ilen, 8); | 
|---|
| 1234 | 1391 |  	} | 
|---|
| 1235 | 1392 |   | 
|---|
| 1236 | 1393 |  	ino_key_init(c, &key, old_dir->i_ino); | 
|---|
| 1237 |  | -	err = ubifs_tnc_add(c, &key, lnum, offs, plen);  | 
|---|
 | 1394 | +	err = ubifs_tnc_add(c, &key, lnum, offs, plen, hash_old_dir);  | 
|---|
| 1238 | 1395 |  	if (err) | 
|---|
| 1239 | 1396 |  		goto out_ro; | 
|---|
| 1240 | 1397 |   | 
|---|
| 1241 | 1398 |  	if (move) { | 
|---|
| 1242 | 1399 |  		offs += ALIGN(plen, 8); | 
|---|
| 1243 | 1400 |  		ino_key_init(c, &key, new_dir->i_ino); | 
|---|
| 1244 |  | -		err = ubifs_tnc_add(c, &key, lnum, offs, plen);  | 
|---|
 | 1401 | +		err = ubifs_tnc_add(c, &key, lnum, offs, plen, hash_new_dir);  | 
|---|
| 1245 | 1402 |  		if (err) | 
|---|
| 1246 | 1403 |  			goto out_ro; | 
|---|
| 1247 | 1404 |  	} | 
|---|
| .. | .. | 
|---|
| 1263 | 1420 |  	release_head(c, BASEHD); | 
|---|
| 1264 | 1421 |  out_ro: | 
|---|
| 1265 | 1422 |  	ubifs_ro_mode(c, err); | 
|---|
| 1266 |  | -	if (last_reference)  | 
|---|
 | 1423 | +	if (orphan_added)  | 
|---|
| 1267 | 1424 |  		ubifs_delete_orphan(c, new_inode->i_ino); | 
|---|
| 1268 | 1425 |  out_finish: | 
|---|
| 1269 | 1426 |  	finish_reservation(c); | 
|---|
| .. | .. | 
|---|
| 1298 | 1455 |  	dlen = old_dlen = le32_to_cpu(dn->ch.len) - UBIFS_DATA_NODE_SZ; | 
|---|
| 1299 | 1456 |  	compr_type = le16_to_cpu(dn->compr_type); | 
|---|
| 1300 | 1457 |   | 
|---|
| 1301 |  | -	if (ubifs_crypt_is_encrypted(inode)) {  | 
|---|
 | 1458 | +	if (IS_ENCRYPTED(inode)) {  | 
|---|
| 1302 | 1459 |  		err = ubifs_decrypt(inode, dn, &dlen, block); | 
|---|
| 1303 | 1460 |  		if (err) | 
|---|
| 1304 | 1461 |  			goto out; | 
|---|
| .. | .. | 
|---|
| 1314 | 1471 |  		ubifs_compress(c, buf, *new_len, &dn->data, &out_len, &compr_type); | 
|---|
| 1315 | 1472 |  	} | 
|---|
| 1316 | 1473 |   | 
|---|
| 1317 |  | -	if (ubifs_crypt_is_encrypted(inode)) {  | 
|---|
 | 1474 | +	if (IS_ENCRYPTED(inode)) {  | 
|---|
| 1318 | 1475 |  		err = ubifs_encrypt(inode, dn, out_len, &old_dlen, block); | 
|---|
| 1319 | 1476 |  		if (err) | 
|---|
| 1320 | 1477 |  			goto out; | 
|---|
| .. | .. | 
|---|
| 1355 | 1512 |  	union ubifs_key key, to_key; | 
|---|
| 1356 | 1513 |  	struct ubifs_ino_node *ino; | 
|---|
| 1357 | 1514 |  	struct ubifs_trun_node *trun; | 
|---|
| 1358 |  | -	struct ubifs_data_node *uninitialized_var(dn);  | 
|---|
 | 1515 | +	struct ubifs_data_node *dn;  | 
|---|
| 1359 | 1516 |  	int err, dlen, len, lnum, offs, bit, sz, sync = IS_SYNC(inode); | 
|---|
| 1360 | 1517 |  	struct ubifs_inode *ui = ubifs_inode(inode); | 
|---|
| 1361 | 1518 |  	ino_t inum = inode->i_ino; | 
|---|
| 1362 | 1519 |  	unsigned int blk; | 
|---|
 | 1520 | +	u8 hash_ino[UBIFS_HASH_ARR_SZ];  | 
|---|
 | 1521 | +	u8 hash_dn[UBIFS_HASH_ARR_SZ];  | 
|---|
| 1363 | 1522 |   | 
|---|
| 1364 | 1523 |  	dbg_jnl("ino %lu, size %lld -> %lld", | 
|---|
| 1365 | 1524 |  		(unsigned long)inum, old_size, new_size); | 
|---|
| .. | .. | 
|---|
| 1369 | 1528 |   | 
|---|
| 1370 | 1529 |  	sz = UBIFS_TRUN_NODE_SZ + UBIFS_INO_NODE_SZ + | 
|---|
| 1371 | 1530 |  	     UBIFS_MAX_DATA_NODE_SZ * WORST_COMPR_FACTOR; | 
|---|
 | 1531 | +  | 
|---|
 | 1532 | +	sz += ubifs_auth_node_sz(c);  | 
|---|
 | 1533 | +  | 
|---|
| 1372 | 1534 |  	ino = kmalloc(sz, GFP_NOFS); | 
|---|
| 1373 | 1535 |  	if (!ino) | 
|---|
| 1374 | 1536 |  		return -ENOMEM; | 
|---|
| .. | .. | 
|---|
| 1414 | 1576 |   | 
|---|
| 1415 | 1577 |  	/* Must make reservation before allocating sequence numbers */ | 
|---|
| 1416 | 1578 |  	len = UBIFS_TRUN_NODE_SZ + UBIFS_INO_NODE_SZ; | 
|---|
| 1417 |  | -	if (dlen)  | 
|---|
 | 1579 | +  | 
|---|
 | 1580 | +	if (ubifs_authenticated(c))  | 
|---|
 | 1581 | +		len += ALIGN(dlen, 8) + ubifs_auth_node_sz(c);  | 
|---|
 | 1582 | +	else  | 
|---|
| 1418 | 1583 |  		len += dlen; | 
|---|
 | 1584 | +  | 
|---|
| 1419 | 1585 |  	err = make_reservation(c, BASEHD, len); | 
|---|
| 1420 | 1586 |  	if (err) | 
|---|
| 1421 | 1587 |  		goto out_free; | 
|---|
| 1422 | 1588 |   | 
|---|
| 1423 | 1589 |  	pack_inode(c, ino, inode, 0); | 
|---|
 | 1590 | +	err = ubifs_node_calc_hash(c, ino, hash_ino);  | 
|---|
 | 1591 | +	if (err)  | 
|---|
 | 1592 | +		goto out_release;  | 
|---|
 | 1593 | +  | 
|---|
| 1424 | 1594 |  	ubifs_prep_grp_node(c, trun, UBIFS_TRUN_NODE_SZ, dlen ? 0 : 1); | 
|---|
| 1425 |  | -	if (dlen)  | 
|---|
 | 1595 | +	if (dlen) {  | 
|---|
| 1426 | 1596 |  		ubifs_prep_grp_node(c, dn, dlen, 1); | 
|---|
 | 1597 | +		err = ubifs_node_calc_hash(c, dn, hash_dn);  | 
|---|
 | 1598 | +		if (err)  | 
|---|
 | 1599 | +			goto out_release;  | 
|---|
 | 1600 | +	}  | 
|---|
| 1427 | 1601 |   | 
|---|
| 1428 | 1602 |  	err = write_head(c, BASEHD, ino, len, &lnum, &offs, sync); | 
|---|
| 1429 | 1603 |  	if (err) | 
|---|
| .. | .. | 
|---|
| 1432 | 1606 |  		ubifs_wbuf_add_ino_nolock(&c->jheads[BASEHD].wbuf, inum); | 
|---|
| 1433 | 1607 |  	release_head(c, BASEHD); | 
|---|
| 1434 | 1608 |   | 
|---|
 | 1609 | +	ubifs_add_auth_dirt(c, lnum);  | 
|---|
 | 1610 | +  | 
|---|
| 1435 | 1611 |  	if (dlen) { | 
|---|
| 1436 | 1612 |  		sz = offs + UBIFS_INO_NODE_SZ + UBIFS_TRUN_NODE_SZ; | 
|---|
| 1437 |  | -		err = ubifs_tnc_add(c, &key, lnum, sz, dlen);  | 
|---|
 | 1613 | +		err = ubifs_tnc_add(c, &key, lnum, sz, dlen, hash_dn);  | 
|---|
| 1438 | 1614 |  		if (err) | 
|---|
| 1439 | 1615 |  			goto out_ro; | 
|---|
| 1440 | 1616 |  	} | 
|---|
| 1441 | 1617 |   | 
|---|
| 1442 | 1618 |  	ino_key_init(c, &key, inum); | 
|---|
| 1443 |  | -	err = ubifs_tnc_add(c, &key, lnum, offs, UBIFS_INO_NODE_SZ);  | 
|---|
 | 1619 | +	err = ubifs_tnc_add(c, &key, lnum, offs, UBIFS_INO_NODE_SZ, hash_ino);  | 
|---|
| 1444 | 1620 |  	if (err) | 
|---|
| 1445 | 1621 |  		goto out_ro; | 
|---|
| 1446 | 1622 |   | 
|---|
| .. | .. | 
|---|
| 1495 | 1671 |  			   const struct inode *inode, | 
|---|
| 1496 | 1672 |  			   const struct fscrypt_name *nm) | 
|---|
| 1497 | 1673 |  { | 
|---|
| 1498 |  | -	int err, xlen, hlen, len, lnum, xent_offs, aligned_xlen;  | 
|---|
 | 1674 | +	int err, xlen, hlen, len, lnum, xent_offs, aligned_xlen, write_len;  | 
|---|
| 1499 | 1675 |  	struct ubifs_dent_node *xent; | 
|---|
| 1500 | 1676 |  	struct ubifs_ino_node *ino; | 
|---|
| 1501 | 1677 |  	union ubifs_key xent_key, key1, key2; | 
|---|
| 1502 | 1678 |  	int sync = IS_DIRSYNC(host); | 
|---|
| 1503 | 1679 |  	struct ubifs_inode *host_ui = ubifs_inode(host); | 
|---|
 | 1680 | +	u8 hash[UBIFS_HASH_ARR_SZ];  | 
|---|
| 1504 | 1681 |   | 
|---|
| 1505 | 1682 |  	ubifs_assert(c, inode->i_nlink == 0); | 
|---|
| 1506 | 1683 |  	ubifs_assert(c, mutex_is_locked(&host_ui->ui_mutex)); | 
|---|
| .. | .. | 
|---|
| 1514 | 1691 |  	hlen = host_ui->data_len + UBIFS_INO_NODE_SZ; | 
|---|
| 1515 | 1692 |  	len = aligned_xlen + UBIFS_INO_NODE_SZ + ALIGN(hlen, 8); | 
|---|
| 1516 | 1693 |   | 
|---|
| 1517 |  | -	xent = kzalloc(len, GFP_NOFS);  | 
|---|
 | 1694 | +	write_len = len + ubifs_auth_node_sz(c);  | 
|---|
 | 1695 | +  | 
|---|
 | 1696 | +	xent = kzalloc(write_len, GFP_NOFS);  | 
|---|
| 1518 | 1697 |  	if (!xent) | 
|---|
| 1519 | 1698 |  		return -ENOMEM; | 
|---|
| 1520 | 1699 |   | 
|---|
| 1521 | 1700 |  	/* Make reservation before allocating sequence numbers */ | 
|---|
| 1522 |  | -	err = make_reservation(c, BASEHD, len);  | 
|---|
 | 1701 | +	err = make_reservation(c, BASEHD, write_len);  | 
|---|
| 1523 | 1702 |  	if (err) { | 
|---|
| 1524 | 1703 |  		kfree(xent); | 
|---|
| 1525 | 1704 |  		return err; | 
|---|
| .. | .. | 
|---|
| 1540 | 1719 |  	pack_inode(c, ino, inode, 0); | 
|---|
| 1541 | 1720 |  	ino = (void *)ino + UBIFS_INO_NODE_SZ; | 
|---|
| 1542 | 1721 |  	pack_inode(c, ino, host, 1); | 
|---|
 | 1722 | +	err = ubifs_node_calc_hash(c, ino, hash);  | 
|---|
 | 1723 | +	if (err)  | 
|---|
 | 1724 | +		goto out_release;  | 
|---|
| 1543 | 1725 |   | 
|---|
| 1544 |  | -	err = write_head(c, BASEHD, xent, len, &lnum, &xent_offs, sync);  | 
|---|
 | 1726 | +	err = write_head(c, BASEHD, xent, write_len, &lnum, &xent_offs, sync);  | 
|---|
| 1545 | 1727 |  	if (!sync && !err) | 
|---|
| 1546 | 1728 |  		ubifs_wbuf_add_ino_nolock(&c->jheads[BASEHD].wbuf, host->i_ino); | 
|---|
| 1547 | 1729 |  	release_head(c, BASEHD); | 
|---|
 | 1730 | +  | 
|---|
 | 1731 | +	ubifs_add_auth_dirt(c, lnum);  | 
|---|
| 1548 | 1732 |  	kfree(xent); | 
|---|
| 1549 | 1733 |  	if (err) | 
|---|
| 1550 | 1734 |  		goto out_ro; | 
|---|
| .. | .. | 
|---|
| 1572 | 1756 |   | 
|---|
| 1573 | 1757 |  	/* And update TNC with the new host inode position */ | 
|---|
| 1574 | 1758 |  	ino_key_init(c, &key1, host->i_ino); | 
|---|
| 1575 |  | -	err = ubifs_tnc_add(c, &key1, lnum, xent_offs + len - hlen, hlen);  | 
|---|
 | 1759 | +	err = ubifs_tnc_add(c, &key1, lnum, xent_offs + len - hlen, hlen, hash);  | 
|---|
| 1576 | 1760 |  	if (err) | 
|---|
| 1577 | 1761 |  		goto out_ro; | 
|---|
| 1578 | 1762 |   | 
|---|
| .. | .. | 
|---|
| 1583 | 1767 |  	mark_inode_clean(c, host_ui); | 
|---|
| 1584 | 1768 |  	return 0; | 
|---|
| 1585 | 1769 |   | 
|---|
 | 1770 | +out_release:  | 
|---|
 | 1771 | +	kfree(xent);  | 
|---|
 | 1772 | +	release_head(c, BASEHD);  | 
|---|
| 1586 | 1773 |  out_ro: | 
|---|
| 1587 | 1774 |  	ubifs_ro_mode(c, err); | 
|---|
| 1588 | 1775 |  	finish_reservation(c); | 
|---|
| .. | .. | 
|---|
| 1610 | 1797 |  	struct ubifs_ino_node *ino; | 
|---|
| 1611 | 1798 |  	union ubifs_key key; | 
|---|
| 1612 | 1799 |  	int sync = IS_DIRSYNC(host); | 
|---|
 | 1800 | +	u8 hash_host[UBIFS_HASH_ARR_SZ];  | 
|---|
 | 1801 | +	u8 hash[UBIFS_HASH_ARR_SZ];  | 
|---|
| 1613 | 1802 |   | 
|---|
| 1614 | 1803 |  	dbg_jnl("ino %lu, ino %lu", host->i_ino, inode->i_ino); | 
|---|
| 1615 |  | -	ubifs_assert(c, host->i_nlink > 0);  | 
|---|
| 1616 | 1804 |  	ubifs_assert(c, inode->i_nlink > 0); | 
|---|
| 1617 | 1805 |  	ubifs_assert(c, mutex_is_locked(&host_ui->ui_mutex)); | 
|---|
| 1618 | 1806 |   | 
|---|
| .. | .. | 
|---|
| 1620 | 1808 |  	len2 = UBIFS_INO_NODE_SZ + ubifs_inode(inode)->data_len; | 
|---|
| 1621 | 1809 |  	aligned_len1 = ALIGN(len1, 8); | 
|---|
| 1622 | 1810 |  	aligned_len = aligned_len1 + ALIGN(len2, 8); | 
|---|
 | 1811 | +  | 
|---|
 | 1812 | +	aligned_len += ubifs_auth_node_sz(c);  | 
|---|
| 1623 | 1813 |   | 
|---|
| 1624 | 1814 |  	ino = kzalloc(aligned_len, GFP_NOFS); | 
|---|
| 1625 | 1815 |  	if (!ino) | 
|---|
| .. | .. | 
|---|
| 1631 | 1821 |  		goto out_free; | 
|---|
| 1632 | 1822 |   | 
|---|
| 1633 | 1823 |  	pack_inode(c, ino, host, 0); | 
|---|
 | 1824 | +	err = ubifs_node_calc_hash(c, ino, hash_host);  | 
|---|
 | 1825 | +	if (err)  | 
|---|
 | 1826 | +		goto out_release;  | 
|---|
| 1634 | 1827 |  	pack_inode(c, (void *)ino + aligned_len1, inode, 1); | 
|---|
 | 1828 | +	err = ubifs_node_calc_hash(c, (void *)ino + aligned_len1, hash);  | 
|---|
 | 1829 | +	if (err)  | 
|---|
 | 1830 | +		goto out_release;  | 
|---|
| 1635 | 1831 |   | 
|---|
| 1636 | 1832 |  	err = write_head(c, BASEHD, ino, aligned_len, &lnum, &offs, 0); | 
|---|
| 1637 | 1833 |  	if (!sync && !err) { | 
|---|
| .. | .. | 
|---|
| 1644 | 1840 |  	if (err) | 
|---|
| 1645 | 1841 |  		goto out_ro; | 
|---|
| 1646 | 1842 |   | 
|---|
 | 1843 | +	ubifs_add_auth_dirt(c, lnum);  | 
|---|
 | 1844 | +  | 
|---|
| 1647 | 1845 |  	ino_key_init(c, &key, host->i_ino); | 
|---|
| 1648 |  | -	err = ubifs_tnc_add(c, &key, lnum, offs, len1);  | 
|---|
 | 1846 | +	err = ubifs_tnc_add(c, &key, lnum, offs, len1, hash_host);  | 
|---|
| 1649 | 1847 |  	if (err) | 
|---|
| 1650 | 1848 |  		goto out_ro; | 
|---|
| 1651 | 1849 |   | 
|---|
| 1652 | 1850 |  	ino_key_init(c, &key, inode->i_ino); | 
|---|
| 1653 |  | -	err = ubifs_tnc_add(c, &key, lnum, offs + aligned_len1, len2);  | 
|---|
 | 1851 | +	err = ubifs_tnc_add(c, &key, lnum, offs + aligned_len1, len2, hash);  | 
|---|
| 1654 | 1852 |  	if (err) | 
|---|
| 1655 | 1853 |  		goto out_ro; | 
|---|
| 1656 | 1854 |   | 
|---|
| .. | .. | 
|---|
| 1662 | 1860 |  	kfree(ino); | 
|---|
| 1663 | 1861 |  	return 0; | 
|---|
| 1664 | 1862 |   | 
|---|
 | 1863 | +out_release:  | 
|---|
 | 1864 | +	release_head(c, BASEHD);  | 
|---|
| 1665 | 1865 |  out_ro: | 
|---|
| 1666 | 1866 |  	ubifs_ro_mode(c, err); | 
|---|
| 1667 | 1867 |  	finish_reservation(c); | 
|---|