From patchwork Wed Jan 30 14:51:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolay Borisov X-Patchwork-Id: 10788737 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 08F32746 for ; Wed, 30 Jan 2019 14:51:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EC2E92F430 for ; Wed, 30 Jan 2019 14:51:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EA4012F436; Wed, 30 Jan 2019 14:51:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7E1C52F435 for ; Wed, 30 Jan 2019 14:51:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726915AbfA3OvL (ORCPT ); Wed, 30 Jan 2019 09:51:11 -0500 Received: from mx2.suse.de ([195.135.220.15]:38122 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1731441AbfA3OvK (ORCPT ); Wed, 30 Jan 2019 09:51:10 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id BDC32B0BA for ; Wed, 30 Jan 2019 14:51:08 +0000 (UTC) From: Nikolay Borisov To: linux-btrfs@vger.kernel.org Cc: jeffm@suse.com, Nikolay Borisov Subject: [PATCH 15/15] btrfs: Switch btrfs_trim_free_extents to find_first_clear_extent_bit Date: Wed, 30 Jan 2019 16:51:02 +0200 Message-Id: <20190130145102.4708-16-nborisov@suse.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190130145102.4708-1-nborisov@suse.com> References: <20190130145102.4708-1-nborisov@suse.com> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Instead of always calling the allocator to search for a free extent, that satisfies the input criteria, switch btrfs_trim_free_extents to using find_first_clear_extent_bit. With this change it's no longer necessary to read the device tree in order to figure out holes in the devices. Now the code always searches in-memory data structure to figure out the space range which contains the requested which should result in speed oups. Signed-off-by: Nikolay Borisov --- fs/btrfs/extent-tree.c | 87 ++++++++++++------------------------------ 1 file changed, 24 insertions(+), 63 deletions(-) diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index f5005ef39f98..7a2b144bdb76 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -11127,54 +11127,6 @@ int btrfs_error_unpin_extent_range(struct btrfs_fs_info *fs_info, return unpin_extent_range(fs_info, start, end, false); } -static bool should_skip_trim(struct btrfs_device *device, u64 *start, u64 *len) -{ - u64 trimmed_start = 0, trimmed_end = 0; - u64 end = *start + *len - 1; - - if (!find_first_extent_bit(&device->alloc_state, *start, &trimmed_start, - &trimmed_end, CHUNK_TRIMMED, NULL)) { - u64 trimmed_len = trimmed_end - trimmed_start + 1; - - if (*start < trimmed_start) { - if (in_range(end, trimmed_start, trimmed_len) || - end > trimmed_end) { - /* - * start|------|end - * ts|--|trimmed_len - * OR - * start|-----|end - * ts|-----|trimmed_len - */ - *len = trimmed_start - *start; - return false; - } else if (end < trimmed_start) { - /* - * start|------|end - * ts|--|trimmed_len - */ - return false; - } - } else if (in_range(*start, trimmed_start, trimmed_len)) { - if (in_range(end, trimmed_start, trimmed_len)) { - /* - * start|------|end - * ts|----------|trimmed_len - */ - return true; - } else { - /* - * start|-----------|end - * ts|----------|trimmed_len - */ - *start = trimmed_end + 1; - *len = end - *start + 1; - return false; - } - } - } - return false; -} /* * It used to be that old block groups would be left around forever. * Iterating over them would be enough to trim unused space. Since we @@ -11198,7 +11150,7 @@ static bool should_skip_trim(struct btrfs_device *device, u64 *start, u64 *len) static int btrfs_trim_free_extents(struct btrfs_device *device, struct fstrim_range *range, u64 *trimmed) { - u64 start = range->start, len = 0; + u64 start = range->start, len = 0, end = 0; int ret; *trimmed = 0; @@ -11225,34 +11177,43 @@ static int btrfs_trim_free_extents(struct btrfs_device *device, if (ret) break; - ret = find_free_dev_extent_start(device, range->minlen, start, - &start, &len); - + ret = find_first_clear_extent_bit(&device->alloc_state, start, + &start, &end, + CHUNK_TRIMMED | CHUNK_ALLOCATED); if (ret) { mutex_unlock(&fs_info->chunk_mutex); - if (ret == -ENOSPC) - ret = 0; + ret = 0; break; } + /* If find_first_clear_extent_bit find a range that spans the + * end of the device it will set end to -1, in this case it's up + * to the caller to trim the value to the size of the device. + */ + end = min(end, device->total_bytes); + len = end - start + 1; + + /* Keep going until we satisfy minlen or reach end of space */ + if (len < range->minlen) { + mutex_unlock(&fs_info->chunk_mutex); + start += len; + continue; + } /* If we are out of the passed range break */ if (start > range->start + range->len - 1) { mutex_unlock(&fs_info->chunk_mutex); - ret = 0; break; } start = max(range->start, start); len = min(range->len, len); - if (!should_skip_trim(device, &start, &len)) { - ret = btrfs_issue_discard(device->bdev, start, len, - &bytes); - if (!ret) - set_extent_bits(&device->alloc_state, start, - start + bytes - 1, - CHUNK_TRIMMED); - } + ret = btrfs_issue_discard(device->bdev, start, len, + &bytes); + if (!ret) + set_extent_bits(&device->alloc_state, start, + start + bytes - 1, + CHUNK_TRIMMED); mutex_unlock(&fs_info->chunk_mutex); if (ret)