| .. | .. |
|---|
| 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 | |
|---|
| .. | .. |
|---|
| 823 | 833 | INIT_LIST_HEAD(&c->jheads[i].buds_list); |
|---|
| 824 | 834 | err = ubifs_wbuf_init(c, &c->jheads[i].wbuf); |
|---|
| 825 | 835 | if (err) |
|---|
| 826 | | - return err; |
|---|
| 836 | + goto out_wbuf; |
|---|
| 827 | 837 | |
|---|
| 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_log_hash; |
|---|
| 845 | + } |
|---|
| 831 | 846 | } |
|---|
| 832 | 847 | |
|---|
| 833 | 848 | /* |
|---|
| .. | .. |
|---|
| 838 | 853 | c->jheads[GCHD].grouped = 0; |
|---|
| 839 | 854 | |
|---|
| 840 | 855 | return 0; |
|---|
| 856 | + |
|---|
| 857 | +out_log_hash: |
|---|
| 858 | + kfree(c->jheads[i].wbuf.buf); |
|---|
| 859 | + kfree(c->jheads[i].wbuf.inodes); |
|---|
| 860 | + |
|---|
| 861 | +out_wbuf: |
|---|
| 862 | + while (i--) { |
|---|
| 863 | + kfree(c->jheads[i].wbuf.buf); |
|---|
| 864 | + kfree(c->jheads[i].wbuf.inodes); |
|---|
| 865 | + kfree(c->jheads[i].log_hash); |
|---|
| 866 | + } |
|---|
| 867 | + kfree(c->jheads); |
|---|
| 868 | + c->jheads = NULL; |
|---|
| 869 | + |
|---|
| 870 | + return err; |
|---|
| 841 | 871 | } |
|---|
| 842 | 872 | |
|---|
| 843 | 873 | /** |
|---|
| .. | .. |
|---|
| 852 | 882 | for (i = 0; i < c->jhead_cnt; i++) { |
|---|
| 853 | 883 | kfree(c->jheads[i].wbuf.buf); |
|---|
| 854 | 884 | kfree(c->jheads[i].wbuf.inodes); |
|---|
| 885 | + kfree(c->jheads[i].log_hash); |
|---|
| 855 | 886 | } |
|---|
| 856 | 887 | kfree(c->jheads); |
|---|
| 857 | 888 | c->jheads = NULL; |
|---|
| .. | .. |
|---|
| 936 | 967 | * Opt_no_chk_data_crc: do not check CRCs when reading data nodes |
|---|
| 937 | 968 | * Opt_override_compr: override default compressor |
|---|
| 938 | 969 | * Opt_assert: set ubifs_assert() action |
|---|
| 970 | + * Opt_auth_key: The key name used for authentication |
|---|
| 971 | + * Opt_auth_hash_name: The hash type used for authentication |
|---|
| 939 | 972 | * Opt_err: just end of array marker |
|---|
| 940 | 973 | */ |
|---|
| 941 | 974 | enum { |
|---|
| .. | .. |
|---|
| 947 | 980 | Opt_no_chk_data_crc, |
|---|
| 948 | 981 | Opt_override_compr, |
|---|
| 949 | 982 | Opt_assert, |
|---|
| 983 | + Opt_auth_key, |
|---|
| 984 | + Opt_auth_hash_name, |
|---|
| 950 | 985 | Opt_ignore, |
|---|
| 951 | 986 | Opt_err, |
|---|
| 952 | 987 | }; |
|---|
| .. | .. |
|---|
| 959 | 994 | {Opt_chk_data_crc, "chk_data_crc"}, |
|---|
| 960 | 995 | {Opt_no_chk_data_crc, "no_chk_data_crc"}, |
|---|
| 961 | 996 | {Opt_override_compr, "compr=%s"}, |
|---|
| 997 | + {Opt_auth_key, "auth_key=%s"}, |
|---|
| 998 | + {Opt_auth_hash_name, "auth_hash_name=%s"}, |
|---|
| 962 | 999 | {Opt_ignore, "ubi=%s"}, |
|---|
| 963 | 1000 | {Opt_ignore, "vol=%s"}, |
|---|
| 964 | 1001 | {Opt_assert, "assert=%s"}, |
|---|
| .. | .. |
|---|
| 1052 | 1089 | c->mount_opts.compr_type = UBIFS_COMPR_LZO; |
|---|
| 1053 | 1090 | else if (!strcmp(name, "zlib")) |
|---|
| 1054 | 1091 | c->mount_opts.compr_type = UBIFS_COMPR_ZLIB; |
|---|
| 1092 | + else if (!strcmp(name, "zstd")) |
|---|
| 1093 | + c->mount_opts.compr_type = UBIFS_COMPR_ZSTD; |
|---|
| 1055 | 1094 | else { |
|---|
| 1056 | 1095 | ubifs_err(c, "unknown compressor \"%s\"", name); //FIXME: is c ready? |
|---|
| 1057 | 1096 | kfree(name); |
|---|
| .. | .. |
|---|
| 1082 | 1121 | kfree(act); |
|---|
| 1083 | 1122 | break; |
|---|
| 1084 | 1123 | } |
|---|
| 1124 | + case Opt_auth_key: |
|---|
| 1125 | + if (!is_remount) { |
|---|
| 1126 | + c->auth_key_name = kstrdup(args[0].from, |
|---|
| 1127 | + GFP_KERNEL); |
|---|
| 1128 | + if (!c->auth_key_name) |
|---|
| 1129 | + return -ENOMEM; |
|---|
| 1130 | + } |
|---|
| 1131 | + break; |
|---|
| 1132 | + case Opt_auth_hash_name: |
|---|
| 1133 | + if (!is_remount) { |
|---|
| 1134 | + c->auth_hash_name = kstrdup(args[0].from, |
|---|
| 1135 | + GFP_KERNEL); |
|---|
| 1136 | + if (!c->auth_hash_name) |
|---|
| 1137 | + return -ENOMEM; |
|---|
| 1138 | + } |
|---|
| 1139 | + break; |
|---|
| 1085 | 1140 | case Opt_ignore: |
|---|
| 1086 | 1141 | break; |
|---|
| 1087 | 1142 | default: |
|---|
| .. | .. |
|---|
| 1102 | 1157 | } |
|---|
| 1103 | 1158 | |
|---|
| 1104 | 1159 | return 0; |
|---|
| 1160 | +} |
|---|
| 1161 | + |
|---|
| 1162 | +/* |
|---|
| 1163 | + * ubifs_release_options - release mount parameters which have been dumped. |
|---|
| 1164 | + * @c: UBIFS file-system description object |
|---|
| 1165 | + */ |
|---|
| 1166 | +static void ubifs_release_options(struct ubifs_info *c) |
|---|
| 1167 | +{ |
|---|
| 1168 | + kfree(c->auth_key_name); |
|---|
| 1169 | + c->auth_key_name = NULL; |
|---|
| 1170 | + kfree(c->auth_hash_name); |
|---|
| 1171 | + c->auth_hash_name = NULL; |
|---|
| 1105 | 1172 | } |
|---|
| 1106 | 1173 | |
|---|
| 1107 | 1174 | /** |
|---|
| .. | .. |
|---|
| 1261 | 1328 | |
|---|
| 1262 | 1329 | c->mounting = 1; |
|---|
| 1263 | 1330 | |
|---|
| 1331 | + if (c->auth_key_name) { |
|---|
| 1332 | + if (IS_ENABLED(CONFIG_UBIFS_FS_AUTHENTICATION)) { |
|---|
| 1333 | + err = ubifs_init_authentication(c); |
|---|
| 1334 | + if (err) |
|---|
| 1335 | + goto out_free; |
|---|
| 1336 | + } else { |
|---|
| 1337 | + ubifs_err(c, "auth_key_name, but UBIFS is built without" |
|---|
| 1338 | + " authentication support"); |
|---|
| 1339 | + err = -EINVAL; |
|---|
| 1340 | + goto out_free; |
|---|
| 1341 | + } |
|---|
| 1342 | + } |
|---|
| 1343 | + |
|---|
| 1264 | 1344 | err = ubifs_read_superblock(c); |
|---|
| 1265 | 1345 | if (err) |
|---|
| 1266 | | - goto out_free; |
|---|
| 1346 | + goto out_auth; |
|---|
| 1267 | 1347 | |
|---|
| 1268 | 1348 | c->probing = 0; |
|---|
| 1269 | 1349 | |
|---|
| .. | .. |
|---|
| 1275 | 1355 | ubifs_err(c, "'compressor \"%s\" is not compiled in", |
|---|
| 1276 | 1356 | ubifs_compr_name(c, c->default_compr)); |
|---|
| 1277 | 1357 | err = -ENOTSUPP; |
|---|
| 1278 | | - goto out_free; |
|---|
| 1358 | + goto out_auth; |
|---|
| 1279 | 1359 | } |
|---|
| 1280 | 1360 | |
|---|
| 1281 | 1361 | err = init_constants_sb(c); |
|---|
| 1282 | 1362 | if (err) |
|---|
| 1283 | | - goto out_free; |
|---|
| 1363 | + goto out_auth; |
|---|
| 1284 | 1364 | |
|---|
| 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); |
|---|
| 1365 | + sz = ALIGN(c->max_idx_node_sz, c->min_io_size) * 2; |
|---|
| 1287 | 1366 | c->cbuf = kmalloc(sz, GFP_NOFS); |
|---|
| 1288 | 1367 | if (!c->cbuf) { |
|---|
| 1289 | 1368 | err = -ENOMEM; |
|---|
| 1290 | | - goto out_free; |
|---|
| 1369 | + goto out_auth; |
|---|
| 1291 | 1370 | } |
|---|
| 1292 | 1371 | |
|---|
| 1293 | 1372 | err = alloc_wbufs(c); |
|---|
| .. | .. |
|---|
| 1346 | 1425 | goto out_lpt; |
|---|
| 1347 | 1426 | } |
|---|
| 1348 | 1427 | |
|---|
| 1428 | + /* |
|---|
| 1429 | + * Handle offline signed images: Now that the master node is |
|---|
| 1430 | + * written and its validation no longer depends on the hash |
|---|
| 1431 | + * in the superblock, we can update the offline signed |
|---|
| 1432 | + * superblock with a HMAC version, |
|---|
| 1433 | + */ |
|---|
| 1434 | + if (ubifs_authenticated(c) && ubifs_hmac_zero(c, c->sup_node->hmac)) { |
|---|
| 1435 | + err = ubifs_hmac_wkm(c, c->sup_node->hmac_wkm); |
|---|
| 1436 | + if (err) |
|---|
| 1437 | + goto out_lpt; |
|---|
| 1438 | + c->superblock_need_write = 1; |
|---|
| 1439 | + } |
|---|
| 1440 | + |
|---|
| 1441 | + if (!c->ro_mount && c->superblock_need_write) { |
|---|
| 1442 | + err = ubifs_write_sb_node(c, c->sup_node); |
|---|
| 1443 | + if (err) |
|---|
| 1444 | + goto out_lpt; |
|---|
| 1445 | + c->superblock_need_write = 0; |
|---|
| 1446 | + } |
|---|
| 1447 | + |
|---|
| 1349 | 1448 | err = dbg_check_idx_size(c, c->bi.old_idx_sz); |
|---|
| 1350 | 1449 | if (err) |
|---|
| 1351 | 1450 | goto out_lpt; |
|---|
| .. | .. |
|---|
| 1379 | 1478 | } |
|---|
| 1380 | 1479 | |
|---|
| 1381 | 1480 | if (c->need_recovery) { |
|---|
| 1382 | | - err = ubifs_recover_size(c); |
|---|
| 1383 | | - if (err) |
|---|
| 1384 | | - goto out_orphans; |
|---|
| 1481 | + if (!ubifs_authenticated(c)) { |
|---|
| 1482 | + err = ubifs_recover_size(c, true); |
|---|
| 1483 | + if (err) |
|---|
| 1484 | + goto out_orphans; |
|---|
| 1485 | + } |
|---|
| 1486 | + |
|---|
| 1385 | 1487 | err = ubifs_rcvry_gc_commit(c); |
|---|
| 1386 | 1488 | if (err) |
|---|
| 1387 | 1489 | goto out_orphans; |
|---|
| 1490 | + |
|---|
| 1491 | + if (ubifs_authenticated(c)) { |
|---|
| 1492 | + err = ubifs_recover_size(c, false); |
|---|
| 1493 | + if (err) |
|---|
| 1494 | + goto out_orphans; |
|---|
| 1495 | + } |
|---|
| 1388 | 1496 | } else { |
|---|
| 1389 | 1497 | err = take_gc_lnum(c); |
|---|
| 1390 | 1498 | if (err) |
|---|
| .. | .. |
|---|
| 1403 | 1511 | if (err) |
|---|
| 1404 | 1512 | goto out_orphans; |
|---|
| 1405 | 1513 | } else if (c->need_recovery) { |
|---|
| 1406 | | - err = ubifs_recover_size(c); |
|---|
| 1514 | + err = ubifs_recover_size(c, false); |
|---|
| 1407 | 1515 | if (err) |
|---|
| 1408 | 1516 | goto out_orphans; |
|---|
| 1409 | 1517 | } else { |
|---|
| .. | .. |
|---|
| 1442 | 1550 | if (err) |
|---|
| 1443 | 1551 | goto out_infos; |
|---|
| 1444 | 1552 | |
|---|
| 1445 | | - err = dbg_debugfs_init_fs(c); |
|---|
| 1446 | | - if (err) |
|---|
| 1447 | | - goto out_infos; |
|---|
| 1553 | + dbg_debugfs_init_fs(c); |
|---|
| 1448 | 1554 | |
|---|
| 1449 | 1555 | c->mounting = 0; |
|---|
| 1450 | 1556 | |
|---|
| .. | .. |
|---|
| 1511 | 1617 | c->bud_bytes, c->bud_bytes >> 10, c->bud_bytes >> 20); |
|---|
| 1512 | 1618 | dbg_gen("max. seq. number: %llu", c->max_sqnum); |
|---|
| 1513 | 1619 | dbg_gen("commit number: %llu", c->cmt_no); |
|---|
| 1620 | + dbg_gen("max. xattrs per inode: %d", ubifs_xattr_max_cnt(c)); |
|---|
| 1621 | + dbg_gen("max orphans: %d", c->max_orphans); |
|---|
| 1514 | 1622 | |
|---|
| 1515 | 1623 | return 0; |
|---|
| 1516 | 1624 | |
|---|
| .. | .. |
|---|
| 1533 | 1641 | free_wbufs(c); |
|---|
| 1534 | 1642 | out_cbuf: |
|---|
| 1535 | 1643 | kfree(c->cbuf); |
|---|
| 1644 | +out_auth: |
|---|
| 1645 | + ubifs_exit_authentication(c); |
|---|
| 1536 | 1646 | out_free: |
|---|
| 1537 | 1647 | kfree(c->write_reserve_buf); |
|---|
| 1538 | 1648 | kfree(c->bu.buf); |
|---|
| 1539 | 1649 | vfree(c->ileb_buf); |
|---|
| 1540 | 1650 | vfree(c->sbuf); |
|---|
| 1541 | 1651 | kfree(c->bottom_up_buf); |
|---|
| 1652 | + kfree(c->sup_node); |
|---|
| 1542 | 1653 | ubifs_debugging_exit(c); |
|---|
| 1543 | 1654 | return err; |
|---|
| 1544 | 1655 | } |
|---|
| .. | .. |
|---|
| 1569 | 1680 | free_wbufs(c); |
|---|
| 1570 | 1681 | free_orphans(c); |
|---|
| 1571 | 1682 | ubifs_lpt_free(c, 0); |
|---|
| 1683 | + ubifs_exit_authentication(c); |
|---|
| 1572 | 1684 | |
|---|
| 1685 | + ubifs_release_options(c); |
|---|
| 1573 | 1686 | kfree(c->cbuf); |
|---|
| 1574 | 1687 | kfree(c->rcvrd_mst_node); |
|---|
| 1575 | 1688 | kfree(c->mst_node); |
|---|
| .. | .. |
|---|
| 1578 | 1691 | vfree(c->ileb_buf); |
|---|
| 1579 | 1692 | vfree(c->sbuf); |
|---|
| 1580 | 1693 | kfree(c->bottom_up_buf); |
|---|
| 1694 | + kfree(c->sup_node); |
|---|
| 1581 | 1695 | ubifs_debugging_exit(c); |
|---|
| 1582 | 1696 | } |
|---|
| 1583 | 1697 | |
|---|
| .. | .. |
|---|
| 1616 | 1730 | if (err) |
|---|
| 1617 | 1731 | goto out; |
|---|
| 1618 | 1732 | |
|---|
| 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 | 1733 | if (c->need_recovery) { |
|---|
| 1635 | 1734 | ubifs_msg(c, "completing deferred recovery"); |
|---|
| 1636 | 1735 | err = ubifs_write_rcvrd_mst_node(c); |
|---|
| 1637 | 1736 | if (err) |
|---|
| 1638 | 1737 | goto out; |
|---|
| 1639 | | - err = ubifs_recover_size(c); |
|---|
| 1640 | | - if (err) |
|---|
| 1641 | | - goto out; |
|---|
| 1738 | + if (!ubifs_authenticated(c)) { |
|---|
| 1739 | + err = ubifs_recover_size(c, true); |
|---|
| 1740 | + if (err) |
|---|
| 1741 | + goto out; |
|---|
| 1742 | + } |
|---|
| 1642 | 1743 | err = ubifs_clean_lebs(c, c->sbuf); |
|---|
| 1643 | 1744 | if (err) |
|---|
| 1644 | 1745 | goto out; |
|---|
| .. | .. |
|---|
| 1658 | 1759 | err = ubifs_write_master(c); |
|---|
| 1659 | 1760 | if (err) |
|---|
| 1660 | 1761 | goto out; |
|---|
| 1762 | + } |
|---|
| 1763 | + |
|---|
| 1764 | + if (c->superblock_need_write) { |
|---|
| 1765 | + struct ubifs_sb_node *sup = c->sup_node; |
|---|
| 1766 | + |
|---|
| 1767 | + err = ubifs_write_sb_node(c, sup); |
|---|
| 1768 | + if (err) |
|---|
| 1769 | + goto out; |
|---|
| 1770 | + |
|---|
| 1771 | + c->superblock_need_write = 0; |
|---|
| 1661 | 1772 | } |
|---|
| 1662 | 1773 | |
|---|
| 1663 | 1774 | c->ileb_buf = vmalloc(c->leb_size); |
|---|
| .. | .. |
|---|
| 1704 | 1815 | goto out; |
|---|
| 1705 | 1816 | } |
|---|
| 1706 | 1817 | |
|---|
| 1707 | | - if (c->need_recovery) |
|---|
| 1818 | + if (c->need_recovery) { |
|---|
| 1708 | 1819 | err = ubifs_rcvry_gc_commit(c); |
|---|
| 1709 | | - else |
|---|
| 1820 | + if (err) |
|---|
| 1821 | + goto out; |
|---|
| 1822 | + |
|---|
| 1823 | + if (ubifs_authenticated(c)) { |
|---|
| 1824 | + err = ubifs_recover_size(c, false); |
|---|
| 1825 | + if (err) |
|---|
| 1826 | + goto out; |
|---|
| 1827 | + } |
|---|
| 1828 | + } else { |
|---|
| 1710 | 1829 | err = ubifs_leb_unmap(c, c->gc_lnum); |
|---|
| 1830 | + } |
|---|
| 1711 | 1831 | if (err) |
|---|
| 1712 | 1832 | goto out; |
|---|
| 1713 | 1833 | |
|---|
| .. | .. |
|---|
| 1931 | 2051 | |
|---|
| 1932 | 2052 | const struct super_operations ubifs_super_operations = { |
|---|
| 1933 | 2053 | .alloc_inode = ubifs_alloc_inode, |
|---|
| 1934 | | - .destroy_inode = ubifs_destroy_inode, |
|---|
| 2054 | + .free_inode = ubifs_free_inode, |
|---|
| 1935 | 2055 | .put_super = ubifs_put_super, |
|---|
| 1936 | 2056 | .write_inode = ubifs_write_inode, |
|---|
| 1937 | 2057 | .drop_inode = ubifs_drop_inode, |
|---|
| .. | .. |
|---|
| 2087 | 2207 | c->vi.vol_id); |
|---|
| 2088 | 2208 | if (err) |
|---|
| 2089 | 2209 | goto out_close; |
|---|
| 2210 | + sb->s_bdi->ra_pages = 0; |
|---|
| 2211 | + sb->s_bdi->io_pages = 0; |
|---|
| 2090 | 2212 | |
|---|
| 2091 | 2213 | sb->s_fs_info = c; |
|---|
| 2092 | 2214 | sb->s_magic = UBIFS_SUPER_MAGIC; |
|---|
| .. | .. |
|---|
| 2099 | 2221 | #ifdef CONFIG_UBIFS_FS_XATTR |
|---|
| 2100 | 2222 | sb->s_xattr = ubifs_xattr_handlers; |
|---|
| 2101 | 2223 | #endif |
|---|
| 2102 | | -#ifdef CONFIG_FS_ENCRYPTION |
|---|
| 2103 | | - sb->s_cop = &ubifs_crypt_operations; |
|---|
| 2104 | | -#endif |
|---|
| 2224 | + fscrypt_set_ops(sb, &ubifs_crypt_operations); |
|---|
| 2105 | 2225 | |
|---|
| 2106 | 2226 | mutex_lock(&c->umount_mutex); |
|---|
| 2107 | 2227 | err = mount_ubifs(c); |
|---|
| .. | .. |
|---|
| 2131 | 2251 | out_unlock: |
|---|
| 2132 | 2252 | mutex_unlock(&c->umount_mutex); |
|---|
| 2133 | 2253 | out_close: |
|---|
| 2254 | + ubifs_release_options(c); |
|---|
| 2134 | 2255 | ubi_close_volume(c->ubi); |
|---|
| 2135 | 2256 | out: |
|---|
| 2136 | 2257 | return err; |
|---|
| .. | .. |
|---|
| 2203 | 2324 | goto out_deact; |
|---|
| 2204 | 2325 | /* We do not support atime */ |
|---|
| 2205 | 2326 | 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 |
|---|
| 2327 | + if (IS_ENABLED(CONFIG_UBIFS_ATIME_SUPPORT)) |
|---|
| 2328 | + ubifs_msg(c, "full atime support is enabled."); |
|---|
| 2329 | + else |
|---|
| 2330 | + sb->s_flags |= SB_NOATIME; |
|---|
| 2211 | 2331 | } |
|---|
| 2212 | 2332 | |
|---|
| 2213 | 2333 | /* 'fill_super()' opens ubi again so we must close it here */ |
|---|
| .. | .. |
|---|
| 2322 | 2442 | if (err) |
|---|
| 2323 | 2443 | goto out_shrinker; |
|---|
| 2324 | 2444 | |
|---|
| 2325 | | - err = dbg_debugfs_init(); |
|---|
| 2326 | | - if (err) |
|---|
| 2327 | | - goto out_compr; |
|---|
| 2445 | + dbg_debugfs_init(); |
|---|
| 2328 | 2446 | |
|---|
| 2329 | 2447 | err = register_filesystem(&ubifs_fs_type); |
|---|
| 2330 | 2448 | if (err) { |
|---|
| .. | .. |
|---|
| 2336 | 2454 | |
|---|
| 2337 | 2455 | out_dbg: |
|---|
| 2338 | 2456 | dbg_debugfs_exit(); |
|---|
| 2339 | | -out_compr: |
|---|
| 2340 | 2457 | ubifs_compressors_exit(); |
|---|
| 2341 | 2458 | out_shrinker: |
|---|
| 2342 | 2459 | unregister_shrinker(&ubifs_shrinker_info); |
|---|
| .. | .. |
|---|
| 2367 | 2484 | module_exit(ubifs_exit); |
|---|
| 2368 | 2485 | |
|---|
| 2369 | 2486 | MODULE_LICENSE("GPL"); |
|---|
| 2487 | +MODULE_IMPORT_NS(ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 2370 | 2488 | MODULE_VERSION(__stringify(UBIFS_VERSION)); |
|---|
| 2371 | 2489 | MODULE_AUTHOR("Artem Bityutskiy, Adrian Hunter"); |
|---|
| 2372 | 2490 | MODULE_DESCRIPTION("UBIFS - UBI File System"); |
|---|