Commit f4a9c169 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 067c2f47 b7f3c7d3
...@@ -427,6 +427,7 @@ struct btrfs_space_info { ...@@ -427,6 +427,7 @@ struct btrfs_space_info {
struct list_head ro_bgs; struct list_head ro_bgs;
struct list_head priority_tickets; struct list_head priority_tickets;
struct list_head tickets; struct list_head tickets;
u64 tickets_id;
struct rw_semaphore groups_sem; struct rw_semaphore groups_sem;
/* for block groups in our same type */ /* for block groups in our same type */
......
...@@ -4966,12 +4966,12 @@ static void wake_all_tickets(struct list_head *head) ...@@ -4966,12 +4966,12 @@ static void wake_all_tickets(struct list_head *head)
*/ */
static void btrfs_async_reclaim_metadata_space(struct work_struct *work) static void btrfs_async_reclaim_metadata_space(struct work_struct *work)
{ {
struct reserve_ticket *last_ticket = NULL;
struct btrfs_fs_info *fs_info; struct btrfs_fs_info *fs_info;
struct btrfs_space_info *space_info; struct btrfs_space_info *space_info;
u64 to_reclaim; u64 to_reclaim;
int flush_state; int flush_state;
int commit_cycles = 0; int commit_cycles = 0;
u64 last_tickets_id;
fs_info = container_of(work, struct btrfs_fs_info, async_reclaim_work); fs_info = container_of(work, struct btrfs_fs_info, async_reclaim_work);
space_info = __find_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA); 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,8 +4984,7 @@ static void btrfs_async_reclaim_metadata_space(struct work_struct *work)
spin_unlock(&space_info->lock); spin_unlock(&space_info->lock);
return; return;
} }
last_ticket = list_first_entry(&space_info->tickets, last_tickets_id = space_info->tickets_id;
struct reserve_ticket, list);
spin_unlock(&space_info->lock); spin_unlock(&space_info->lock);
flush_state = FLUSH_DELAYED_ITEMS_NR; flush_state = FLUSH_DELAYED_ITEMS_NR;
...@@ -5005,10 +5004,10 @@ static void btrfs_async_reclaim_metadata_space(struct work_struct *work) ...@@ -5005,10 +5004,10 @@ static void btrfs_async_reclaim_metadata_space(struct work_struct *work)
space_info); space_info);
ticket = list_first_entry(&space_info->tickets, ticket = list_first_entry(&space_info->tickets,
struct reserve_ticket, list); struct reserve_ticket, list);
if (last_ticket == ticket) { if (last_tickets_id == space_info->tickets_id) {
flush_state++; flush_state++;
} else { } else {
last_ticket = ticket; last_tickets_id = space_info->tickets_id;
flush_state = FLUSH_DELAYED_ITEMS_NR; flush_state = FLUSH_DELAYED_ITEMS_NR;
if (commit_cycles) if (commit_cycles)
commit_cycles--; commit_cycles--;
...@@ -5384,6 +5383,7 @@ static void space_info_add_old_bytes(struct btrfs_fs_info *fs_info, ...@@ -5384,6 +5383,7 @@ static void space_info_add_old_bytes(struct btrfs_fs_info *fs_info,
list_del_init(&ticket->list); list_del_init(&ticket->list);
num_bytes -= ticket->bytes; num_bytes -= ticket->bytes;
ticket->bytes = 0; ticket->bytes = 0;
space_info->tickets_id++;
wake_up(&ticket->wait); wake_up(&ticket->wait);
} else { } else {
ticket->bytes -= num_bytes; ticket->bytes -= num_bytes;
...@@ -5426,6 +5426,7 @@ static void space_info_add_new_bytes(struct btrfs_fs_info *fs_info, ...@@ -5426,6 +5426,7 @@ static void space_info_add_new_bytes(struct btrfs_fs_info *fs_info,
num_bytes -= ticket->bytes; num_bytes -= ticket->bytes;
space_info->bytes_may_use += ticket->bytes; space_info->bytes_may_use += ticket->bytes;
ticket->bytes = 0; ticket->bytes = 0;
space_info->tickets_id++;
wake_up(&ticket->wait); wake_up(&ticket->wait);
} else { } else {
trace_btrfs_space_reservation(fs_info, "space_info", trace_btrfs_space_reservation(fs_info, "space_info",
...@@ -8216,6 +8217,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans, ...@@ -8216,6 +8217,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
{ {
int ret; int ret;
struct btrfs_block_group_cache *block_group; struct btrfs_block_group_cache *block_group;
struct btrfs_space_info *space_info;
/* /*
* Mixed block groups will exclude before processing the log so we only * 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,9 +8233,14 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
if (!block_group) if (!block_group)
return -EINVAL; return -EINVAL;
ret = btrfs_add_reserved_bytes(block_group, ins->offset, space_info = block_group->space_info;
ins->offset, 0); spin_lock(&space_info->lock);
BUG_ON(ret); /* logic error */ spin_lock(&block_group->lock);
space_info->bytes_reserved += ins->offset;
block_group->reserved += ins->offset;
spin_unlock(&block_group->lock);
spin_unlock(&space_info->lock);
ret = alloc_reserved_file_extent(trans, root, 0, root_objectid, ret = alloc_reserved_file_extent(trans, root, 0, root_objectid,
0, owner, offset, ins, 1); 0, owner, offset, ins, 1);
btrfs_put_block_group(block_group); btrfs_put_block_group(block_group);
......
...@@ -2867,6 +2867,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, ...@@ -2867,6 +2867,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
if (log_root_tree->log_transid_committed >= root_log_ctx.log_transid) { if (log_root_tree->log_transid_committed >= root_log_ctx.log_transid) {
blk_finish_plug(&plug); blk_finish_plug(&plug);
list_del_init(&root_log_ctx.list);
mutex_unlock(&log_root_tree->log_mutex); mutex_unlock(&log_root_tree->log_mutex);
ret = root_log_ctx.log_ret; ret = root_log_ctx.log_ret;
goto out; goto out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment