Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus-4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs

Pull btrfs cleanups and fixes from Chris Mason:
"These are small cleanups, and also some fixes for our async worker
thread initialization.

I was having some trouble testing these, but it ended up being a
combination of changing around my test servers and a shiny new
schedule while atomic from the new start/finish_plug in
writeback_sb_inodes().

That one only hits on btrfs raid5/6 or MD raid10, and if I wasn't
changing a bunch of things in my test setup at once it would have been
really clear. Fix for writeback_sb_inodes() on the way as well"

* 'for-linus-4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
Btrfs: cleanup: remove unnecessary check before btrfs_free_path is called
btrfs: async_thread: Fix workqueue 'max_active' value when initializing
btrfs: Add raid56 support for updating num_tolerated_disk_barrier_failures in btrfs_balance
btrfs: Cleanup for btrfs_calc_num_tolerated_disk_barrier_failures
btrfs: Remove noused chunk_tree and chunk_objectid from scrub_enumerate_chunks and scrub_chunk
btrfs: Update out-of-date "skip parity stripe" comment

+81 -95
+34 -23
fs/btrfs/async-thread.c
··· 42 42 43 43 /* Thresholding related variants */ 44 44 atomic_t pending; 45 - int max_active; 46 - int current_max; 45 + 46 + /* Up limit of concurrency workers */ 47 + int limit_active; 48 + 49 + /* Current number of concurrency workers */ 50 + int current_active; 51 + 52 + /* Threshold to change current_active */ 47 53 int thresh; 48 54 unsigned int count; 49 55 spinlock_t thres_lock; ··· 94 88 BTRFS_WORK_HELPER(scrubparity_helper); 95 89 96 90 static struct __btrfs_workqueue * 97 - __btrfs_alloc_workqueue(const char *name, unsigned int flags, int max_active, 91 + __btrfs_alloc_workqueue(const char *name, unsigned int flags, int limit_active, 98 92 int thresh) 99 93 { 100 94 struct __btrfs_workqueue *ret = kzalloc(sizeof(*ret), GFP_NOFS); ··· 102 96 if (!ret) 103 97 return NULL; 104 98 105 - ret->max_active = max_active; 99 + ret->limit_active = limit_active; 106 100 atomic_set(&ret->pending, 0); 107 101 if (thresh == 0) 108 102 thresh = DFT_THRESHOLD; 109 103 /* For low threshold, disabling threshold is a better choice */ 110 104 if (thresh < DFT_THRESHOLD) { 111 - ret->current_max = max_active; 105 + ret->current_active = limit_active; 112 106 ret->thresh = NO_THRESHOLD; 113 107 } else { 114 - ret->current_max = 1; 108 + /* 109 + * For threshold-able wq, let its concurrency grow on demand. 110 + * Use minimal max_active at alloc time to reduce resource 111 + * usage. 112 + */ 113 + ret->current_active = 1; 115 114 ret->thresh = thresh; 116 115 } 117 116 118 117 if (flags & WQ_HIGHPRI) 119 118 ret->normal_wq = alloc_workqueue("%s-%s-high", flags, 120 - ret->max_active, 121 - "btrfs", name); 119 + ret->current_active, "btrfs", 120 + name); 122 121 else 123 122 ret->normal_wq = alloc_workqueue("%s-%s", flags, 124 - ret->max_active, "btrfs", 123 + ret->current_active, "btrfs", 125 124 name); 126 125 if (!ret->normal_wq) { 127 126 kfree(ret); ··· 145 134 146 135 struct btrfs_workqueue *btrfs_alloc_workqueue(const char *name, 147 136 unsigned int flags, 148 - int max_active, 137 + int limit_active, 149 138 int thresh) 150 139 { 151 140 struct btrfs_workqueue *ret = kzalloc(sizeof(*ret), GFP_NOFS); ··· 154 143 return NULL; 155 144 156 145 ret->normal = __btrfs_alloc_workqueue(name, flags & ~WQ_HIGHPRI, 157 - max_active, thresh); 146 + limit_active, thresh); 158 147 if (!ret->normal) { 159 148 kfree(ret); 160 149 return NULL; 161 150 } 162 151 163 152 if (flags & WQ_HIGHPRI) { 164 - ret->high = __btrfs_alloc_workqueue(name, flags, max_active, 153 + ret->high = __btrfs_alloc_workqueue(name, flags, limit_active, 165 154 thresh); 166 155 if (!ret->high) { 167 156 __btrfs_destroy_workqueue(ret->normal); ··· 191 180 */ 192 181 static inline void thresh_exec_hook(struct __btrfs_workqueue *wq) 193 182 { 194 - int new_max_active; 183 + int new_current_active; 195 184 long pending; 196 185 int need_change = 0; 197 186 ··· 208 197 wq->count %= (wq->thresh / 4); 209 198 if (!wq->count) 210 199 goto out; 211 - new_max_active = wq->current_max; 200 + new_current_active = wq->current_active; 212 201 213 202 /* 214 203 * pending may be changed later, but it's OK since we really ··· 216 205 */ 217 206 pending = atomic_read(&wq->pending); 218 207 if (pending > wq->thresh) 219 - new_max_active++; 208 + new_current_active++; 220 209 if (pending < wq->thresh / 2) 221 - new_max_active--; 222 - new_max_active = clamp_val(new_max_active, 1, wq->max_active); 223 - if (new_max_active != wq->current_max) { 210 + new_current_active--; 211 + new_current_active = clamp_val(new_current_active, 1, wq->limit_active); 212 + if (new_current_active != wq->current_active) { 224 213 need_change = 1; 225 - wq->current_max = new_max_active; 214 + wq->current_active = new_current_active; 226 215 } 227 216 out: 228 217 spin_unlock(&wq->thres_lock); 229 218 230 219 if (need_change) { 231 - workqueue_set_max_active(wq->normal_wq, wq->current_max); 220 + workqueue_set_max_active(wq->normal_wq, wq->current_active); 232 221 } 233 222 } 234 223 ··· 362 351 kfree(wq); 363 352 } 364 353 365 - void btrfs_workqueue_set_max(struct btrfs_workqueue *wq, int max) 354 + void btrfs_workqueue_set_max(struct btrfs_workqueue *wq, int limit_active) 366 355 { 367 356 if (!wq) 368 357 return; 369 - wq->normal->max_active = max; 358 + wq->normal->limit_active = limit_active; 370 359 if (wq->high) 371 - wq->high->max_active = max; 360 + wq->high->limit_active = limit_active; 372 361 } 373 362 374 363 void btrfs_set_work_high_priority(struct btrfs_work *work)
+1 -1
fs/btrfs/async-thread.h
··· 69 69 70 70 struct btrfs_workqueue *btrfs_alloc_workqueue(const char *name, 71 71 unsigned int flags, 72 - int max_active, 72 + int limit_active, 73 73 int thresh); 74 74 void btrfs_init_work(struct btrfs_work *work, btrfs_work_func_t helper, 75 75 btrfs_func_t func,
+1 -2
fs/btrfs/dev-replace.c
··· 183 183 } 184 184 185 185 out: 186 - if (path) 187 - btrfs_free_path(path); 186 + btrfs_free_path(path); 188 187 return ret; 189 188 } 190 189
+35 -39
fs/btrfs/disk-io.c
··· 3443 3443 return 0; 3444 3444 } 3445 3445 3446 + int btrfs_get_num_tolerated_disk_barrier_failures(u64 flags) 3447 + { 3448 + if ((flags & (BTRFS_BLOCK_GROUP_DUP | 3449 + BTRFS_BLOCK_GROUP_RAID0 | 3450 + BTRFS_AVAIL_ALLOC_BIT_SINGLE)) || 3451 + ((flags & BTRFS_BLOCK_GROUP_PROFILE_MASK) == 0)) 3452 + return 0; 3453 + 3454 + if (flags & (BTRFS_BLOCK_GROUP_RAID1 | 3455 + BTRFS_BLOCK_GROUP_RAID5 | 3456 + BTRFS_BLOCK_GROUP_RAID10)) 3457 + return 1; 3458 + 3459 + if (flags & BTRFS_BLOCK_GROUP_RAID6) 3460 + return 2; 3461 + 3462 + pr_warn("BTRFS: unknown raid type: %llu\n", flags); 3463 + return 0; 3464 + } 3465 + 3446 3466 int btrfs_calc_num_tolerated_disk_barrier_failures( 3447 3467 struct btrfs_fs_info *fs_info) 3448 3468 { ··· 3472 3452 BTRFS_BLOCK_GROUP_SYSTEM, 3473 3453 BTRFS_BLOCK_GROUP_METADATA, 3474 3454 BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_METADATA}; 3475 - int num_types = 4; 3476 3455 int i; 3477 3456 int c; 3478 3457 int num_tolerated_disk_barrier_failures = 3479 3458 (int)fs_info->fs_devices->num_devices; 3480 3459 3481 - for (i = 0; i < num_types; i++) { 3460 + for (i = 0; i < ARRAY_SIZE(types); i++) { 3482 3461 struct btrfs_space_info *tmp; 3483 3462 3484 3463 sinfo = NULL; ··· 3495 3476 3496 3477 down_read(&sinfo->groups_sem); 3497 3478 for (c = 0; c < BTRFS_NR_RAID_TYPES; c++) { 3498 - if (!list_empty(&sinfo->block_groups[c])) { 3499 - u64 flags; 3479 + u64 flags; 3500 3480 3501 - btrfs_get_block_group_info( 3502 - &sinfo->block_groups[c], &space); 3503 - if (space.total_bytes == 0 || 3504 - space.used_bytes == 0) 3505 - continue; 3506 - flags = space.flags; 3507 - /* 3508 - * return 3509 - * 0: if dup, single or RAID0 is configured for 3510 - * any of metadata, system or data, else 3511 - * 1: if RAID5 is configured, or if RAID1 or 3512 - * RAID10 is configured and only two mirrors 3513 - * are used, else 3514 - * 2: if RAID6 is configured, else 3515 - * num_mirrors - 1: if RAID1 or RAID10 is 3516 - * configured and more than 3517 - * 2 mirrors are used. 3518 - */ 3519 - if (num_tolerated_disk_barrier_failures > 0 && 3520 - ((flags & (BTRFS_BLOCK_GROUP_DUP | 3521 - BTRFS_BLOCK_GROUP_RAID0)) || 3522 - ((flags & BTRFS_BLOCK_GROUP_PROFILE_MASK) 3523 - == 0))) 3524 - num_tolerated_disk_barrier_failures = 0; 3525 - else if (num_tolerated_disk_barrier_failures > 1) { 3526 - if (flags & (BTRFS_BLOCK_GROUP_RAID1 | 3527 - BTRFS_BLOCK_GROUP_RAID5 | 3528 - BTRFS_BLOCK_GROUP_RAID10)) { 3529 - num_tolerated_disk_barrier_failures = 1; 3530 - } else if (flags & 3531 - BTRFS_BLOCK_GROUP_RAID6) { 3532 - num_tolerated_disk_barrier_failures = 2; 3533 - } 3534 - } 3535 - } 3481 + if (list_empty(&sinfo->block_groups[c])) 3482 + continue; 3483 + 3484 + btrfs_get_block_group_info(&sinfo->block_groups[c], 3485 + &space); 3486 + if (space.total_bytes == 0 || space.used_bytes == 0) 3487 + continue; 3488 + flags = space.flags; 3489 + 3490 + num_tolerated_disk_barrier_failures = min( 3491 + num_tolerated_disk_barrier_failures, 3492 + btrfs_get_num_tolerated_disk_barrier_failures( 3493 + flags)); 3536 3494 } 3537 3495 up_read(&sinfo->groups_sem); 3538 3496 }
+1
fs/btrfs/disk-io.h
··· 139 139 u64 objectid); 140 140 int btree_lock_page_hook(struct page *page, void *data, 141 141 void (*flush_fn)(void *)); 142 + int btrfs_get_num_tolerated_disk_barrier_failures(u64 flags); 142 143 int btrfs_calc_num_tolerated_disk_barrier_failures( 143 144 struct btrfs_fs_info *fs_info); 144 145 int __init btrfs_end_io_wq_init(void);
+1 -2
fs/btrfs/inode.c
··· 6909 6909 6910 6910 trace_btrfs_get_extent(root, em); 6911 6911 6912 - if (path) 6913 - btrfs_free_path(path); 6912 + btrfs_free_path(path); 6914 6913 if (trans) { 6915 6914 ret = btrfs_end_transaction(trans, root); 6916 6915 if (!err)
+3 -9
fs/btrfs/scrub.c
··· 3267 3267 scrub_blocked_if_needed(fs_info); 3268 3268 } 3269 3269 3270 - /* for raid56, we skip parity stripe */ 3271 3270 if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) { 3272 3271 ret = get_raid56_logic_offset(physical, num, map, 3273 3272 &logical, 3274 3273 &stripe_logical); 3275 3274 logical += base; 3276 3275 if (ret) { 3276 + /* it is parity strip */ 3277 3277 stripe_logical += base; 3278 3278 stripe_end = stripe_logical + increment; 3279 3279 ret = scrub_raid56_parity(sctx, map, scrub_dev, ··· 3480 3480 3481 3481 static noinline_for_stack int scrub_chunk(struct scrub_ctx *sctx, 3482 3482 struct btrfs_device *scrub_dev, 3483 - u64 chunk_tree, u64 chunk_objectid, 3484 3483 u64 chunk_offset, u64 length, 3485 3484 u64 dev_offset, int is_dev_replace) 3486 3485 { ··· 3530 3531 struct btrfs_root *root = sctx->dev_root; 3531 3532 struct btrfs_fs_info *fs_info = root->fs_info; 3532 3533 u64 length; 3533 - u64 chunk_tree; 3534 - u64 chunk_objectid; 3535 3534 u64 chunk_offset; 3536 3535 int ret = 0; 3537 3536 int slot; ··· 3593 3596 if (found_key.offset + length <= start) 3594 3597 goto skip; 3595 3598 3596 - chunk_tree = btrfs_dev_extent_chunk_tree(l, dev_extent); 3597 - chunk_objectid = btrfs_dev_extent_chunk_objectid(l, dev_extent); 3598 3599 chunk_offset = btrfs_dev_extent_chunk_offset(l, dev_extent); 3599 3600 3600 3601 /* ··· 3625 3630 dev_replace->cursor_right = found_key.offset + length; 3626 3631 dev_replace->cursor_left = found_key.offset; 3627 3632 dev_replace->item_needs_writeback = 1; 3628 - ret = scrub_chunk(sctx, scrub_dev, chunk_tree, chunk_objectid, 3629 - chunk_offset, length, found_key.offset, 3630 - is_dev_replace); 3633 + ret = scrub_chunk(sctx, scrub_dev, chunk_offset, length, 3634 + found_key.offset, is_dev_replace); 3631 3635 3632 3636 /* 3633 3637 * flush, submit all pending read and write bios, afterwards
+1 -2
fs/btrfs/tree-defrag.c
··· 115 115 ret = -EAGAIN; 116 116 } 117 117 out: 118 - if (path) 119 - btrfs_free_path(path); 118 + btrfs_free_path(path); 120 119 if (ret == -EAGAIN) { 121 120 if (root->defrag_max.objectid > root->defrag_progress.objectid) 122 121 goto done;
+4 -17
fs/btrfs/volumes.c
··· 3585 3585 } while (read_seqretry(&fs_info->profiles_lock, seq)); 3586 3586 3587 3587 if (bctl->sys.flags & BTRFS_BALANCE_ARGS_CONVERT) { 3588 - int num_tolerated_disk_barrier_failures; 3589 - u64 target = bctl->sys.target; 3590 - 3591 - num_tolerated_disk_barrier_failures = 3592 - btrfs_calc_num_tolerated_disk_barrier_failures(fs_info); 3593 - if (num_tolerated_disk_barrier_failures > 0 && 3594 - (target & 3595 - (BTRFS_BLOCK_GROUP_DUP | BTRFS_BLOCK_GROUP_RAID0 | 3596 - BTRFS_AVAIL_ALLOC_BIT_SINGLE))) 3597 - num_tolerated_disk_barrier_failures = 0; 3598 - else if (num_tolerated_disk_barrier_failures > 1 && 3599 - (target & 3600 - (BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID10))) 3601 - num_tolerated_disk_barrier_failures = 1; 3602 - 3603 - fs_info->num_tolerated_disk_barrier_failures = 3604 - num_tolerated_disk_barrier_failures; 3588 + fs_info->num_tolerated_disk_barrier_failures = min( 3589 + btrfs_calc_num_tolerated_disk_barrier_failures(fs_info), 3590 + btrfs_get_num_tolerated_disk_barrier_failures( 3591 + bctl->sys.target)); 3605 3592 } 3606 3593 3607 3594 ret = insert_balance_item(fs_info->tree_root, bctl);