forked from Minki/linux
for-5.9-tag
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE8rQSAMVO+zA4DBdWxWXV+ddtWDsFAl81Q0wACgkQxWXV+ddt WDtbqw/+NeFlvQzsCeQV9PX7RjYf9MFEQIThxo33xDl+ersgcOD8MuPa/hY1hoO0 gOn2eRPcVe/RIPBezRbxX9bnqlfW6N0VnBNLJHypMapB2hR6WFcFt7CAMoXKRmHV RDM37pA2TNULr8XYrJ0+J5Vy1NWp5HdKzEV6bXfsOSzMSdAVMheXNec93suLEB/g 9QGXX6kaaq0Hcpy7tQQBtm2lbVj8/M3LOUAmYOB/JNCPtsJEB/2EO2b63TB4s2cW 0lpiPehW2m/Pv5GjqQM+iN5fbt9yhKB6lqEEgoHZPgI2tLFyh5WlTWKET7uxqj7G YBzZjiq1WREEl9KWLYZuthcXPLX2XgJ4gLSlckygi1e4MpPlJ4pa30Bj9OyIEIjP FOeR0lelRYcjmZrQW4Kana0qq8K0JJzvo2dSqaJBGF9CaveN3BAGQ9ttNhgIIpS5 4kBKlv2SCJ9Anhn8la6bFwlfuR2ggMhDShxIGBQpA1OKf0oJyi2dtavSIbuXwFbd 6KA37cyp4cDK9ycmTN5YxZSndzZSqUEh5Wt4gLk32NeIxhyCX4aTvjQj5KqM1MNw N/WrTJQ27D6jfi+PBRBmT7U6qEujySXUimJRFTJzk+Px8Q/QMzGAFPCqz6iXv3u3 lX1Ywha9iQ0g2IZVoaq1ZjDDp4xOqIakAjaXez3dFhu3Mq3Kc70= =7b8U -----END PGP SIGNATURE----- Merge tag 'for-5.9-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux Pull more btrfs updates from David Sterba: "One minor update, the rest are fixes that have arrived a bit late for the first batch. There are also some recent fixes for bugs that were discovered during the merge window and pop up during testing. User visible change: - show correct subvolume path in /proc/mounts for bind mounts Fixes: - fix compression messages when remounting with different level or compression algorithm - tree-log: fix some memory leaks on error handling paths - restore I_VERSION on remount - fix return values and error code mixups - fix umount crash with quotas enabled when removing sysfs files - fix trim range on a shrunk device" * tag 'for-5.9-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: trim: fix underflow in trim length to prevent access beyond device boundary btrfs: fix return value mixup in btrfs_get_extent btrfs: sysfs: fix NULL pointer dereference at btrfs_sysfs_del_qgroups() btrfs: check correct variable after allocation in btrfs_backref_iter_alloc btrfs: make sure SB_I_VERSION doesn't get unset by remount btrfs: fix memory leaks after failure to lookup checksums during inode logging btrfs: don't show full path of bind mounts in subvol= btrfs: fix messages after changing compression level by remount btrfs: only search for left_info if there is no right_info in try_merge_free_space btrfs: inode: fix NULL pointer dereference if inode doesn't need compression
This commit is contained in:
commit
23c2c8c6fa
|
@ -2303,7 +2303,7 @@ struct btrfs_backref_iter *btrfs_backref_iter_alloc(
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ret->path = btrfs_alloc_path();
|
ret->path = btrfs_alloc_path();
|
||||||
if (!ret) {
|
if (!ret->path) {
|
||||||
kfree(ret);
|
kfree(ret);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,8 @@ struct io_failure_record;
|
||||||
*/
|
*/
|
||||||
#define CHUNK_ALLOCATED EXTENT_DIRTY
|
#define CHUNK_ALLOCATED EXTENT_DIRTY
|
||||||
#define CHUNK_TRIMMED EXTENT_DEFRAG
|
#define CHUNK_TRIMMED EXTENT_DEFRAG
|
||||||
|
#define CHUNK_STATE_MASK (CHUNK_ALLOCATED | \
|
||||||
|
CHUNK_TRIMMED)
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
IO_TREE_FS_PINNED_EXTENTS,
|
IO_TREE_FS_PINNED_EXTENTS,
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "delalloc-space.h"
|
#include "delalloc-space.h"
|
||||||
#include "block-group.h"
|
#include "block-group.h"
|
||||||
#include "discard.h"
|
#include "discard.h"
|
||||||
|
#include "rcu-string.h"
|
||||||
|
|
||||||
#undef SCRAMBLE_DELAYED_REFS
|
#undef SCRAMBLE_DELAYED_REFS
|
||||||
|
|
||||||
|
@ -5668,6 +5669,19 @@ static int btrfs_trim_free_extents(struct btrfs_device *device, u64 *trimmed)
|
||||||
&start, &end,
|
&start, &end,
|
||||||
CHUNK_TRIMMED | CHUNK_ALLOCATED);
|
CHUNK_TRIMMED | CHUNK_ALLOCATED);
|
||||||
|
|
||||||
|
/* Check if there are any CHUNK_* bits left */
|
||||||
|
if (start > device->total_bytes) {
|
||||||
|
WARN_ON(IS_ENABLED(CONFIG_BTRFS_DEBUG));
|
||||||
|
btrfs_warn_in_rcu(fs_info,
|
||||||
|
"ignoring attempt to trim beyond device size: offset %llu length %llu device %s device size %llu",
|
||||||
|
start, end - start + 1,
|
||||||
|
rcu_str_deref(device->name),
|
||||||
|
device->total_bytes);
|
||||||
|
mutex_unlock(&fs_info->chunk_mutex);
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Ensure we skip the reserved area in the first 1M */
|
/* Ensure we skip the reserved area in the first 1M */
|
||||||
start = max_t(u64, start, SZ_1M);
|
start = max_t(u64, start, SZ_1M);
|
||||||
|
|
||||||
|
|
|
@ -2282,7 +2282,7 @@ out:
|
||||||
static bool try_merge_free_space(struct btrfs_free_space_ctl *ctl,
|
static bool try_merge_free_space(struct btrfs_free_space_ctl *ctl,
|
||||||
struct btrfs_free_space *info, bool update_stat)
|
struct btrfs_free_space *info, bool update_stat)
|
||||||
{
|
{
|
||||||
struct btrfs_free_space *left_info;
|
struct btrfs_free_space *left_info = NULL;
|
||||||
struct btrfs_free_space *right_info;
|
struct btrfs_free_space *right_info;
|
||||||
bool merged = false;
|
bool merged = false;
|
||||||
u64 offset = info->offset;
|
u64 offset = info->offset;
|
||||||
|
@ -2298,7 +2298,7 @@ static bool try_merge_free_space(struct btrfs_free_space_ctl *ctl,
|
||||||
if (right_info && rb_prev(&right_info->offset_index))
|
if (right_info && rb_prev(&right_info->offset_index))
|
||||||
left_info = rb_entry(rb_prev(&right_info->offset_index),
|
left_info = rb_entry(rb_prev(&right_info->offset_index),
|
||||||
struct btrfs_free_space, offset_index);
|
struct btrfs_free_space, offset_index);
|
||||||
else
|
else if (!right_info)
|
||||||
left_info = tree_search_offset(ctl, offset - 1, 0, 0);
|
left_info = tree_search_offset(ctl, offset - 1, 0, 0);
|
||||||
|
|
||||||
/* See try_merge_free_space() comment. */
|
/* See try_merge_free_space() comment. */
|
||||||
|
|
|
@ -654,12 +654,18 @@ cont:
|
||||||
page_error_op |
|
page_error_op |
|
||||||
PAGE_END_WRITEBACK);
|
PAGE_END_WRITEBACK);
|
||||||
|
|
||||||
for (i = 0; i < nr_pages; i++) {
|
/*
|
||||||
WARN_ON(pages[i]->mapping);
|
* Ensure we only free the compressed pages if we have
|
||||||
put_page(pages[i]);
|
* them allocated, as we can still reach here with
|
||||||
|
* inode_need_compress() == false.
|
||||||
|
*/
|
||||||
|
if (pages) {
|
||||||
|
for (i = 0; i < nr_pages; i++) {
|
||||||
|
WARN_ON(pages[i]->mapping);
|
||||||
|
put_page(pages[i]);
|
||||||
|
}
|
||||||
|
kfree(pages);
|
||||||
}
|
}
|
||||||
kfree(pages);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6622,7 +6628,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
|
||||||
extent_type == BTRFS_FILE_EXTENT_PREALLOC) {
|
extent_type == BTRFS_FILE_EXTENT_PREALLOC) {
|
||||||
/* Only regular file could have regular/prealloc extent */
|
/* Only regular file could have regular/prealloc extent */
|
||||||
if (!S_ISREG(inode->vfs_inode.i_mode)) {
|
if (!S_ISREG(inode->vfs_inode.i_mode)) {
|
||||||
ret = -EUCLEAN;
|
err = -EUCLEAN;
|
||||||
btrfs_crit(fs_info,
|
btrfs_crit(fs_info,
|
||||||
"regular/prealloc extent found for non-regular inode %llu",
|
"regular/prealloc extent found for non-regular inode %llu",
|
||||||
btrfs_ino(inode));
|
btrfs_ino(inode));
|
||||||
|
|
|
@ -517,6 +517,7 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
|
||||||
char *compress_type;
|
char *compress_type;
|
||||||
bool compress_force = false;
|
bool compress_force = false;
|
||||||
enum btrfs_compression_type saved_compress_type;
|
enum btrfs_compression_type saved_compress_type;
|
||||||
|
int saved_compress_level;
|
||||||
bool saved_compress_force;
|
bool saved_compress_force;
|
||||||
int no_compress = 0;
|
int no_compress = 0;
|
||||||
|
|
||||||
|
@ -598,6 +599,7 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
|
||||||
info->compress_type : BTRFS_COMPRESS_NONE;
|
info->compress_type : BTRFS_COMPRESS_NONE;
|
||||||
saved_compress_force =
|
saved_compress_force =
|
||||||
btrfs_test_opt(info, FORCE_COMPRESS);
|
btrfs_test_opt(info, FORCE_COMPRESS);
|
||||||
|
saved_compress_level = info->compress_level;
|
||||||
if (token == Opt_compress ||
|
if (token == Opt_compress ||
|
||||||
token == Opt_compress_force ||
|
token == Opt_compress_force ||
|
||||||
strncmp(args[0].from, "zlib", 4) == 0) {
|
strncmp(args[0].from, "zlib", 4) == 0) {
|
||||||
|
@ -642,6 +644,8 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
|
||||||
no_compress = 0;
|
no_compress = 0;
|
||||||
} else if (strncmp(args[0].from, "no", 2) == 0) {
|
} else if (strncmp(args[0].from, "no", 2) == 0) {
|
||||||
compress_type = "no";
|
compress_type = "no";
|
||||||
|
info->compress_level = 0;
|
||||||
|
info->compress_type = 0;
|
||||||
btrfs_clear_opt(info->mount_opt, COMPRESS);
|
btrfs_clear_opt(info->mount_opt, COMPRESS);
|
||||||
btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS);
|
btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS);
|
||||||
compress_force = false;
|
compress_force = false;
|
||||||
|
@ -662,11 +666,11 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
|
||||||
*/
|
*/
|
||||||
btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS);
|
btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS);
|
||||||
}
|
}
|
||||||
if ((btrfs_test_opt(info, COMPRESS) &&
|
if (no_compress == 1) {
|
||||||
(info->compress_type != saved_compress_type ||
|
btrfs_info(info, "use no compression");
|
||||||
compress_force != saved_compress_force)) ||
|
} else if ((info->compress_type != saved_compress_type) ||
|
||||||
(!btrfs_test_opt(info, COMPRESS) &&
|
(compress_force != saved_compress_force) ||
|
||||||
no_compress == 1)) {
|
(info->compress_level != saved_compress_level)) {
|
||||||
btrfs_info(info, "%s %s compression, level %d",
|
btrfs_info(info, "%s %s compression, level %d",
|
||||||
(compress_force) ? "force" : "use",
|
(compress_force) ? "force" : "use",
|
||||||
compress_type, info->compress_level);
|
compress_type, info->compress_level);
|
||||||
|
@ -1382,6 +1386,7 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)
|
||||||
{
|
{
|
||||||
struct btrfs_fs_info *info = btrfs_sb(dentry->d_sb);
|
struct btrfs_fs_info *info = btrfs_sb(dentry->d_sb);
|
||||||
const char *compress_type;
|
const char *compress_type;
|
||||||
|
const char *subvol_name;
|
||||||
|
|
||||||
if (btrfs_test_opt(info, DEGRADED))
|
if (btrfs_test_opt(info, DEGRADED))
|
||||||
seq_puts(seq, ",degraded");
|
seq_puts(seq, ",degraded");
|
||||||
|
@ -1468,8 +1473,13 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)
|
||||||
seq_puts(seq, ",ref_verify");
|
seq_puts(seq, ",ref_verify");
|
||||||
seq_printf(seq, ",subvolid=%llu",
|
seq_printf(seq, ",subvolid=%llu",
|
||||||
BTRFS_I(d_inode(dentry))->root->root_key.objectid);
|
BTRFS_I(d_inode(dentry))->root->root_key.objectid);
|
||||||
seq_puts(seq, ",subvol=");
|
subvol_name = btrfs_get_subvol_name_from_objectid(info,
|
||||||
seq_dentry(seq, dentry, " \t\n\\");
|
BTRFS_I(d_inode(dentry))->root->root_key.objectid);
|
||||||
|
if (!IS_ERR(subvol_name)) {
|
||||||
|
seq_puts(seq, ",subvol=");
|
||||||
|
seq_escape(seq, subvol_name, " \t\n\\");
|
||||||
|
kfree(subvol_name);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1950,6 +1960,12 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
|
||||||
set_bit(BTRFS_FS_OPEN, &fs_info->flags);
|
set_bit(BTRFS_FS_OPEN, &fs_info->flags);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
|
/*
|
||||||
|
* We need to set SB_I_VERSION here otherwise it'll get cleared by VFS,
|
||||||
|
* since the absence of the flag means it can be toggled off by remount.
|
||||||
|
*/
|
||||||
|
*flags |= SB_I_VERSION;
|
||||||
|
|
||||||
wake_up_process(fs_info->transaction_kthread);
|
wake_up_process(fs_info->transaction_kthread);
|
||||||
btrfs_remount_cleanup(fs_info, old_opts);
|
btrfs_remount_cleanup(fs_info, old_opts);
|
||||||
clear_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state);
|
clear_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state);
|
||||||
|
|
|
@ -1565,9 +1565,11 @@ void btrfs_sysfs_del_qgroups(struct btrfs_fs_info *fs_info)
|
||||||
rbtree_postorder_for_each_entry_safe(qgroup, next,
|
rbtree_postorder_for_each_entry_safe(qgroup, next,
|
||||||
&fs_info->qgroup_tree, node)
|
&fs_info->qgroup_tree, node)
|
||||||
btrfs_sysfs_del_one_qgroup(fs_info, qgroup);
|
btrfs_sysfs_del_one_qgroup(fs_info, qgroup);
|
||||||
kobject_del(fs_info->qgroups_kobj);
|
if (fs_info->qgroups_kobj) {
|
||||||
kobject_put(fs_info->qgroups_kobj);
|
kobject_del(fs_info->qgroups_kobj);
|
||||||
fs_info->qgroups_kobj = NULL;
|
kobject_put(fs_info->qgroups_kobj);
|
||||||
|
fs_info->qgroups_kobj = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called when qgroups get initialized, thus there is no need for locking */
|
/* Called when qgroups get initialized, thus there is no need for locking */
|
||||||
|
|
|
@ -4036,11 +4036,8 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
|
||||||
fs_info->csum_root,
|
fs_info->csum_root,
|
||||||
ds + cs, ds + cs + cl - 1,
|
ds + cs, ds + cs + cl - 1,
|
||||||
&ordered_sums, 0);
|
&ordered_sums, 0);
|
||||||
if (ret) {
|
if (ret)
|
||||||
btrfs_release_path(dst_path);
|
break;
|
||||||
kfree(ins_data);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4053,7 +4050,6 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
|
||||||
* we have to do this after the loop above to avoid changing the
|
* we have to do this after the loop above to avoid changing the
|
||||||
* log tree while trying to change the log tree.
|
* log tree while trying to change the log tree.
|
||||||
*/
|
*/
|
||||||
ret = 0;
|
|
||||||
while (!list_empty(&ordered_sums)) {
|
while (!list_empty(&ordered_sums)) {
|
||||||
struct btrfs_ordered_sum *sums = list_entry(ordered_sums.next,
|
struct btrfs_ordered_sum *sums = list_entry(ordered_sums.next,
|
||||||
struct btrfs_ordered_sum,
|
struct btrfs_ordered_sum,
|
||||||
|
|
|
@ -4720,6 +4720,10 @@ again:
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&fs_info->chunk_mutex);
|
mutex_lock(&fs_info->chunk_mutex);
|
||||||
|
/* Clear all state bits beyond the shrunk device size */
|
||||||
|
clear_extent_bits(&device->alloc_state, new_size, (u64)-1,
|
||||||
|
CHUNK_STATE_MASK);
|
||||||
|
|
||||||
btrfs_device_set_disk_total_bytes(device, new_size);
|
btrfs_device_set_disk_total_bytes(device, new_size);
|
||||||
if (list_empty(&device->post_commit_list))
|
if (list_empty(&device->post_commit_list))
|
||||||
list_add_tail(&device->post_commit_list,
|
list_add_tail(&device->post_commit_list,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user