for-5.10-rc3-tag
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE8rQSAMVO+zA4DBdWxWXV+ddtWDsFAl+qtyAACgkQxWXV+ddt WDusYg/+P1SroRe2n33Pi6v9w47Luqjfi5qMfdrV/ex7g9bP/7dVPvAa0YJr7CpA UHpvcgWMFK2e29oOoeEoYXukHQ4BKtC6F5L0MPgVJocDT6xsAWM3v98VZn69Olcu TcUNkxUVbj7OBbQDaINV8dXnTbQWNOsfNlYXH+nPgWqrjSDbPoLkXIEVfZ9CTBeZ P/qEshkTXqvx1Pux/uRcKrMSu+lSFICKlLvky0b9gRpg4usVlF8jlGQrvJHQvqnP lECR1cb7/nf2PQ+HdPpgigD24bddiiORoyGW68Q1zZHgs+kGfL6p4M3WF04WINrV Taiv7WVZ6qHiEB+LDxlOx2cy0Z6YzFOaGSASz+Hh64hvOezBOVGvCF1U9U/Dp+MC n6QjUiw6c0rIjbdoxpTfQETCdIt/l3qXfOVEr9Zjr2KEbasLsZXdGSf3ydr81Uff 94CwrXp2wq429zu4mdCfOwihF/288+VrN8XRfkSy5RFQ5hHVnZBFQO4KbRIQ4i5X ZIjHQPX0jA/XN/jpUde/RJL5AyLz20n0o9I3frjXwSs+rvU3f0wD//fxmXlRUshM hsFXFKO0VdaFtoywVIf7VK/fDsKQhiq+9Yg48A8ylpk+W7meMjeDYuYMIEhMQX3m S1OMG1Qf27pWXD6KEzpaqzI4SrYBOGVDsX8qxMxRws7n55koVJc= =3FTR -----END PGP SIGNATURE----- Merge tag 'for-5.10-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux Pull btrfs fixes from David Sterba: "A handful of minor fixes and updates: - handle missing device replace item on mount (syzbot report) - fix space reservation calculation when finishing relocation - fix memory leak on error path in ref-verify (debugging feature) - fix potential overflow during defrag on 32bit arches - minor code update to silence smatch warning - minor error message updates" * tag 'for-5.10-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: ref-verify: fix memory leak in btrfs_ref_tree_mod btrfs: dev-replace: fail mount if we don't have replace item with target device btrfs: scrub: update message regarding read-only status btrfs: clean up NULL checks in qgroup_unreserve_range() btrfs: fix min reserved size calculation in merge_reloc_root btrfs: print the block rsv type when we fail our reservation btrfs: fix potential overflow in cluster_pages_for_defrag on 32bit arch
This commit is contained in:
commit
e2f0c565ec
@ -511,7 +511,8 @@ again:
|
|||||||
/*DEFAULT_RATELIMIT_BURST*/ 1);
|
/*DEFAULT_RATELIMIT_BURST*/ 1);
|
||||||
if (__ratelimit(&_rs))
|
if (__ratelimit(&_rs))
|
||||||
WARN(1, KERN_DEBUG
|
WARN(1, KERN_DEBUG
|
||||||
"BTRFS: block rsv returned %d\n", ret);
|
"BTRFS: block rsv %d returned %d\n",
|
||||||
|
block_rsv->type, ret);
|
||||||
}
|
}
|
||||||
try_reserve:
|
try_reserve:
|
||||||
ret = btrfs_reserve_metadata_bytes(root, block_rsv, blocksize,
|
ret = btrfs_reserve_metadata_bytes(root, block_rsv, blocksize,
|
||||||
|
@ -91,6 +91,17 @@ int btrfs_init_dev_replace(struct btrfs_fs_info *fs_info)
|
|||||||
ret = btrfs_search_slot(NULL, dev_root, &key, path, 0, 0);
|
ret = btrfs_search_slot(NULL, dev_root, &key, path, 0, 0);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
no_valid_dev_replace_entry_found:
|
no_valid_dev_replace_entry_found:
|
||||||
|
/*
|
||||||
|
* We don't have a replace item or it's corrupted. If there is
|
||||||
|
* a replace target, fail the mount.
|
||||||
|
*/
|
||||||
|
if (btrfs_find_device(fs_info->fs_devices,
|
||||||
|
BTRFS_DEV_REPLACE_DEVID, NULL, NULL, false)) {
|
||||||
|
btrfs_err(fs_info,
|
||||||
|
"found replace target device without a valid replace item");
|
||||||
|
ret = -EUCLEAN;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
dev_replace->replace_state =
|
dev_replace->replace_state =
|
||||||
BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED;
|
BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED;
|
||||||
@ -143,8 +154,19 @@ no_valid_dev_replace_entry_found:
|
|||||||
case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED:
|
case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED:
|
||||||
case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED:
|
case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED:
|
||||||
case BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED:
|
case BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED:
|
||||||
dev_replace->srcdev = NULL;
|
/*
|
||||||
dev_replace->tgtdev = NULL;
|
* We don't have an active replace item but if there is a
|
||||||
|
* replace target, fail the mount.
|
||||||
|
*/
|
||||||
|
if (btrfs_find_device(fs_info->fs_devices,
|
||||||
|
BTRFS_DEV_REPLACE_DEVID, NULL, NULL, false)) {
|
||||||
|
btrfs_err(fs_info,
|
||||||
|
"replace devid present without an active replace item");
|
||||||
|
ret = -EUCLEAN;
|
||||||
|
} else {
|
||||||
|
dev_replace->srcdev = NULL;
|
||||||
|
dev_replace->tgtdev = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED:
|
case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED:
|
||||||
case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED:
|
case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED:
|
||||||
|
@ -1274,6 +1274,7 @@ static int cluster_pages_for_defrag(struct inode *inode,
|
|||||||
u64 page_start;
|
u64 page_start;
|
||||||
u64 page_end;
|
u64 page_end;
|
||||||
u64 page_cnt;
|
u64 page_cnt;
|
||||||
|
u64 start = (u64)start_index << PAGE_SHIFT;
|
||||||
int ret;
|
int ret;
|
||||||
int i;
|
int i;
|
||||||
int i_done;
|
int i_done;
|
||||||
@ -1290,8 +1291,7 @@ static int cluster_pages_for_defrag(struct inode *inode,
|
|||||||
page_cnt = min_t(u64, (u64)num_pages, (u64)file_end - start_index + 1);
|
page_cnt = min_t(u64, (u64)num_pages, (u64)file_end - start_index + 1);
|
||||||
|
|
||||||
ret = btrfs_delalloc_reserve_space(BTRFS_I(inode), &data_reserved,
|
ret = btrfs_delalloc_reserve_space(BTRFS_I(inode), &data_reserved,
|
||||||
start_index << PAGE_SHIFT,
|
start, page_cnt << PAGE_SHIFT);
|
||||||
page_cnt << PAGE_SHIFT);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
i_done = 0;
|
i_done = 0;
|
||||||
@ -1380,8 +1380,7 @@ again:
|
|||||||
btrfs_mod_outstanding_extents(BTRFS_I(inode), 1);
|
btrfs_mod_outstanding_extents(BTRFS_I(inode), 1);
|
||||||
spin_unlock(&BTRFS_I(inode)->lock);
|
spin_unlock(&BTRFS_I(inode)->lock);
|
||||||
btrfs_delalloc_release_space(BTRFS_I(inode), data_reserved,
|
btrfs_delalloc_release_space(BTRFS_I(inode), data_reserved,
|
||||||
start_index << PAGE_SHIFT,
|
start, (page_cnt - i_done) << PAGE_SHIFT, true);
|
||||||
(page_cnt - i_done) << PAGE_SHIFT, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1408,8 +1407,7 @@ out:
|
|||||||
put_page(pages[i]);
|
put_page(pages[i]);
|
||||||
}
|
}
|
||||||
btrfs_delalloc_release_space(BTRFS_I(inode), data_reserved,
|
btrfs_delalloc_release_space(BTRFS_I(inode), data_reserved,
|
||||||
start_index << PAGE_SHIFT,
|
start, page_cnt << PAGE_SHIFT, true);
|
||||||
page_cnt << PAGE_SHIFT, true);
|
|
||||||
btrfs_delalloc_release_extents(BTRFS_I(inode), page_cnt << PAGE_SHIFT);
|
btrfs_delalloc_release_extents(BTRFS_I(inode), page_cnt << PAGE_SHIFT);
|
||||||
extent_changeset_free(data_reserved);
|
extent_changeset_free(data_reserved);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -3435,24 +3435,20 @@ static int qgroup_unreserve_range(struct btrfs_inode *inode,
|
|||||||
{
|
{
|
||||||
struct rb_node *node;
|
struct rb_node *node;
|
||||||
struct rb_node *next;
|
struct rb_node *next;
|
||||||
struct ulist_node *entry = NULL;
|
struct ulist_node *entry;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
node = reserved->range_changed.root.rb_node;
|
node = reserved->range_changed.root.rb_node;
|
||||||
|
if (!node)
|
||||||
|
return 0;
|
||||||
while (node) {
|
while (node) {
|
||||||
entry = rb_entry(node, struct ulist_node, rb_node);
|
entry = rb_entry(node, struct ulist_node, rb_node);
|
||||||
if (entry->val < start)
|
if (entry->val < start)
|
||||||
node = node->rb_right;
|
node = node->rb_right;
|
||||||
else if (entry)
|
|
||||||
node = node->rb_left;
|
|
||||||
else
|
else
|
||||||
break;
|
node = node->rb_left;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Empty changeset */
|
|
||||||
if (!entry)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (entry->val > start && rb_prev(&entry->rb_node))
|
if (entry->val > start && rb_prev(&entry->rb_node))
|
||||||
entry = rb_entry(rb_prev(&entry->rb_node), struct ulist_node,
|
entry = rb_entry(rb_prev(&entry->rb_node), struct ulist_node,
|
||||||
rb_node);
|
rb_node);
|
||||||
|
@ -860,6 +860,7 @@ int btrfs_ref_tree_mod(struct btrfs_fs_info *fs_info,
|
|||||||
"dropping a ref for a root that doesn't have a ref on the block");
|
"dropping a ref for a root that doesn't have a ref on the block");
|
||||||
dump_block_entry(fs_info, be);
|
dump_block_entry(fs_info, be);
|
||||||
dump_ref_action(fs_info, ra);
|
dump_ref_action(fs_info, ra);
|
||||||
|
kfree(ref);
|
||||||
kfree(ra);
|
kfree(ra);
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
@ -1648,6 +1648,7 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc,
|
|||||||
struct btrfs_root_item *root_item;
|
struct btrfs_root_item *root_item;
|
||||||
struct btrfs_path *path;
|
struct btrfs_path *path;
|
||||||
struct extent_buffer *leaf;
|
struct extent_buffer *leaf;
|
||||||
|
int reserve_level;
|
||||||
int level;
|
int level;
|
||||||
int max_level;
|
int max_level;
|
||||||
int replaced = 0;
|
int replaced = 0;
|
||||||
@ -1696,7 +1697,8 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc,
|
|||||||
* Thus the needed metadata size is at most root_level * nodesize,
|
* Thus the needed metadata size is at most root_level * nodesize,
|
||||||
* and * 2 since we have two trees to COW.
|
* and * 2 since we have two trees to COW.
|
||||||
*/
|
*/
|
||||||
min_reserved = fs_info->nodesize * btrfs_root_level(root_item) * 2;
|
reserve_level = max_t(int, 1, btrfs_root_level(root_item));
|
||||||
|
min_reserved = fs_info->nodesize * reserve_level * 2;
|
||||||
memset(&next_key, 0, sizeof(next_key));
|
memset(&next_key, 0, sizeof(next_key));
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -3866,8 +3866,9 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start,
|
|||||||
if (!is_dev_replace && !readonly &&
|
if (!is_dev_replace && !readonly &&
|
||||||
!test_bit(BTRFS_DEV_STATE_WRITEABLE, &dev->dev_state)) {
|
!test_bit(BTRFS_DEV_STATE_WRITEABLE, &dev->dev_state)) {
|
||||||
mutex_unlock(&fs_info->fs_devices->device_list_mutex);
|
mutex_unlock(&fs_info->fs_devices->device_list_mutex);
|
||||||
btrfs_err_in_rcu(fs_info, "scrub: device %s is not writable",
|
btrfs_err_in_rcu(fs_info,
|
||||||
rcu_str_deref(dev->name));
|
"scrub on devid %llu: filesystem on %s is not writable",
|
||||||
|
devid, rcu_str_deref(dev->name));
|
||||||
ret = -EROFS;
|
ret = -EROFS;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -1056,22 +1056,13 @@ static void __btrfs_free_extra_devids(struct btrfs_fs_devices *fs_devices,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device->devid == BTRFS_DEV_REPLACE_DEVID) {
|
/*
|
||||||
/*
|
* We have already validated the presence of BTRFS_DEV_REPLACE_DEVID,
|
||||||
* In the first step, keep the device which has
|
* in btrfs_init_dev_replace() so just continue.
|
||||||
* the correct fsid and the devid that is used
|
*/
|
||||||
* for the dev_replace procedure.
|
if (device->devid == BTRFS_DEV_REPLACE_DEVID)
|
||||||
* In the second step, the dev_replace state is
|
continue;
|
||||||
* read from the device tree and it is known
|
|
||||||
* whether the procedure is really active or
|
|
||||||
* not, which means whether this device is
|
|
||||||
* used or whether it should be removed.
|
|
||||||
*/
|
|
||||||
if (step == 0 || test_bit(BTRFS_DEV_STATE_REPLACE_TGT,
|
|
||||||
&device->dev_state)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (device->bdev) {
|
if (device->bdev) {
|
||||||
blkdev_put(device->bdev, device->mode);
|
blkdev_put(device->bdev, device->mode);
|
||||||
device->bdev = NULL;
|
device->bdev = NULL;
|
||||||
@ -1080,9 +1071,6 @@ static void __btrfs_free_extra_devids(struct btrfs_fs_devices *fs_devices,
|
|||||||
if (test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state)) {
|
if (test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state)) {
|
||||||
list_del_init(&device->dev_alloc_list);
|
list_del_init(&device->dev_alloc_list);
|
||||||
clear_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state);
|
clear_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state);
|
||||||
if (!test_bit(BTRFS_DEV_STATE_REPLACE_TGT,
|
|
||||||
&device->dev_state))
|
|
||||||
fs_devices->rw_devices--;
|
|
||||||
}
|
}
|
||||||
list_del_init(&device->dev_list);
|
list_del_init(&device->dev_list);
|
||||||
fs_devices->num_devices--;
|
fs_devices->num_devices--;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user