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