Re: [PATCH 1/2] Btrfs: fix reclaim counter leak of space_info objects

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Apr 07, 2020 at 11:38:49AM +0100, fdmanana@xxxxxxxxxx wrote:
> From: Filipe Manana <fdmanana@xxxxxxxx>
> 
> Whenever we add a ticket to a space_info object we increment the object's
> reclaim_size counter witht the ticket's bytes, and we decrement it with
> the corresponding amount only when we are able to grant the requested
> space to the ticket. When we are not able to grant the space to a ticket,
> or when the ticket is removed due to a signal (e.g. an application has
> received sigterm from the terminal) we never decrement the counter with
> the corresponding bytes from the ticket. This leak can result in the
> space reclaim code to later do much more work than necessary. So fix it
> by decrementing the counter when those two cases happen as well.
> 
> Fixes: db161806dc5615 ("btrfs: account ticket size at add/delete time")
> Signed-off-by: Filipe Manana <fdmanana@xxxxxxxx>

There's a minor conflict with Josef's patch "btrfs: run
btrfs_try_granting_tickets if a priority ticket fails" so I'll apply
yours to misc-5.7 as it's a regression fix.

> @@ -1121,7 +1129,7 @@ static int handle_reserve_ticket(struct btrfs_fs_info *fs_info,
>  		 * either the async reclaim job deletes the ticket from the list
>  		 * or we delete it ourselves at wait_reserve_ticket().
>  		 */
> -		list_del_init(&ticket->list);
> +		remove_ticket(space_info, ticket);
>  		if (!ret)
>  			ret = -ENOSPC;
>  	}

The conflicting hunk is:

--- a/fs/btrfs/space-info.c
+++ b/fs/btrfs/space-info.c
@@ -1156,11 +1156,17 @@ static int handle_reserve_ticket(struct btrfs_fs_info *fs_info,
        ret = ticket->error;
        if (ticket->bytes || ticket->error) {
                /*
-                * Need to delete here for priority tickets. For regular tickets
-                * either the async reclaim job deletes the ticket from the list
-                * or we delete it ourselves at wait_reserve_ticket().
+                * We were a priority ticket, so we need to delete ourselves
+                * from the list.  Because we could have other priority tickets
+                * behind us that require less space, run
+                * btrfs_try_granting_tickets() to see if their reservations can
+                * now be made.
                 */
-               list_del_init(&ticket->list);
+               if (!list_empty(&ticket->list)) {
+                       list_del_init(&ticket->list);
+                       btrfs_try_granting_tickets(fs_info, space_info);
+               }
+
                if (!ret)
                        ret = -ENOSPC;
        }
---

so I assume the correct fixup is to replace list_del_init with
remove_ticket.



[Index of Archives]     [Linux Filesystem Development]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux