Skip to content

Commit 1fb00cb

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs fixes from Chris Mason: "The biggest of these comes from Liu Bo, who tracked down a hang we've been hitting since moving to kernel workqueues (it's a btrfs bug, not in the generic code). His patch needs backporting to 3.16 and 3.15 stable, which I'll send once this is in. Otherwise these are assorted fixes. Most were integrated last week during KS, but I wanted to give everyone the chance to test the result, so I waited for rc2 to come out before sending" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: (24 commits) Btrfs: fix task hang under heavy compressed write Btrfs: fix filemap_flush call in btrfs_file_release Btrfs: fix crash on endio of reading corrupted block btrfs: fix leak in qgroup_subtree_accounting() error path btrfs: Use right extent length when inserting overlap extent map. Btrfs: clone, don't create invalid hole extent map Btrfs: don't monopolize a core when evicting inode Btrfs: fix hole detection during file fsync Btrfs: ensure tmpfile inode is always persisted with link count of 0 Btrfs: race free update of commit root for ro snapshots Btrfs: fix regression of btrfs device replace Btrfs: don't consider the missing device when allocating new chunks Btrfs: Fix wrong device size when we are resizing the device Btrfs: don't write any data into a readonly device when scrub Btrfs: Fix the problem that the replace destroys the seed filesystem btrfs: Return right extent when fiemap gives unaligned offset and len. Btrfs: fix wrong extent mapping for DirectIO Btrfs: fix wrong write range for filemap_fdatawrite_range() Btrfs: fix wrong missing device counter decrease Btrfs: fix unzeroed members in fs_devices when creating a fs from seed fs ...
2 parents c0fe5dc + 9e0af23 commit 1fb00cb

17 files changed

+312
-135
lines changed

fs/btrfs/async-thread.c

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
#include <linux/list.h>
2323
#include <linux/spinlock.h>
2424
#include <linux/freezer.h>
25-
#include <linux/workqueue.h>
2625
#include "async-thread.h"
2726
#include "ctree.h"
2827

@@ -55,8 +54,39 @@ struct btrfs_workqueue {
5554
struct __btrfs_workqueue *high;
5655
};
5756

58-
static inline struct __btrfs_workqueue
59-
*__btrfs_alloc_workqueue(const char *name, int flags, int max_active,
57+
static void normal_work_helper(struct btrfs_work *work);
58+
59+
#define BTRFS_WORK_HELPER(name) \
60+
void btrfs_##name(struct work_struct *arg) \
61+
{ \
62+
struct btrfs_work *work = container_of(arg, struct btrfs_work, \
63+
normal_work); \
64+
normal_work_helper(work); \
65+
}
66+
67+
BTRFS_WORK_HELPER(worker_helper);
68+
BTRFS_WORK_HELPER(delalloc_helper);
69+
BTRFS_WORK_HELPER(flush_delalloc_helper);
70+
BTRFS_WORK_HELPER(cache_helper);
71+
BTRFS_WORK_HELPER(submit_helper);
72+
BTRFS_WORK_HELPER(fixup_helper);
73+
BTRFS_WORK_HELPER(endio_helper);
74+
BTRFS_WORK_HELPER(endio_meta_helper);
75+
BTRFS_WORK_HELPER(endio_meta_write_helper);
76+
BTRFS_WORK_HELPER(endio_raid56_helper);
77+
BTRFS_WORK_HELPER(rmw_helper);
78+
BTRFS_WORK_HELPER(endio_write_helper);
79+
BTRFS_WORK_HELPER(freespace_write_helper);
80+
BTRFS_WORK_HELPER(delayed_meta_helper);
81+
BTRFS_WORK_HELPER(readahead_helper);
82+
BTRFS_WORK_HELPER(qgroup_rescan_helper);
83+
BTRFS_WORK_HELPER(extent_refs_helper);
84+
BTRFS_WORK_HELPER(scrub_helper);
85+
BTRFS_WORK_HELPER(scrubwrc_helper);
86+
BTRFS_WORK_HELPER(scrubnc_helper);
87+
88+
static struct __btrfs_workqueue *
89+
__btrfs_alloc_workqueue(const char *name, int flags, int max_active,
6090
int thresh)
6191
{
6292
struct __btrfs_workqueue *ret = kzalloc(sizeof(*ret), GFP_NOFS);
@@ -232,13 +262,11 @@ static void run_ordered_work(struct __btrfs_workqueue *wq)
232262
spin_unlock_irqrestore(lock, flags);
233263
}
234264

235-
static void normal_work_helper(struct work_struct *arg)
265+
static void normal_work_helper(struct btrfs_work *work)
236266
{
237-
struct btrfs_work *work;
238267
struct __btrfs_workqueue *wq;
239268
int need_order = 0;
240269

241-
work = container_of(arg, struct btrfs_work, normal_work);
242270
/*
243271
* We should not touch things inside work in the following cases:
244272
* 1) after work->func() if it has no ordered_free
@@ -262,15 +290,15 @@ static void normal_work_helper(struct work_struct *arg)
262290
trace_btrfs_all_work_done(work);
263291
}
264292

265-
void btrfs_init_work(struct btrfs_work *work,
293+
void btrfs_init_work(struct btrfs_work *work, btrfs_work_func_t uniq_func,
266294
btrfs_func_t func,
267295
btrfs_func_t ordered_func,
268296
btrfs_func_t ordered_free)
269297
{
270298
work->func = func;
271299
work->ordered_func = ordered_func;
272300
work->ordered_free = ordered_free;
273-
INIT_WORK(&work->normal_work, normal_work_helper);
301+
INIT_WORK(&work->normal_work, uniq_func);
274302
INIT_LIST_HEAD(&work->ordered_list);
275303
work->flags = 0;
276304
}

fs/btrfs/async-thread.h

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@
1919

2020
#ifndef __BTRFS_ASYNC_THREAD_
2121
#define __BTRFS_ASYNC_THREAD_
22+
#include <linux/workqueue.h>
2223

2324
struct btrfs_workqueue;
2425
/* Internal use only */
2526
struct __btrfs_workqueue;
2627
struct btrfs_work;
2728
typedef void (*btrfs_func_t)(struct btrfs_work *arg);
29+
typedef void (*btrfs_work_func_t)(struct work_struct *arg);
2830

2931
struct btrfs_work {
3032
btrfs_func_t func;
@@ -38,11 +40,35 @@ struct btrfs_work {
3840
unsigned long flags;
3941
};
4042

43+
#define BTRFS_WORK_HELPER_PROTO(name) \
44+
void btrfs_##name(struct work_struct *arg)
45+
46+
BTRFS_WORK_HELPER_PROTO(worker_helper);
47+
BTRFS_WORK_HELPER_PROTO(delalloc_helper);
48+
BTRFS_WORK_HELPER_PROTO(flush_delalloc_helper);
49+
BTRFS_WORK_HELPER_PROTO(cache_helper);
50+
BTRFS_WORK_HELPER_PROTO(submit_helper);
51+
BTRFS_WORK_HELPER_PROTO(fixup_helper);
52+
BTRFS_WORK_HELPER_PROTO(endio_helper);
53+
BTRFS_WORK_HELPER_PROTO(endio_meta_helper);
54+
BTRFS_WORK_HELPER_PROTO(endio_meta_write_helper);
55+
BTRFS_WORK_HELPER_PROTO(endio_raid56_helper);
56+
BTRFS_WORK_HELPER_PROTO(rmw_helper);
57+
BTRFS_WORK_HELPER_PROTO(endio_write_helper);
58+
BTRFS_WORK_HELPER_PROTO(freespace_write_helper);
59+
BTRFS_WORK_HELPER_PROTO(delayed_meta_helper);
60+
BTRFS_WORK_HELPER_PROTO(readahead_helper);
61+
BTRFS_WORK_HELPER_PROTO(qgroup_rescan_helper);
62+
BTRFS_WORK_HELPER_PROTO(extent_refs_helper);
63+
BTRFS_WORK_HELPER_PROTO(scrub_helper);
64+
BTRFS_WORK_HELPER_PROTO(scrubwrc_helper);
65+
BTRFS_WORK_HELPER_PROTO(scrubnc_helper);
66+
4167
struct btrfs_workqueue *btrfs_alloc_workqueue(const char *name,
4268
int flags,
4369
int max_active,
4470
int thresh);
45-
void btrfs_init_work(struct btrfs_work *work,
71+
void btrfs_init_work(struct btrfs_work *work, btrfs_work_func_t helper,
4672
btrfs_func_t func,
4773
btrfs_func_t ordered_func,
4874
btrfs_func_t ordered_free);

fs/btrfs/delayed-inode.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,8 +1395,8 @@ static int btrfs_wq_run_delayed_node(struct btrfs_delayed_root *delayed_root,
13951395
return -ENOMEM;
13961396

13971397
async_work->delayed_root = delayed_root;
1398-
btrfs_init_work(&async_work->work, btrfs_async_run_delayed_root,
1399-
NULL, NULL);
1398+
btrfs_init_work(&async_work->work, btrfs_delayed_meta_helper,
1399+
btrfs_async_run_delayed_root, NULL, NULL);
14001400
async_work->nr = nr;
14011401

14021402
btrfs_queue_work(root->fs_info->delayed_workers, &async_work->work);

fs/btrfs/disk-io.c

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
#include "btrfs_inode.h"
4040
#include "volumes.h"
4141
#include "print-tree.h"
42-
#include "async-thread.h"
4342
#include "locking.h"
4443
#include "tree-log.h"
4544
#include "free-space-cache.h"
@@ -693,35 +692,41 @@ static void end_workqueue_bio(struct bio *bio, int err)
693692
{
694693
struct end_io_wq *end_io_wq = bio->bi_private;
695694
struct btrfs_fs_info *fs_info;
695+
struct btrfs_workqueue *wq;
696+
btrfs_work_func_t func;
696697

697698
fs_info = end_io_wq->info;
698699
end_io_wq->error = err;
699-
btrfs_init_work(&end_io_wq->work, end_workqueue_fn, NULL, NULL);
700700

701701
if (bio->bi_rw & REQ_WRITE) {
702-
if (end_io_wq->metadata == BTRFS_WQ_ENDIO_METADATA)
703-
btrfs_queue_work(fs_info->endio_meta_write_workers,
704-
&end_io_wq->work);
705-
else if (end_io_wq->metadata == BTRFS_WQ_ENDIO_FREE_SPACE)
706-
btrfs_queue_work(fs_info->endio_freespace_worker,
707-
&end_io_wq->work);
708-
else if (end_io_wq->metadata == BTRFS_WQ_ENDIO_RAID56)
709-
btrfs_queue_work(fs_info->endio_raid56_workers,
710-
&end_io_wq->work);
711-
else
712-
btrfs_queue_work(fs_info->endio_write_workers,
713-
&end_io_wq->work);
702+
if (end_io_wq->metadata == BTRFS_WQ_ENDIO_METADATA) {
703+
wq = fs_info->endio_meta_write_workers;
704+
func = btrfs_endio_meta_write_helper;
705+
} else if (end_io_wq->metadata == BTRFS_WQ_ENDIO_FREE_SPACE) {
706+
wq = fs_info->endio_freespace_worker;
707+
func = btrfs_freespace_write_helper;
708+
} else if (end_io_wq->metadata == BTRFS_WQ_ENDIO_RAID56) {
709+
wq = fs_info->endio_raid56_workers;
710+
func = btrfs_endio_raid56_helper;
711+
} else {
712+
wq = fs_info->endio_write_workers;
713+
func = btrfs_endio_write_helper;
714+
}
714715
} else {
715-
if (end_io_wq->metadata == BTRFS_WQ_ENDIO_RAID56)
716-
btrfs_queue_work(fs_info->endio_raid56_workers,
717-
&end_io_wq->work);
718-
else if (end_io_wq->metadata)
719-
btrfs_queue_work(fs_info->endio_meta_workers,
720-
&end_io_wq->work);
721-
else
722-
btrfs_queue_work(fs_info->endio_workers,
723-
&end_io_wq->work);
716+
if (end_io_wq->metadata == BTRFS_WQ_ENDIO_RAID56) {
717+
wq = fs_info->endio_raid56_workers;
718+
func = btrfs_endio_raid56_helper;
719+
} else if (end_io_wq->metadata) {
720+
wq = fs_info->endio_meta_workers;
721+
func = btrfs_endio_meta_helper;
722+
} else {
723+
wq = fs_info->endio_workers;
724+
func = btrfs_endio_helper;
725+
}
724726
}
727+
728+
btrfs_init_work(&end_io_wq->work, func, end_workqueue_fn, NULL, NULL);
729+
btrfs_queue_work(wq, &end_io_wq->work);
725730
}
726731

727732
/*
@@ -828,7 +833,7 @@ int btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct inode *inode,
828833
async->submit_bio_start = submit_bio_start;
829834
async->submit_bio_done = submit_bio_done;
830835

831-
btrfs_init_work(&async->work, run_one_async_start,
836+
btrfs_init_work(&async->work, btrfs_worker_helper, run_one_async_start,
832837
run_one_async_done, run_one_async_free);
833838

834839
async->bio_flags = bio_flags;
@@ -3450,7 +3455,8 @@ static int write_all_supers(struct btrfs_root *root, int max_mirrors)
34503455
btrfs_set_stack_device_generation(dev_item, 0);
34513456
btrfs_set_stack_device_type(dev_item, dev->type);
34523457
btrfs_set_stack_device_id(dev_item, dev->devid);
3453-
btrfs_set_stack_device_total_bytes(dev_item, dev->total_bytes);
3458+
btrfs_set_stack_device_total_bytes(dev_item,
3459+
dev->disk_total_bytes);
34543460
btrfs_set_stack_device_bytes_used(dev_item, dev->bytes_used);
34553461
btrfs_set_stack_device_io_align(dev_item, dev->io_align);
34563462
btrfs_set_stack_device_io_width(dev_item, dev->io_width);

fs/btrfs/extent-tree.c

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,8 @@ static int cache_block_group(struct btrfs_block_group_cache *cache,
552552
caching_ctl->block_group = cache;
553553
caching_ctl->progress = cache->key.objectid;
554554
atomic_set(&caching_ctl->count, 1);
555-
btrfs_init_work(&caching_ctl->work, caching_thread, NULL, NULL);
555+
btrfs_init_work(&caching_ctl->work, btrfs_cache_helper,
556+
caching_thread, NULL, NULL);
556557

557558
spin_lock(&cache->lock);
558559
/*
@@ -2749,8 +2750,8 @@ int btrfs_async_run_delayed_refs(struct btrfs_root *root,
27492750
async->sync = 0;
27502751
init_completion(&async->wait);
27512752

2752-
btrfs_init_work(&async->work, delayed_ref_async_start,
2753-
NULL, NULL);
2753+
btrfs_init_work(&async->work, btrfs_extent_refs_helper,
2754+
delayed_ref_async_start, NULL, NULL);
27542755

27552756
btrfs_queue_work(root->fs_info->extent_workers, &async->work);
27562757

@@ -3586,13 +3587,7 @@ static u64 get_restripe_target(struct btrfs_fs_info *fs_info, u64 flags)
35863587
*/
35873588
static u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags)
35883589
{
3589-
/*
3590-
* we add in the count of missing devices because we want
3591-
* to make sure that any RAID levels on a degraded FS
3592-
* continue to be honored.
3593-
*/
3594-
u64 num_devices = root->fs_info->fs_devices->rw_devices +
3595-
root->fs_info->fs_devices->missing_devices;
3590+
u64 num_devices = root->fs_info->fs_devices->rw_devices;
35963591
u64 target;
35973592
u64 tmp;
35983593

@@ -8440,13 +8435,7 @@ static u64 update_block_group_flags(struct btrfs_root *root, u64 flags)
84408435
if (stripped)
84418436
return extended_to_chunk(stripped);
84428437

8443-
/*
8444-
* we add in the count of missing devices because we want
8445-
* to make sure that any RAID levels on a degraded FS
8446-
* continue to be honored.
8447-
*/
8448-
num_devices = root->fs_info->fs_devices->rw_devices +
8449-
root->fs_info->fs_devices->missing_devices;
8438+
num_devices = root->fs_info->fs_devices->rw_devices;
84508439

84518440
stripped = BTRFS_BLOCK_GROUP_RAID0 |
84528441
BTRFS_BLOCK_GROUP_RAID5 | BTRFS_BLOCK_GROUP_RAID6 |

fs/btrfs/extent_io.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2532,6 +2532,7 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
25322532
test_bit(BIO_UPTODATE, &bio->bi_flags);
25332533
if (err)
25342534
uptodate = 0;
2535+
offset += len;
25352536
continue;
25362537
}
25372538
}
@@ -4207,8 +4208,8 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
42074208
return -ENOMEM;
42084209
path->leave_spinning = 1;
42094210

4210-
start = ALIGN(start, BTRFS_I(inode)->root->sectorsize);
4211-
len = ALIGN(len, BTRFS_I(inode)->root->sectorsize);
4211+
start = round_down(start, BTRFS_I(inode)->root->sectorsize);
4212+
len = round_up(max, BTRFS_I(inode)->root->sectorsize) - start;
42124213

42134214
/*
42144215
* lookup the last file extent. We're not using i_size here

fs/btrfs/file.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1840,7 +1840,15 @@ int btrfs_release_file(struct inode *inode, struct file *filp)
18401840
{
18411841
if (filp->private_data)
18421842
btrfs_ioctl_trans_end(filp);
1843-
filemap_flush(inode->i_mapping);
1843+
/*
1844+
* ordered_data_close is set by settattr when we are about to truncate
1845+
* a file from a non-zero size to a zero size. This tries to
1846+
* flush down new bytes that may have been written if the
1847+
* application were using truncate to replace a file in place.
1848+
*/
1849+
if (test_and_clear_bit(BTRFS_INODE_ORDERED_DATA_CLOSE,
1850+
&BTRFS_I(inode)->runtime_flags))
1851+
filemap_flush(inode->i_mapping);
18441852
return 0;
18451853
}
18461854

@@ -2088,10 +2096,9 @@ static int fill_holes(struct btrfs_trans_handle *trans, struct inode *inode,
20882096
goto out;
20892097
}
20902098

2091-
if (hole_mergeable(inode, leaf, path->slots[0]+1, offset, end)) {
2099+
if (hole_mergeable(inode, leaf, path->slots[0], offset, end)) {
20922100
u64 num_bytes;
20932101

2094-
path->slots[0]++;
20952102
key.offset = offset;
20962103
btrfs_set_item_key_safe(root, path, &key);
20972104
fi = btrfs_item_ptr(leaf, path->slots[0],
@@ -2216,7 +2223,7 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
22162223
goto out_only_mutex;
22172224
}
22182225

2219-
lockstart = round_up(offset , BTRFS_I(inode)->root->sectorsize);
2226+
lockstart = round_up(offset, BTRFS_I(inode)->root->sectorsize);
22202227
lockend = round_down(offset + len,
22212228
BTRFS_I(inode)->root->sectorsize) - 1;
22222229
same_page = ((offset >> PAGE_CACHE_SHIFT) ==
@@ -2277,7 +2284,7 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
22772284
tail_start + tail_len, 0, 1);
22782285
if (ret)
22792286
goto out_only_mutex;
2280-
}
2287+
}
22812288
}
22822289
}
22832290

0 commit comments

Comments
 (0)