aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-09-09 15:52:31 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-09-09 15:52:31 -0400
commitf4a9c169c29efea31b22aec0012ad29df6cf84d4 (patch)
treecc26d338a7a752b63351972ca1aa14dfe0bbdf0e
parent067c2f472d81b8b235176ce8e2cb221c4edc1a9e (diff)
parentb7f3c7d345f72240055efcdf4111fb2e0d01be99 (diff)
Merge branch 'for-linus-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs fixes from Chris Mason: "I'm not proud of how long it took me to track down that one liner in btrfs_sync_log(), but the good news is the patches I was trying to blame for these problems were actually fine (sorry Filipe)" * 'for-linus-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: btrfs: introduce tickets_id to determine whether asynchronous metadata reclaim work makes progress btrfs: remove root_log_ctx from ctx list before btrfs_sync_log returns btrfs: do not decrease bytes_may_use when replaying extents
-rw-r--r--fs/btrfs/ctree.h1
-rw-r--r--fs/btrfs/extent-tree.c23
-rw-r--r--fs/btrfs/tree-log.c1
3 files changed, 17 insertions, 8 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index eff3993c77b3..33fe03551105 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -427,6 +427,7 @@ struct btrfs_space_info {
427 struct list_head ro_bgs; 427 struct list_head ro_bgs;
428 struct list_head priority_tickets; 428 struct list_head priority_tickets;
429 struct list_head tickets; 429 struct list_head tickets;
430 u64 tickets_id;
430 431
431 struct rw_semaphore groups_sem; 432 struct rw_semaphore groups_sem;
432 /* for block groups in our same type */ 433 /* for block groups in our same type */
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 8c8a4d1e02b9..38c2df84cabd 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -4966,12 +4966,12 @@ static void wake_all_tickets(struct list_head *head)
4966 */ 4966 */
4967static void btrfs_async_reclaim_metadata_space(struct work_struct *work) 4967static void btrfs_async_reclaim_metadata_space(struct work_struct *work)
4968{ 4968{
4969 struct reserve_ticket *last_ticket = NULL;
4970 struct btrfs_fs_info *fs_info; 4969 struct btrfs_fs_info *fs_info;
4971 struct btrfs_space_info *space_info; 4970 struct btrfs_space_info *space_info;
4972 u64 to_reclaim; 4971 u64 to_reclaim;
4973 int flush_state; 4972 int flush_state;
4974 int commit_cycles = 0; 4973 int commit_cycles = 0;
4974 u64 last_tickets_id;
4975 4975
4976 fs_info = container_of(work, struct btrfs_fs_info, async_reclaim_work); 4976 fs_info = container_of(work, struct btrfs_fs_info, async_reclaim_work);
4977 space_info = __find_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA); 4977 space_info = __find_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA);
@@ -4984,8 +4984,7 @@ static void btrfs_async_reclaim_metadata_space(struct work_struct *work)
4984 spin_unlock(&space_info->lock); 4984 spin_unlock(&space_info->lock);
4985 return; 4985 return;
4986 } 4986 }
4987 last_ticket = list_first_entry(&space_info->tickets, 4987 last_tickets_id = space_info->tickets_id;
4988 struct reserve_ticket, list);
4989 spin_unlock(&space_info->lock); 4988 spin_unlock(&space_info->lock);
4990 4989
4991 flush_state = FLUSH_DELAYED_ITEMS_NR; 4990 flush_state = FLUSH_DELAYED_ITEMS_NR;
@@ -5005,10 +5004,10 @@ static void btrfs_async_reclaim_metadata_space(struct work_struct *work)
5005 space_info); 5004 space_info);
5006 ticket = list_first_entry(&space_info->tickets, 5005 ticket = list_first_entry(&space_info->tickets,
5007 struct reserve_ticket, list); 5006 struct reserve_ticket, list);
5008 if (last_ticket == ticket) { 5007 if (last_tickets_id == space_info->tickets_id) {
5009 flush_state++; 5008 flush_state++;
5010 } else { 5009 } else {
5011 last_ticket = ticket; 5010 last_tickets_id = space_info->tickets_id;
5012 flush_state = FLUSH_DELAYED_ITEMS_NR; 5011 flush_state = FLUSH_DELAYED_ITEMS_NR;
5013 if (commit_cycles) 5012 if (commit_cycles)
5014 commit_cycles--; 5013 commit_cycles--;
@@ -5384,6 +5383,7 @@ again:
5384 list_del_init(&ticket->list); 5383 list_del_init(&ticket->list);
5385 num_bytes -= ticket->bytes; 5384 num_bytes -= ticket->bytes;
5386 ticket->bytes = 0; 5385 ticket->bytes = 0;
5386 space_info->tickets_id++;
5387 wake_up(&ticket->wait); 5387 wake_up(&ticket->wait);
5388 } else { 5388 } else {
5389 ticket->bytes -= num_bytes; 5389 ticket->bytes -= num_bytes;
@@ -5426,6 +5426,7 @@ again:
5426 num_bytes -= ticket->bytes; 5426 num_bytes -= ticket->bytes;
5427 space_info->bytes_may_use += ticket->bytes; 5427 space_info->bytes_may_use += ticket->bytes;
5428 ticket->bytes = 0; 5428 ticket->bytes = 0;
5429 space_info->tickets_id++;
5429 wake_up(&ticket->wait); 5430 wake_up(&ticket->wait);
5430 } else { 5431 } else {
5431 trace_btrfs_space_reservation(fs_info, "space_info", 5432 trace_btrfs_space_reservation(fs_info, "space_info",
@@ -8216,6 +8217,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
8216{ 8217{
8217 int ret; 8218 int ret;
8218 struct btrfs_block_group_cache *block_group; 8219 struct btrfs_block_group_cache *block_group;
8220 struct btrfs_space_info *space_info;
8219 8221
8220 /* 8222 /*
8221 * Mixed block groups will exclude before processing the log so we only 8223 * Mixed block groups will exclude before processing the log so we only
@@ -8231,9 +8233,14 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
8231 if (!block_group) 8233 if (!block_group)
8232 return -EINVAL; 8234 return -EINVAL;
8233 8235
8234 ret = btrfs_add_reserved_bytes(block_group, ins->offset, 8236 space_info = block_group->space_info;
8235 ins->offset, 0); 8237 spin_lock(&space_info->lock);
8236 BUG_ON(ret); /* logic error */ 8238 spin_lock(&block_group->lock);
8239 space_info->bytes_reserved += ins->offset;
8240 block_group->reserved += ins->offset;
8241 spin_unlock(&block_group->lock);
8242 spin_unlock(&space_info->lock);
8243
8237 ret = alloc_reserved_file_extent(trans, root, 0, root_objectid, 8244 ret = alloc_reserved_file_extent(trans, root, 0, root_objectid,
8238 0, owner, offset, ins, 1); 8245 0, owner, offset, ins, 1);
8239 btrfs_put_block_group(block_group); 8246 btrfs_put_block_group(block_group);
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index e935035ac034..ef9c55bc7907 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -2867,6 +2867,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
2867 2867
2868 if (log_root_tree->log_transid_committed >= root_log_ctx.log_transid) { 2868 if (log_root_tree->log_transid_committed >= root_log_ctx.log_transid) {
2869 blk_finish_plug(&plug); 2869 blk_finish_plug(&plug);
2870 list_del_init(&root_log_ctx.list);
2870 mutex_unlock(&log_root_tree->log_mutex); 2871 mutex_unlock(&log_root_tree->log_mutex);
2871 ret = root_log_ctx.log_ret; 2872 ret = root_log_ctx.log_ret;
2872 goto out; 2873 goto out;