for-5.13-rc1-tag
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE8rQSAMVO+zA4DBdWxWXV+ddtWDsFAmCZnCIACgkQxWXV+ddt WDuEvhAAmC+Mkrz25GbQnSIp2FKYCCQK34D0rdghml0Bc0cJcDh3yhgIB6ZTHZ7e Z+UZu84ISK31OHKDzXtX0MINN2wuU4u4kd6PHtYj0wSVl3cX6E/K5j6YcThfI1Ru vCW5O87V9SCV5NnykIFt3sbYvsPKtF9lhgPQprj4np+wxaSyNlEF2c+zLTI3J7NV +8OlM4oi8GocZd1aAwGpVM3qUPyQSHEb9oUEp6aV1ERuAs6LIyeGks3Cag6gjPnq dYz3jV9HyZB5GtX0dmv4LeRFIog1uFi+SIEFl5RpqhB3sXN3n6XHMka4x20FXiWy PfX9+Nf4bQGx6F9rGsgHNHQP5dVhHAkZcq3E0n0yshIfNe8wDHBRlmk0wbfj4K7I VYv85SxEYpigG8KzF5gjiar4EqsaJVQcJioMxVE7z9vrW6xlOWD1lf/ViUZnB3wd IQEyGz2qOe9eqJD+dnyN7QkN9WKGSUr2p1Q/DngCIwFzKWf1qIlETNXrIL+AZ97r v4G5mMq9dCxs3s8c5SGbdF9qqK8gEuaV3iWQAoKOciuy6fbc553Q90I1v3OhW+by j2yVoo3nJbBJBuLBNWPDUlwxQF/EHPQ6nh3fvxNRgwksXgRmqywdJb5dQ8hcKgSH RsvinJhtKo5rTgtgGgmNvmLAjKIieW1lIVG4ha0O/m49HeaohDE= =GNNs -----END PGP SIGNATURE----- Merge tag 'for-5.13-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux Pull btrfs fixes from David Sterba: "First batch of various fixes, here's a list of notable ones: - fix unmountable seed device after fstrim - fix silent data loss in zoned mode due to ordered extent splitting - fix race leading to unpersisted data and metadata on fsync - fix deadlock when cloning inline extents and using qgroups" * tag 'for-5.13-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: initialize return variable in cleanup_free_space_cache_v1 btrfs: zoned: sanity check zone type btrfs: fix unmountable seed device after fstrim btrfs: fix deadlock when cloning inline extents and using qgroups btrfs: fix race leading to unpersisted data and metadata on fsync btrfs: do not consider send context as valid when trying to flush qgroups btrfs: zoned: fix silent data loss after failure splitting ordered extent
This commit is contained in:
commit
142b507f91
@ -3127,7 +3127,7 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_inode *inode, u64 new_size,
|
||||
u32 min_type);
|
||||
|
||||
int btrfs_start_delalloc_snapshot(struct btrfs_root *root);
|
||||
int btrfs_start_delalloc_snapshot(struct btrfs_root *root, bool in_reclaim_context);
|
||||
int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, long nr,
|
||||
bool in_reclaim_context);
|
||||
int btrfs_set_extent_delalloc(struct btrfs_inode *inode, u64 start, u64 end,
|
||||
|
@ -1340,12 +1340,16 @@ int btrfs_discard_extent(struct btrfs_fs_info *fs_info, u64 bytenr,
|
||||
stripe = bbio->stripes;
|
||||
for (i = 0; i < bbio->num_stripes; i++, stripe++) {
|
||||
u64 bytes;
|
||||
struct btrfs_device *device = stripe->dev;
|
||||
|
||||
if (!stripe->dev->bdev) {
|
||||
if (!device->bdev) {
|
||||
ASSERT(btrfs_test_opt(fs_info, DEGRADED));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state))
|
||||
continue;
|
||||
|
||||
ret = do_discard_extent(stripe, &bytes);
|
||||
if (!ret) {
|
||||
discarded_bytes += bytes;
|
||||
|
@ -2067,6 +2067,30 @@ static int start_ordered_ops(struct inode *inode, loff_t start, loff_t end)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline bool skip_inode_logging(const struct btrfs_log_ctx *ctx)
|
||||
{
|
||||
struct btrfs_inode *inode = BTRFS_I(ctx->inode);
|
||||
struct btrfs_fs_info *fs_info = inode->root->fs_info;
|
||||
|
||||
if (btrfs_inode_in_log(inode, fs_info->generation) &&
|
||||
list_empty(&ctx->ordered_extents))
|
||||
return true;
|
||||
|
||||
/*
|
||||
* If we are doing a fast fsync we can not bail out if the inode's
|
||||
* last_trans is <= then the last committed transaction, because we only
|
||||
* update the last_trans of the inode during ordered extent completion,
|
||||
* and for a fast fsync we don't wait for that, we only wait for the
|
||||
* writeback to complete.
|
||||
*/
|
||||
if (inode->last_trans <= fs_info->last_trans_committed &&
|
||||
(test_bit(BTRFS_INODE_NEEDS_FULL_SYNC, &inode->runtime_flags) ||
|
||||
list_empty(&ctx->ordered_extents)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* fsync call for both files and directories. This logs the inode into
|
||||
* the tree log instead of forcing full commits whenever possible.
|
||||
@ -2185,17 +2209,8 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
|
||||
|
||||
atomic_inc(&root->log_batch);
|
||||
|
||||
/*
|
||||
* If we are doing a fast fsync we can not bail out if the inode's
|
||||
* last_trans is <= then the last committed transaction, because we only
|
||||
* update the last_trans of the inode during ordered extent completion,
|
||||
* and for a fast fsync we don't wait for that, we only wait for the
|
||||
* writeback to complete.
|
||||
*/
|
||||
smp_mb();
|
||||
if (btrfs_inode_in_log(BTRFS_I(inode), fs_info->generation) ||
|
||||
(BTRFS_I(inode)->last_trans <= fs_info->last_trans_committed &&
|
||||
(full_sync || list_empty(&ctx.ordered_extents)))) {
|
||||
if (skip_inode_logging(&ctx)) {
|
||||
/*
|
||||
* We've had everything committed since the last time we were
|
||||
* modified so clear this flag in case it was set for whatever
|
||||
|
@ -3949,7 +3949,7 @@ static int cleanup_free_space_cache_v1(struct btrfs_fs_info *fs_info,
|
||||
{
|
||||
struct btrfs_block_group *block_group;
|
||||
struct rb_node *node;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
btrfs_info(fs_info, "cleaning free space cache v1");
|
||||
|
||||
|
@ -9678,7 +9678,7 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int btrfs_start_delalloc_snapshot(struct btrfs_root *root)
|
||||
int btrfs_start_delalloc_snapshot(struct btrfs_root *root, bool in_reclaim_context)
|
||||
{
|
||||
struct writeback_control wbc = {
|
||||
.nr_to_write = LONG_MAX,
|
||||
@ -9691,7 +9691,7 @@ int btrfs_start_delalloc_snapshot(struct btrfs_root *root)
|
||||
if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state))
|
||||
return -EROFS;
|
||||
|
||||
return start_delalloc_inodes(root, &wbc, true, false);
|
||||
return start_delalloc_inodes(root, &wbc, true, in_reclaim_context);
|
||||
}
|
||||
|
||||
int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, long nr,
|
||||
|
@ -907,7 +907,7 @@ static noinline int btrfs_mksnapshot(const struct path *parent,
|
||||
*/
|
||||
btrfs_drew_read_lock(&root->snapshot_lock);
|
||||
|
||||
ret = btrfs_start_delalloc_snapshot(root);
|
||||
ret = btrfs_start_delalloc_snapshot(root, false);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
|
@ -984,7 +984,7 @@ int btrfs_split_ordered_extent(struct btrfs_ordered_extent *ordered, u64 pre,
|
||||
|
||||
if (pre)
|
||||
ret = clone_ordered_extent(ordered, 0, pre);
|
||||
if (post)
|
||||
if (ret == 0 && post)
|
||||
ret = clone_ordered_extent(ordered, pre + ordered->disk_num_bytes,
|
||||
post);
|
||||
|
||||
|
@ -3545,11 +3545,15 @@ static int try_flush_qgroup(struct btrfs_root *root)
|
||||
struct btrfs_trans_handle *trans;
|
||||
int ret;
|
||||
|
||||
/* Can't hold an open transaction or we run the risk of deadlocking */
|
||||
ASSERT(current->journal_info == NULL ||
|
||||
current->journal_info == BTRFS_SEND_TRANS_STUB);
|
||||
if (WARN_ON(current->journal_info &&
|
||||
current->journal_info != BTRFS_SEND_TRANS_STUB))
|
||||
/*
|
||||
* Can't hold an open transaction or we run the risk of deadlocking,
|
||||
* and can't either be under the context of a send operation (where
|
||||
* current->journal_info is set to BTRFS_SEND_TRANS_STUB), as that
|
||||
* would result in a crash when starting a transaction and does not
|
||||
* make sense either (send is a read-only operation).
|
||||
*/
|
||||
ASSERT(current->journal_info == NULL);
|
||||
if (WARN_ON(current->journal_info))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
@ -3562,7 +3566,7 @@ static int try_flush_qgroup(struct btrfs_root *root)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = btrfs_start_delalloc_snapshot(root);
|
||||
ret = btrfs_start_delalloc_snapshot(root, true);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
btrfs_wait_ordered_extents(root, U64_MAX, 0, (u64)-1);
|
||||
|
@ -7170,7 +7170,7 @@ static int flush_delalloc_roots(struct send_ctx *sctx)
|
||||
int i;
|
||||
|
||||
if (root) {
|
||||
ret = btrfs_start_delalloc_snapshot(root);
|
||||
ret = btrfs_start_delalloc_snapshot(root, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
btrfs_wait_ordered_extents(root, U64_MAX, 0, U64_MAX);
|
||||
@ -7178,7 +7178,7 @@ static int flush_delalloc_roots(struct send_ctx *sctx)
|
||||
|
||||
for (i = 0; i < sctx->clone_roots_cnt; i++) {
|
||||
root = sctx->clone_roots[i].root;
|
||||
ret = btrfs_start_delalloc_snapshot(root);
|
||||
ret = btrfs_start_delalloc_snapshot(root, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
btrfs_wait_ordered_extents(root, U64_MAX, 0, U64_MAX);
|
||||
|
@ -6061,7 +6061,8 @@ static int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
|
||||
* (since logging them is pointless, a link count of 0 means they
|
||||
* will never be accessible).
|
||||
*/
|
||||
if (btrfs_inode_in_log(inode, trans->transid) ||
|
||||
if ((btrfs_inode_in_log(inode, trans->transid) &&
|
||||
list_empty(&ctx->ordered_extents)) ||
|
||||
inode->vfs_inode.i_nlink == 0) {
|
||||
ret = BTRFS_NO_LOG_SYNC;
|
||||
goto end_no_trans;
|
||||
|
@ -1126,6 +1126,11 @@ int btrfs_load_block_group_zone_info(struct btrfs_block_group *cache, bool new)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (zone.type == BLK_ZONE_TYPE_CONVENTIONAL) {
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (zone.cond) {
|
||||
case BLK_ZONE_COND_OFFLINE:
|
||||
case BLK_ZONE_COND_READONLY:
|
||||
|
Loading…
Reference in New Issue
Block a user