| .. | .. | 
|---|
 | 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 (Битюцкий Артём) | 
|---|
| .. | .. | 
|---|
| 38 | 26 |  			 struct ubifs_znode *znode, int lnum, int offs, int len) | 
|---|
| 39 | 27 |  { | 
|---|
| 40 | 28 |  	struct ubifs_znode *zp; | 
|---|
 | 29 | +	u8 hash[UBIFS_HASH_ARR_SZ];  | 
|---|
| 41 | 30 |  	int i, err; | 
|---|
| 42 | 31 |   | 
|---|
| 43 | 32 |  	/* Make index node */ | 
|---|
| .. | .. | 
|---|
| 52 | 41 |  		br->lnum = cpu_to_le32(zbr->lnum); | 
|---|
| 53 | 42 |  		br->offs = cpu_to_le32(zbr->offs); | 
|---|
| 54 | 43 |  		br->len = cpu_to_le32(zbr->len); | 
|---|
 | 44 | +		ubifs_copy_hash(c, zbr->hash, ubifs_branch_hash(c, br));  | 
|---|
| 55 | 45 |  		if (!zbr->lnum || !zbr->len) { | 
|---|
| 56 | 46 |  			ubifs_err(c, "bad ref in znode"); | 
|---|
| 57 | 47 |  			ubifs_dump_znode(c, znode); | 
|---|
| .. | .. | 
|---|
| 62 | 52 |  		} | 
|---|
| 63 | 53 |  	} | 
|---|
| 64 | 54 |  	ubifs_prepare_node(c, idx, len, 0); | 
|---|
 | 55 | +	ubifs_node_calc_hash(c, idx, hash);  | 
|---|
| 65 | 56 |   | 
|---|
| 66 | 57 |  	znode->lnum = lnum; | 
|---|
| 67 | 58 |  	znode->offs = offs; | 
|---|
| .. | .. | 
|---|
| 78 | 69 |  		zbr->lnum = lnum; | 
|---|
| 79 | 70 |  		zbr->offs = offs; | 
|---|
| 80 | 71 |  		zbr->len = len; | 
|---|
 | 72 | +		ubifs_copy_hash(c, hash, zbr->hash);  | 
|---|
| 81 | 73 |  	} else { | 
|---|
| 82 | 74 |  		c->zroot.lnum = lnum; | 
|---|
| 83 | 75 |  		c->zroot.offs = offs; | 
|---|
| 84 | 76 |  		c->zroot.len = len; | 
|---|
 | 77 | +		ubifs_copy_hash(c, hash, c->zroot.hash);  | 
|---|
| 85 | 78 |  	} | 
|---|
| 86 | 79 |  	c->calc_idx_sz += ALIGN(len, 8); | 
|---|
| 87 | 80 |   | 
|---|
| .. | .. | 
|---|
| 667 | 660 |  			znode->cnext = c->cnext; | 
|---|
| 668 | 661 |  			break; | 
|---|
| 669 | 662 |  		} | 
|---|
 | 663 | +		znode->cparent = znode->parent;  | 
|---|
 | 664 | +		znode->ciip = znode->iip;  | 
|---|
| 670 | 665 |  		znode->cnext = cnext; | 
|---|
| 671 | 666 |  		znode = cnext; | 
|---|
| 672 | 667 |  		cnt += 1; | 
|---|
| .. | .. | 
|---|
| 860 | 855 |  	} | 
|---|
| 861 | 856 |   | 
|---|
| 862 | 857 |  	while (1) { | 
|---|
 | 858 | +		u8 hash[UBIFS_HASH_ARR_SZ];  | 
|---|
 | 859 | +  | 
|---|
| 863 | 860 |  		cond_resched(); | 
|---|
| 864 | 861 |   | 
|---|
| 865 | 862 |  		znode = cnext; | 
|---|
| .. | .. | 
|---|
| 877 | 874 |  			br->lnum = cpu_to_le32(zbr->lnum); | 
|---|
| 878 | 875 |  			br->offs = cpu_to_le32(zbr->offs); | 
|---|
| 879 | 876 |  			br->len = cpu_to_le32(zbr->len); | 
|---|
 | 877 | +			ubifs_copy_hash(c, zbr->hash, ubifs_branch_hash(c, br));  | 
|---|
| 880 | 878 |  			if (!zbr->lnum || !zbr->len) { | 
|---|
| 881 | 879 |  				ubifs_err(c, "bad ref in znode"); | 
|---|
| 882 | 880 |  				ubifs_dump_znode(c, znode); | 
|---|
| .. | .. | 
|---|
| 888 | 886 |  		} | 
|---|
| 889 | 887 |  		len = ubifs_idx_node_sz(c, znode->child_cnt); | 
|---|
| 890 | 888 |  		ubifs_prepare_node(c, idx, len, 0); | 
|---|
 | 889 | +		ubifs_node_calc_hash(c, idx, hash);  | 
|---|
 | 890 | +  | 
|---|
 | 891 | +		mutex_lock(&c->tnc_mutex);  | 
|---|
 | 892 | +  | 
|---|
 | 893 | +		if (znode->cparent)  | 
|---|
 | 894 | +			ubifs_copy_hash(c, hash,  | 
|---|
 | 895 | +					znode->cparent->zbranch[znode->ciip].hash);  | 
|---|
 | 896 | +  | 
|---|
 | 897 | +		if (znode->parent) {  | 
|---|
 | 898 | +			if (!ubifs_zn_obsolete(znode))  | 
|---|
 | 899 | +				ubifs_copy_hash(c, hash,  | 
|---|
 | 900 | +					znode->parent->zbranch[znode->iip].hash);  | 
|---|
 | 901 | +		} else {  | 
|---|
 | 902 | +			ubifs_copy_hash(c, hash, c->zroot.hash);  | 
|---|
 | 903 | +		}  | 
|---|
 | 904 | +  | 
|---|
 | 905 | +		mutex_unlock(&c->tnc_mutex);  | 
|---|
| 891 | 906 |   | 
|---|
| 892 | 907 |  		/* Determine the index node position */ | 
|---|
| 893 | 908 |  		if (lnum == -1) { | 
|---|