Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp7013663ybi; Thu, 13 Jun 2019 08:09:34 -0700 (PDT) X-Google-Smtp-Source: APXvYqzK649i8SYtZHw1Xj3hK8ZfqUmWV0XfpSXo1bv8atLWReRE1qsCkZRthvJbOD9ia7o0eget X-Received: by 2002:a63:a41:: with SMTP id z1mr30542342pgk.389.1560438574614; Thu, 13 Jun 2019 08:09:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1560438574; cv=none; d=google.com; s=arc-20160816; b=AXCrBjYBIlPErmdm6xy/IouJRhFhdz8r/qfKtO7fYAt4IAJpLxAfpZ7tOR2KldBDT9 qWy7mUDJCKP4EWlehlcBju/Omo6+7uLpsKgLGPrm295z+gNyjNVtJH6D4BznqvKgKHrQ GoLEX96qVQgnv6fdfe8C6mw+6QIubW/juB3QQt990xz+iLuKz+P0nZRz6OUMUxsb1R8+ X/dZcdHOXug81WoMsZHKr76z/YKGiTs2XChATb7ZJhPRkfSIQvefbt6wyRPbXutnHn73 QsMIcxbXU4BXeerxL+/DD86HsvsGOL1zegxk69z04wskmActgRfYRW5jEHkHXeAJwaJu W72A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date:dkim-signature; bh=7/wwP73Rmwv2oX6WgY9L8tV3nZFxh0BFz9mVMjZ9eDw=; b=EKyA2ifwVZjxCkzm0G31zoJ84CVwzqWTsL59uyo1jkg9YDUcpTbLKDNU/e6VAGoWI0 zmTpLJi/6Ob/z3ohoAq/dWd2htpyPtIuIwmYmDXxJdQlCHpTFKZx2mhvv/Ewijf20KMZ hZlfu5xPOMOYSbb1eo50pIzlPmrrF5zdDkGpkWSc/aHQQk4nsasUpSPpNenNHi0XXLUq R4GilLz7IDn9deh30iYl3HhKwOkaYrWaYHahwcqP0zxrjlN8nWUYqmDxt5lTbPjLAEfV GZMgSkki/1u3k5d0MS+WVN9/NOYiVj8B/Co5Lprbf12Thjih6GaOs15Et9D6Qj78ehxN jBvg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@toxicpanda-com.20150623.gappssmtp.com header.s=20150623 header.b=zN0eaAjB; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p22si3365043plr.160.2019.06.13.08.09.19; Thu, 13 Jun 2019 08:09:34 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@toxicpanda-com.20150623.gappssmtp.com header.s=20150623 header.b=zN0eaAjB; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727137AbfFMPIt (ORCPT + 99 others); Thu, 13 Jun 2019 11:08:49 -0400 Received: from mail-qt1-f196.google.com ([209.85.160.196]:39816 "EHLO mail-qt1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732372AbfFMN7C (ORCPT ); Thu, 13 Jun 2019 09:59:02 -0400 Received: by mail-qt1-f196.google.com with SMTP id i34so22616142qta.6 for ; Thu, 13 Jun 2019 06:59:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=7/wwP73Rmwv2oX6WgY9L8tV3nZFxh0BFz9mVMjZ9eDw=; b=zN0eaAjBRKEAF7wyunO1c81hHLsBqXRf5wBu9ZgU/KA+UCJSSOU4KTjShEqxMgNa9H KGUP+TxWE86lLkh8Zq+SDlaT8zLSHBvJvyxR7qaraxPNNYdW5+Z+bX2QTiOSzDLCzoBv 0Ccc3wtPcgDejXXkxAhFEOo5DgVe2VyuBRpUob2F2mAI4eoI3/z7ccMnvBhsDRkjZFfz HlYNbyhNLFyhf34e0avcBMYc8eW1W3n4lPiYcPNzCsqKp1E6hITw6Q9CQ2L1C6kZkXdj kYAK+ftGhNJEkrMzTgCE8jbkkjgvowhwiu648WHuUrWPblLpyoin9POEyRkuhWyNTvwL yvxw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=7/wwP73Rmwv2oX6WgY9L8tV3nZFxh0BFz9mVMjZ9eDw=; b=oxndynrb2lZ3uR6LMnvgT3lQY+7tuyKLnYtkvcQwhT2DNP5OasyDrwNJ8/XqnGtURA 6a39X0dQWzRnGMttNwTAb7FN8AKuRhmRKzGfNJz73EM92if/N1RTsGN4WIdQNjgoCVdD 1HDB4FDmh850RPLd3goXH9n3QUJ/1bT6+cVk5gl1Np2VGs+q3y3sf2xDSgcZ/PFHEZ0S sLQVaKY6bTlOsB2SqeqYmTugCK0AhmrPUYp9YVSjDbhVuTbEtEcZQwevs8H9npxA6gVh dU07qxqtGoFtBK60/S/2YEfH0hE7rKiiCFHfbAxhabVHqKyPSmL+Cx/xFIASw5htoMyn 3mjA== X-Gm-Message-State: APjAAAV8dxXMA5W3A8jvTrVjBCjudv+vHjvkSsz53MuNqT4pcSjRJqWT QDoebOR87t62cgOKJl42Y+OvRA== X-Received: by 2002:ac8:152:: with SMTP id f18mr72304199qtg.84.1560434340859; Thu, 13 Jun 2019 06:59:00 -0700 (PDT) Received: from localhost ([2620:10d:c091:480::9d6b]) by smtp.gmail.com with ESMTPSA id u7sm1404209qkh.61.2019.06.13.06.58.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 13 Jun 2019 06:59:00 -0700 (PDT) Date: Thu, 13 Jun 2019 09:58:59 -0400 From: Josef Bacik To: Naohiro Aota Cc: linux-btrfs@vger.kernel.org, David Sterba , Chris Mason , Josef Bacik , Qu Wenruo , Nikolay Borisov , linux-kernel@vger.kernel.org, Hannes Reinecke , linux-fsdevel@vger.kernel.org, Damien Le Moal , Matias =?utf-8?B?QmrDuHJsaW5n?= , Johannes Thumshirn , Bart Van Assche Subject: Re: [PATCH 02/19] btrfs: Get zone information of zoned block devices Message-ID: <20190613135858.re7jp6tsfjpg2pnl@MacBook-Pro-91.local> References: <20190607131025.31996-1-naohiro.aota@wdc.com> <20190607131025.31996-3-naohiro.aota@wdc.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20190607131025.31996-3-naohiro.aota@wdc.com> User-Agent: NeoMutt/20180716 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, Jun 07, 2019 at 10:10:08PM +0900, Naohiro Aota wrote: > If a zoned block device is found, get its zone information (number of zones > and zone size) using the new helper function btrfs_get_dev_zonetypes(). To > avoid costly run-time zone report commands to test the device zones type > during block allocation, attach the seqzones bitmap to the device structure > to indicate if a zone is sequential or accept random writes. > > This patch also introduces the helper function btrfs_dev_is_sequential() to > test if the zone storing a block is a sequential write required zone. > > Signed-off-by: Damien Le Moal > Signed-off-by: Naohiro Aota > --- > fs/btrfs/volumes.c | 143 +++++++++++++++++++++++++++++++++++++++++++++ > fs/btrfs/volumes.h | 33 +++++++++++ > 2 files changed, 176 insertions(+) > > diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c > index 1c2a6e4b39da..b673178718e3 100644 > --- a/fs/btrfs/volumes.c > +++ b/fs/btrfs/volumes.c > @@ -786,6 +786,135 @@ static int btrfs_free_stale_devices(const char *path, > return ret; > } > > +static int __btrfs_get_dev_zones(struct btrfs_device *device, u64 pos, > + struct blk_zone **zones, > + unsigned int *nr_zones, gfp_t gfp_mask) > +{ > + struct blk_zone *z = *zones; > + int ret; > + > + if (!z) { > + z = kcalloc(*nr_zones, sizeof(struct blk_zone), GFP_KERNEL); > + if (!z) > + return -ENOMEM; > + } > + > + ret = blkdev_report_zones(device->bdev, pos >> SECTOR_SHIFT, > + z, nr_zones, gfp_mask); > + if (ret != 0) { > + btrfs_err(device->fs_info, "Get zone at %llu failed %d\n", > + pos, ret); > + return ret; > + } > + > + *zones = z; > + > + return 0; > +} > + > +static void btrfs_destroy_dev_zonetypes(struct btrfs_device *device) > +{ > + kfree(device->seq_zones); > + kfree(device->empty_zones); > + device->seq_zones = NULL; > + device->empty_zones = NULL; > + device->nr_zones = 0; > + device->zone_size = 0; > + device->zone_size_shift = 0; > +} > + > +int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos, > + struct blk_zone *zone, gfp_t gfp_mask) > +{ > + unsigned int nr_zones = 1; > + int ret; > + > + ret = __btrfs_get_dev_zones(device, pos, &zone, &nr_zones, gfp_mask); > + if (ret != 0 || !nr_zones) > + return ret ? ret : -EIO; > + > + return 0; > +} > + > +int btrfs_get_dev_zonetypes(struct btrfs_device *device) > +{ > + struct block_device *bdev = device->bdev; > + sector_t nr_sectors = bdev->bd_part->nr_sects; > + sector_t sector = 0; > + struct blk_zone *zones = NULL; > + unsigned int i, n = 0, nr_zones; > + int ret; > + > + device->zone_size = 0; > + device->zone_size_shift = 0; > + device->nr_zones = 0; > + device->seq_zones = NULL; > + device->empty_zones = NULL; > + > + if (!bdev_is_zoned(bdev)) > + return 0; > + > + device->zone_size = (u64)bdev_zone_sectors(bdev) << SECTOR_SHIFT; > + device->zone_size_shift = ilog2(device->zone_size); > + device->nr_zones = nr_sectors >> ilog2(bdev_zone_sectors(bdev)); > + if (nr_sectors & (bdev_zone_sectors(bdev) - 1)) > + device->nr_zones++; > + > + device->seq_zones = kcalloc(BITS_TO_LONGS(device->nr_zones), > + sizeof(*device->seq_zones), GFP_KERNEL); > + if (!device->seq_zones) > + return -ENOMEM; > + > + device->empty_zones = kcalloc(BITS_TO_LONGS(device->nr_zones), > + sizeof(*device->empty_zones), GFP_KERNEL); > + if (!device->empty_zones) > + return -ENOMEM; > + > +#define BTRFS_REPORT_NR_ZONES 4096 > + > + /* Get zones type */ > + while (sector < nr_sectors) { > + nr_zones = BTRFS_REPORT_NR_ZONES; > + ret = __btrfs_get_dev_zones(device, sector << SECTOR_SHIFT, > + &zones, &nr_zones, GFP_KERNEL); > + if (ret != 0 || !nr_zones) { > + if (!ret) > + ret = -EIO; > + goto out; > + } > + > + for (i = 0; i < nr_zones; i++) { > + if (zones[i].type == BLK_ZONE_TYPE_SEQWRITE_REQ) > + set_bit(n, device->seq_zones); > + if (zones[i].cond == BLK_ZONE_COND_EMPTY) > + set_bit(n, device->empty_zones); > + sector = zones[i].start + zones[i].len; > + n++; > + } > + } > + > + if (n != device->nr_zones) { > + btrfs_err(device->fs_info, > + "Inconsistent number of zones (%u / %u)\n", n, > + device->nr_zones); > + ret = -EIO; > + goto out; > + } > + > + btrfs_info(device->fs_info, > + "host-%s zoned block device, %u zones of %llu sectors\n", > + bdev_zoned_model(bdev) == BLK_ZONED_HM ? "managed" : "aware", > + device->nr_zones, device->zone_size >> SECTOR_SHIFT); > + > +out: > + kfree(zones); > + > + if (ret) > + btrfs_destroy_dev_zonetypes(device); > + > + return ret; > +} > + > static int btrfs_open_one_device(struct btrfs_fs_devices *fs_devices, > struct btrfs_device *device, fmode_t flags, > void *holder) > @@ -842,6 +971,11 @@ static int btrfs_open_one_device(struct btrfs_fs_devices *fs_devices, > clear_bit(BTRFS_DEV_STATE_IN_FS_METADATA, &device->dev_state); > device->mode = flags; > > + /* Get zone type information of zoned block devices */ > + ret = btrfs_get_dev_zonetypes(device); > + if (ret != 0) > + goto error_brelse; > + > fs_devices->open_devices++; > if (test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state) && > device->devid != BTRFS_DEV_REPLACE_DEVID) { > @@ -1243,6 +1377,7 @@ static void btrfs_close_bdev(struct btrfs_device *device) > } > > blkdev_put(device->bdev, device->mode); > + btrfs_destroy_dev_zonetypes(device); > } > > static void btrfs_close_one_device(struct btrfs_device *device) > @@ -2664,6 +2799,13 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path > mutex_unlock(&fs_info->chunk_mutex); > mutex_unlock(&fs_devices->device_list_mutex); > > + /* Get zone type information of zoned block devices */ > + ret = btrfs_get_dev_zonetypes(device); > + if (ret) { > + btrfs_abort_transaction(trans, ret); > + goto error_sysfs; > + } > + > if (seeding_dev) { > mutex_lock(&fs_info->chunk_mutex); > ret = init_first_rw_device(trans); > @@ -2729,6 +2871,7 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path > return ret; > > error_sysfs: > + btrfs_destroy_dev_zonetypes(device); > btrfs_sysfs_rm_device_link(fs_devices, device); > mutex_lock(&fs_info->fs_devices->device_list_mutex); > mutex_lock(&fs_info->chunk_mutex); > diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h > index b8a0e8d0672d..1599641e216c 100644 > --- a/fs/btrfs/volumes.h > +++ b/fs/btrfs/volumes.h > @@ -62,6 +62,16 @@ struct btrfs_device { > > struct block_device *bdev; > > + /* > + * Number of zones, zone size and types of zones if bdev is a > + * zoned block device. > + */ > + u64 zone_size; > + u8 zone_size_shift; > + u32 nr_zones; > + unsigned long *seq_zones; > + unsigned long *empty_zones; > + Also make a struct btrfs_zone_info and have a pointer to one here if we have zone devices. Thanks, Josef