diff options
Diffstat (limited to 'fs/btrfs/inode.c')
| -rw-r--r-- | fs/btrfs/inode.c | 389 | 
1 files changed, 190 insertions, 199 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index fc66872b4c74..b77dd22b8cdb 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -308,7 +308,7 @@ static void __cold btrfs_print_data_csum_error(struct btrfs_inode *inode,  	const u32 csum_size = root->fs_info->csum_size;  	/* For data reloc tree, it's better to do a backref lookup instead. */ -	if (btrfs_root_id(root) == BTRFS_DATA_RELOC_TREE_OBJECTID) +	if (btrfs_is_data_reloc_root(root))  		return print_data_reloc_error(inode, logical_start, csum,  					      csum_expected, mirror_num); @@ -395,8 +395,8 @@ void btrfs_inode_unlock(struct btrfs_inode *inode, unsigned int ilock_flags)  static inline void btrfs_cleanup_ordered_extents(struct btrfs_inode *inode,  						 u64 offset, u64 bytes)  { -	unsigned long index = offset >> PAGE_SHIFT; -	unsigned long end_index = (offset + bytes - 1) >> PAGE_SHIFT; +	pgoff_t index = offset >> PAGE_SHIFT; +	const pgoff_t end_index = (offset + bytes - 1) >> PAGE_SHIFT;  	struct folio *folio;  	while (index <= end_index) { @@ -423,18 +423,18 @@ static int btrfs_dirty_inode(struct btrfs_inode *inode);  static int btrfs_init_inode_security(struct btrfs_trans_handle *trans,  				     struct btrfs_new_inode_args *args)  { -	int err; +	int ret;  	if (args->default_acl) { -		err = __btrfs_set_acl(trans, args->inode, args->default_acl, +		ret = __btrfs_set_acl(trans, args->inode, args->default_acl,  				      ACL_TYPE_DEFAULT); -		if (err) -			return err; +		if (ret) +			return ret;  	}  	if (args->acl) { -		err = __btrfs_set_acl(trans, args->inode, args->acl, ACL_TYPE_ACCESS); -		if (err) -			return err; +		ret = __btrfs_set_acl(trans, args->inode, args->acl, ACL_TYPE_ACCESS); +		if (ret) +			return ret;  	}  	if (!args->default_acl && !args->acl)  		cache_no_acl(args->inode); @@ -781,12 +781,15 @@ static inline int inode_need_compress(struct btrfs_inode *inode, u64 start,  		return 0;  	} +	/* Defrag ioctl takes precedence over mount options and properties. */ +	if (inode->defrag_compress == BTRFS_DEFRAG_DONT_COMPRESS) +		return 0; +	if (BTRFS_COMPRESS_NONE < inode->defrag_compress && +	    inode->defrag_compress < BTRFS_NR_COMPRESS_TYPES) +		return 1;  	/* force compress */  	if (btrfs_test_opt(fs_info, FORCE_COMPRESS))  		return 1; -	/* defrag ioctl */ -	if (inode->defrag_compress) -		return 1;  	/* bad compression ratios */  	if (inode->flags & BTRFS_INODE_NOCOMPRESS)  		return 0; @@ -808,12 +811,11 @@ static inline void inode_should_defrag(struct btrfs_inode *inode,  static int extent_range_clear_dirty_for_io(struct btrfs_inode *inode, u64 start, u64 end)  { -	unsigned long end_index = end >> PAGE_SHIFT; +	const pgoff_t end_index = end >> PAGE_SHIFT;  	struct folio *folio;  	int ret = 0; -	for (unsigned long index = start >> PAGE_SHIFT; -	     index <= end_index; index++) { +	for (pgoff_t index = start >> PAGE_SHIFT; index <= end_index; index++) {  		folio = filemap_get_folio(inode->vfs_inode.i_mapping, index);  		if (IS_ERR(folio)) {  			if (!ret) @@ -943,7 +945,7 @@ again:  		goto cleanup_and_bail_uncompressed;  	} -	if (inode->defrag_compress) { +	if (0 < inode->defrag_compress && inode->defrag_compress < BTRFS_NR_COMPRESS_TYPES) {  		compress_type = inode->defrag_compress;  		compress_level = inode->defrag_compress_level;  	} else if (inode->prop_compress) { @@ -1755,7 +1757,8 @@ static int fallback_to_cow(struct btrfs_inode *inode,  		spin_unlock(&sinfo->lock);  		if (count > 0) -			btrfs_clear_extent_bits(io_tree, start, end, EXTENT_NORESERVE); +			btrfs_clear_extent_bit(io_tree, start, end, EXTENT_NORESERVE, +					       &cached_state);  	}  	btrfs_unlock_extent(io_tree, start, end, &cached_state); @@ -2328,8 +2331,7 @@ int btrfs_run_delalloc_range(struct btrfs_inode *inode, struct folio *locked_fol  	 * The range must cover part of the @locked_folio, or a return of 1  	 * can confuse the caller.  	 */ -	ASSERT(!(end <= folio_pos(locked_folio) || -		 start >= folio_pos(locked_folio) + folio_size(locked_folio))); +	ASSERT(!(end <= folio_pos(locked_folio) || start >= folio_end(locked_folio)));  	if (should_nocow(inode, start, end)) {  		ret = run_delalloc_nocow(inode, locked_folio, start, end); @@ -2737,7 +2739,7 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work)  	struct btrfs_inode *inode = fixup->inode;  	struct btrfs_fs_info *fs_info = inode->root->fs_info;  	u64 page_start = folio_pos(folio); -	u64 page_end = folio_pos(folio) + folio_size(folio) - 1; +	u64 page_end = folio_end(folio) - 1;  	int ret = 0;  	bool free_delalloc_space = true; @@ -2881,7 +2883,7 @@ int btrfs_writepage_cow_fixup(struct folio *folio)  		DEBUG_WARN();  		btrfs_err_rl(fs_info,  	"root %lld ino %llu folio %llu is marked dirty without notifying the fs", -			     BTRFS_I(inode)->root->root_key.objectid, +			     btrfs_root_id(BTRFS_I(inode)->root),  			     btrfs_ino(BTRFS_I(inode)),  			     folio_pos(folio));  		return -EUCLEAN; @@ -3375,8 +3377,8 @@ bool btrfs_data_csum_ok(struct btrfs_bio *bbio, struct btrfs_device *dev,  	    btrfs_test_range_bit(&inode->io_tree, file_offset, end, EXTENT_NODATASUM,  				 NULL)) {  		/* Skip the range without csum for data reloc inode */ -		btrfs_clear_extent_bits(&inode->io_tree, file_offset, end, -					EXTENT_NODATASUM); +		btrfs_clear_extent_bit(&inode->io_tree, file_offset, end, +				       EXTENT_NODATASUM, NULL);  		return true;  	} @@ -3946,6 +3948,7 @@ static int btrfs_read_locked_inode(struct btrfs_inode *inode, struct btrfs_path  	btrfs_inode_split_flags(btrfs_inode_flags(leaf, inode_item),  				&inode->flags, &inode->ro_flags);  	btrfs_update_inode_mapping_flags(inode); +	btrfs_set_inode_mapping_order(inode);  cache_index:  	/* @@ -4078,45 +4081,35 @@ static void fill_inode_item(struct btrfs_trans_handle *trans,  			    struct btrfs_inode_item *item,  			    struct inode *inode)  { -	struct btrfs_map_token token;  	u64 flags; -	btrfs_init_map_token(&token, leaf); - -	btrfs_set_token_inode_uid(&token, item, i_uid_read(inode)); -	btrfs_set_token_inode_gid(&token, item, i_gid_read(inode)); -	btrfs_set_token_inode_size(&token, item, BTRFS_I(inode)->disk_i_size); -	btrfs_set_token_inode_mode(&token, item, inode->i_mode); -	btrfs_set_token_inode_nlink(&token, item, inode->i_nlink); - -	btrfs_set_token_timespec_sec(&token, &item->atime, -				     inode_get_atime_sec(inode)); -	btrfs_set_token_timespec_nsec(&token, &item->atime, -				      inode_get_atime_nsec(inode)); - -	btrfs_set_token_timespec_sec(&token, &item->mtime, -				     inode_get_mtime_sec(inode)); -	btrfs_set_token_timespec_nsec(&token, &item->mtime, -				      inode_get_mtime_nsec(inode)); - -	btrfs_set_token_timespec_sec(&token, &item->ctime, -				     inode_get_ctime_sec(inode)); -	btrfs_set_token_timespec_nsec(&token, &item->ctime, -				      inode_get_ctime_nsec(inode)); - -	btrfs_set_token_timespec_sec(&token, &item->otime, BTRFS_I(inode)->i_otime_sec); -	btrfs_set_token_timespec_nsec(&token, &item->otime, BTRFS_I(inode)->i_otime_nsec); - -	btrfs_set_token_inode_nbytes(&token, item, inode_get_bytes(inode)); -	btrfs_set_token_inode_generation(&token, item, -					 BTRFS_I(inode)->generation); -	btrfs_set_token_inode_sequence(&token, item, inode_peek_iversion(inode)); -	btrfs_set_token_inode_transid(&token, item, trans->transid); -	btrfs_set_token_inode_rdev(&token, item, inode->i_rdev); +	btrfs_set_inode_uid(leaf, item, i_uid_read(inode)); +	btrfs_set_inode_gid(leaf, item, i_gid_read(inode)); +	btrfs_set_inode_size(leaf, item, BTRFS_I(inode)->disk_i_size); +	btrfs_set_inode_mode(leaf, item, inode->i_mode); +	btrfs_set_inode_nlink(leaf, item, inode->i_nlink); + +	btrfs_set_timespec_sec(leaf, &item->atime, inode_get_atime_sec(inode)); +	btrfs_set_timespec_nsec(leaf, &item->atime, inode_get_atime_nsec(inode)); + +	btrfs_set_timespec_sec(leaf, &item->mtime, inode_get_mtime_sec(inode)); +	btrfs_set_timespec_nsec(leaf, &item->mtime, inode_get_mtime_nsec(inode)); + +	btrfs_set_timespec_sec(leaf, &item->ctime, inode_get_ctime_sec(inode)); +	btrfs_set_timespec_nsec(leaf, &item->ctime, inode_get_ctime_nsec(inode)); + +	btrfs_set_timespec_sec(leaf, &item->otime, BTRFS_I(inode)->i_otime_sec); +	btrfs_set_timespec_nsec(leaf, &item->otime, BTRFS_I(inode)->i_otime_nsec); + +	btrfs_set_inode_nbytes(leaf, item, inode_get_bytes(inode)); +	btrfs_set_inode_generation(leaf, item, BTRFS_I(inode)->generation); +	btrfs_set_inode_sequence(leaf, item, inode_peek_iversion(inode)); +	btrfs_set_inode_transid(leaf, item, trans->transid); +	btrfs_set_inode_rdev(leaf, item, inode->i_rdev);  	flags = btrfs_inode_combine_flags(BTRFS_I(inode)->flags,  					  BTRFS_I(inode)->ro_flags); -	btrfs_set_token_inode_flags(&token, item, flags); -	btrfs_set_token_inode_block_group(&token, item, 0); +	btrfs_set_inode_flags(leaf, item, flags); +	btrfs_set_inode_block_group(leaf, item, 0);  }  /* @@ -4215,20 +4208,22 @@ static int __btrfs_unlink_inode(struct btrfs_trans_handle *trans,  	u64 dir_ino = btrfs_ino(dir);  	path = btrfs_alloc_path(); -	if (!path) { -		ret = -ENOMEM; -		goto out; -	} +	if (!path) +		return -ENOMEM;  	di = btrfs_lookup_dir_item(trans, root, path, dir_ino, name, -1);  	if (IS_ERR_OR_NULL(di)) { -		ret = di ? PTR_ERR(di) : -ENOENT; -		goto err; +		btrfs_free_path(path); +		return di ? PTR_ERR(di) : -ENOENT;  	}  	ret = btrfs_delete_one_dir_name(trans, root, path, di); +	/* +	 * Down the call chains below we'll also need to allocate a path, so no +	 * need to hold on to this one for longer than necessary. +	 */ +	btrfs_free_path(path);  	if (ret) -		goto err; -	btrfs_release_path(path); +		return ret;  	/*  	 * If we don't have dir index, we have to get it by looking up @@ -4254,7 +4249,7 @@ static int __btrfs_unlink_inode(struct btrfs_trans_handle *trans,  	   "failed to delete reference to %.*s, root %llu inode %llu parent %llu",  			   name->len, name->name, btrfs_root_id(root), ino, dir_ino);  		btrfs_abort_transaction(trans, ret); -		goto err; +		return ret;  	}  skip_backref:  	if (rename_ctx) @@ -4263,7 +4258,7 @@ skip_backref:  	ret = btrfs_delete_delayed_dir_index(trans, dir, index);  	if (ret) {  		btrfs_abort_transaction(trans, ret); -		goto err; +		return ret;  	}  	/* @@ -4287,19 +4282,14 @@ skip_backref:  	 * holding.  	 */  	btrfs_run_delayed_iput(fs_info, inode); -err: -	btrfs_free_path(path); -	if (ret) -		goto out;  	btrfs_i_size_write(dir, dir->vfs_inode.i_size - name->len * 2);  	inode_inc_iversion(&inode->vfs_inode);  	inode_set_ctime_current(&inode->vfs_inode);  	inode_inc_iversion(&dir->vfs_inode);   	inode_set_mtime_to_ts(&dir->vfs_inode, inode_set_ctime_current(&dir->vfs_inode)); -	ret = btrfs_update_inode(trans, dir); -out: -	return ret; + +	return btrfs_update_inode(trans, dir);  }  int btrfs_unlink_inode(struct btrfs_trans_handle *trans, @@ -4704,32 +4694,33 @@ out_up_write:  	return ret;  } -static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) +static int btrfs_rmdir(struct inode *vfs_dir, struct dentry *dentry)  { -	struct inode *inode = d_inode(dentry); -	struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info; +	struct btrfs_inode *dir = BTRFS_I(vfs_dir); +	struct btrfs_inode *inode = BTRFS_I(d_inode(dentry)); +	struct btrfs_fs_info *fs_info = inode->root->fs_info;  	int ret = 0;  	struct btrfs_trans_handle *trans;  	struct fscrypt_name fname; -	if (inode->i_size > BTRFS_EMPTY_DIR_SIZE) +	if (inode->vfs_inode.i_size > BTRFS_EMPTY_DIR_SIZE)  		return -ENOTEMPTY; -	if (btrfs_ino(BTRFS_I(inode)) == BTRFS_FIRST_FREE_OBJECTID) { +	if (btrfs_ino(inode) == BTRFS_FIRST_FREE_OBJECTID) {  		if (unlikely(btrfs_fs_incompat(fs_info, EXTENT_TREE_V2))) {  			btrfs_err(fs_info,  			"extent tree v2 doesn't support snapshot deletion yet");  			return -EOPNOTSUPP;  		} -		return btrfs_delete_subvolume(BTRFS_I(dir), dentry); +		return btrfs_delete_subvolume(dir, dentry);  	} -	ret = fscrypt_setup_filename(dir, &dentry->d_name, 1, &fname); +	ret = fscrypt_setup_filename(vfs_dir, &dentry->d_name, 1, &fname);  	if (ret)  		return ret;  	/* This needs to handle no-key deletions later on */ -	trans = __unlink_start_trans(BTRFS_I(dir)); +	trans = __unlink_start_trans(dir);  	if (IS_ERR(trans)) {  		ret = PTR_ERR(trans);  		goto out_notrans; @@ -4749,23 +4740,22 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)  	 * This is because we can't unlink other roots when replaying the dir  	 * deletes for directory foo.  	 */ -	if (BTRFS_I(inode)->last_unlink_trans >= trans->transid) -		btrfs_record_snapshot_destroy(trans, BTRFS_I(dir)); +	if (inode->last_unlink_trans >= trans->transid) +		btrfs_record_snapshot_destroy(trans, dir); -	if (unlikely(btrfs_ino(BTRFS_I(inode)) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) { -		ret = btrfs_unlink_subvol(trans, BTRFS_I(dir), dentry); +	if (unlikely(btrfs_ino(inode) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) { +		ret = btrfs_unlink_subvol(trans, dir, dentry);  		goto out;  	} -	ret = btrfs_orphan_add(trans, BTRFS_I(inode)); +	ret = btrfs_orphan_add(trans, inode);  	if (ret)  		goto out;  	/* now the directory is empty */ -	ret = btrfs_unlink_inode(trans, BTRFS_I(dir), BTRFS_I(d_inode(dentry)), -				 &fname.disk_name); +	ret = btrfs_unlink_inode(trans, dir, inode, &fname.disk_name);  	if (!ret) -		btrfs_i_size_write(BTRFS_I(inode), 0); +		btrfs_i_size_write(inode, 0);  out:  	btrfs_end_transaction(trans);  out_notrans: @@ -4821,9 +4811,9 @@ again:  	 */  	zero_start = max_t(u64, folio_pos(folio), start); -	zero_end = folio_pos(folio) + folio_size(folio) - 1; +	zero_end = folio_end(folio);  	folio_zero_range(folio, zero_start - folio_pos(folio), -			 zero_end - zero_start + 1); +			 zero_end - zero_start);  out_unlock:  	folio_unlock(folio); @@ -4861,7 +4851,6 @@ int btrfs_truncate_block(struct btrfs_inode *inode, u64 offset, u64 start, u64 e  	pgoff_t index = (offset >> PAGE_SHIFT);  	struct folio *folio;  	gfp_t mask = btrfs_alloc_write_mask(mapping); -	size_t write_bytes = blocksize;  	int ret = 0;  	const bool in_head_block = is_inside_block(offset, round_down(start, blocksize),  						   blocksize); @@ -4913,8 +4902,12 @@ int btrfs_truncate_block(struct btrfs_inode *inode, u64 offset, u64 start, u64 e  	ret = btrfs_check_data_free_space(inode, &data_reserved, block_start,  					  blocksize, false);  	if (ret < 0) { +		size_t write_bytes = blocksize; +  		if (btrfs_check_nocow_lock(inode, block_start, &write_bytes, false) > 0) { -			/* For nocow case, no need to reserve data space */ +			/* For nocow case, no need to reserve data space. */ +			ASSERT(write_bytes == blocksize, "write_bytes=%zu blocksize=%u", +			       write_bytes, blocksize);  			only_release_metadata = true;  		} else {  			goto out; @@ -5001,8 +4994,7 @@ again:  		 * not reach disk, it still affects our page caches.  		 */  		zero_start = max_t(u64, folio_pos(folio), start); -		zero_end = min_t(u64, folio_pos(folio) + folio_size(folio) - 1, -				 end); +		zero_end = min_t(u64, folio_end(folio) - 1, end);  	} else {  		zero_start = max_t(u64, block_start, start);  		zero_end = min_t(u64, block_end, end); @@ -5014,11 +5006,12 @@ again:  				  block_end + 1 - block_start);  	btrfs_folio_set_dirty(fs_info, folio, block_start,  			      block_end + 1 - block_start); -	btrfs_unlock_extent(io_tree, block_start, block_end, &cached_state);  	if (only_release_metadata)  		btrfs_set_extent_bit(&inode->io_tree, block_start, block_end, -				     EXTENT_NORESERVE, NULL); +				     EXTENT_NORESERVE, &cached_state); + +	btrfs_unlock_extent(io_tree, block_start, block_end, &cached_state);  out_unlock:  	if (ret) { @@ -5256,7 +5249,7 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr)  		ret = btrfs_truncate(BTRFS_I(inode), newsize == oldsize);  		if (ret && inode->i_nlink) { -			int err; +			int ret2;  			/*  			 * Truncate failed, so fix up the in-memory size. We @@ -5264,9 +5257,9 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr)  			 * wait for disk_i_size to be stable and then update the  			 * in-memory size to match.  			 */ -			err = btrfs_wait_ordered_range(BTRFS_I(inode), 0, (u64)-1); -			if (err) -				return err; +			ret2 = btrfs_wait_ordered_range(BTRFS_I(inode), 0, (u64)-1); +			if (ret2) +				return ret2;  			i_size_write(inode, BTRFS_I(inode)->disk_i_size);  		}  	} @@ -5279,31 +5272,31 @@ static int btrfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,  {  	struct inode *inode = d_inode(dentry);  	struct btrfs_root *root = BTRFS_I(inode)->root; -	int err; +	int ret;  	if (btrfs_root_readonly(root))  		return -EROFS; -	err = setattr_prepare(idmap, dentry, attr); -	if (err) -		return err; +	ret = setattr_prepare(idmap, dentry, attr); +	if (ret) +		return ret;  	if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) { -		err = btrfs_setsize(inode, attr); -		if (err) -			return err; +		ret = btrfs_setsize(inode, attr); +		if (ret) +			return ret;  	}  	if (attr->ia_valid) {  		setattr_copy(idmap, inode, attr);  		inode_inc_iversion(inode); -		err = btrfs_dirty_inode(BTRFS_I(inode)); +		ret = btrfs_dirty_inode(BTRFS_I(inode)); -		if (!err && attr->ia_valid & ATTR_MODE) -			err = posix_acl_chmod(idmap, dentry, inode->i_mode); +		if (!ret && attr->ia_valid & ATTR_MODE) +			ret = posix_acl_chmod(idmap, dentry, inode->i_mode);  	} -	return err; +	return ret;  }  /* @@ -5437,7 +5430,7 @@ void btrfs_evict_inode(struct inode *inode)  	struct btrfs_fs_info *fs_info;  	struct btrfs_trans_handle *trans;  	struct btrfs_root *root = BTRFS_I(inode)->root; -	struct btrfs_block_rsv *rsv = NULL; +	struct btrfs_block_rsv rsv;  	int ret;  	trace_btrfs_inode_evict(inode); @@ -5485,11 +5478,9 @@ void btrfs_evict_inode(struct inode *inode)  	 */  	btrfs_kill_delayed_inode_items(BTRFS_I(inode)); -	rsv = btrfs_alloc_block_rsv(fs_info, BTRFS_BLOCK_RSV_TEMP); -	if (!rsv) -		goto out; -	rsv->size = btrfs_calc_metadata_size(fs_info, 1); -	rsv->failfast = true; +	btrfs_init_metadata_block_rsv(fs_info, &rsv, BTRFS_BLOCK_RSV_TEMP); +	rsv.size = btrfs_calc_metadata_size(fs_info, 1); +	rsv.failfast = true;  	btrfs_i_size_write(BTRFS_I(inode), 0); @@ -5501,11 +5492,11 @@ void btrfs_evict_inode(struct inode *inode)  			.min_type = 0,  		}; -		trans = evict_refill_and_join(root, rsv); +		trans = evict_refill_and_join(root, &rsv);  		if (IS_ERR(trans)) -			goto out; +			goto out_release; -		trans->block_rsv = rsv; +		trans->block_rsv = &rsv;  		ret = btrfs_truncate_inode_items(trans, root, &control);  		trans->block_rsv = &fs_info->trans_block_rsv; @@ -5517,7 +5508,7 @@ void btrfs_evict_inode(struct inode *inode)  		 */  		btrfs_btree_balance_dirty_nodelay(fs_info);  		if (ret && ret != -ENOSPC && ret != -EAGAIN) -			goto out; +			goto out_release;  		else if (!ret)  			break;  	} @@ -5531,16 +5522,17 @@ void btrfs_evict_inode(struct inode *inode)  	 * If it turns out that we are dropping too many of these, we might want  	 * to add a mechanism for retrying these after a commit.  	 */ -	trans = evict_refill_and_join(root, rsv); +	trans = evict_refill_and_join(root, &rsv);  	if (!IS_ERR(trans)) { -		trans->block_rsv = rsv; +		trans->block_rsv = &rsv;  		btrfs_orphan_del(trans, BTRFS_I(inode));  		trans->block_rsv = &fs_info->trans_block_rsv;  		btrfs_end_transaction(trans);  	} +out_release: +	btrfs_block_rsv_release(fs_info, &rsv, (u64)-1, NULL);  out: -	btrfs_free_block_rsv(fs_info, rsv);  	/*  	 * If we didn't successfully delete, the orphan item will still be in  	 * the tree and we'll retry on the next mount. Again, we might also want @@ -6173,8 +6165,7 @@ again:  	if (ret)  		goto nopos; -	ret = btrfs_readdir_delayed_dir_index(ctx, &ins_list); -	if (ret) +	if (btrfs_readdir_delayed_dir_index(ctx, &ins_list))  		goto nopos;  	/* @@ -6467,6 +6458,7 @@ int btrfs_create_new_inode(struct btrfs_trans_handle *trans,  			BTRFS_I(inode)->flags |= BTRFS_INODE_NODATACOW |  				BTRFS_INODE_NODATASUM;  		btrfs_update_inode_mapping_flags(BTRFS_I(inode)); +		btrfs_set_inode_mapping_order(BTRFS_I(inode));  	}  	ret = btrfs_insert_inode_locked(inode); @@ -6610,13 +6602,17 @@ int btrfs_create_new_inode(struct btrfs_trans_handle *trans,  	if (args->orphan) {  		ret = btrfs_orphan_add(trans, BTRFS_I(inode)); +		if (ret) { +			btrfs_abort_transaction(trans, ret); +			goto discard; +		}  	} else {  		ret = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode), name,  				     0, BTRFS_I(inode)->dir_index); -	} -	if (ret) { -		btrfs_abort_transaction(trans, ret); -		goto discard; +		if (ret) { +			btrfs_abort_transaction(trans, ret); +			goto discard; +		}  	}  	return 0; @@ -6703,20 +6699,18 @@ int btrfs_add_link(struct btrfs_trans_handle *trans,  fail_dir_item:  	if (unlikely(ino == BTRFS_FIRST_FREE_OBJECTID)) {  		u64 local_index; -		int err; -		err = btrfs_del_root_ref(trans, key.objectid, -					 btrfs_root_id(root), parent_ino, -					 &local_index, name); -		if (err) -			btrfs_abort_transaction(trans, err); +		int ret2; + +		ret2 = btrfs_del_root_ref(trans, key.objectid, btrfs_root_id(root), +					  parent_ino, &local_index, name); +		if (ret2) +			btrfs_abort_transaction(trans, ret2);  	} else if (add_backref) { -		u64 local_index; -		int err; +		int ret2; -		err = btrfs_del_inode_ref(trans, root, name, ino, parent_ino, -					  &local_index); -		if (err) -			btrfs_abort_transaction(trans, err); +		ret2 = btrfs_del_inode_ref(trans, root, name, ino, parent_ino, NULL); +		if (ret2) +			btrfs_abort_transaction(trans, ret2);  	}  	/* Return the original error code */ @@ -6735,20 +6729,20 @@ static int btrfs_create_common(struct inode *dir, struct dentry *dentry,  	};  	unsigned int trans_num_items;  	struct btrfs_trans_handle *trans; -	int err; +	int ret; -	err = btrfs_new_inode_prepare(&new_inode_args, &trans_num_items); -	if (err) +	ret = btrfs_new_inode_prepare(&new_inode_args, &trans_num_items); +	if (ret)  		goto out_inode;  	trans = btrfs_start_transaction(root, trans_num_items);  	if (IS_ERR(trans)) { -		err = PTR_ERR(trans); +		ret = PTR_ERR(trans);  		goto out_new_inode_args;  	} -	err = btrfs_create_new_inode(trans, &new_inode_args); -	if (!err) +	ret = btrfs_create_new_inode(trans, &new_inode_args); +	if (!ret)  		d_instantiate_new(dentry, inode);  	btrfs_end_transaction(trans); @@ -6756,9 +6750,9 @@ static int btrfs_create_common(struct inode *dir, struct dentry *dentry,  out_new_inode_args:  	btrfs_new_inode_args_destroy(&new_inode_args);  out_inode: -	if (err) +	if (ret)  		iput(inode); -	return err; +	return ret;  }  static int btrfs_mknod(struct mnt_idmap *idmap, struct inode *dir, @@ -6799,7 +6793,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,  	struct btrfs_fs_info *fs_info = inode_to_fs_info(inode);  	struct fscrypt_name fname;  	u64 index; -	int err; +	int ret;  	int drop_inode = 0;  	/* do not allow sys_link's with other subvols of the same device */ @@ -6809,12 +6803,12 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,  	if (inode->i_nlink >= BTRFS_LINK_MAX)  		return -EMLINK; -	err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &fname); -	if (err) +	ret = fscrypt_setup_filename(dir, &dentry->d_name, 0, &fname); +	if (ret)  		goto fail; -	err = btrfs_set_inode_index(BTRFS_I(dir), &index); -	if (err) +	ret = btrfs_set_inode_index(BTRFS_I(dir), &index); +	if (ret)  		goto fail;  	/* @@ -6825,7 +6819,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,  	 */  	trans = btrfs_start_transaction(root, inode->i_nlink ? 5 : 6);  	if (IS_ERR(trans)) { -		err = PTR_ERR(trans); +		ret = PTR_ERR(trans);  		trans = NULL;  		goto fail;  	} @@ -6838,24 +6832,24 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,  	ihold(inode);  	set_bit(BTRFS_INODE_COPY_EVERYTHING, &BTRFS_I(inode)->runtime_flags); -	err = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode), +	ret = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode),  			     &fname.disk_name, 1, index); -	if (err) { +	if (ret) {  		drop_inode = 1;  	} else {  		struct dentry *parent = dentry->d_parent; -		err = btrfs_update_inode(trans, BTRFS_I(inode)); -		if (err) +		ret = btrfs_update_inode(trans, BTRFS_I(inode)); +		if (ret)  			goto fail;  		if (inode->i_nlink == 1) {  			/*  			 * If new hard link count is 1, it's a file created  			 * with open(2) O_TMPFILE flag.  			 */ -			err = btrfs_orphan_del(trans, BTRFS_I(inode)); -			if (err) +			ret = btrfs_orphan_del(trans, BTRFS_I(inode)); +			if (ret)  				goto fail;  		}  		d_instantiate(dentry, inode); @@ -6871,7 +6865,7 @@ fail:  		iput(inode);  	}  	btrfs_btree_balance_dirty(fs_info); -	return err; +	return ret;  }  static struct dentry *btrfs_mkdir(struct mnt_idmap *idmap, struct inode *dir, @@ -7364,13 +7358,13 @@ struct extent_map *btrfs_create_io_em(struct btrfs_inode *inode, u64 start,  static void wait_subpage_spinlock(struct folio *folio)  {  	struct btrfs_fs_info *fs_info = folio_to_fs_info(folio); -	struct btrfs_subpage *subpage; +	struct btrfs_folio_state *bfs;  	if (!btrfs_is_subpage(fs_info, folio))  		return;  	ASSERT(folio_test_private(folio) && folio_get_private(folio)); -	subpage = folio_get_private(folio); +	bfs = folio_get_private(folio);  	/*  	 * This may look insane as we just acquire the spinlock and release it, @@ -7383,8 +7377,8 @@ static void wait_subpage_spinlock(struct folio *folio)  	 * Here we just acquire the spinlock so that all existing callers  	 * should exit and we're safe to release/invalidate the page.  	 */ -	spin_lock_irq(&subpage->lock); -	spin_unlock_irq(&subpage->lock); +	spin_lock_irq(&bfs->lock); +	spin_unlock_irq(&bfs->lock);  }  static int btrfs_launder_folio(struct folio *folio) @@ -7607,7 +7601,7 @@ static int btrfs_truncate(struct btrfs_inode *inode, bool skip_writeback)  	};  	struct btrfs_root *root = inode->root;  	struct btrfs_fs_info *fs_info = root->fs_info; -	struct btrfs_block_rsv *rsv; +	struct btrfs_block_rsv rsv;  	int ret;  	struct btrfs_trans_handle *trans;  	u64 mask = fs_info->sectorsize - 1; @@ -7649,11 +7643,9 @@ static int btrfs_truncate(struct btrfs_inode *inode, bool skip_writeback)  	 * 2) fs_info->trans_block_rsv - this will have 1 items worth left for  	 * updating the inode.  	 */ -	rsv = btrfs_alloc_block_rsv(fs_info, BTRFS_BLOCK_RSV_TEMP); -	if (!rsv) -		return -ENOMEM; -	rsv->size = min_size; -	rsv->failfast = true; +	btrfs_init_metadata_block_rsv(fs_info, &rsv, BTRFS_BLOCK_RSV_TEMP); +	rsv.size = min_size; +	rsv.failfast = true;  	/*  	 * 1 for the truncate slack space @@ -7666,7 +7658,7 @@ static int btrfs_truncate(struct btrfs_inode *inode, bool skip_writeback)  	}  	/* Migrate the slack space for the truncate to our reserve */ -	ret = btrfs_block_rsv_migrate(&fs_info->trans_block_rsv, rsv, +	ret = btrfs_block_rsv_migrate(&fs_info->trans_block_rsv, &rsv,  				      min_size, false);  	/*  	 * We have reserved 2 metadata units when we started the transaction and @@ -7678,7 +7670,7 @@ static int btrfs_truncate(struct btrfs_inode *inode, bool skip_writeback)  		goto out;  	} -	trans->block_rsv = rsv; +	trans->block_rsv = &rsv;  	while (1) {  		struct extent_state *cached_state = NULL; @@ -7721,9 +7713,9 @@ static int btrfs_truncate(struct btrfs_inode *inode, bool skip_writeback)  			break;  		} -		btrfs_block_rsv_release(fs_info, rsv, -1, NULL); +		btrfs_block_rsv_release(fs_info, &rsv, -1, NULL);  		ret = btrfs_block_rsv_migrate(&fs_info->trans_block_rsv, -					      rsv, min_size, false); +					      &rsv, min_size, false);  		/*  		 * We have reserved 2 metadata units when we started the  		 * transaction and min_size matches 1 unit, so this should never @@ -7732,7 +7724,7 @@ static int btrfs_truncate(struct btrfs_inode *inode, bool skip_writeback)  		if (WARN_ON(ret))  			break; -		trans->block_rsv = rsv; +		trans->block_rsv = &rsv;  	}  	/* @@ -7771,7 +7763,7 @@ static int btrfs_truncate(struct btrfs_inode *inode, bool skip_writeback)  		btrfs_btree_balance_dirty(fs_info);  	}  out: -	btrfs_free_block_rsv(fs_info, rsv); +	btrfs_block_rsv_release(fs_info, &rsv, (u64)-1, NULL);  	/*  	 * So if we truncate and then write and fsync we normally would just  	 * write the extents that changed, which is a problem if we need to @@ -8026,7 +8018,7 @@ static int btrfs_getattr(struct mnt_idmap *idmap,  	generic_fillattr(idmap, request_mask, inode, stat);  	stat->dev = BTRFS_I(inode)->root->anon_dev; -	stat->subvol = BTRFS_I(inode)->root->root_key.objectid; +	stat->subvol = btrfs_root_id(BTRFS_I(inode)->root);  	stat->result_mask |= STATX_SUBVOL;  	spin_lock(&BTRFS_I(inode)->lock); @@ -8823,7 +8815,7 @@ static int btrfs_symlink(struct mnt_idmap *idmap, struct inode *dir,  		.dentry = dentry,  	};  	unsigned int trans_num_items; -	int err; +	int ret;  	int name_len;  	int datasize;  	unsigned long ptr; @@ -8850,26 +8842,26 @@ static int btrfs_symlink(struct mnt_idmap *idmap, struct inode *dir,  	inode_set_bytes(inode, name_len);  	new_inode_args.inode = inode; -	err = btrfs_new_inode_prepare(&new_inode_args, &trans_num_items); -	if (err) +	ret = btrfs_new_inode_prepare(&new_inode_args, &trans_num_items); +	if (ret)  		goto out_inode;  	/* 1 additional item for the inline extent */  	trans_num_items++;  	trans = btrfs_start_transaction(root, trans_num_items);  	if (IS_ERR(trans)) { -		err = PTR_ERR(trans); +		ret = PTR_ERR(trans);  		goto out_new_inode_args;  	} -	err = btrfs_create_new_inode(trans, &new_inode_args); -	if (err) +	ret = btrfs_create_new_inode(trans, &new_inode_args); +	if (ret)  		goto out;  	path = btrfs_alloc_path();  	if (!path) { -		err = -ENOMEM; -		btrfs_abort_transaction(trans, err); +		ret = -ENOMEM; +		btrfs_abort_transaction(trans, ret);  		discard_new_inode(inode);  		inode = NULL;  		goto out; @@ -8878,10 +8870,9 @@ static int btrfs_symlink(struct mnt_idmap *idmap, struct inode *dir,  	key.type = BTRFS_EXTENT_DATA_KEY;  	key.offset = 0;  	datasize = btrfs_file_extent_calc_inline_size(name_len); -	err = btrfs_insert_empty_item(trans, root, path, &key, -				      datasize); -	if (err) { -		btrfs_abort_transaction(trans, err); +	ret = btrfs_insert_empty_item(trans, root, path, &key, datasize); +	if (ret) { +		btrfs_abort_transaction(trans, ret);  		btrfs_free_path(path);  		discard_new_inode(inode);  		inode = NULL; @@ -8903,16 +8894,16 @@ static int btrfs_symlink(struct mnt_idmap *idmap, struct inode *dir,  	btrfs_free_path(path);  	d_instantiate_new(dentry, inode); -	err = 0; +	ret = 0;  out:  	btrfs_end_transaction(trans);  	btrfs_btree_balance_dirty(fs_info);  out_new_inode_args:  	btrfs_new_inode_args_destroy(&new_inode_args);  out_inode: -	if (err) +	if (ret)  		iput(inode); -	return err; +	return ret;  }  static struct btrfs_trans_handle *insert_prealloc_file_extent(  | 
