diff options
-rw-r--r-- | fs/ubifs/journal.c | 144 | ||||
-rw-r--r-- | fs/ubifs/replay.c | 4 | ||||
-rw-r--r-- | fs/ubifs/tnc.c | 10 | ||||
-rw-r--r-- | fs/ubifs/ubifs.h | 7 |
4 files changed, 135 insertions, 30 deletions
diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c index de7ac9e7acce..7c12bdfa9a7a 100644 --- a/fs/ubifs/journal.c +++ b/fs/ubifs/journal.c | |||
@@ -518,6 +518,9 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, | |||
518 | struct ubifs_dent_node *dent; | 518 | struct ubifs_dent_node *dent; |
519 | struct ubifs_ino_node *ino; | 519 | struct ubifs_ino_node *ino; |
520 | union ubifs_key dent_key, ino_key; | 520 | union ubifs_key dent_key, ino_key; |
521 | u8 hash_dent[UBIFS_HASH_ARR_SZ]; | ||
522 | u8 hash_ino[UBIFS_HASH_ARR_SZ]; | ||
523 | u8 hash_ino_host[UBIFS_HASH_ARR_SZ]; | ||
521 | 524 | ||
522 | ubifs_assert(c, mutex_is_locked(&host_ui->ui_mutex)); | 525 | ubifs_assert(c, mutex_is_locked(&host_ui->ui_mutex)); |
523 | 526 | ||
@@ -572,11 +575,21 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, | |||
572 | 575 | ||
573 | zero_dent_node_unused(dent); | 576 | zero_dent_node_unused(dent); |
574 | ubifs_prep_grp_node(c, dent, dlen, 0); | 577 | ubifs_prep_grp_node(c, dent, dlen, 0); |
578 | err = ubifs_node_calc_hash(c, dent, hash_dent); | ||
579 | if (err) | ||
580 | goto out_release; | ||
575 | 581 | ||
576 | ino = (void *)dent + aligned_dlen; | 582 | ino = (void *)dent + aligned_dlen; |
577 | pack_inode(c, ino, inode, 0); | 583 | pack_inode(c, ino, inode, 0); |
584 | err = ubifs_node_calc_hash(c, ino, hash_ino); | ||
585 | if (err) | ||
586 | goto out_release; | ||
587 | |||
578 | ino = (void *)ino + aligned_ilen; | 588 | ino = (void *)ino + aligned_ilen; |
579 | pack_inode(c, ino, dir, 1); | 589 | pack_inode(c, ino, dir, 1); |
590 | err = ubifs_node_calc_hash(c, ino, hash_ino_host); | ||
591 | if (err) | ||
592 | goto out_release; | ||
580 | 593 | ||
581 | if (last_reference) { | 594 | if (last_reference) { |
582 | err = ubifs_add_orphan(c, inode->i_ino); | 595 | err = ubifs_add_orphan(c, inode->i_ino); |
@@ -608,7 +621,8 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, | |||
608 | goto out_ro; | 621 | goto out_ro; |
609 | err = ubifs_add_dirt(c, lnum, dlen); | 622 | err = ubifs_add_dirt(c, lnum, dlen); |
610 | } else | 623 | } else |
611 | err = ubifs_tnc_add_nm(c, &dent_key, lnum, dent_offs, dlen, nm); | 624 | err = ubifs_tnc_add_nm(c, &dent_key, lnum, dent_offs, dlen, |
625 | hash_dent, nm); | ||
612 | if (err) | 626 | if (err) |
613 | goto out_ro; | 627 | goto out_ro; |
614 | 628 | ||
@@ -620,14 +634,14 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, | |||
620 | */ | 634 | */ |
621 | ino_key_init(c, &ino_key, inode->i_ino); | 635 | ino_key_init(c, &ino_key, inode->i_ino); |
622 | ino_offs = dent_offs + aligned_dlen; | 636 | ino_offs = dent_offs + aligned_dlen; |
623 | err = ubifs_tnc_add(c, &ino_key, lnum, ino_offs, ilen); | 637 | err = ubifs_tnc_add(c, &ino_key, lnum, ino_offs, ilen, hash_ino); |
624 | if (err) | 638 | if (err) |
625 | goto out_ro; | 639 | goto out_ro; |
626 | 640 | ||
627 | ino_key_init(c, &ino_key, dir->i_ino); | 641 | ino_key_init(c, &ino_key, dir->i_ino); |
628 | ino_offs += aligned_ilen; | 642 | ino_offs += aligned_ilen; |
629 | err = ubifs_tnc_add(c, &ino_key, lnum, ino_offs, | 643 | err = ubifs_tnc_add(c, &ino_key, lnum, ino_offs, |
630 | UBIFS_INO_NODE_SZ + host_ui->data_len); | 644 | UBIFS_INO_NODE_SZ + host_ui->data_len, hash_ino_host); |
631 | if (err) | 645 | if (err) |
632 | goto out_ro; | 646 | goto out_ro; |
633 | 647 | ||
@@ -680,6 +694,7 @@ int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode, | |||
680 | int dlen = COMPRESSED_DATA_NODE_BUF_SZ, allocated = 1; | 694 | int dlen = COMPRESSED_DATA_NODE_BUF_SZ, allocated = 1; |
681 | struct ubifs_inode *ui = ubifs_inode(inode); | 695 | struct ubifs_inode *ui = ubifs_inode(inode); |
682 | bool encrypted = ubifs_crypt_is_encrypted(inode); | 696 | bool encrypted = ubifs_crypt_is_encrypted(inode); |
697 | u8 hash[UBIFS_HASH_ARR_SZ]; | ||
683 | 698 | ||
684 | dbg_jnlk(key, "ino %lu, blk %u, len %d, key ", | 699 | dbg_jnlk(key, "ino %lu, blk %u, len %d, key ", |
685 | (unsigned long)key_inum(c, key), key_block(c, key), len); | 700 | (unsigned long)key_inum(c, key), key_block(c, key), len); |
@@ -738,10 +753,15 @@ int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode, | |||
738 | err = write_head(c, DATAHD, data, dlen, &lnum, &offs, 0); | 753 | err = write_head(c, DATAHD, data, dlen, &lnum, &offs, 0); |
739 | if (err) | 754 | if (err) |
740 | goto out_release; | 755 | goto out_release; |
756 | |||
757 | err = ubifs_node_calc_hash(c, data, hash); | ||
758 | if (err) | ||
759 | goto out_release; | ||
760 | |||
741 | ubifs_wbuf_add_ino_nolock(&c->jheads[DATAHD].wbuf, key_inum(c, key)); | 761 | ubifs_wbuf_add_ino_nolock(&c->jheads[DATAHD].wbuf, key_inum(c, key)); |
742 | release_head(c, DATAHD); | 762 | release_head(c, DATAHD); |
743 | 763 | ||
744 | err = ubifs_tnc_add(c, key, lnum, offs, dlen); | 764 | err = ubifs_tnc_add(c, key, lnum, offs, dlen, hash); |
745 | if (err) | 765 | if (err) |
746 | goto out_ro; | 766 | goto out_ro; |
747 | 767 | ||
@@ -780,6 +800,7 @@ int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode) | |||
780 | struct ubifs_ino_node *ino; | 800 | struct ubifs_ino_node *ino; |
781 | struct ubifs_inode *ui = ubifs_inode(inode); | 801 | struct ubifs_inode *ui = ubifs_inode(inode); |
782 | int sync = 0, len = UBIFS_INO_NODE_SZ, last_reference = !inode->i_nlink; | 802 | int sync = 0, len = UBIFS_INO_NODE_SZ, last_reference = !inode->i_nlink; |
803 | u8 hash[UBIFS_HASH_ARR_SZ]; | ||
783 | 804 | ||
784 | dbg_jnl("ino %lu, nlink %u", inode->i_ino, inode->i_nlink); | 805 | dbg_jnl("ino %lu, nlink %u", inode->i_ino, inode->i_nlink); |
785 | 806 | ||
@@ -801,6 +822,10 @@ int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode) | |||
801 | goto out_free; | 822 | goto out_free; |
802 | 823 | ||
803 | pack_inode(c, ino, inode, 1); | 824 | pack_inode(c, ino, inode, 1); |
825 | err = ubifs_node_calc_hash(c, ino, hash); | ||
826 | if (err) | ||
827 | goto out_release; | ||
828 | |||
804 | err = write_head(c, BASEHD, ino, len, &lnum, &offs, sync); | 829 | err = write_head(c, BASEHD, ino, len, &lnum, &offs, sync); |
805 | if (err) | 830 | if (err) |
806 | goto out_release; | 831 | goto out_release; |
@@ -819,7 +844,7 @@ int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode) | |||
819 | union ubifs_key key; | 844 | union ubifs_key key; |
820 | 845 | ||
821 | ino_key_init(c, &key, inode->i_ino); | 846 | ino_key_init(c, &key, inode->i_ino); |
822 | err = ubifs_tnc_add(c, &key, lnum, offs, len); | 847 | err = ubifs_tnc_add(c, &key, lnum, offs, len, hash); |
823 | } | 848 | } |
824 | if (err) | 849 | if (err) |
825 | goto out_ro; | 850 | goto out_ro; |
@@ -929,6 +954,10 @@ int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir, | |||
929 | int aligned_dlen1, aligned_dlen2; | 954 | int aligned_dlen1, aligned_dlen2; |
930 | int twoparents = (fst_dir != snd_dir); | 955 | int twoparents = (fst_dir != snd_dir); |
931 | void *p; | 956 | void *p; |
957 | u8 hash_dent1[UBIFS_HASH_ARR_SZ]; | ||
958 | u8 hash_dent2[UBIFS_HASH_ARR_SZ]; | ||
959 | u8 hash_p1[UBIFS_HASH_ARR_SZ]; | ||
960 | u8 hash_p2[UBIFS_HASH_ARR_SZ]; | ||
932 | 961 | ||
933 | ubifs_assert(c, ubifs_inode(fst_dir)->data_len == 0); | 962 | ubifs_assert(c, ubifs_inode(fst_dir)->data_len == 0); |
934 | ubifs_assert(c, ubifs_inode(snd_dir)->data_len == 0); | 963 | ubifs_assert(c, ubifs_inode(snd_dir)->data_len == 0); |
@@ -964,6 +993,9 @@ int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir, | |||
964 | set_dent_cookie(c, dent1); | 993 | set_dent_cookie(c, dent1); |
965 | zero_dent_node_unused(dent1); | 994 | zero_dent_node_unused(dent1); |
966 | ubifs_prep_grp_node(c, dent1, dlen1, 0); | 995 | ubifs_prep_grp_node(c, dent1, dlen1, 0); |
996 | err = ubifs_node_calc_hash(c, dent1, hash_dent1); | ||
997 | if (err) | ||
998 | goto out_release; | ||
967 | 999 | ||
968 | /* Make new dent for 2nd entry */ | 1000 | /* Make new dent for 2nd entry */ |
969 | dent2 = (void *)dent1 + aligned_dlen1; | 1001 | dent2 = (void *)dent1 + aligned_dlen1; |
@@ -977,14 +1009,26 @@ int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir, | |||
977 | set_dent_cookie(c, dent2); | 1009 | set_dent_cookie(c, dent2); |
978 | zero_dent_node_unused(dent2); | 1010 | zero_dent_node_unused(dent2); |
979 | ubifs_prep_grp_node(c, dent2, dlen2, 0); | 1011 | ubifs_prep_grp_node(c, dent2, dlen2, 0); |
1012 | err = ubifs_node_calc_hash(c, dent2, hash_dent2); | ||
1013 | if (err) | ||
1014 | goto out_release; | ||
980 | 1015 | ||
981 | p = (void *)dent2 + aligned_dlen2; | 1016 | p = (void *)dent2 + aligned_dlen2; |
982 | if (!twoparents) | 1017 | if (!twoparents) { |
983 | pack_inode(c, p, fst_dir, 1); | 1018 | pack_inode(c, p, fst_dir, 1); |
984 | else { | 1019 | err = ubifs_node_calc_hash(c, p, hash_p1); |
1020 | if (err) | ||
1021 | goto out_release; | ||
1022 | } else { | ||
985 | pack_inode(c, p, fst_dir, 0); | 1023 | pack_inode(c, p, fst_dir, 0); |
1024 | err = ubifs_node_calc_hash(c, p, hash_p1); | ||
1025 | if (err) | ||
1026 | goto out_release; | ||
986 | p += ALIGN(plen, 8); | 1027 | p += ALIGN(plen, 8); |
987 | pack_inode(c, p, snd_dir, 1); | 1028 | pack_inode(c, p, snd_dir, 1); |
1029 | err = ubifs_node_calc_hash(c, p, hash_p2); | ||
1030 | if (err) | ||
1031 | goto out_release; | ||
988 | } | 1032 | } |
989 | 1033 | ||
990 | err = write_head(c, BASEHD, dent1, len, &lnum, &offs, sync); | 1034 | err = write_head(c, BASEHD, dent1, len, &lnum, &offs, sync); |
@@ -999,27 +1043,27 @@ int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir, | |||
999 | release_head(c, BASEHD); | 1043 | release_head(c, BASEHD); |
1000 | 1044 | ||
1001 | dent_key_init(c, &key, snd_dir->i_ino, snd_nm); | 1045 | dent_key_init(c, &key, snd_dir->i_ino, snd_nm); |
1002 | err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen1, snd_nm); | 1046 | err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen1, hash_dent1, snd_nm); |
1003 | if (err) | 1047 | if (err) |
1004 | goto out_ro; | 1048 | goto out_ro; |
1005 | 1049 | ||
1006 | offs += aligned_dlen1; | 1050 | offs += aligned_dlen1; |
1007 | dent_key_init(c, &key, fst_dir->i_ino, fst_nm); | 1051 | dent_key_init(c, &key, fst_dir->i_ino, fst_nm); |
1008 | err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen2, fst_nm); | 1052 | err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen2, hash_dent2, fst_nm); |
1009 | if (err) | 1053 | if (err) |
1010 | goto out_ro; | 1054 | goto out_ro; |
1011 | 1055 | ||
1012 | offs += aligned_dlen2; | 1056 | offs += aligned_dlen2; |
1013 | 1057 | ||
1014 | ino_key_init(c, &key, fst_dir->i_ino); | 1058 | ino_key_init(c, &key, fst_dir->i_ino); |
1015 | err = ubifs_tnc_add(c, &key, lnum, offs, plen); | 1059 | err = ubifs_tnc_add(c, &key, lnum, offs, plen, hash_p1); |
1016 | if (err) | 1060 | if (err) |
1017 | goto out_ro; | 1061 | goto out_ro; |
1018 | 1062 | ||
1019 | if (twoparents) { | 1063 | if (twoparents) { |
1020 | offs += ALIGN(plen, 8); | 1064 | offs += ALIGN(plen, 8); |
1021 | ino_key_init(c, &key, snd_dir->i_ino); | 1065 | ino_key_init(c, &key, snd_dir->i_ino); |
1022 | err = ubifs_tnc_add(c, &key, lnum, offs, plen); | 1066 | err = ubifs_tnc_add(c, &key, lnum, offs, plen, hash_p2); |
1023 | if (err) | 1067 | if (err) |
1024 | goto out_ro; | 1068 | goto out_ro; |
1025 | } | 1069 | } |
@@ -1072,6 +1116,11 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir, | |||
1072 | int last_reference = !!(new_inode && new_inode->i_nlink == 0); | 1116 | int last_reference = !!(new_inode && new_inode->i_nlink == 0); |
1073 | int move = (old_dir != new_dir); | 1117 | int move = (old_dir != new_dir); |
1074 | struct ubifs_inode *uninitialized_var(new_ui); | 1118 | struct ubifs_inode *uninitialized_var(new_ui); |
1119 | u8 hash_old_dir[UBIFS_HASH_ARR_SZ]; | ||
1120 | u8 hash_new_dir[UBIFS_HASH_ARR_SZ]; | ||
1121 | u8 hash_new_inode[UBIFS_HASH_ARR_SZ]; | ||
1122 | u8 hash_dent1[UBIFS_HASH_ARR_SZ]; | ||
1123 | u8 hash_dent2[UBIFS_HASH_ARR_SZ]; | ||
1075 | 1124 | ||
1076 | ubifs_assert(c, ubifs_inode(old_dir)->data_len == 0); | 1125 | ubifs_assert(c, ubifs_inode(old_dir)->data_len == 0); |
1077 | ubifs_assert(c, ubifs_inode(new_dir)->data_len == 0); | 1126 | ubifs_assert(c, ubifs_inode(new_dir)->data_len == 0); |
@@ -1114,6 +1163,9 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir, | |||
1114 | set_dent_cookie(c, dent); | 1163 | set_dent_cookie(c, dent); |
1115 | zero_dent_node_unused(dent); | 1164 | zero_dent_node_unused(dent); |
1116 | ubifs_prep_grp_node(c, dent, dlen1, 0); | 1165 | ubifs_prep_grp_node(c, dent, dlen1, 0); |
1166 | err = ubifs_node_calc_hash(c, dent, hash_dent1); | ||
1167 | if (err) | ||
1168 | goto out_release; | ||
1117 | 1169 | ||
1118 | dent2 = (void *)dent + aligned_dlen1; | 1170 | dent2 = (void *)dent + aligned_dlen1; |
1119 | dent2->ch.node_type = UBIFS_DENT_NODE; | 1171 | dent2->ch.node_type = UBIFS_DENT_NODE; |
@@ -1133,19 +1185,36 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir, | |||
1133 | set_dent_cookie(c, dent2); | 1185 | set_dent_cookie(c, dent2); |
1134 | zero_dent_node_unused(dent2); | 1186 | zero_dent_node_unused(dent2); |
1135 | ubifs_prep_grp_node(c, dent2, dlen2, 0); | 1187 | ubifs_prep_grp_node(c, dent2, dlen2, 0); |
1188 | err = ubifs_node_calc_hash(c, dent2, hash_dent2); | ||
1189 | if (err) | ||
1190 | goto out_release; | ||
1136 | 1191 | ||
1137 | p = (void *)dent2 + aligned_dlen2; | 1192 | p = (void *)dent2 + aligned_dlen2; |
1138 | if (new_inode) { | 1193 | if (new_inode) { |
1139 | pack_inode(c, p, new_inode, 0); | 1194 | pack_inode(c, p, new_inode, 0); |
1195 | err = ubifs_node_calc_hash(c, p, hash_new_inode); | ||
1196 | if (err) | ||
1197 | goto out_release; | ||
1198 | |||
1140 | p += ALIGN(ilen, 8); | 1199 | p += ALIGN(ilen, 8); |
1141 | } | 1200 | } |
1142 | 1201 | ||
1143 | if (!move) | 1202 | if (!move) { |
1144 | pack_inode(c, p, old_dir, 1); | 1203 | pack_inode(c, p, old_dir, 1); |
1145 | else { | 1204 | err = ubifs_node_calc_hash(c, p, hash_old_dir); |
1205 | if (err) | ||
1206 | goto out_release; | ||
1207 | } else { | ||
1146 | pack_inode(c, p, old_dir, 0); | 1208 | pack_inode(c, p, old_dir, 0); |
1209 | err = ubifs_node_calc_hash(c, p, hash_old_dir); | ||
1210 | if (err) | ||
1211 | goto out_release; | ||
1212 | |||
1147 | p += ALIGN(plen, 8); | 1213 | p += ALIGN(plen, 8); |
1148 | pack_inode(c, p, new_dir, 1); | 1214 | pack_inode(c, p, new_dir, 1); |
1215 | err = ubifs_node_calc_hash(c, p, hash_new_dir); | ||
1216 | if (err) | ||
1217 | goto out_release; | ||
1149 | } | 1218 | } |
1150 | 1219 | ||
1151 | if (last_reference) { | 1220 | if (last_reference) { |
@@ -1172,14 +1241,14 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir, | |||
1172 | release_head(c, BASEHD); | 1241 | release_head(c, BASEHD); |
1173 | 1242 | ||
1174 | dent_key_init(c, &key, new_dir->i_ino, new_nm); | 1243 | dent_key_init(c, &key, new_dir->i_ino, new_nm); |
1175 | err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen1, new_nm); | 1244 | err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen1, hash_dent1, new_nm); |
1176 | if (err) | 1245 | if (err) |
1177 | goto out_ro; | 1246 | goto out_ro; |
1178 | 1247 | ||
1179 | offs += aligned_dlen1; | 1248 | offs += aligned_dlen1; |
1180 | if (whiteout) { | 1249 | if (whiteout) { |
1181 | dent_key_init(c, &key, old_dir->i_ino, old_nm); | 1250 | dent_key_init(c, &key, old_dir->i_ino, old_nm); |
1182 | err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen2, old_nm); | 1251 | err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen2, hash_dent2, old_nm); |
1183 | if (err) | 1252 | if (err) |
1184 | goto out_ro; | 1253 | goto out_ro; |
1185 | 1254 | ||
@@ -1198,21 +1267,21 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir, | |||
1198 | offs += aligned_dlen2; | 1267 | offs += aligned_dlen2; |
1199 | if (new_inode) { | 1268 | if (new_inode) { |
1200 | ino_key_init(c, &key, new_inode->i_ino); | 1269 | ino_key_init(c, &key, new_inode->i_ino); |
1201 | err = ubifs_tnc_add(c, &key, lnum, offs, ilen); | 1270 | err = ubifs_tnc_add(c, &key, lnum, offs, ilen, hash_new_inode); |
1202 | if (err) | 1271 | if (err) |
1203 | goto out_ro; | 1272 | goto out_ro; |
1204 | offs += ALIGN(ilen, 8); | 1273 | offs += ALIGN(ilen, 8); |
1205 | } | 1274 | } |
1206 | 1275 | ||
1207 | ino_key_init(c, &key, old_dir->i_ino); | 1276 | ino_key_init(c, &key, old_dir->i_ino); |
1208 | err = ubifs_tnc_add(c, &key, lnum, offs, plen); | 1277 | err = ubifs_tnc_add(c, &key, lnum, offs, plen, hash_old_dir); |
1209 | if (err) | 1278 | if (err) |
1210 | goto out_ro; | 1279 | goto out_ro; |
1211 | 1280 | ||
1212 | if (move) { | 1281 | if (move) { |
1213 | offs += ALIGN(plen, 8); | 1282 | offs += ALIGN(plen, 8); |
1214 | ino_key_init(c, &key, new_dir->i_ino); | 1283 | ino_key_init(c, &key, new_dir->i_ino); |
1215 | err = ubifs_tnc_add(c, &key, lnum, offs, plen); | 1284 | err = ubifs_tnc_add(c, &key, lnum, offs, plen, hash_new_dir); |
1216 | if (err) | 1285 | if (err) |
1217 | goto out_ro; | 1286 | goto out_ro; |
1218 | } | 1287 | } |
@@ -1331,6 +1400,8 @@ int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode, | |||
1331 | struct ubifs_inode *ui = ubifs_inode(inode); | 1400 | struct ubifs_inode *ui = ubifs_inode(inode); |
1332 | ino_t inum = inode->i_ino; | 1401 | ino_t inum = inode->i_ino; |
1333 | unsigned int blk; | 1402 | unsigned int blk; |
1403 | u8 hash_ino[UBIFS_HASH_ARR_SZ]; | ||
1404 | u8 hash_dn[UBIFS_HASH_ARR_SZ]; | ||
1334 | 1405 | ||
1335 | dbg_jnl("ino %lu, size %lld -> %lld", | 1406 | dbg_jnl("ino %lu, size %lld -> %lld", |
1336 | (unsigned long)inum, old_size, new_size); | 1407 | (unsigned long)inum, old_size, new_size); |
@@ -1392,9 +1463,17 @@ int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode, | |||
1392 | goto out_free; | 1463 | goto out_free; |
1393 | 1464 | ||
1394 | pack_inode(c, ino, inode, 0); | 1465 | pack_inode(c, ino, inode, 0); |
1466 | err = ubifs_node_calc_hash(c, ino, hash_ino); | ||
1467 | if (err) | ||
1468 | goto out_release; | ||
1469 | |||
1395 | ubifs_prep_grp_node(c, trun, UBIFS_TRUN_NODE_SZ, dlen ? 0 : 1); | 1470 | ubifs_prep_grp_node(c, trun, UBIFS_TRUN_NODE_SZ, dlen ? 0 : 1); |
1396 | if (dlen) | 1471 | if (dlen) { |
1397 | ubifs_prep_grp_node(c, dn, dlen, 1); | 1472 | ubifs_prep_grp_node(c, dn, dlen, 1); |
1473 | err = ubifs_node_calc_hash(c, dn, hash_dn); | ||
1474 | if (err) | ||
1475 | goto out_release; | ||
1476 | } | ||
1398 | 1477 | ||
1399 | err = write_head(c, BASEHD, ino, len, &lnum, &offs, sync); | 1478 | err = write_head(c, BASEHD, ino, len, &lnum, &offs, sync); |
1400 | if (err) | 1479 | if (err) |
@@ -1405,13 +1484,13 @@ int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode, | |||
1405 | 1484 | ||
1406 | if (dlen) { | 1485 | if (dlen) { |
1407 | sz = offs + UBIFS_INO_NODE_SZ + UBIFS_TRUN_NODE_SZ; | 1486 | sz = offs + UBIFS_INO_NODE_SZ + UBIFS_TRUN_NODE_SZ; |
1408 | err = ubifs_tnc_add(c, &key, lnum, sz, dlen); | 1487 | err = ubifs_tnc_add(c, &key, lnum, sz, dlen, hash_dn); |
1409 | if (err) | 1488 | if (err) |
1410 | goto out_ro; | 1489 | goto out_ro; |
1411 | } | 1490 | } |
1412 | 1491 | ||
1413 | ino_key_init(c, &key, inum); | 1492 | ino_key_init(c, &key, inum); |
1414 | err = ubifs_tnc_add(c, &key, lnum, offs, UBIFS_INO_NODE_SZ); | 1493 | err = ubifs_tnc_add(c, &key, lnum, offs, UBIFS_INO_NODE_SZ, hash_ino); |
1415 | if (err) | 1494 | if (err) |
1416 | goto out_ro; | 1495 | goto out_ro; |
1417 | 1496 | ||
@@ -1472,6 +1551,7 @@ int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host, | |||
1472 | union ubifs_key xent_key, key1, key2; | 1551 | union ubifs_key xent_key, key1, key2; |
1473 | int sync = IS_DIRSYNC(host); | 1552 | int sync = IS_DIRSYNC(host); |
1474 | struct ubifs_inode *host_ui = ubifs_inode(host); | 1553 | struct ubifs_inode *host_ui = ubifs_inode(host); |
1554 | u8 hash[UBIFS_HASH_ARR_SZ]; | ||
1475 | 1555 | ||
1476 | ubifs_assert(c, inode->i_nlink == 0); | 1556 | ubifs_assert(c, inode->i_nlink == 0); |
1477 | ubifs_assert(c, mutex_is_locked(&host_ui->ui_mutex)); | 1557 | ubifs_assert(c, mutex_is_locked(&host_ui->ui_mutex)); |
@@ -1511,6 +1591,9 @@ int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host, | |||
1511 | pack_inode(c, ino, inode, 0); | 1591 | pack_inode(c, ino, inode, 0); |
1512 | ino = (void *)ino + UBIFS_INO_NODE_SZ; | 1592 | ino = (void *)ino + UBIFS_INO_NODE_SZ; |
1513 | pack_inode(c, ino, host, 1); | 1593 | pack_inode(c, ino, host, 1); |
1594 | err = ubifs_node_calc_hash(c, ino, hash); | ||
1595 | if (err) | ||
1596 | goto out_release; | ||
1514 | 1597 | ||
1515 | err = write_head(c, BASEHD, xent, len, &lnum, &xent_offs, sync); | 1598 | err = write_head(c, BASEHD, xent, len, &lnum, &xent_offs, sync); |
1516 | if (!sync && !err) | 1599 | if (!sync && !err) |
@@ -1543,7 +1626,7 @@ int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host, | |||
1543 | 1626 | ||
1544 | /* And update TNC with the new host inode position */ | 1627 | /* And update TNC with the new host inode position */ |
1545 | ino_key_init(c, &key1, host->i_ino); | 1628 | ino_key_init(c, &key1, host->i_ino); |
1546 | err = ubifs_tnc_add(c, &key1, lnum, xent_offs + len - hlen, hlen); | 1629 | err = ubifs_tnc_add(c, &key1, lnum, xent_offs + len - hlen, hlen, hash); |
1547 | if (err) | 1630 | if (err) |
1548 | goto out_ro; | 1631 | goto out_ro; |
1549 | 1632 | ||
@@ -1554,6 +1637,9 @@ int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host, | |||
1554 | mark_inode_clean(c, host_ui); | 1637 | mark_inode_clean(c, host_ui); |
1555 | return 0; | 1638 | return 0; |
1556 | 1639 | ||
1640 | out_release: | ||
1641 | kfree(xent); | ||
1642 | release_head(c, BASEHD); | ||
1557 | out_ro: | 1643 | out_ro: |
1558 | ubifs_ro_mode(c, err); | 1644 | ubifs_ro_mode(c, err); |
1559 | finish_reservation(c); | 1645 | finish_reservation(c); |
@@ -1581,6 +1667,8 @@ int ubifs_jnl_change_xattr(struct ubifs_info *c, const struct inode *inode, | |||
1581 | struct ubifs_ino_node *ino; | 1667 | struct ubifs_ino_node *ino; |
1582 | union ubifs_key key; | 1668 | union ubifs_key key; |
1583 | int sync = IS_DIRSYNC(host); | 1669 | int sync = IS_DIRSYNC(host); |
1670 | u8 hash_host[UBIFS_HASH_ARR_SZ]; | ||
1671 | u8 hash[UBIFS_HASH_ARR_SZ]; | ||
1584 | 1672 | ||
1585 | dbg_jnl("ino %lu, ino %lu", host->i_ino, inode->i_ino); | 1673 | dbg_jnl("ino %lu, ino %lu", host->i_ino, inode->i_ino); |
1586 | ubifs_assert(c, host->i_nlink > 0); | 1674 | ubifs_assert(c, host->i_nlink > 0); |
@@ -1602,7 +1690,13 @@ int ubifs_jnl_change_xattr(struct ubifs_info *c, const struct inode *inode, | |||
1602 | goto out_free; | 1690 | goto out_free; |
1603 | 1691 | ||
1604 | pack_inode(c, ino, host, 0); | 1692 | pack_inode(c, ino, host, 0); |
1693 | err = ubifs_node_calc_hash(c, ino, hash_host); | ||
1694 | if (err) | ||
1695 | goto out_release; | ||
1605 | pack_inode(c, (void *)ino + aligned_len1, inode, 1); | 1696 | pack_inode(c, (void *)ino + aligned_len1, inode, 1); |
1697 | err = ubifs_node_calc_hash(c, (void *)ino + aligned_len1, hash); | ||
1698 | if (err) | ||
1699 | goto out_release; | ||
1606 | 1700 | ||
1607 | err = write_head(c, BASEHD, ino, aligned_len, &lnum, &offs, 0); | 1701 | err = write_head(c, BASEHD, ino, aligned_len, &lnum, &offs, 0); |
1608 | if (!sync && !err) { | 1702 | if (!sync && !err) { |
@@ -1616,12 +1710,12 @@ int ubifs_jnl_change_xattr(struct ubifs_info *c, const struct inode *inode, | |||
1616 | goto out_ro; | 1710 | goto out_ro; |
1617 | 1711 | ||
1618 | ino_key_init(c, &key, host->i_ino); | 1712 | ino_key_init(c, &key, host->i_ino); |
1619 | err = ubifs_tnc_add(c, &key, lnum, offs, len1); | 1713 | err = ubifs_tnc_add(c, &key, lnum, offs, len1, hash_host); |
1620 | if (err) | 1714 | if (err) |
1621 | goto out_ro; | 1715 | goto out_ro; |
1622 | 1716 | ||
1623 | ino_key_init(c, &key, inode->i_ino); | 1717 | ino_key_init(c, &key, inode->i_ino); |
1624 | err = ubifs_tnc_add(c, &key, lnum, offs + aligned_len1, len2); | 1718 | err = ubifs_tnc_add(c, &key, lnum, offs + aligned_len1, len2, hash); |
1625 | if (err) | 1719 | if (err) |
1626 | goto out_ro; | 1720 | goto out_ro; |
1627 | 1721 | ||
@@ -1633,6 +1727,8 @@ int ubifs_jnl_change_xattr(struct ubifs_info *c, const struct inode *inode, | |||
1633 | kfree(ino); | 1727 | kfree(ino); |
1634 | return 0; | 1728 | return 0; |
1635 | 1729 | ||
1730 | out_release: | ||
1731 | release_head(c, BASEHD); | ||
1636 | out_ro: | 1732 | out_ro: |
1637 | ubifs_ro_mode(c, err); | 1733 | ubifs_ro_mode(c, err); |
1638 | finish_reservation(c); | 1734 | finish_reservation(c); |
diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c index 4844538eb926..bccb35f72277 100644 --- a/fs/ubifs/replay.c +++ b/fs/ubifs/replay.c | |||
@@ -228,7 +228,7 @@ static int apply_replay_entry(struct ubifs_info *c, struct replay_entry *r) | |||
228 | err = ubifs_tnc_remove_nm(c, &r->key, &r->nm); | 228 | err = ubifs_tnc_remove_nm(c, &r->key, &r->nm); |
229 | else | 229 | else |
230 | err = ubifs_tnc_add_nm(c, &r->key, r->lnum, r->offs, | 230 | err = ubifs_tnc_add_nm(c, &r->key, r->lnum, r->offs, |
231 | r->len, &r->nm); | 231 | r->len, NULL, &r->nm); |
232 | } else { | 232 | } else { |
233 | if (r->deletion) | 233 | if (r->deletion) |
234 | switch (key_type(c, &r->key)) { | 234 | switch (key_type(c, &r->key)) { |
@@ -248,7 +248,7 @@ static int apply_replay_entry(struct ubifs_info *c, struct replay_entry *r) | |||
248 | } | 248 | } |
249 | else | 249 | else |
250 | err = ubifs_tnc_add(c, &r->key, r->lnum, r->offs, | 250 | err = ubifs_tnc_add(c, &r->key, r->lnum, r->offs, |
251 | r->len); | 251 | r->len, NULL); |
252 | if (err) | 252 | if (err) |
253 | return err; | 253 | return err; |
254 | 254 | ||
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c index 8502c07c1e0a..bb5f989a6e06 100644 --- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c | |||
@@ -2260,13 +2260,14 @@ do_split: | |||
2260 | * @lnum: LEB number of node | 2260 | * @lnum: LEB number of node |
2261 | * @offs: node offset | 2261 | * @offs: node offset |
2262 | * @len: node length | 2262 | * @len: node length |
2263 | * @hash: The hash over the node | ||
2263 | * | 2264 | * |
2264 | * This function adds a node with key @key to TNC. The node may be new or it may | 2265 | * This function adds a node with key @key to TNC. The node may be new or it may |
2265 | * obsolete some existing one. Returns %0 on success or negative error code on | 2266 | * obsolete some existing one. Returns %0 on success or negative error code on |
2266 | * failure. | 2267 | * failure. |
2267 | */ | 2268 | */ |
2268 | int ubifs_tnc_add(struct ubifs_info *c, const union ubifs_key *key, int lnum, | 2269 | int ubifs_tnc_add(struct ubifs_info *c, const union ubifs_key *key, int lnum, |
2269 | int offs, int len) | 2270 | int offs, int len, const u8 *hash) |
2270 | { | 2271 | { |
2271 | int found, n, err = 0; | 2272 | int found, n, err = 0; |
2272 | struct ubifs_znode *znode; | 2273 | struct ubifs_znode *znode; |
@@ -2281,6 +2282,7 @@ int ubifs_tnc_add(struct ubifs_info *c, const union ubifs_key *key, int lnum, | |||
2281 | zbr.lnum = lnum; | 2282 | zbr.lnum = lnum; |
2282 | zbr.offs = offs; | 2283 | zbr.offs = offs; |
2283 | zbr.len = len; | 2284 | zbr.len = len; |
2285 | ubifs_copy_hash(c, hash, zbr.hash); | ||
2284 | key_copy(c, key, &zbr.key); | 2286 | key_copy(c, key, &zbr.key); |
2285 | err = tnc_insert(c, znode, &zbr, n + 1); | 2287 | err = tnc_insert(c, znode, &zbr, n + 1); |
2286 | } else if (found == 1) { | 2288 | } else if (found == 1) { |
@@ -2291,6 +2293,7 @@ int ubifs_tnc_add(struct ubifs_info *c, const union ubifs_key *key, int lnum, | |||
2291 | zbr->lnum = lnum; | 2293 | zbr->lnum = lnum; |
2292 | zbr->offs = offs; | 2294 | zbr->offs = offs; |
2293 | zbr->len = len; | 2295 | zbr->len = len; |
2296 | ubifs_copy_hash(c, hash, zbr->hash); | ||
2294 | } else | 2297 | } else |
2295 | err = found; | 2298 | err = found; |
2296 | if (!err) | 2299 | if (!err) |
@@ -2392,13 +2395,14 @@ out_unlock: | |||
2392 | * @lnum: LEB number of node | 2395 | * @lnum: LEB number of node |
2393 | * @offs: node offset | 2396 | * @offs: node offset |
2394 | * @len: node length | 2397 | * @len: node length |
2398 | * @hash: The hash over the node | ||
2395 | * @nm: node name | 2399 | * @nm: node name |
2396 | * | 2400 | * |
2397 | * This is the same as 'ubifs_tnc_add()' but it should be used with keys which | 2401 | * This is the same as 'ubifs_tnc_add()' but it should be used with keys which |
2398 | * may have collisions, like directory entry keys. | 2402 | * may have collisions, like directory entry keys. |
2399 | */ | 2403 | */ |
2400 | int ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key, | 2404 | int ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key, |
2401 | int lnum, int offs, int len, | 2405 | int lnum, int offs, int len, const u8 *hash, |
2402 | const struct fscrypt_name *nm) | 2406 | const struct fscrypt_name *nm) |
2403 | { | 2407 | { |
2404 | int found, n, err = 0; | 2408 | int found, n, err = 0; |
@@ -2441,6 +2445,7 @@ int ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key, | |||
2441 | zbr->lnum = lnum; | 2445 | zbr->lnum = lnum; |
2442 | zbr->offs = offs; | 2446 | zbr->offs = offs; |
2443 | zbr->len = len; | 2447 | zbr->len = len; |
2448 | ubifs_copy_hash(c, hash, zbr->hash); | ||
2444 | goto out_unlock; | 2449 | goto out_unlock; |
2445 | } | 2450 | } |
2446 | } | 2451 | } |
@@ -2452,6 +2457,7 @@ int ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key, | |||
2452 | zbr.lnum = lnum; | 2457 | zbr.lnum = lnum; |
2453 | zbr.offs = offs; | 2458 | zbr.offs = offs; |
2454 | zbr.len = len; | 2459 | zbr.len = len; |
2460 | ubifs_copy_hash(c, hash, zbr.hash); | ||
2455 | key_copy(c, key, &zbr.key); | 2461 | key_copy(c, key, &zbr.key); |
2456 | err = tnc_insert(c, znode, &zbr, n + 1); | 2462 | err = tnc_insert(c, znode, &zbr, n + 1); |
2457 | if (err) | 2463 | if (err) |
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 42e904b060f9..a7e423347e6d 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h | |||
@@ -747,6 +747,7 @@ struct ubifs_jhead { | |||
747 | * @lnum: LEB number of the target node (indexing node or data node) | 747 | * @lnum: LEB number of the target node (indexing node or data node) |
748 | * @offs: target node offset within @lnum | 748 | * @offs: target node offset within @lnum |
749 | * @len: target node length | 749 | * @len: target node length |
750 | * @hash: the hash of the target node | ||
750 | */ | 751 | */ |
751 | struct ubifs_zbranch { | 752 | struct ubifs_zbranch { |
752 | union ubifs_key key; | 753 | union ubifs_key key; |
@@ -757,6 +758,7 @@ struct ubifs_zbranch { | |||
757 | int lnum; | 758 | int lnum; |
758 | int offs; | 759 | int offs; |
759 | int len; | 760 | int len; |
761 | u8 hash[UBIFS_HASH_ARR_SZ]; | ||
760 | }; | 762 | }; |
761 | 763 | ||
762 | /** | 764 | /** |
@@ -1818,11 +1820,12 @@ int ubifs_tnc_lookup_dh(struct ubifs_info *c, const union ubifs_key *key, | |||
1818 | int ubifs_tnc_locate(struct ubifs_info *c, const union ubifs_key *key, | 1820 | int ubifs_tnc_locate(struct ubifs_info *c, const union ubifs_key *key, |
1819 | void *node, int *lnum, int *offs); | 1821 | void *node, int *lnum, int *offs); |
1820 | int ubifs_tnc_add(struct ubifs_info *c, const union ubifs_key *key, int lnum, | 1822 | int ubifs_tnc_add(struct ubifs_info *c, const union ubifs_key *key, int lnum, |
1821 | int offs, int len); | 1823 | int offs, int len, const u8 *hash); |
1822 | int ubifs_tnc_replace(struct ubifs_info *c, const union ubifs_key *key, | 1824 | int ubifs_tnc_replace(struct ubifs_info *c, const union ubifs_key *key, |
1823 | int old_lnum, int old_offs, int lnum, int offs, int len); | 1825 | int old_lnum, int old_offs, int lnum, int offs, int len); |
1824 | int ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key, | 1826 | int ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key, |
1825 | int lnum, int offs, int len, const struct fscrypt_name *nm); | 1827 | int lnum, int offs, int len, const u8 *hash, |
1828 | const struct fscrypt_name *nm); | ||
1826 | int ubifs_tnc_remove(struct ubifs_info *c, const union ubifs_key *key); | 1829 | int ubifs_tnc_remove(struct ubifs_info *c, const union ubifs_key *key); |
1827 | int ubifs_tnc_remove_nm(struct ubifs_info *c, const union ubifs_key *key, | 1830 | int ubifs_tnc_remove_nm(struct ubifs_info *c, const union ubifs_key *key, |
1828 | const struct fscrypt_name *nm); | 1831 | const struct fscrypt_name *nm); |