On 18.08.2017 23:09, josef@xxxxxxxxxxxxxx wrote:
> From: Josef Bacik <jbacik@xxxxxx>
>
> Nikolay reported that generic/273 was failing currently with ENOSPC.
> Turns out this is because we get to the point where the outstanding
> reservations are greater than the pinned space on the fs. This is a
> mistake, previously we used the current reservation amount in
> may_commit_transaction, not the entire outstanding reservation amount.
> Fix this to find the minimum byte size needed to make progress in
> flushing, and pass that into may_commit_transaction. From there we can
> make a smarter decision on whether to commit the transaction or not.
> This fixes the failure in generic/273.
>
How about achieving the same end-goal with this diff. E.g. localising
the changes in may_commit transaction?
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 6ca75dc62a3c..49629266f824 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -4837,6 +4837,13 @@ static void shrink_delalloc(struct btrfs_fs_info
*fs_info, u64 to_reclaim,
}
}
+struct reserve_ticket {
+ u64 bytes;
+ int error;
+ struct list_head list;
+ wait_queue_head_t wait;
+};
+
/**
* maybe_commit_transaction - possibly commit the transaction if its ok to
* @root - the root we're allocating for
@@ -4873,9 +4880,24 @@ static int may_commit_transaction(struct
btrfs_fs_info *fs_info,
if (space_info != delayed_rsv->space_info)
return -ENOSPC;
+ spin_lock(&space_info->lock);
+ if (!list_empty(&space_info->tickets))
+ bytes = list_first_entry(&space_info->tickets,
+ struct reserve_ticket,
+ list)->bytes;
+ else if (!list_empty(&space_info->priority_tickets))
+ bytes = list_first_entry(&space_info->priority_tickets,
+ struct reserve_ticket,
+ list)->bytes;
+ spin_unlock(&space_info->lock);
+
spin_lock(&delayed_rsv->lock);
+ if (delayed_rsv->size > bytes)
+ bytes = 0;
+ else
+ bytes -= delayed_rsv->size;
if (percpu_counter_compare(&space_info->total_bytes_pinned,
- bytes - delayed_rsv->size) < 0) {
+ bytes) < 0) {
spin_unlock(&delayed_rsv->lock);
return -ENOSPC;
}
@@ -4889,13 +4911,6 @@ static int may_commit_transaction(struct
btrfs_fs_info *fs_info,
return btrfs_commit_transaction(trans);
}
-struct reserve_ticket {
- u64 bytes;
- int error;
- struct list_head list;
- wait_queue_head_t wait;
-};
-
/*
* Try to flush some data based on policy set by @state. This is only
advisory
* and may fail for various reasons. The caller is supposed to examine the
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html