From patchwork Wed Apr 14 01:33:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naohiro Aota X-Patchwork-Id: 12201703 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 352C6C43470 for ; Wed, 14 Apr 2021 01:34:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1F278613C3 for ; Wed, 14 Apr 2021 01:34:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349076AbhDNBeW (ORCPT ); Tue, 13 Apr 2021 21:34:22 -0400 Received: from esa3.hgst.iphmx.com ([216.71.153.141]:18400 "EHLO esa3.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231878AbhDNBeE (ORCPT ); Tue, 13 Apr 2021 21:34:04 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1618364024; x=1649900024; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=83kyN5f/gaEoADXr8s+jQJ7fslqUI+KQk9/TLXZBRBo=; b=mlECpj3zrJ2/x1Z5CW9xAxvctrMSFgWtbL/iPsqb3TG1xpczgtO7A/Ck F9+UIW8MBugNkJsbUl1M49hdG4/psGQ7JYgeiL9L5sjtboCC5JWT5g2o3 RlZKnT0ilMJyTfi7o4c+9ABPHLqraq0M5rWQNLaDzEKjdLWEv3SpYbLwZ Gy/VBupT4K70mY7gtWtc2wU7rljWlTWyUEqfV/1KjgiX+MS9lGXYC7F9Q 4cmOmMyrBnAMZg6KS4YDfjqnI1hxA3R9tsxEUMjmqLzGVUkjjKOp8vNwY pMHXUPpYCfg7s4MG8I22dG6FEaJY1qucUvczRkHn9hO9kBbBsvkQWeK7Q A==; IronPort-SDR: ySYhUrDisXDAIkWzdJjEVCWHVznuEVGDiuryFKvla6/HEyxwTO8AQeNgFuy+kxQ0pnlGkeKU1T titKB0NKbIHi0/Sp9/xlPy2Gj4xwv5MDbecC498YNjG+LhvfT1Eq/QIHaP9Y6ejVOO23D4JLde a2xR3QbS43zvPBcBpP6gwX8e/k0DVE8x1bOG4fFbTuylbbKf4X/5D2BrJRqiIPd91M6TNuFMKl hJV8pGRUs4nRK+BSiejmmR3hrQsfJn4BZy+L8Lo6elBeKucLiHjrCHaKgRAKC5i0PgMSoflCQ2 7kY= X-IronPort-AV: E=Sophos;i="5.82,221,1613404800"; d="scan'208";a="169210799" Received: from uls-op-cesaip01.wdc.com (HELO uls-op-cesaep01.wdc.com) ([199.255.45.14]) by ob1.hgst.iphmx.com with ESMTP; 14 Apr 2021 09:33:43 +0800 IronPort-SDR: rLWgn+VrCQALg97mW0Ndkt+qISnYihYAXi4weGuMZf4jI5ou9QVjfj0eC8Uzj4ieRNt1bkL5wi mWPXeTgqWsJytvtrzvdZl7HiEkg4aOESiQ6fAdgvCJe3Ikx5bP8ElQP6Wry6aM2OifYya+VKHn 2IlnvKQKWRNZEvtZ6/G/G2O8B9RoYBYEXJmAMilj2WEzRrOD88J7wRdCr7+vfLbOl9Kzm5ujWl MGVbibSrBqR5F9umehFko8H6IDZFdsMTWBzidvZgMJFH/dnr2dztCNvHLB77PKZi/1jG2aH6VE VPPTqqA7GjhAKC+jIkfypFx1 Received: from uls-op-cesaip02.wdc.com ([10.248.3.37]) by uls-op-cesaep01.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Apr 2021 18:14:46 -0700 IronPort-SDR: IvpUHBlcp0DJxhTt2Lwt+nDn3Rn7FiA9B4m/qg8TUxVMcBx0QR5QHvI8NjO93oNNSYTSl9bRgD 9bB76rMPrSA5/ynjrM0c67hFOAYrLa0bihC2DjHW8t9RvVGGBwFZZiTJDn9AROX30s/ma0k2Nz MMfCsIZPO5/vOvs905uE3lqeJNOQH+LgaI8y1aOFNC+qgXEr921mCqr+JFoqMWF1d4UF4tKjWj TXcdpFQUP6ke6kE3bGTjhfagG8LMfyImnM6GKgxVW5WLGTfc7DdXQO8wzprAeHyUOzbjZFVKcv d0c= WDCIronportException: Internal Received: from jpf004864.ad.shared (HELO naota-xeon.wdc.com) ([10.225.53.142]) by uls-op-cesaip02.wdc.com with ESMTP; 13 Apr 2021 18:33:43 -0700 From: Naohiro Aota To: Karel Zak Cc: util-linux@vger.kernel.org, linux-btrfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, Damien Le Moal , Johannes Thumshirn , Naohiro Aota Subject: [PATCH v2 1/3] blkid: implement zone-aware probing Date: Wed, 14 Apr 2021 10:33:37 +0900 Message-Id: <20210414013339.2936229-2-naohiro.aota@wdc.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210414013339.2936229-1-naohiro.aota@wdc.com> References: <20210414013339.2936229-1-naohiro.aota@wdc.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org This patch makes libblkid zone-aware. It can probe the magic located at some offset from the beginning of some specific zone of a device. Ths patch introduces some new fields to struct blkid_idmag. They indicate the magic location is placed related to a zone, and the offset in the zone. Also, this commit introduces `zone_size` to struct blkid_struct_probe. It stores the size of zones of a device. Signed-off-by: Naohiro Aota Reviewed-by: Damien Le Moal Reviewed-by: Johannes Thumshirn --- configure.ac | 1 + libblkid/src/blkidP.h | 5 +++++ libblkid/src/probe.c | 29 +++++++++++++++++++++++++++-- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index bebb4085425a..52b164e834db 100644 --- a/configure.ac +++ b/configure.ac @@ -302,6 +302,7 @@ AC_CHECK_HEADERS([ \ lastlog.h \ libutil.h \ linux/btrfs.h \ + linux/blkzoned.h \ linux/capability.h \ linux/cdrom.h \ linux/falloc.h \ diff --git a/libblkid/src/blkidP.h b/libblkid/src/blkidP.h index a3fe6748a969..e3a160aa97c0 100644 --- a/libblkid/src/blkidP.h +++ b/libblkid/src/blkidP.h @@ -150,6 +150,10 @@ struct blkid_idmag const char *hoff; /* hint which contains byte offset to kboff */ long kboff; /* kilobyte offset of superblock */ unsigned int sboff; /* byte offset within superblock */ + + int is_zoned; /* indicate magic location is calcluated based on zone position */ + long zonenum; /* zone number which has superblock */ + long kboff_inzone; /* kilobyte offset of superblock in a zone */ }; /* @@ -206,6 +210,7 @@ struct blkid_struct_probe dev_t disk_devno; /* devno of the whole-disk or 0 */ unsigned int blkssz; /* sector size (BLKSSZGET ioctl) */ mode_t mode; /* struct stat.sb_mode */ + uint64_t zone_size; /* zone size (BLKGETZONESZ ioctl) */ int flags; /* private library flags */ int prob_flags; /* always zeroized by blkid_do_*() */ diff --git a/libblkid/src/probe.c b/libblkid/src/probe.c index a47a8720d4ac..9d180aab5242 100644 --- a/libblkid/src/probe.c +++ b/libblkid/src/probe.c @@ -94,6 +94,9 @@ #ifdef HAVE_LINUX_CDROM_H #include #endif +#ifdef HAVE_LINUX_BLKZONED_H +#include +#endif #ifdef HAVE_SYS_STAT_H #include #endif @@ -897,6 +900,7 @@ int blkid_probe_set_device(blkid_probe pr, int fd, pr->wipe_off = 0; pr->wipe_size = 0; pr->wipe_chain = NULL; + pr->zone_size = 0; if (fd < 0) return 1; @@ -996,6 +1000,15 @@ int blkid_probe_set_device(blkid_probe pr, int fd, #endif free(dm_uuid); +# ifdef HAVE_LINUX_BLKZONED_H + if (S_ISBLK(sb.st_mode)) { + uint32_t zone_size_sector; + + if (!ioctl(pr->fd, BLKGETZONESZ, &zone_size_sector)) + pr->zone_size = zone_size_sector << 9; + } +# endif + DBG(LOWPROBE, ul_debug("ready for low-probing, offset=%"PRIu64", size=%"PRIu64"", pr->off, pr->size)); DBG(LOWPROBE, ul_debug("whole-disk: %s, regfile: %s", @@ -1064,12 +1077,24 @@ int blkid_probe_get_idmag(blkid_probe pr, const struct blkid_idinfo *id, /* try to detect by magic string */ while(mag && mag->magic) { unsigned char *buf; + uint64_t kboff; uint64_t hint_offset; if (!mag->hoff || blkid_probe_get_hint(pr, mag->hoff, &hint_offset) < 0) hint_offset = 0; - off = hint_offset + ((mag->kboff + (mag->sboff >> 10)) << 10); + /* If the magic is for zoned device, skip non-zoned device */ + if (mag->is_zoned && !pr->zone_size) { + mag++; + continue; + } + + if (!mag->is_zoned) + kboff = mag->kboff; + else + kboff = ((mag->zonenum * pr->zone_size) >> 10) + mag->kboff_inzone; + + off = hint_offset + ((kboff + (mag->sboff >> 10)) << 10); buf = blkid_probe_get_buffer(pr, off, 1024); if (!buf && errno) @@ -1079,7 +1104,7 @@ int blkid_probe_get_idmag(blkid_probe pr, const struct blkid_idinfo *id, buf + (mag->sboff & 0x3ff), mag->len)) { DBG(LOWPROBE, ul_debug("\tmagic sboff=%u, kboff=%ld", - mag->sboff, mag->kboff)); + mag->sboff, kboff)); if (offset) *offset = off + (mag->sboff & 0x3ff); if (res) From patchwork Wed Apr 14 01:33:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naohiro Aota X-Patchwork-Id: 12201699 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6126AC4360C for ; Wed, 14 Apr 2021 01:34:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4DE7E613BD for ; Wed, 14 Apr 2021 01:34:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231878AbhDNBeW (ORCPT ); Tue, 13 Apr 2021 21:34:22 -0400 Received: from esa3.hgst.iphmx.com ([216.71.153.141]:18400 "EHLO esa3.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237624AbhDNBeG (ORCPT ); Tue, 13 Apr 2021 21:34:06 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1618364025; x=1649900025; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=t1/zQNdBSaYeGirxTK0VlosDvsj2KiJySzpDedAB4iU=; b=ef4RIqU+4dGZ6r1DVAwagXRSTmxqx5m8uORzZmvOiPZRkY6XfCOnyZPE 2lJggqnrJa0JnW+t3z/Cb3r3M47pOfo9VOpH9bNXVbbHLtlWYoaspyLvi z0JiST8r7822vWIU8PvbwQejq11JC/UQj2vkOTcXBYainiq3HmOuFGb6x SytUDH77LoHWBx3Nv3Z0C7B7wHIqcQkBEoE7zBWEkyonabJxtvT4rJngq GW4AnTuBWUME1CzlhVHlgRD5k9T18SVb7Tt5sgEjT7S7tp/P8GKz3ABp6 be1fP6mYgwgW14MZ757uhXf1mk2j4K6ZXeYxDasZR/cwB4P3IfOUmxNUM w==; IronPort-SDR: 0G3gvvjEfYyIyccvWjMMetzfVin82fjThLLEw80coe5m1Q3zHy+5VNgvN+wIgbTbvDQhco8EPc 6Ctwy71F+pZjBQNRxfxZupq6XITOrV+60/KSCeIH5moFVi25v9GHELm7IUCy0P5mmRk+6OuWaw HyE4J0gj7iqN7gmNZqEiwxdpZi15FRI4kJQUH/ao4ME5JkfuCN17M9zsTJJNfx5DrmNWvgHnIO De1DsW5s1M77m8vCoxqKmeVuejc/KL1CIedO2C2l90HGOZGTnT2KOxzS2lrJ9JrckEoQG16/BQ 9Xs= X-IronPort-AV: E=Sophos;i="5.82,221,1613404800"; d="scan'208";a="169210801" Received: from uls-op-cesaip01.wdc.com (HELO uls-op-cesaep01.wdc.com) ([199.255.45.14]) by ob1.hgst.iphmx.com with ESMTP; 14 Apr 2021 09:33:45 +0800 IronPort-SDR: Nthx4uEL+JAiEfx/sD7cHXo6ej5iedRkhO2751ekzxbF9CXL3USao+PfQ2t81XfL9sJC64ivlt GTyqYAA7BZ5luqferEUg5QmOwYgZkn3coTPKe9fl6uybXSF1hwcgY3DYv0eg6WvlQkfFe5S2G5 sAgexvfSi8VEprLGyJ20GOJtGYUbvEowRH9S7beOtHGMrzIc9+RIGAAWQF/5wr25RybHk/B66D b9n3z+6RgqL99ab0jdV0rnb6MvlO1exAIxV8PCin4sskgxHyse9kSfSUyKBu64265xMF8v4CUH OsQ33s6T3sLiQBlzg/xvOfCb Received: from uls-op-cesaip02.wdc.com ([10.248.3.37]) by uls-op-cesaep01.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Apr 2021 18:14:48 -0700 IronPort-SDR: TdGyokjCq38g4o07hGIXJmCiCe8w7g1FSf4t4amTFax74VI3VsWU03YkF0a62gcwl/tqiR7m4W 4PFxC+E/S92lqbk0GtomQiNlYQdZ5JI836TgA3zMBtEeOGt3DZ3bDQGxTbrGqHc0cyliUwWSn6 +PFnr60wQPfQrxPDvsN7cGcnISSCW3qzIV9MVGXN3BHUdS8J9g3yUxW9KDTAIVlvbflyj4xqAo nKZlONcPlKxBuWCKZsTWPB/jkSZ6IlrYP6K04tHLs6/1TFBgbFjFlL8X0GJzY7LDQNnLA9iu6D EcE= WDCIronportException: Internal Received: from jpf004864.ad.shared (HELO naota-xeon.wdc.com) ([10.225.53.142]) by uls-op-cesaip02.wdc.com with ESMTP; 13 Apr 2021 18:33:44 -0700 From: Naohiro Aota To: Karel Zak Cc: util-linux@vger.kernel.org, linux-btrfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, Damien Le Moal , Johannes Thumshirn , Naohiro Aota Subject: [PATCH v2 2/3] blkid: add magic and probing for zoned btrfs Date: Wed, 14 Apr 2021 10:33:38 +0900 Message-Id: <20210414013339.2936229-3-naohiro.aota@wdc.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210414013339.2936229-1-naohiro.aota@wdc.com> References: <20210414013339.2936229-1-naohiro.aota@wdc.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org This commit adds zone-aware magics and probing functions for zoned btrfs. Superblock (and its copies) is the only data structure in btrfs with a fixed location on a device. Since we cannot overwrite in a sequential write required zone, we cannot place superblock in the zone. Thus, zoned btrfs use superblock log writing to update superblock on sequential write required zones. It uses two zones as a circular buffer to write updated superblocks. Once the first zone is filled up, start writing into the second buffer. When both zones are filled up and before start writing to the first zone again, it reset the first zone. We can determine the position of the latest superblock by reading write pointer information from a device. One corner case is when both zones are full. For this situation, we read out the last superblock of each zone and compare them to determine which zone is older. The magics can detect a superblock magic ("_BHRfs_M") at the beginning of zone #0 or zone #1 to see if it is zoned btrfs. When both zones are filled up, zoned btrfs reset the first zone to write a new superblock. If btrfs crash at the moment, we do not see a superblock at zone #0. Thus, we need to check not only zone #0 but also zone #1. It also supports temporary magic ("!BHRfS_M") in zone #0. The mkfs.btrfs first writes the temporary superblock to the zone during the mkfs process. It will survive there until the zones are filled up and reset. So, we also need to detect this temporary magic. Finally, this commit extends probe_btrfs() to load the latest superblock determined by the write pointers. Signed-off-by: Naohiro Aota Reviewed-by: Johannes Thumshirn Tested-by: Johannes Thumshirn --- libblkid/src/superblocks/btrfs.c | 185 ++++++++++++++++++++++++++++++- 1 file changed, 184 insertions(+), 1 deletion(-) diff --git a/libblkid/src/superblocks/btrfs.c b/libblkid/src/superblocks/btrfs.c index f0fde700d896..812918ac1f42 100644 --- a/libblkid/src/superblocks/btrfs.c +++ b/libblkid/src/superblocks/btrfs.c @@ -9,6 +9,12 @@ #include #include #include +#include +#include + +#ifdef HAVE_LINUX_BLKZONED_H +#include +#endif #include "superblocks.h" @@ -59,11 +65,176 @@ struct btrfs_super_block { uint8_t label[256]; } __attribute__ ((__packed__)); +#define BTRFS_SUPER_INFO_SIZE 4096 + +/* Number of superblock log zones */ +#define BTRFS_NR_SB_LOG_ZONES 2 + +/* Introduce some macros and types to unify the code with kernel side */ +#define SECTOR_SHIFT 9 + +#define ASSERT(x) assert(x) + +typedef uint64_t u64; +typedef uint64_t sector_t; +typedef uint8_t u8; + +#ifdef HAVE_LINUX_BLKZONED_H +static int sb_write_pointer(int fd, struct blk_zone *zones, u64 *wp_ret) +{ + bool empty[BTRFS_NR_SB_LOG_ZONES]; + bool full[BTRFS_NR_SB_LOG_ZONES]; + sector_t sector; + + ASSERT(zones[0].type != BLK_ZONE_TYPE_CONVENTIONAL && + zones[1].type != BLK_ZONE_TYPE_CONVENTIONAL); + + empty[0] = zones[0].cond == BLK_ZONE_COND_EMPTY; + empty[1] = zones[1].cond == BLK_ZONE_COND_EMPTY; + full[0] = zones[0].cond == BLK_ZONE_COND_FULL; + full[1] = zones[1].cond == BLK_ZONE_COND_FULL; + + /* + * Possible states of log buffer zones + * + * Empty[0] In use[0] Full[0] + * Empty[1] * x 0 + * In use[1] 0 x 0 + * Full[1] 1 1 C + * + * Log position: + * *: Special case, no superblock is written + * 0: Use write pointer of zones[0] + * 1: Use write pointer of zones[1] + * C: Compare super blcoks from zones[0] and zones[1], use the latest + * one determined by generation + * x: Invalid state + */ + + if (empty[0] && empty[1]) { + /* Special case to distinguish no superblock to read */ + *wp_ret = zones[0].start << SECTOR_SHIFT; + return -ENOENT; + } else if (full[0] && full[1]) { + /* Compare two super blocks */ + u8 buf[BTRFS_NR_SB_LOG_ZONES][BTRFS_SUPER_INFO_SIZE]; + struct btrfs_super_block *super[BTRFS_NR_SB_LOG_ZONES]; + int i; + int ret; + + for (i = 0; i < BTRFS_NR_SB_LOG_ZONES; i++) { + u64 bytenr; + + bytenr = ((zones[i].start + zones[i].len) + << SECTOR_SHIFT) - BTRFS_SUPER_INFO_SIZE; + + ret = pread64(fd, buf[i], BTRFS_SUPER_INFO_SIZE, + bytenr); + if (ret != BTRFS_SUPER_INFO_SIZE) + return -EIO; + super[i] = (struct btrfs_super_block *)&buf[i]; + } + + if (super[0]->generation > super[1]->generation) + sector = zones[1].start; + else + sector = zones[0].start; + } else if (!full[0] && (empty[1] || full[1])) { + sector = zones[0].wp; + } else if (full[0]) { + sector = zones[1].wp; + } else { + return -EUCLEAN; + } + *wp_ret = sector << SECTOR_SHIFT; + return 0; +} + +static int sb_log_offset(blkid_probe pr, uint64_t *bytenr_ret) +{ + uint32_t zone_num = 0; + uint32_t zone_size_sector; + struct blk_zone_report *rep; + struct blk_zone *zones; + size_t rep_size; + int ret; + uint64_t wp; + + zone_size_sector = pr->zone_size >> SECTOR_SHIFT; + + rep_size = sizeof(struct blk_zone_report) + sizeof(struct blk_zone) * 2; + rep = malloc(rep_size); + if (!rep) + return -errno; + + memset(rep, 0, rep_size); + rep->sector = zone_num * zone_size_sector; + rep->nr_zones = 2; + + ret = ioctl(pr->fd, BLKREPORTZONE, rep); + if (ret) { + ret = -errno; + goto out; + } + if (rep->nr_zones != 2) { + ret = 1; + goto out; + } + + zones = (struct blk_zone *)(rep + 1); + + if (zones[0].type == BLK_ZONE_TYPE_CONVENTIONAL) { + *bytenr_ret = zones[0].start << SECTOR_SHIFT; + ret = 0; + goto out; + } else if (zones[1].type == BLK_ZONE_TYPE_CONVENTIONAL) { + *bytenr_ret = zones[1].start << SECTOR_SHIFT; + ret = 0; + goto out; + } + + ret = sb_write_pointer(pr->fd, zones, &wp); + if (ret != -ENOENT && ret) { + ret = 1; + goto out; + } + if (ret != -ENOENT) { + if (wp == zones[0].start << SECTOR_SHIFT) + wp = (zones[1].start + zones[1].len) << SECTOR_SHIFT; + wp -= BTRFS_SUPER_INFO_SIZE; + } + *bytenr_ret = wp; + + ret = 0; +out: + free(rep); + + return ret; +} +#endif + static int probe_btrfs(blkid_probe pr, const struct blkid_idmag *mag) { struct btrfs_super_block *bfs; - bfs = blkid_probe_get_sb(pr, mag, struct btrfs_super_block); + if (pr->zone_size) { +#ifdef HAVE_LINUX_BLKZONED_H + uint64_t offset = 0; + int ret; + + ret = sb_log_offset(pr, &offset); + if (ret) + return ret; + bfs = (struct btrfs_super_block *) + blkid_probe_get_buffer(pr, offset, + sizeof(struct btrfs_super_block)); +#else + /* Nothing can be done */ + return 1; +#endif + } else { + bfs = blkid_probe_get_sb(pr, mag, struct btrfs_super_block); + } if (!bfs) return errno ? -errno : 1; @@ -88,6 +259,18 @@ const struct blkid_idinfo btrfs_idinfo = .magics = { { .magic = "_BHRfS_M", .len = 8, .sboff = 0x40, .kboff = 64 }, + /* For zoned btrfs */ + { .magic = "_BHRfS_M", .len = 8, .sboff = 0x40, + .is_zoned = 1, .zonenum = 0, .kboff_inzone = 0 }, + { .magic = "_BHRfS_M", .len = 8, .sboff = 0x40, + .is_zoned = 1, .zonenum = 1, .kboff_inzone = 0 }, + /* + * For zoned btrfs, we also need to detect a temporary superblock + * at zone #0. Mkfs.btrfs creates it in the initialize process. + * It persits until both zones are filled up then reset. + */ + { .magic = "!BHRfS_M", .len = 8, .sboff = 0x40, + .is_zoned = 1, .zonenum = 0, .kboff_inzone = 0 }, { NULL } } }; From patchwork Wed Apr 14 01:33:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naohiro Aota X-Patchwork-Id: 12201701 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1120CC43617 for ; Wed, 14 Apr 2021 01:34:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EB460613C0 for ; Wed, 14 Apr 2021 01:34:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345993AbhDNBeX (ORCPT ); Tue, 13 Apr 2021 21:34:23 -0400 Received: from esa3.hgst.iphmx.com ([216.71.153.141]:18400 "EHLO esa3.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349037AbhDNBeK (ORCPT ); Tue, 13 Apr 2021 21:34:10 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1618364030; x=1649900030; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ysMS2Kknxl6RT6GJVQKK3OyY+VYyJdNtAln3ZU9K/js=; b=lUHPbvZj0mZslJ+YzQKFtIMZ361q41QEmGEhU/xL2dbEM1Waz+dyg6y0 moefvVvnQmtDLO8OWMy6MhmKSfEfc26SvdxMI9plsoeZaAoh5Uv8tWwEm L3KHUTd7s+tAY61bDObp2BZGSVYAegcUwm4tdmccd5hUlUcTj90R6mgAF I7NXBEFwOW1aZMxN8bhAmD7MekyCT2xg9yE357vlYyrQvefJ4iPEYE2pq fK+slGJyRnEYocqjkpas02IEwiFWYC5pTqnIaEqLGlz0Q3ZBrrCDy5jXV vsErBM2iZCi2RPJSCR2nKemCt8U6oKNTCC8/nB/2m8jz0+tiJbTs2+NpQ w==; IronPort-SDR: OZm9K9CleR3Wu/4XUvJD9GkJ8fwqmO2tzcR+SMvewoThEsEyIIphj2pBQArZOQ+Nc7rHhCRlNK eHfVIcEdEtdLUaoYI4EuMTmUQqfjgAq2liq0tEZw5irZmf5lsMQxMTJpkaV2wCUsWdVsuLFaDP d1tw5ErqmsjcaQRaCphhGYq3I5vpFx7QZjAP46snY/rzjy4tMYpJW0Lx851m8XqwFCu+M2lprL pEWb5RWFrPv5Znp5b33CXDMGyZ3gxYwI4D+ByatTewmISJXS51cnFFRMuj34soLPGkutDRoblj 7pE= X-IronPort-AV: E=Sophos;i="5.82,221,1613404800"; d="scan'208";a="169210804" Received: from uls-op-cesaip01.wdc.com (HELO uls-op-cesaep01.wdc.com) ([199.255.45.14]) by ob1.hgst.iphmx.com with ESMTP; 14 Apr 2021 09:33:47 +0800 IronPort-SDR: t/TVvgCgSiFx+dCUSDnGTaOmDm5JT7tWP7F8ZCm3J1wTwLhDV8ftSZrfqBlIEL21F8Yr88dddH mF9H9/heseL38Q8AvLa1cn+glQqsB1qy37nhPFHPVayXTsnxvLIvVgeNXeFuYtlBOcLue4TsWl dKw21hyzgum0urP0+9/UvQDKwnoSsb9q1FQHea3chCiyONKO9Xte24nJP37I7Pc8Zx/Lbk3YYt lWLiun+tpLx/nEbpJ1C0WuOTLDawb1AvIJ4IXmJ0XkuCS87l1ssdA5CYdjWB5m4eygO/JdBpzY wDJb7rTLJluRbbS83yHvasHz Received: from uls-op-cesaip02.wdc.com ([10.248.3.37]) by uls-op-cesaep01.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Apr 2021 18:14:49 -0700 IronPort-SDR: N/cfITB36rmpPLvy1J8sWpHrK8IcoFamkC7dluKdztovi+qnsZXvzw6TFjE4oddjvqQHqN2UJI oJ3PmXIKWbXm4RnLACnmfKJQk4dqa4eTVqCtGFdXNu0ct/9hA+kcvMdWTk20DhIMAmrBetOltw D+GnnqGMh1V30jGRlvwbjKLh5fXdBq+qGks9LEjPPzRy/ElTP8K4dStVwgbXBwtIHP0lub6+uR nkJOC/XqiA2dgYow4TFGO3V+TkMRmgfjoE08ZwHuuNI32WsvDNHER4SGvFZPapc3Mo5vH65Iu5 Iw4= WDCIronportException: Internal Received: from jpf004864.ad.shared (HELO naota-xeon.wdc.com) ([10.225.53.142]) by uls-op-cesaip02.wdc.com with ESMTP; 13 Apr 2021 18:33:46 -0700 From: Naohiro Aota To: Karel Zak Cc: util-linux@vger.kernel.org, linux-btrfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, Damien Le Moal , Johannes Thumshirn , Naohiro Aota Subject: [PATCH v2 3/3] blkid: support zone reset for wipefs Date: Wed, 14 Apr 2021 10:33:39 +0900 Message-Id: <20210414013339.2936229-4-naohiro.aota@wdc.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210414013339.2936229-1-naohiro.aota@wdc.com> References: <20210414013339.2936229-1-naohiro.aota@wdc.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org We cannot overwrite superblock magic in a sequential required zone. So, wipefs cannot work as it is. Instead, this commit implements the wiping by zone resetting. Zone resetting must be done only for a sequential write zone. This is checked by is_conventional(). Signed-off-by: Naohiro Aota Reviewed-by: Damien Le Moal Reviewed-by: Johannes Thumshirn --- libblkid/src/probe.c | 79 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 73 insertions(+), 6 deletions(-) diff --git a/libblkid/src/probe.c b/libblkid/src/probe.c index 9d180aab5242..23c3621627d4 100644 --- a/libblkid/src/probe.c +++ b/libblkid/src/probe.c @@ -107,6 +107,7 @@ #include #include #include +#include #include "blkidP.h" #include "all-io.h" @@ -1228,6 +1229,48 @@ int blkid_do_probe(blkid_probe pr) return rc; } +#ifdef HAVE_LINUX_BLKZONED_H +static int is_conventional(blkid_probe pr, uint64_t offset) +{ + struct blk_zone_report *rep = NULL; + size_t rep_size; + int ret; + uint64_t zone_mask; + + if (!pr->zone_size) + return 1; + + rep_size = sizeof(struct blk_zone_report) + sizeof(struct blk_zone); + rep = calloc(1, rep_size); + if (!rep) + return -1; + + zone_mask = ~(pr->zone_size - 1); + rep->sector = (offset & zone_mask) >> 9; + rep->nr_zones = 1; + ret = ioctl(blkid_probe_get_fd(pr), BLKREPORTZONE, rep); + if (ret) { + free(rep); + return -1; + } + + if (rep->zones[0].type == BLK_ZONE_TYPE_CONVENTIONAL) + ret = 1; + else + ret = 0; + + free(rep); + + return ret; +} +#else +static inline int is_conventional(blkid_probe pr __attribute__((__unused__)), + uint64_t offset __attribute__((__unused__))) +{ + return 1; +} +#endif + /** * blkid_do_wipe: * @pr: prober @@ -1267,6 +1310,7 @@ int blkid_do_wipe(blkid_probe pr, int dryrun) const char *off = NULL; size_t len = 0; uint64_t offset, magoff; + bool conventional; char buf[BUFSIZ]; int fd, rc = 0; struct blkid_chain *chn; @@ -1302,6 +1346,11 @@ int blkid_do_wipe(blkid_probe pr, int dryrun) if (len > sizeof(buf)) len = sizeof(buf); + rc = is_conventional(pr, offset); + if (rc < 0) + return rc; + conventional = rc == 1; + DBG(LOWPROBE, ul_debug( "do_wipe [offset=0x%"PRIx64" (%"PRIu64"), len=%zu, chain=%s, idx=%d, dryrun=%s]\n", offset, offset, len, chn->driver->name, chn->idx, dryrun ? "yes" : "not")); @@ -1309,13 +1358,31 @@ int blkid_do_wipe(blkid_probe pr, int dryrun) if (lseek(fd, offset, SEEK_SET) == (off_t) -1) return -1; - memset(buf, 0, len); - if (!dryrun && len) { - /* wipen on device */ - if (write_all(fd, buf, len)) - return -1; - fsync(fd); + if (conventional) { + memset(buf, 0, len); + + /* wipen on device */ + if (write_all(fd, buf, len)) + return -1; + fsync(fd); + } else { +#ifdef HAVE_LINUX_BLKZONED_H + uint64_t zone_mask = ~(pr->zone_size - 1); + struct blk_zone_range range = { + .sector = (offset & zone_mask) >> 9, + .nr_sectors = pr->zone_size >> 9, + }; + + rc = ioctl(fd, BLKRESETZONE, &range); + if (rc < 0) + return -1; +#else + /* Should not reach here */ + assert(0); +#endif + } + pr->flags &= ~BLKID_FL_MODIF_BUFF; /* be paranoid */ return blkid_probe_step_back(pr);