.. | .. |
---|
| 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); |
---|