| .. | .. |
|---|
| 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 |
|---|
| .. | .. |
|---|
| 37 | 25 | #include <linux/math64.h> |
|---|
| 38 | 26 | #include <linux/writeback.h> |
|---|
| 39 | 27 | #include "ubifs.h" |
|---|
| 28 | + |
|---|
| 29 | +static int ubifs_default_version_set(const char *val, const struct kernel_param *kp) |
|---|
| 30 | +{ |
|---|
| 31 | + int n = 0, ret; |
|---|
| 32 | + |
|---|
| 33 | + ret = kstrtoint(val, 10, &n); |
|---|
| 34 | + if (ret != 0 || n < 4 || n > UBIFS_FORMAT_VERSION) |
|---|
| 35 | + return -EINVAL; |
|---|
| 36 | + return param_set_int(val, kp); |
|---|
| 37 | +} |
|---|
| 38 | + |
|---|
| 39 | +static const struct kernel_param_ops ubifs_default_version_ops = { |
|---|
| 40 | + .set = ubifs_default_version_set, |
|---|
| 41 | + .get = param_get_int, |
|---|
| 42 | +}; |
|---|
| 43 | + |
|---|
| 44 | +int ubifs_default_version = UBIFS_FORMAT_VERSION; |
|---|
| 45 | +module_param_cb(default_version, &ubifs_default_version_ops, &ubifs_default_version, 0600); |
|---|
| 40 | 46 | |
|---|
| 41 | 47 | /* |
|---|
| 42 | 48 | * Maximum amount of memory we may 'kmalloc()' without worrying that we are |
|---|
| .. | .. |
|---|
| 129 | 135 | goto out_ino; |
|---|
| 130 | 136 | |
|---|
| 131 | 137 | inode->i_flags |= S_NOCMTIME; |
|---|
| 132 | | -#ifndef CONFIG_UBIFS_ATIME_SUPPORT |
|---|
| 133 | | - inode->i_flags |= S_NOATIME; |
|---|
| 134 | | -#endif |
|---|
| 138 | + |
|---|
| 139 | + if (!IS_ENABLED(CONFIG_UBIFS_ATIME_SUPPORT)) |
|---|
| 140 | + inode->i_flags |= S_NOATIME; |
|---|
| 141 | + |
|---|
| 135 | 142 | set_nlink(inode, le32_to_cpu(ino->nlink)); |
|---|
| 136 | 143 | i_uid_write(inode, le32_to_cpu(ino->uid)); |
|---|
| 137 | 144 | i_gid_write(inode, le32_to_cpu(ino->gid)); |
|---|
| .. | .. |
|---|
| 268 | 275 | memset((void *)ui + sizeof(struct inode), 0, |
|---|
| 269 | 276 | sizeof(struct ubifs_inode) - sizeof(struct inode)); |
|---|
| 270 | 277 | mutex_init(&ui->ui_mutex); |
|---|
| 278 | + init_rwsem(&ui->xattr_sem); |
|---|
| 271 | 279 | spin_lock_init(&ui->ui_lock); |
|---|
| 272 | 280 | return &ui->vfs_inode; |
|---|
| 273 | 281 | }; |
|---|
| 274 | 282 | |
|---|
| 275 | | -static void ubifs_i_callback(struct rcu_head *head) |
|---|
| 276 | | -{ |
|---|
| 277 | | - struct inode *inode = container_of(head, struct inode, i_rcu); |
|---|
| 278 | | - struct ubifs_inode *ui = ubifs_inode(inode); |
|---|
| 279 | | - |
|---|
| 280 | | - fscrypt_free_inode(inode); |
|---|
| 281 | | - kmem_cache_free(ubifs_inode_slab, ui); |
|---|
| 282 | | -} |
|---|
| 283 | | - |
|---|
| 284 | | -static void ubifs_destroy_inode(struct inode *inode) |
|---|
| 283 | +static void ubifs_free_inode(struct inode *inode) |
|---|
| 285 | 284 | { |
|---|
| 286 | 285 | struct ubifs_inode *ui = ubifs_inode(inode); |
|---|
| 287 | 286 | |
|---|
| 288 | 287 | kfree(ui->data); |
|---|
| 289 | | - call_rcu(&inode->i_rcu, ubifs_i_callback); |
|---|
| 288 | + fscrypt_free_inode(inode); |
|---|
| 289 | + |
|---|
| 290 | + kmem_cache_free(ubifs_inode_slab, ui); |
|---|
| 290 | 291 | } |
|---|
| 291 | 292 | |
|---|
| 292 | 293 | /* |
|---|
| .. | .. |
|---|
| 591 | 592 | c->ranges[UBIFS_REF_NODE].len = UBIFS_REF_NODE_SZ; |
|---|
| 592 | 593 | c->ranges[UBIFS_TRUN_NODE].len = UBIFS_TRUN_NODE_SZ; |
|---|
| 593 | 594 | c->ranges[UBIFS_CS_NODE].len = UBIFS_CS_NODE_SZ; |
|---|
| 595 | + c->ranges[UBIFS_AUTH_NODE].min_len = UBIFS_AUTH_NODE_SZ; |
|---|
| 596 | + c->ranges[UBIFS_AUTH_NODE].max_len = UBIFS_AUTH_NODE_SZ + |
|---|
| 597 | + UBIFS_MAX_HMAC_LEN; |
|---|
| 598 | + c->ranges[UBIFS_SIG_NODE].min_len = UBIFS_SIG_NODE_SZ; |
|---|
| 599 | + c->ranges[UBIFS_SIG_NODE].max_len = c->leb_size - UBIFS_SB_NODE_SZ; |
|---|
| 594 | 600 | |
|---|
| 595 | 601 | c->ranges[UBIFS_INO_NODE].min_len = UBIFS_INO_NODE_SZ; |
|---|
| 596 | 602 | c->ranges[UBIFS_INO_NODE].max_len = UBIFS_MAX_INO_NODE_SZ; |
|---|
| .. | .. |
|---|
| 632 | 638 | c->max_bu_buf_len = UBIFS_MAX_BULK_READ * UBIFS_MAX_DATA_NODE_SZ; |
|---|
| 633 | 639 | if (c->max_bu_buf_len > c->leb_size) |
|---|
| 634 | 640 | c->max_bu_buf_len = c->leb_size; |
|---|
| 641 | + |
|---|
| 642 | + /* Log is ready, preserve one LEB for commits. */ |
|---|
| 643 | + c->min_log_bytes = c->leb_size; |
|---|
| 644 | + |
|---|
| 635 | 645 | return 0; |
|---|
| 636 | 646 | } |
|---|
| 637 | 647 | |
|---|
| .. | .. |
|---|
| 828 | 838 | c->jheads[i].wbuf.sync_callback = &bud_wbuf_callback; |
|---|
| 829 | 839 | c->jheads[i].wbuf.jhead = i; |
|---|
| 830 | 840 | c->jheads[i].grouped = 1; |
|---|
| 841 | + c->jheads[i].log_hash = ubifs_hash_get_desc(c); |
|---|
| 842 | + if (IS_ERR(c->jheads[i].log_hash)) { |
|---|
| 843 | + err = PTR_ERR(c->jheads[i].log_hash); |
|---|
| 844 | + goto out; |
|---|
| 845 | + } |
|---|
| 831 | 846 | } |
|---|
| 832 | 847 | |
|---|
| 833 | 848 | /* |
|---|
| .. | .. |
|---|
| 838 | 853 | c->jheads[GCHD].grouped = 0; |
|---|
| 839 | 854 | |
|---|
| 840 | 855 | return 0; |
|---|
| 856 | + |
|---|
| 857 | +out: |
|---|
| 858 | + while (i--) |
|---|
| 859 | + kfree(c->jheads[i].log_hash); |
|---|
| 860 | + |
|---|
| 861 | + return err; |
|---|
| 841 | 862 | } |
|---|
| 842 | 863 | |
|---|
| 843 | 864 | /** |
|---|
| .. | .. |
|---|
| 852 | 873 | for (i = 0; i < c->jhead_cnt; i++) { |
|---|
| 853 | 874 | kfree(c->jheads[i].wbuf.buf); |
|---|
| 854 | 875 | kfree(c->jheads[i].wbuf.inodes); |
|---|
| 876 | + kfree(c->jheads[i].log_hash); |
|---|
| 855 | 877 | } |
|---|
| 856 | 878 | kfree(c->jheads); |
|---|
| 857 | 879 | c->jheads = NULL; |
|---|
| .. | .. |
|---|
| 936 | 958 | * Opt_no_chk_data_crc: do not check CRCs when reading data nodes |
|---|
| 937 | 959 | * Opt_override_compr: override default compressor |
|---|
| 938 | 960 | * Opt_assert: set ubifs_assert() action |
|---|
| 961 | + * Opt_auth_key: The key name used for authentication |
|---|
| 962 | + * Opt_auth_hash_name: The hash type used for authentication |
|---|
| 939 | 963 | * Opt_err: just end of array marker |
|---|
| 940 | 964 | */ |
|---|
| 941 | 965 | enum { |
|---|
| .. | .. |
|---|
| 947 | 971 | Opt_no_chk_data_crc, |
|---|
| 948 | 972 | Opt_override_compr, |
|---|
| 949 | 973 | Opt_assert, |
|---|
| 974 | + Opt_auth_key, |
|---|
| 975 | + Opt_auth_hash_name, |
|---|
| 950 | 976 | Opt_ignore, |
|---|
| 951 | 977 | Opt_err, |
|---|
| 952 | 978 | }; |
|---|
| .. | .. |
|---|
| 959 | 985 | {Opt_chk_data_crc, "chk_data_crc"}, |
|---|
| 960 | 986 | {Opt_no_chk_data_crc, "no_chk_data_crc"}, |
|---|
| 961 | 987 | {Opt_override_compr, "compr=%s"}, |
|---|
| 988 | + {Opt_auth_key, "auth_key=%s"}, |
|---|
| 989 | + {Opt_auth_hash_name, "auth_hash_name=%s"}, |
|---|
| 962 | 990 | {Opt_ignore, "ubi=%s"}, |
|---|
| 963 | 991 | {Opt_ignore, "vol=%s"}, |
|---|
| 964 | 992 | {Opt_assert, "assert=%s"}, |
|---|
| .. | .. |
|---|
| 1052 | 1080 | c->mount_opts.compr_type = UBIFS_COMPR_LZO; |
|---|
| 1053 | 1081 | else if (!strcmp(name, "zlib")) |
|---|
| 1054 | 1082 | c->mount_opts.compr_type = UBIFS_COMPR_ZLIB; |
|---|
| 1083 | + else if (!strcmp(name, "zstd")) |
|---|
| 1084 | + c->mount_opts.compr_type = UBIFS_COMPR_ZSTD; |
|---|
| 1055 | 1085 | else { |
|---|
| 1056 | 1086 | ubifs_err(c, "unknown compressor \"%s\"", name); //FIXME: is c ready? |
|---|
| 1057 | 1087 | kfree(name); |
|---|
| .. | .. |
|---|
| 1082 | 1112 | kfree(act); |
|---|
| 1083 | 1113 | break; |
|---|
| 1084 | 1114 | } |
|---|
| 1115 | + case Opt_auth_key: |
|---|
| 1116 | + if (!is_remount) { |
|---|
| 1117 | + c->auth_key_name = kstrdup(args[0].from, |
|---|
| 1118 | + GFP_KERNEL); |
|---|
| 1119 | + if (!c->auth_key_name) |
|---|
| 1120 | + return -ENOMEM; |
|---|
| 1121 | + } |
|---|
| 1122 | + break; |
|---|
| 1123 | + case Opt_auth_hash_name: |
|---|
| 1124 | + if (!is_remount) { |
|---|
| 1125 | + c->auth_hash_name = kstrdup(args[0].from, |
|---|
| 1126 | + GFP_KERNEL); |
|---|
| 1127 | + if (!c->auth_hash_name) |
|---|
| 1128 | + return -ENOMEM; |
|---|
| 1129 | + } |
|---|
| 1130 | + break; |
|---|
| 1085 | 1131 | case Opt_ignore: |
|---|
| 1086 | 1132 | break; |
|---|
| 1087 | 1133 | default: |
|---|
| .. | .. |
|---|
| 1102 | 1148 | } |
|---|
| 1103 | 1149 | |
|---|
| 1104 | 1150 | return 0; |
|---|
| 1151 | +} |
|---|
| 1152 | + |
|---|
| 1153 | +/* |
|---|
| 1154 | + * ubifs_release_options - release mount parameters which have been dumped. |
|---|
| 1155 | + * @c: UBIFS file-system description object |
|---|
| 1156 | + */ |
|---|
| 1157 | +static void ubifs_release_options(struct ubifs_info *c) |
|---|
| 1158 | +{ |
|---|
| 1159 | + kfree(c->auth_key_name); |
|---|
| 1160 | + c->auth_key_name = NULL; |
|---|
| 1161 | + kfree(c->auth_hash_name); |
|---|
| 1162 | + c->auth_hash_name = NULL; |
|---|
| 1105 | 1163 | } |
|---|
| 1106 | 1164 | |
|---|
| 1107 | 1165 | /** |
|---|
| .. | .. |
|---|
| 1261 | 1319 | |
|---|
| 1262 | 1320 | c->mounting = 1; |
|---|
| 1263 | 1321 | |
|---|
| 1322 | + if (c->auth_key_name) { |
|---|
| 1323 | + if (IS_ENABLED(CONFIG_UBIFS_FS_AUTHENTICATION)) { |
|---|
| 1324 | + err = ubifs_init_authentication(c); |
|---|
| 1325 | + if (err) |
|---|
| 1326 | + goto out_free; |
|---|
| 1327 | + } else { |
|---|
| 1328 | + ubifs_err(c, "auth_key_name, but UBIFS is built without" |
|---|
| 1329 | + " authentication support"); |
|---|
| 1330 | + err = -EINVAL; |
|---|
| 1331 | + goto out_free; |
|---|
| 1332 | + } |
|---|
| 1333 | + } |
|---|
| 1334 | + |
|---|
| 1264 | 1335 | err = ubifs_read_superblock(c); |
|---|
| 1265 | 1336 | if (err) |
|---|
| 1266 | | - goto out_free; |
|---|
| 1337 | + goto out_auth; |
|---|
| 1267 | 1338 | |
|---|
| 1268 | 1339 | c->probing = 0; |
|---|
| 1269 | 1340 | |
|---|
| .. | .. |
|---|
| 1275 | 1346 | ubifs_err(c, "'compressor \"%s\" is not compiled in", |
|---|
| 1276 | 1347 | ubifs_compr_name(c, c->default_compr)); |
|---|
| 1277 | 1348 | err = -ENOTSUPP; |
|---|
| 1278 | | - goto out_free; |
|---|
| 1349 | + goto out_auth; |
|---|
| 1279 | 1350 | } |
|---|
| 1280 | 1351 | |
|---|
| 1281 | 1352 | err = init_constants_sb(c); |
|---|
| 1282 | 1353 | if (err) |
|---|
| 1283 | | - goto out_free; |
|---|
| 1354 | + goto out_auth; |
|---|
| 1284 | 1355 | |
|---|
| 1285 | | - sz = ALIGN(c->max_idx_node_sz, c->min_io_size); |
|---|
| 1286 | | - sz = ALIGN(sz + c->max_idx_node_sz, c->min_io_size); |
|---|
| 1356 | + sz = ALIGN(c->max_idx_node_sz, c->min_io_size) * 2; |
|---|
| 1287 | 1357 | c->cbuf = kmalloc(sz, GFP_NOFS); |
|---|
| 1288 | 1358 | if (!c->cbuf) { |
|---|
| 1289 | 1359 | err = -ENOMEM; |
|---|
| 1290 | | - goto out_free; |
|---|
| 1360 | + goto out_auth; |
|---|
| 1291 | 1361 | } |
|---|
| 1292 | 1362 | |
|---|
| 1293 | 1363 | err = alloc_wbufs(c); |
|---|
| .. | .. |
|---|
| 1346 | 1416 | goto out_lpt; |
|---|
| 1347 | 1417 | } |
|---|
| 1348 | 1418 | |
|---|
| 1419 | + /* |
|---|
| 1420 | + * Handle offline signed images: Now that the master node is |
|---|
| 1421 | + * written and its validation no longer depends on the hash |
|---|
| 1422 | + * in the superblock, we can update the offline signed |
|---|
| 1423 | + * superblock with a HMAC version, |
|---|
| 1424 | + */ |
|---|
| 1425 | + if (ubifs_authenticated(c) && ubifs_hmac_zero(c, c->sup_node->hmac)) { |
|---|
| 1426 | + err = ubifs_hmac_wkm(c, c->sup_node->hmac_wkm); |
|---|
| 1427 | + if (err) |
|---|
| 1428 | + goto out_lpt; |
|---|
| 1429 | + c->superblock_need_write = 1; |
|---|
| 1430 | + } |
|---|
| 1431 | + |
|---|
| 1432 | + if (!c->ro_mount && c->superblock_need_write) { |
|---|
| 1433 | + err = ubifs_write_sb_node(c, c->sup_node); |
|---|
| 1434 | + if (err) |
|---|
| 1435 | + goto out_lpt; |
|---|
| 1436 | + c->superblock_need_write = 0; |
|---|
| 1437 | + } |
|---|
| 1438 | + |
|---|
| 1349 | 1439 | err = dbg_check_idx_size(c, c->bi.old_idx_sz); |
|---|
| 1350 | 1440 | if (err) |
|---|
| 1351 | 1441 | goto out_lpt; |
|---|
| .. | .. |
|---|
| 1379 | 1469 | } |
|---|
| 1380 | 1470 | |
|---|
| 1381 | 1471 | if (c->need_recovery) { |
|---|
| 1382 | | - err = ubifs_recover_size(c); |
|---|
| 1383 | | - if (err) |
|---|
| 1384 | | - goto out_orphans; |
|---|
| 1472 | + if (!ubifs_authenticated(c)) { |
|---|
| 1473 | + err = ubifs_recover_size(c, true); |
|---|
| 1474 | + if (err) |
|---|
| 1475 | + goto out_orphans; |
|---|
| 1476 | + } |
|---|
| 1477 | + |
|---|
| 1385 | 1478 | err = ubifs_rcvry_gc_commit(c); |
|---|
| 1386 | 1479 | if (err) |
|---|
| 1387 | 1480 | goto out_orphans; |
|---|
| 1481 | + |
|---|
| 1482 | + if (ubifs_authenticated(c)) { |
|---|
| 1483 | + err = ubifs_recover_size(c, false); |
|---|
| 1484 | + if (err) |
|---|
| 1485 | + goto out_orphans; |
|---|
| 1486 | + } |
|---|
| 1388 | 1487 | } else { |
|---|
| 1389 | 1488 | err = take_gc_lnum(c); |
|---|
| 1390 | 1489 | if (err) |
|---|
| .. | .. |
|---|
| 1403 | 1502 | if (err) |
|---|
| 1404 | 1503 | goto out_orphans; |
|---|
| 1405 | 1504 | } else if (c->need_recovery) { |
|---|
| 1406 | | - err = ubifs_recover_size(c); |
|---|
| 1505 | + err = ubifs_recover_size(c, false); |
|---|
| 1407 | 1506 | if (err) |
|---|
| 1408 | 1507 | goto out_orphans; |
|---|
| 1409 | 1508 | } else { |
|---|
| .. | .. |
|---|
| 1442 | 1541 | if (err) |
|---|
| 1443 | 1542 | goto out_infos; |
|---|
| 1444 | 1543 | |
|---|
| 1445 | | - err = dbg_debugfs_init_fs(c); |
|---|
| 1446 | | - if (err) |
|---|
| 1447 | | - goto out_infos; |
|---|
| 1544 | + dbg_debugfs_init_fs(c); |
|---|
| 1448 | 1545 | |
|---|
| 1449 | 1546 | c->mounting = 0; |
|---|
| 1450 | 1547 | |
|---|
| .. | .. |
|---|
| 1511 | 1608 | c->bud_bytes, c->bud_bytes >> 10, c->bud_bytes >> 20); |
|---|
| 1512 | 1609 | dbg_gen("max. seq. number: %llu", c->max_sqnum); |
|---|
| 1513 | 1610 | dbg_gen("commit number: %llu", c->cmt_no); |
|---|
| 1611 | + dbg_gen("max. xattrs per inode: %d", ubifs_xattr_max_cnt(c)); |
|---|
| 1612 | + dbg_gen("max orphans: %d", c->max_orphans); |
|---|
| 1514 | 1613 | |
|---|
| 1515 | 1614 | return 0; |
|---|
| 1516 | 1615 | |
|---|
| .. | .. |
|---|
| 1533 | 1632 | free_wbufs(c); |
|---|
| 1534 | 1633 | out_cbuf: |
|---|
| 1535 | 1634 | kfree(c->cbuf); |
|---|
| 1635 | +out_auth: |
|---|
| 1636 | + ubifs_exit_authentication(c); |
|---|
| 1536 | 1637 | out_free: |
|---|
| 1537 | 1638 | kfree(c->write_reserve_buf); |
|---|
| 1538 | 1639 | kfree(c->bu.buf); |
|---|
| 1539 | 1640 | vfree(c->ileb_buf); |
|---|
| 1540 | 1641 | vfree(c->sbuf); |
|---|
| 1541 | 1642 | kfree(c->bottom_up_buf); |
|---|
| 1643 | + kfree(c->sup_node); |
|---|
| 1542 | 1644 | ubifs_debugging_exit(c); |
|---|
| 1543 | 1645 | return err; |
|---|
| 1544 | 1646 | } |
|---|
| .. | .. |
|---|
| 1569 | 1671 | free_wbufs(c); |
|---|
| 1570 | 1672 | free_orphans(c); |
|---|
| 1571 | 1673 | ubifs_lpt_free(c, 0); |
|---|
| 1674 | + ubifs_exit_authentication(c); |
|---|
| 1572 | 1675 | |
|---|
| 1676 | + ubifs_release_options(c); |
|---|
| 1573 | 1677 | kfree(c->cbuf); |
|---|
| 1574 | 1678 | kfree(c->rcvrd_mst_node); |
|---|
| 1575 | 1679 | kfree(c->mst_node); |
|---|
| .. | .. |
|---|
| 1578 | 1682 | vfree(c->ileb_buf); |
|---|
| 1579 | 1683 | vfree(c->sbuf); |
|---|
| 1580 | 1684 | kfree(c->bottom_up_buf); |
|---|
| 1685 | + kfree(c->sup_node); |
|---|
| 1581 | 1686 | ubifs_debugging_exit(c); |
|---|
| 1582 | 1687 | } |
|---|
| 1583 | 1688 | |
|---|
| .. | .. |
|---|
| 1616 | 1721 | if (err) |
|---|
| 1617 | 1722 | goto out; |
|---|
| 1618 | 1723 | |
|---|
| 1619 | | - if (c->old_leb_cnt != c->leb_cnt) { |
|---|
| 1620 | | - struct ubifs_sb_node *sup; |
|---|
| 1621 | | - |
|---|
| 1622 | | - sup = ubifs_read_sb_node(c); |
|---|
| 1623 | | - if (IS_ERR(sup)) { |
|---|
| 1624 | | - err = PTR_ERR(sup); |
|---|
| 1625 | | - goto out; |
|---|
| 1626 | | - } |
|---|
| 1627 | | - sup->leb_cnt = cpu_to_le32(c->leb_cnt); |
|---|
| 1628 | | - err = ubifs_write_sb_node(c, sup); |
|---|
| 1629 | | - kfree(sup); |
|---|
| 1630 | | - if (err) |
|---|
| 1631 | | - goto out; |
|---|
| 1632 | | - } |
|---|
| 1633 | | - |
|---|
| 1634 | 1724 | if (c->need_recovery) { |
|---|
| 1635 | 1725 | ubifs_msg(c, "completing deferred recovery"); |
|---|
| 1636 | 1726 | err = ubifs_write_rcvrd_mst_node(c); |
|---|
| 1637 | 1727 | if (err) |
|---|
| 1638 | 1728 | goto out; |
|---|
| 1639 | | - err = ubifs_recover_size(c); |
|---|
| 1640 | | - if (err) |
|---|
| 1641 | | - goto out; |
|---|
| 1729 | + if (!ubifs_authenticated(c)) { |
|---|
| 1730 | + err = ubifs_recover_size(c, true); |
|---|
| 1731 | + if (err) |
|---|
| 1732 | + goto out; |
|---|
| 1733 | + } |
|---|
| 1642 | 1734 | err = ubifs_clean_lebs(c, c->sbuf); |
|---|
| 1643 | 1735 | if (err) |
|---|
| 1644 | 1736 | goto out; |
|---|
| .. | .. |
|---|
| 1658 | 1750 | err = ubifs_write_master(c); |
|---|
| 1659 | 1751 | if (err) |
|---|
| 1660 | 1752 | goto out; |
|---|
| 1753 | + } |
|---|
| 1754 | + |
|---|
| 1755 | + if (c->superblock_need_write) { |
|---|
| 1756 | + struct ubifs_sb_node *sup = c->sup_node; |
|---|
| 1757 | + |
|---|
| 1758 | + err = ubifs_write_sb_node(c, sup); |
|---|
| 1759 | + if (err) |
|---|
| 1760 | + goto out; |
|---|
| 1761 | + |
|---|
| 1762 | + c->superblock_need_write = 0; |
|---|
| 1661 | 1763 | } |
|---|
| 1662 | 1764 | |
|---|
| 1663 | 1765 | c->ileb_buf = vmalloc(c->leb_size); |
|---|
| .. | .. |
|---|
| 1704 | 1806 | goto out; |
|---|
| 1705 | 1807 | } |
|---|
| 1706 | 1808 | |
|---|
| 1707 | | - if (c->need_recovery) |
|---|
| 1809 | + if (c->need_recovery) { |
|---|
| 1708 | 1810 | err = ubifs_rcvry_gc_commit(c); |
|---|
| 1709 | | - else |
|---|
| 1811 | + if (err) |
|---|
| 1812 | + goto out; |
|---|
| 1813 | + |
|---|
| 1814 | + if (ubifs_authenticated(c)) { |
|---|
| 1815 | + err = ubifs_recover_size(c, false); |
|---|
| 1816 | + if (err) |
|---|
| 1817 | + goto out; |
|---|
| 1818 | + } |
|---|
| 1819 | + } else { |
|---|
| 1710 | 1820 | err = ubifs_leb_unmap(c, c->gc_lnum); |
|---|
| 1821 | + } |
|---|
| 1711 | 1822 | if (err) |
|---|
| 1712 | 1823 | goto out; |
|---|
| 1713 | 1824 | |
|---|
| .. | .. |
|---|
| 1931 | 2042 | |
|---|
| 1932 | 2043 | const struct super_operations ubifs_super_operations = { |
|---|
| 1933 | 2044 | .alloc_inode = ubifs_alloc_inode, |
|---|
| 1934 | | - .destroy_inode = ubifs_destroy_inode, |
|---|
| 2045 | + .free_inode = ubifs_free_inode, |
|---|
| 1935 | 2046 | .put_super = ubifs_put_super, |
|---|
| 1936 | 2047 | .write_inode = ubifs_write_inode, |
|---|
| 1937 | 2048 | .drop_inode = ubifs_drop_inode, |
|---|
| .. | .. |
|---|
| 2087 | 2198 | c->vi.vol_id); |
|---|
| 2088 | 2199 | if (err) |
|---|
| 2089 | 2200 | goto out_close; |
|---|
| 2201 | + sb->s_bdi->ra_pages = 0; |
|---|
| 2202 | + sb->s_bdi->io_pages = 0; |
|---|
| 2090 | 2203 | |
|---|
| 2091 | 2204 | sb->s_fs_info = c; |
|---|
| 2092 | 2205 | sb->s_magic = UBIFS_SUPER_MAGIC; |
|---|
| .. | .. |
|---|
| 2099 | 2212 | #ifdef CONFIG_UBIFS_FS_XATTR |
|---|
| 2100 | 2213 | sb->s_xattr = ubifs_xattr_handlers; |
|---|
| 2101 | 2214 | #endif |
|---|
| 2102 | | -#ifdef CONFIG_FS_ENCRYPTION |
|---|
| 2103 | | - sb->s_cop = &ubifs_crypt_operations; |
|---|
| 2104 | | -#endif |
|---|
| 2215 | + fscrypt_set_ops(sb, &ubifs_crypt_operations); |
|---|
| 2105 | 2216 | |
|---|
| 2106 | 2217 | mutex_lock(&c->umount_mutex); |
|---|
| 2107 | 2218 | err = mount_ubifs(c); |
|---|
| .. | .. |
|---|
| 2131 | 2242 | out_unlock: |
|---|
| 2132 | 2243 | mutex_unlock(&c->umount_mutex); |
|---|
| 2133 | 2244 | out_close: |
|---|
| 2245 | + ubifs_release_options(c); |
|---|
| 2134 | 2246 | ubi_close_volume(c->ubi); |
|---|
| 2135 | 2247 | out: |
|---|
| 2136 | 2248 | return err; |
|---|
| .. | .. |
|---|
| 2203 | 2315 | goto out_deact; |
|---|
| 2204 | 2316 | /* We do not support atime */ |
|---|
| 2205 | 2317 | sb->s_flags |= SB_ACTIVE; |
|---|
| 2206 | | -#ifndef CONFIG_UBIFS_ATIME_SUPPORT |
|---|
| 2207 | | - sb->s_flags |= SB_NOATIME; |
|---|
| 2208 | | -#else |
|---|
| 2209 | | - ubifs_msg(c, "full atime support is enabled."); |
|---|
| 2210 | | -#endif |
|---|
| 2318 | + if (IS_ENABLED(CONFIG_UBIFS_ATIME_SUPPORT)) |
|---|
| 2319 | + ubifs_msg(c, "full atime support is enabled."); |
|---|
| 2320 | + else |
|---|
| 2321 | + sb->s_flags |= SB_NOATIME; |
|---|
| 2211 | 2322 | } |
|---|
| 2212 | 2323 | |
|---|
| 2213 | 2324 | /* 'fill_super()' opens ubi again so we must close it here */ |
|---|
| .. | .. |
|---|
| 2322 | 2433 | if (err) |
|---|
| 2323 | 2434 | goto out_shrinker; |
|---|
| 2324 | 2435 | |
|---|
| 2325 | | - err = dbg_debugfs_init(); |
|---|
| 2326 | | - if (err) |
|---|
| 2327 | | - goto out_compr; |
|---|
| 2436 | + dbg_debugfs_init(); |
|---|
| 2328 | 2437 | |
|---|
| 2329 | 2438 | err = register_filesystem(&ubifs_fs_type); |
|---|
| 2330 | 2439 | if (err) { |
|---|
| .. | .. |
|---|
| 2336 | 2445 | |
|---|
| 2337 | 2446 | out_dbg: |
|---|
| 2338 | 2447 | dbg_debugfs_exit(); |
|---|
| 2339 | | -out_compr: |
|---|
| 2340 | 2448 | ubifs_compressors_exit(); |
|---|
| 2341 | 2449 | out_shrinker: |
|---|
| 2342 | 2450 | unregister_shrinker(&ubifs_shrinker_info); |
|---|
| .. | .. |
|---|
| 2367 | 2475 | module_exit(ubifs_exit); |
|---|
| 2368 | 2476 | |
|---|
| 2369 | 2477 | MODULE_LICENSE("GPL"); |
|---|
| 2478 | +MODULE_IMPORT_NS(ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 2370 | 2479 | MODULE_VERSION(__stringify(UBIFS_VERSION)); |
|---|
| 2371 | 2480 | MODULE_AUTHOR("Artem Bityutskiy, Adrian Hunter"); |
|---|
| 2372 | 2481 | MODULE_DESCRIPTION("UBIFS - UBI File System"); |
|---|