Commit 73082fbd authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull btrfs fixes from David Sterba:

 - space reservation fixes:
     - correctly undo 'may_use' accounting for remap tree
     - avoid double decrement of 'may_use' when submitting async io

 - actually enable the shutdown ioctl callback (not just the superblock
   ops)

 - raid stripe tree fixes when deleting extents
     - add missing error handling
     - fix various incorrect values set

 - fix transaction state when removing a directory, possibly leading to
   EIO during log replay

 - additional b-tree node key checks during metadata readahead

 - error handling and transaction abort updates

* tag 'for-7.1-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: fix double-decrement of bytes_may_use in submit_one_async_extent()
  btrfs: check return value of btrfs_partially_delete_raid_extent()
  btrfs: handle -EAGAIN from btrfs_duplicate_item and refresh stale leaf pointer
  btrfs: replace ASSERT with proper error handling in stripe lookup fallback
  btrfs: fix wrong min_objectid in btrfs_previous_item() call
  btrfs: fix raid stripe search missing entries at leaf boundaries
  btrfs: copy devid in btrfs_partially_delete_raid_extent()
  btrfs: handle unexpected free-space-tree key types
  btrfs: fix missing last_unlink_trans update when removing a directory
  btrfs: don't clobber errors in add_remap_tree_entries()
  btrfs: enable shutdown ioctl for non-experimental builds
  btrfs: apply first key check for readahead when possible
  btrfs: abort transaction in do_remap_reloc_trans() on failure
  btrfs: fix bytes_may_use leak in do_remap_reloc_trans()
  btrfs: fix bytes_may_use leak in move_existing_remap()
parents d762a96e 82323b1a
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -4641,7 +4641,8 @@ int try_release_extent_buffer(struct folio *folio)
 * to read the block we will not block on anything.
 */
void btrfs_readahead_tree_block(struct btrfs_fs_info *fs_info,
				u64 bytenr, u64 owner_root, u64 gen, int level)
				u64 bytenr, u64 owner_root, u64 gen, int level,
				const struct btrfs_key *first_key)
{
	struct btrfs_tree_parent_check check = {
		.level = level,
@@ -4650,6 +4651,11 @@ void btrfs_readahead_tree_block(struct btrfs_fs_info *fs_info,
	struct extent_buffer *eb;
	int ret;

	if (first_key) {
		memcpy(&check.first_key, first_key, sizeof(struct btrfs_key));
		check.has_first_key = true;
	}

	eb = btrfs_find_create_tree_block(fs_info, bytenr, owner_root, level);
	if (IS_ERR(eb))
		return;
@@ -4677,9 +4683,13 @@ void btrfs_readahead_tree_block(struct btrfs_fs_info *fs_info,
 */
void btrfs_readahead_node_child(struct extent_buffer *node, int slot)
{
	struct btrfs_key node_key;

	btrfs_node_key_to_cpu(node, &node_key, slot);
	btrfs_readahead_tree_block(node->fs_info,
				   btrfs_node_blockptr(node, slot),
				   btrfs_header_owner(node),
				   btrfs_node_ptr_generation(node, slot),
				   btrfs_header_level(node) - 1);
				   btrfs_header_level(node) - 1,
				   &node_key);
}
+2 −1
Original line number Diff line number Diff line
@@ -287,7 +287,8 @@ static inline void wait_on_extent_buffer_writeback(struct extent_buffer *eb)
}

void btrfs_readahead_tree_block(struct btrfs_fs_info *fs_info,
				u64 bytenr, u64 owner_root, u64 gen, int level);
				u64 bytenr, u64 owner_root, u64 gen, int level,
				const struct btrfs_key *first_key);
void btrfs_readahead_node_child(struct extent_buffer *node, int slot);

/* Note: this can be used in for loops without caching the value in a variable. */
+15 −3
Original line number Diff line number Diff line
@@ -259,7 +259,11 @@ int btrfs_convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans,
				nr++;
				path->slots[0]--;
			} else {
				ASSERT(0);
				btrfs_err(fs_info, "unexpected free space tree key type %u",
					  found_key.type);
				ret = -EUCLEAN;
				btrfs_abort_transaction(trans, ret);
				goto out;
			}
		}

@@ -405,7 +409,11 @@ int btrfs_convert_free_space_to_extents(struct btrfs_trans_handle *trans,

				nr++;
			} else {
				ASSERT(0);
				btrfs_err(fs_info, "unexpected free space tree key type %u",
					  found_key.type);
				ret = -EUCLEAN;
				btrfs_abort_transaction(trans, ret);
				goto out;
			}
		}

@@ -1518,7 +1526,11 @@ int btrfs_remove_block_group_free_space(struct btrfs_trans_handle *trans,
				nr++;
				path->slots[0]--;
			} else {
				ASSERT(0);
				btrfs_err(trans->fs_info, "unexpected free space tree key type %u",
					  found_key.type);
				ret = -EUCLEAN;
				btrfs_abort_transaction(trans, ret);
				return ret;
			}
		}

+3 −1
Original line number Diff line number Diff line
@@ -1153,7 +1153,7 @@ static void submit_one_async_extent(struct async_chunk *async_chunk,
				     NULL, &cached,
				     EXTENT_LOCKED | EXTENT_DELALLOC |
				     EXTENT_DELALLOC_NEW |
				     EXTENT_DEFRAG | EXTENT_DO_ACCOUNTING,
				     EXTENT_DEFRAG | EXTENT_CLEAR_META_RESV,
				     PAGE_UNLOCK | PAGE_START_WRITEBACK |
				     PAGE_END_WRITEBACK);
	if (async_extent->cb)
@@ -4959,6 +4959,8 @@ static int btrfs_rmdir(struct inode *vfs_dir, struct dentry *dentry)
	if (ret)
		goto out;

	btrfs_record_unlink_dir(trans, dir, inode, false);

	/* now the directory is empty */
	ret = btrfs_unlink_inode(trans, dir, inode, &fname.disk_name);
	if (!ret)
+3 −4
Original line number Diff line number Diff line
@@ -5102,7 +5102,6 @@ static int btrfs_ioctl_subvol_sync(struct btrfs_fs_info *fs_info, void __user *a
	return 0;
}

#ifdef CONFIG_BTRFS_EXPERIMENTAL
static int btrfs_ioctl_shutdown(struct btrfs_fs_info *fs_info, unsigned long arg)
{
	int ret = 0;
@@ -5134,10 +5133,12 @@ static int btrfs_ioctl_shutdown(struct btrfs_fs_info *fs_info, unsigned long arg
	case BTRFS_SHUTDOWN_FLAGS_NOLOGFLUSH:
		btrfs_force_shutdown(fs_info);
		break;
	default:
		ret = -EINVAL;
		break;
	}
	return ret;
}
#endif

long btrfs_ioctl(struct file *file, unsigned int
		cmd, unsigned long arg)
@@ -5294,10 +5295,8 @@ long btrfs_ioctl(struct file *file, unsigned int
#endif
	case BTRFS_IOC_SUBVOL_SYNC_WAIT:
		return btrfs_ioctl_subvol_sync(fs_info, argp);
#ifdef CONFIG_BTRFS_EXPERIMENTAL
	case BTRFS_IOC_SHUTDOWN:
		return btrfs_ioctl_shutdown(fs_info, arg);
#endif
	}

	return -ENOTTY;
Loading