for-5.16-rc1-tag
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE8rQSAMVO+zA4DBdWxWXV+ddtWDsFAmGWiSAACgkQxWXV+ddt WDtKiA//VFrxg5I1yrTyyVvc2RqcPg0aCopO6wIAgcHV1yzseJ7AyP7two1p5dg8 3DPDKaXFvONZYXl8j9ZuzFiryKPGJxp1KSagKyt6EKDRYm50HOreTC1Qt2ZvLJHn wHohwHX96yv+4gyKvpCBZVpp3dSIDbsbCxlpz3mm7kZv//wHxA5l0chZpHbTqUF6 JloRSrOIGlSeQYPog1Lnu1c92qoGzLL5n47aXS3s5afpkqqkOlKZLsyb90N4uJx4 M1htsl4ga7b3OB8jbR95wlbd/qXsB+dvaBUQHgDm4hafW6ma5ft9NhuePQnQlaVH ub/rlfNTsKl6jly9eNJ6wGpqi/OBlhA4qCmQVbVDE+HhWUJbdUiQ5UgxoOrQlkOP Pd3NvW+95qg+Lj/egUA/Mrtz1v/6oSKcf3gQVKMNIrnk6lOUVZWtQhBe5YS3qHih PzxrCp4ThlvmVeemHS7783akiwkI49wUn7a6dUD87x81ghemUHJzC83/mgs1rl/0 7Q1QLetgfrZpko3W4GzS2J3WwKTB0tvBXxsZ8gU5gI0FNkx90bR8+xI0fVF8IGJo QglHn9gepb6si7BCxyKDTlQNMt23s7GFH5/4hHtkomtlR6vpRbPJAq5mpOrqsLgJ VGc/SwCJPSmynqRAxuCn+DqlfaMZZaqtvgVVWnhJl9ylKyUAQKU= =ze0L -----END PGP SIGNATURE----- Merge tag 'for-5.16-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux Pull btrfs fixes from David Sterba: "Several xes and one old ioctl deprecation. Namely there's fix for crashes/warnings with lzo compression that was suspected to be caused by first pull merge resolution, but it was a different bug. Summary: - regression fix for a crash in lzo due to missing boundary checks of the page array - fix crashes on ARM64 due to missing barriers when synchronizing status bits between work queues - silence lockdep when reading chunk tree during mount - fix false positive warning in integrity checker on devices with disabled write caching - fix signedness of bitfields in scrub - start deprecation of balance v1 ioctl" * tag 'for-5.16-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: deprecate BTRFS_IOC_BALANCE ioctl btrfs: make 1-bit bit-fields of scrub_page unsigned int btrfs: check-integrity: fix a warning on write caching disabled disk btrfs: silence lockdep when reading chunk tree during mount btrfs: fix memory ordering between normal and ordered work functions btrfs: fix a out-of-bound access in copy_compressed_data_to_page()
This commit is contained in:
commit
6fdf886424
@ -234,6 +234,13 @@ static void run_ordered_work(struct __btrfs_workqueue *wq,
|
|||||||
ordered_list);
|
ordered_list);
|
||||||
if (!test_bit(WORK_DONE_BIT, &work->flags))
|
if (!test_bit(WORK_DONE_BIT, &work->flags))
|
||||||
break;
|
break;
|
||||||
|
/*
|
||||||
|
* Orders all subsequent loads after reading WORK_DONE_BIT,
|
||||||
|
* paired with the smp_mb__before_atomic in btrfs_work_helper
|
||||||
|
* this guarantees that the ordered function will see all
|
||||||
|
* updates from ordinary work function.
|
||||||
|
*/
|
||||||
|
smp_rmb();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* we are going to call the ordered done function, but
|
* we are going to call the ordered done function, but
|
||||||
@ -317,6 +324,13 @@ static void btrfs_work_helper(struct work_struct *normal_work)
|
|||||||
thresh_exec_hook(wq);
|
thresh_exec_hook(wq);
|
||||||
work->func(work);
|
work->func(work);
|
||||||
if (need_order) {
|
if (need_order) {
|
||||||
|
/*
|
||||||
|
* Ensures all memory accesses done in the work function are
|
||||||
|
* ordered before setting the WORK_DONE_BIT. Ensuring the thread
|
||||||
|
* which is going to executed the ordered work sees them.
|
||||||
|
* Pairs with the smp_rmb in run_ordered_work.
|
||||||
|
*/
|
||||||
|
smp_mb__before_atomic();
|
||||||
set_bit(WORK_DONE_BIT, &work->flags);
|
set_bit(WORK_DONE_BIT, &work->flags);
|
||||||
run_ordered_work(wq, work);
|
run_ordered_work(wq, work);
|
||||||
} else {
|
} else {
|
||||||
|
@ -3978,11 +3978,23 @@ static void btrfs_end_empty_barrier(struct bio *bio)
|
|||||||
*/
|
*/
|
||||||
static void write_dev_flush(struct btrfs_device *device)
|
static void write_dev_flush(struct btrfs_device *device)
|
||||||
{
|
{
|
||||||
struct request_queue *q = bdev_get_queue(device->bdev);
|
|
||||||
struct bio *bio = device->flush_bio;
|
struct bio *bio = device->flush_bio;
|
||||||
|
|
||||||
|
#ifndef CONFIG_BTRFS_FS_CHECK_INTEGRITY
|
||||||
|
/*
|
||||||
|
* When a disk has write caching disabled, we skip submission of a bio
|
||||||
|
* with flush and sync requests before writing the superblock, since
|
||||||
|
* it's not needed. However when the integrity checker is enabled, this
|
||||||
|
* results in reports that there are metadata blocks referred by a
|
||||||
|
* superblock that were not properly flushed. So don't skip the bio
|
||||||
|
* submission only when the integrity checker is enabled for the sake
|
||||||
|
* of simplicity, since this is a debug tool and not meant for use in
|
||||||
|
* non-debug builds.
|
||||||
|
*/
|
||||||
|
struct request_queue *q = bdev_get_queue(device->bdev);
|
||||||
if (!test_bit(QUEUE_FLAG_WC, &q->queue_flags))
|
if (!test_bit(QUEUE_FLAG_WC, &q->queue_flags))
|
||||||
return;
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
bio_reset(bio);
|
bio_reset(bio);
|
||||||
bio->bi_end_io = btrfs_end_empty_barrier;
|
bio->bi_end_io = btrfs_end_empty_barrier;
|
||||||
|
@ -3985,6 +3985,10 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg)
|
|||||||
bool need_unlock; /* for mut. excl. ops lock */
|
bool need_unlock; /* for mut. excl. ops lock */
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (!arg)
|
||||||
|
btrfs_warn(fs_info,
|
||||||
|
"IOC_BALANCE ioctl (v1) is deprecated and will be removed in kernel 5.18");
|
||||||
|
|
||||||
if (!capable(CAP_SYS_ADMIN))
|
if (!capable(CAP_SYS_ADMIN))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
|
@ -125,6 +125,7 @@ static inline size_t read_compress_length(const char *buf)
|
|||||||
static int copy_compressed_data_to_page(char *compressed_data,
|
static int copy_compressed_data_to_page(char *compressed_data,
|
||||||
size_t compressed_size,
|
size_t compressed_size,
|
||||||
struct page **out_pages,
|
struct page **out_pages,
|
||||||
|
unsigned long max_nr_page,
|
||||||
u32 *cur_out,
|
u32 *cur_out,
|
||||||
const u32 sectorsize)
|
const u32 sectorsize)
|
||||||
{
|
{
|
||||||
@ -133,6 +134,9 @@ static int copy_compressed_data_to_page(char *compressed_data,
|
|||||||
struct page *cur_page;
|
struct page *cur_page;
|
||||||
char *kaddr;
|
char *kaddr;
|
||||||
|
|
||||||
|
if ((*cur_out / PAGE_SIZE) >= max_nr_page)
|
||||||
|
return -E2BIG;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We never allow a segment header crossing sector boundary, previous
|
* We never allow a segment header crossing sector boundary, previous
|
||||||
* run should ensure we have enough space left inside the sector.
|
* run should ensure we have enough space left inside the sector.
|
||||||
@ -161,6 +165,10 @@ static int copy_compressed_data_to_page(char *compressed_data,
|
|||||||
orig_out + compressed_size - *cur_out);
|
orig_out + compressed_size - *cur_out);
|
||||||
|
|
||||||
kunmap(cur_page);
|
kunmap(cur_page);
|
||||||
|
|
||||||
|
if ((*cur_out / PAGE_SIZE) >= max_nr_page)
|
||||||
|
return -E2BIG;
|
||||||
|
|
||||||
cur_page = out_pages[*cur_out / PAGE_SIZE];
|
cur_page = out_pages[*cur_out / PAGE_SIZE];
|
||||||
/* Allocate a new page */
|
/* Allocate a new page */
|
||||||
if (!cur_page) {
|
if (!cur_page) {
|
||||||
@ -203,6 +211,7 @@ int lzo_compress_pages(struct list_head *ws, struct address_space *mapping,
|
|||||||
const u32 sectorsize = btrfs_sb(mapping->host->i_sb)->sectorsize;
|
const u32 sectorsize = btrfs_sb(mapping->host->i_sb)->sectorsize;
|
||||||
struct page *page_in = NULL;
|
struct page *page_in = NULL;
|
||||||
char *sizes_ptr;
|
char *sizes_ptr;
|
||||||
|
const unsigned long max_nr_page = *out_pages;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
/* Points to the file offset of input data */
|
/* Points to the file offset of input data */
|
||||||
u64 cur_in = start;
|
u64 cur_in = start;
|
||||||
@ -210,6 +219,7 @@ int lzo_compress_pages(struct list_head *ws, struct address_space *mapping,
|
|||||||
u32 cur_out = 0;
|
u32 cur_out = 0;
|
||||||
u32 len = *total_out;
|
u32 len = *total_out;
|
||||||
|
|
||||||
|
ASSERT(max_nr_page > 0);
|
||||||
*out_pages = 0;
|
*out_pages = 0;
|
||||||
*total_out = 0;
|
*total_out = 0;
|
||||||
*total_in = 0;
|
*total_in = 0;
|
||||||
@ -248,7 +258,8 @@ int lzo_compress_pages(struct list_head *ws, struct address_space *mapping,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = copy_compressed_data_to_page(workspace->cbuf, out_len,
|
ret = copy_compressed_data_to_page(workspace->cbuf, out_len,
|
||||||
pages, &cur_out, sectorsize);
|
pages, max_nr_page,
|
||||||
|
&cur_out, sectorsize);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -73,8 +73,8 @@ struct scrub_page {
|
|||||||
u64 physical_for_dev_replace;
|
u64 physical_for_dev_replace;
|
||||||
atomic_t refs;
|
atomic_t refs;
|
||||||
u8 mirror_num;
|
u8 mirror_num;
|
||||||
int have_csum:1;
|
unsigned int have_csum:1;
|
||||||
int io_error:1;
|
unsigned int io_error:1;
|
||||||
u8 csum[BTRFS_CSUM_SIZE];
|
u8 csum[BTRFS_CSUM_SIZE];
|
||||||
|
|
||||||
struct scrub_recover *recover;
|
struct scrub_recover *recover;
|
||||||
|
@ -7558,6 +7558,19 @@ int btrfs_read_chunk_tree(struct btrfs_fs_info *fs_info)
|
|||||||
*/
|
*/
|
||||||
fs_info->fs_devices->total_rw_bytes = 0;
|
fs_info->fs_devices->total_rw_bytes = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lockdep complains about possible circular locking dependency between
|
||||||
|
* a disk's open_mutex (struct gendisk.open_mutex), the rw semaphores
|
||||||
|
* used for freeze procection of a fs (struct super_block.s_writers),
|
||||||
|
* which we take when starting a transaction, and extent buffers of the
|
||||||
|
* chunk tree if we call read_one_dev() while holding a lock on an
|
||||||
|
* extent buffer of the chunk tree. Since we are mounting the filesystem
|
||||||
|
* and at this point there can't be any concurrent task modifying the
|
||||||
|
* chunk tree, to keep it simple, just skip locking on the chunk tree.
|
||||||
|
*/
|
||||||
|
ASSERT(!test_bit(BTRFS_FS_OPEN, &fs_info->flags));
|
||||||
|
path->skip_locking = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read all device items, and then all the chunk items. All
|
* Read all device items, and then all the chunk items. All
|
||||||
* device items are found before any chunk item (their object id
|
* device items are found before any chunk item (their object id
|
||||||
@ -7583,10 +7596,6 @@ int btrfs_read_chunk_tree(struct btrfs_fs_info *fs_info)
|
|||||||
goto error;
|
goto error;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* The nodes on level 1 are not locked but we don't need to do
|
|
||||||
* that during mount time as nothing else can access the tree
|
|
||||||
*/
|
|
||||||
node = path->nodes[1];
|
node = path->nodes[1];
|
||||||
if (node) {
|
if (node) {
|
||||||
if (last_ra_node != node->start) {
|
if (last_ra_node != node->start) {
|
||||||
@ -7614,7 +7623,6 @@ int btrfs_read_chunk_tree(struct btrfs_fs_info *fs_info)
|
|||||||
* requirement for chunk allocation, see the comment on
|
* requirement for chunk allocation, see the comment on
|
||||||
* top of btrfs_chunk_alloc() for details.
|
* top of btrfs_chunk_alloc() for details.
|
||||||
*/
|
*/
|
||||||
ASSERT(!test_bit(BTRFS_FS_OPEN, &fs_info->flags));
|
|
||||||
chunk = btrfs_item_ptr(leaf, slot, struct btrfs_chunk);
|
chunk = btrfs_item_ptr(leaf, slot, struct btrfs_chunk);
|
||||||
ret = read_one_chunk(&found_key, leaf, chunk);
|
ret = read_one_chunk(&found_key, leaf, chunk);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
Loading…
Reference in New Issue
Block a user