From patchwork Tue Apr 13 22:10:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naohiro Aota X-Patchwork-Id: 12201493 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.5 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,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham 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 96135C433ED for ; Tue, 13 Apr 2021 22:11:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7A62C61220 for ; Tue, 13 Apr 2021 22:11:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347184AbhDMWLu (ORCPT ); Tue, 13 Apr 2021 18:11:50 -0400 Received: from esa2.hgst.iphmx.com ([68.232.143.124]:59043 "EHLO esa2.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347217AbhDMWLs (ORCPT ); Tue, 13 Apr 2021 18:11:48 -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=1618351906; x=1649887906; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=gMLLv7zxga9NpYxzVeX9/lyMs74L5yS+qRs7J0Cu344=; b=rBDD4ohw9uz6h8R/Y9boDLx8CWEskLnXgSf4wWmg50ahUnoDbIX018U3 6yln7w1HZSRxC7nylmESi2VRh/EBcRS/1y6kXpV+YwFePN3/zIqI9LfT8 B+vLrsMi3YqsYhKfQGrnaUBeFK1/pfPmzgaGzq9CmHQ1flJYKc9jZwEZC RVd+fb3Yf1kTuyY00b5XDTA0SQL8EAR46FNtXHnPZwgWnUwVUdgv8gNvw aLNOynivB2rig8ppjrGaFCUOiUGjccF2GNOMvUdEnxz6pJz5HNsYBUqx5 E8uJafUfwdJOzA/AdggAxW7xqHiMYJ/JZIG6gHhRagTUlsThN5prLMedh Q==; IronPort-SDR: O5l7iTatSomjV/vDxD6RzGdr32+BiVnRo4hFSadEHg58lwi7Mbf2uZCvNpak/ahzB95FbENLQH PtYwQa819V9UKW8Hn34tJrX/PVBgh/9MU9xt2u2IUCrgawZGM90pS7e2KtLZMqpOs1VeTzWqX6 4dsgQUGnnCD7XGoRIFn8DyjOrvQzpRk0OZqPx7Hcsv9hycWEnHgec/0xxaFZBR2hvIKNjHhEe2 r8oJTm+MmCDgaFegYzAzpt3iO2dMwy596XkWNXm4WOZQGay+xcSzb7AgmKQ6JEDiGcTO5dbD+K DA0= X-IronPort-AV: E=Sophos;i="5.82,220,1613404800"; d="scan'208";a="268872447" 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 06:11:10 +0800 IronPort-SDR: oTBJnWRI04NLhCiQWt+MTV0TVinvTM04jvP4HcPmcskX+yw9jtsZhRTyc3lf8UD4yzuHOqSTra Iz9c5DrTuLx12a2LSjGS7kYhhnVVoUhAT7ADeh7vb4JxJXQHZuI4eqYE3hvOcLtTZClVJVSTE+ yb9nf3Hkfi48S9U7IN9PS6yFMZ1K1BdIwuxXEYpS9gagn6xIY3KTQdsWvznWCfzbLZgNU5qcSP 8+ieuLVnSCfc1+rIQNONJDj1NKl/ogq+XSFcASDDMqGzx+JqzAXWulfYAQdsYLIJdQIHlTIrjY DXvgFZ1439lo4XWU+OyG4HdE Received: from uls-op-cesaip01.wdc.com ([10.248.3.36]) by uls-op-cesaep01.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Apr 2021 14:52:00 -0700 IronPort-SDR: 6F17vYSiViBhohpOk8+Z2LMTtu9dBa9CZPjzWUVlz4rATXIYVKPeG0P3va55VRmxWsyipZH/LJ YJ35UwE3OINdx3riTeIaZ4EM3kqK5jLEI+xt2ex9KlRAuDk8Asuwm86/2G9MUqOwa8PXCxSlof ok6QR8BoARdqm3wjlQirXyZ4GalyiSQiFJ1Adc9IBTOjNx7VyTDQdeiA3Tuaf/VIryDLPX3HD8 JxjamZy8YMnUWDnlWtmWxx/TMexIQfI3c97eZEelJMie0r1KoTXRW5wqTBKVta64fIEbxfKZyO NcA= WDCIronportException: Internal Received: from 39xlxy2.ad.shared (HELO naota-xeon.wdc.com) ([10.225.53.108]) by uls-op-cesaip01.wdc.com with ESMTP; 13 Apr 2021 15:10:56 -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 1/3] blkid: implement zone-aware probing Date: Wed, 14 Apr 2021 07:10:49 +0900 Message-Id: <20210413221051.2600455-2-naohiro.aota@wdc.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210413221051.2600455-1-naohiro.aota@wdc.com> References: <20210413221051.2600455-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 --- configure.ac | 1 + libblkid/src/blkidP.h | 5 +++++ libblkid/src/probe.c | 26 ++++++++++++++++++++++++-- 3 files changed, 30 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..102766e57aa0 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 @@ -871,6 +874,7 @@ int blkid_probe_set_device(blkid_probe pr, int fd, #ifdef CDROM_GET_CAPABILITY long last_written = 0; #endif + uint32_t zone_size_sector; blkid_reset_probe(pr); blkid_probe_reset_buffers(pr); @@ -897,6 +901,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 +1001,11 @@ 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) && !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 +1074,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 +1101,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 Tue Apr 13 22:10:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naohiro Aota X-Patchwork-Id: 12201491 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.5 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,URIBL_BLOCKED,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 E6A7BC43470 for ; Tue, 13 Apr 2021 22:11:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C316C61220 for ; Tue, 13 Apr 2021 22:11:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348612AbhDMWLq (ORCPT ); Tue, 13 Apr 2021 18:11:46 -0400 Received: from esa4.hgst.iphmx.com ([216.71.154.42]:61121 "EHLO esa4.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348606AbhDMWLo (ORCPT ); Tue, 13 Apr 2021 18:11:44 -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=1618351884; x=1649887884; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=hyNh92FJwTcN5aIA5q6FBjo9XhWtYtRSocxvel7oIGw=; b=kZkgW42AVbvRIadmIPt0T/KfzgohBQ5HLTT5x46oGcp1ctlsUseb1svZ dqrTHaiwdqxIaMurliIqmAypRW7MNcHdMjYAzO2AVQ2x6vcHYHYeu2sgt pVBXefDe4dk0m0COfQPZeRXFs6oxPEYOVw9Wy7jFSW91L7IvFsZEdo1WZ LrmfATjgHevxXbmPje6Zg/rQOm5OIc+Yw9gDSVs7SllVKdAqO0zaM5CYb MG5xHnFJGG5Jkfns4tO8yNxfpH2gRd4Onlgfvzk/IkZb7dl2Ar9TnAY4P oyurRoTvdbvrHd4l4RqiMQwCRJy7j966VOV8lDokxq4/k37fY5GRyMohr A==; IronPort-SDR: NqHbA5X8NkwsTo1LnXMhL1jrAWD/Gkwfsbz9kjBKFglkcxbPvrMrKHID4Y5CqxFMpBkjzXluHR GYtnz/T1+klbX/GSWb050GDFkYtHRJbtdhmbLAKf5DkDo6255IQFK/JLyDz18P5rWKZ7KfOcvr avdpDvCO2rWuTHrJfDSQPfo0zawVi0jA+F8pF227tfl4M19uTt8EKkPQPcyQ0JP5tEExnBubp8 yplyfmlq8zt3VtBy2EbXbT1vGnP/dgoKwB8Rj3PyQHllkxDE3mfmJTmMRkoj9J+51HvpQx4joW teQ= X-IronPort-AV: E=Sophos;i="5.82,220,1613404800"; d="scan'208";a="164254961" Received: from h199-255-45-14.hgst.com (HELO uls-op-cesaep01.wdc.com) ([199.255.45.14]) by ob1.hgst.iphmx.com with ESMTP; 14 Apr 2021 06:11:05 +0800 IronPort-SDR: VRIi9vUNPdXo1h6Zl6+3fHQdYGA7DNgOF97UhIdVH6wNMYjU6BvjIIgAlvjpMD9wc1ljh/Nz+n Y9vNP4sK24WAjrLh+5sh/Axdt+gYGrJQJvzL9iWS7/0q7KUAow87K+22tcnOZxpuqbqhTAJ+19 5q428jgXoLy33XOHZQR1xq8YuxNr7mWIsy1e7dxNiqF3HI/8GywkkVypFhpCMnoDBuAQEp85QL 6yOkUggz8kSJYFAHIY8elhmKUV+qIXT5oLho2vyh8XxaunyT03NjdZnafv/UlEgKVtHHsFy2r5 Vb3davD8Sm2KRfc2HSmL9dkO Received: from uls-op-cesaip01.wdc.com ([10.248.3.36]) by uls-op-cesaep01.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Apr 2021 14:52:02 -0700 IronPort-SDR: qbzNBobj0RVXkg61fKOBDz3CU+zXJNsdqzbp5KzwPqMwlqgJLaK65uNR0uaCSVtpS0wE5iljFq +49IWlwwTSu0zAF0N8vtYPiPfyzJ2GnOIyZJC1u0BG46kVKP8q6qJGF5J+nVtAWFlM/DR/JbMZ gD6BIoI8Zh/Q++NX8Jmsu+mreEjWOCYKiQ7vaWTRR/5q1Yw74rnwYGPi2E7Aq6yqWcp2/YEBsi XBrs7ogFqyGutGeRzaqBADlAuo7NNezkcA7DqvaDDM9osDrLljaql4z21BypVFSuj1LY8hoy7M LgY= WDCIronportException: Internal Received: from 39xlxy2.ad.shared (HELO naota-xeon.wdc.com) ([10.225.53.108]) by uls-op-cesaip01.wdc.com with ESMTP; 13 Apr 2021 15:10:58 -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 2/3] blkid: add magic and probing for zoned btrfs Date: Wed, 14 Apr 2021 07:10:50 +0900 Message-Id: <20210413221051.2600455-3-naohiro.aota@wdc.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210413221051.2600455-1-naohiro.aota@wdc.com> References: <20210413221051.2600455-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 --- libblkid/src/superblocks/btrfs.c | 178 ++++++++++++++++++++++++++++++- 1 file changed, 177 insertions(+), 1 deletion(-) diff --git a/libblkid/src/superblocks/btrfs.c b/libblkid/src/superblocks/btrfs.c index f0fde700d896..bce4055054fb 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,169 @@ 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; + +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; +} + static int probe_btrfs(blkid_probe pr, const struct blkid_idmag *mag) { struct btrfs_super_block *bfs; + int ret; - bfs = blkid_probe_get_sb(pr, mag, struct btrfs_super_block); + if (pr->zone_size) { + uint64_t offset = 0; + + 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 { + bfs = blkid_probe_get_sb(pr, mag, struct btrfs_super_block); + } if (!bfs) return errno ? -errno : 1; @@ -88,6 +252,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 Tue Apr 13 22:10:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naohiro Aota X-Patchwork-Id: 12201495 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.5 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,URIBL_BLOCKED,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 1154FC433B4 for ; Tue, 13 Apr 2021 22:11:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E643161246 for ; Tue, 13 Apr 2021 22:11:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348628AbhDMWMI (ORCPT ); Tue, 13 Apr 2021 18:12:08 -0400 Received: from esa4.hgst.iphmx.com ([216.71.154.42]:5817 "EHLO esa4.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348615AbhDMWMG (ORCPT ); Tue, 13 Apr 2021 18:12: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=1618351906; x=1649887906; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=/cFInViD5uKiWQWCCh4dWTsaKAByi7k1gtbm9ZK+N4E=; b=XdlFfOIaMx1Q+U+v0eckWXO795f66SwUycb+ZjhqC3ViqJkbi5+EuTI7 A79maIuUOLRkVUXndu4VrMRiarFxhcd59hiBmbAVJMm6cmMZBnbXaDuoP /Mwnm5rv8iZRndCstkEr40SVOr6qWi9SVjROnuo19UFrSezrlOpt2rbXL xnfZDgD+MR6yM3gaAQJhrkuyxyoge2DMVgPjvVcWEkcXFjZEImOqeB5p/ c8W9XpycRd1Fv6oikzpLy2sCW+0/KIlTPp7TkU1dUVFreHwXUMpyOcjVk P4gBvsqN3vVJE2wpcsErMkoyfeRJo2fKDYJJN2Jl4xNedlL07ZWyd1hE7 Q==; IronPort-SDR: s+6TtNmoCSsinWUJtspmpQm9v7eXTWzunMd/3J9arRy2gquC/OndWCI3mQ0zhWGSTUqpQDlCoa PzwrpIHpBRWqz82yo38xs2UqtL1m1+gK3iI6fED0pZWNbic6nVJxdb4k0yFdNUgt9FvzvnfHnB hGuGhX1A7PKQupjhoCBh8VQlkNZGxrQGRQz4r8N3JANCsX3ZOf5ohbdAxsPfGwI1VWsw3U/bVZ jSnkVdx+aIBqjruPSONPALS16eSEtK41r28q5hOsyE8eTbF23Qo2WuAxWvMLqi0Tc08wBNl9Tr ih8= X-IronPort-AV: E=Sophos;i="5.82,220,1613404800"; d="scan'208";a="164254976" Received: from h199-255-45-14.hgst.com (HELO uls-op-cesaep01.wdc.com) ([199.255.45.14]) by ob1.hgst.iphmx.com with ESMTP; 14 Apr 2021 06:11:27 +0800 IronPort-SDR: U+3K6gRHqMzFrxx6B9J0/UHzn3BY3gqEg0uyVUpV2s3oPVjL8lzGCqOjjpHoXhgP1iy024VPKa AifezWSAT0yx6VOGy/tpAMKfGR1vOWVC2NBwIjx3VIUTH1EwqtYyJVhwnUXaZElclFJkSNTHOP y72yVRjhR8Tf4sDoxliDjl0wF+6jnkGiEsh/q+kRaPRPJcFTO9at3F0s4Az00OLWx851TfVIJF KCQfTCuMmWBp4o/gkXYx/DDT2HXX/mRIQI0BzBn932DGv4Dr8GVFvPXcm02tzyLPYSoRDDov9M eMMoyydQ/8SabkW3DUd65q/t Received: from uls-op-cesaip01.wdc.com ([10.248.3.36]) by uls-op-cesaep01.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Apr 2021 14:52:04 -0700 IronPort-SDR: DLOAUPh1EDMXm84y7UMyBlzr40f98K8xkvsxdPUoBhO2UXt7CXjOK8l6NZaquup9uGO0l/CekZ EOAs9xEZKh5e7YRbBjTaTg/ET/pzewalF2Yc0+AjJfTCiWTWQ9eBsmXHfozvlPt4W+voevGdNM isOJshnzawZvYnH25smuJyVhD9xqblC0jnlvMQFFOErzWY7BVyLedwEBmkK7cczksuyY2fk9b1 +kN5dnvqWdhHUwXVHzL6uoqE/4hdxT8ptI/EFZkK6yAZq9e4O/q2Jq26M0P/Hm4y2pthk+/Fet o0E= WDCIronportException: Internal Received: from 39xlxy2.ad.shared (HELO naota-xeon.wdc.com) ([10.225.53.108]) by uls-op-cesaip01.wdc.com with ESMTP; 13 Apr 2021 15:10:59 -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 3/3] blkid: support zone reset for wipefs Date: Wed, 14 Apr 2021 07:10:51 +0900 Message-Id: <20210413221051.2600455-4-naohiro.aota@wdc.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210413221051.2600455-1-naohiro.aota@wdc.com> References: <20210413221051.2600455-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 --- libblkid/src/probe.c | 65 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/libblkid/src/probe.c b/libblkid/src/probe.c index 102766e57aa0..7454a14bdfe6 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" @@ -1225,6 +1226,40 @@ int blkid_do_probe(blkid_probe pr) return rc; } +static int is_conventional(blkid_probe pr, uint64_t offset) +{ + struct blk_zone_report *rep = NULL; + size_t rep_size; + bool conventional; + int ret; + + if (!pr->zone_size) + return 1; + + rep_size = sizeof(struct blk_zone_report) + sizeof(struct blk_zone); + rep = malloc(rep_size); + if (!rep) + return -1; + + memset(rep, 0, rep_size); + rep->sector = (offset & pr->zone_size) >> 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; +} + /** * blkid_do_wipe: * @pr: prober @@ -1264,6 +1299,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; @@ -1299,6 +1335,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")); @@ -1306,13 +1347,25 @@ 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 { + struct blk_zone_range range = { + (offset & pr->zone_size) >> 9, + pr->zone_size >> 9, + }; + + rc = ioctl(fd, BLKRESETZONE, &range); + if (rc < 0) + return -1; + } + pr->flags &= ~BLKID_FL_MODIF_BUFF; /* be paranoid */ return blkid_probe_step_back(pr);