From 02f493668ba60181ee49f21e7ea55e388e45aa2a Mon Sep 17 00:00:00 2001 From: Adam Kupczyk Date: Mon, 29 Jan 2024 15:34:18 +0000 Subject: [PATCH] os/bluestore: Modify read/write_bdev_label functions Modify read_bdev_label and write_bdev_label functions to operate on any disk location. Default falls back to original position 0, which is now named BDEV_LABEL_POSITION. Signed-off-by: Adam Kupczyk (cherry picked from commit 8e7b9deb65347b80b5c1ab895654bce6681741ab) --- src/os/bluestore/BlueStore.cc | 68 ++++++++++++++++++++++------- src/os/bluestore/BlueStore.h | 12 +++-- src/os/bluestore/bluestore_common.h | 3 +- 3 files changed, 63 insertions(+), 20 deletions(-) diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index ad2d2bad393..1b942e9b515 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -6472,8 +6472,11 @@ void BlueStore::_close_path() path_fd = -1; } -int BlueStore::_write_bdev_label(CephContext *cct, - const string &path, bluestore_bdev_label_t label) +int BlueStore::_write_bdev_label( + CephContext *cct, + const string &path, + bluestore_bdev_label_t label, + std::vector locations) { dout(10) << __func__ << " path " << path << " label " << label << dendl; bufferlist bl; @@ -6493,26 +6496,43 @@ int BlueStore::_write_bdev_label(CephContext *cct, return fd; } bl.rebuild_aligned_size_and_memory(BDEV_LABEL_BLOCK_SIZE, BDEV_LABEL_BLOCK_SIZE, IOV_MAX); - int r = bl.write_fd(fd); - if (r < 0) { - derr << __func__ << " failed to write to " << path - << ": " << cpp_strerror(r) << dendl; - goto out; + int r = 0; + if (std::find(locations.begin(), locations.end(), BDEV_LABEL_POSITION) == + locations.end()) { + locations.push_back(BDEV_LABEL_POSITION); + } + for (uint64_t position : locations) { + r = bl.write_fd(fd, position); + if (r < 0) { + derr << __func__ << " failed to write to " << path + << ": " << cpp_strerror(r) << dendl; + goto out; + } } r = ::fsync(fd); if (r < 0) { derr << __func__ << " failed to fsync " << path - << ": " << cpp_strerror(r) << dendl; + << ": " << cpp_strerror(r) << dendl; } out: VOID_TEMP_FAILURE_RETRY(::close(fd)); return r; } +/* + Reads bdev label at specific position. -int BlueStore::_read_bdev_label(CephContext* cct, const string &path, - bluestore_bdev_label_t *label) + Returns: + 0 - label read successful + 1 - position outside device + <0 - error +*/ +int BlueStore::_read_bdev_label( + CephContext* cct, + const std::string &path, + bluestore_bdev_label_t *label, + uint64_t disk_position) { - dout(10) << __func__ << dendl; + dout(10) << __func__ << " position=0x" << std::hex << disk_position << std::dec << dendl; int fd = TEMP_FAILURE_RETRY(::open(path.c_str(), O_RDONLY|O_CLOEXEC)); if (fd < 0) { fd = -errno; @@ -6521,14 +6541,32 @@ int BlueStore::_read_bdev_label(CephContext* cct, const string &path, return fd; } bufferlist bl; - int r = bl.read_fd(fd, BDEV_LABEL_BLOCK_SIZE); - VOID_TEMP_FAILURE_RETRY(::close(fd)); + unique_ptr buf(new char[BDEV_LABEL_BLOCK_SIZE]); + struct stat st; + int r = ::fstat(fd, &st); if (r < 0) { - derr << __func__ << " failed to read from " << path - << ": " << cpp_strerror(r) << dendl; + r = -errno; + derr << __func__ << " failed to fstat " << path << ": " << cpp_strerror(r) << dendl; + VOID_TEMP_FAILURE_RETRY(::close(fd)); return r; } + if (st.st_size <= int64_t(disk_position + BDEV_LABEL_BLOCK_SIZE)) { + dout(10) << __func__ << " position=0x" << std::hex << disk_position + << " dev size=0x" << st.st_size << std::dec << dendl; + return 1; + } + r = safe_pread_exact(fd, buf.get(), BDEV_LABEL_BLOCK_SIZE, disk_position); + if (r < 0) { + derr << __func__ << " failed to read from " << path + << " at 0x" << std::hex << disk_position << std::dec + <<": " << cpp_strerror(r) << dendl; + } + VOID_TEMP_FAILURE_RETRY(::close(fd)); + if (r < 0) { + return r; + } + bl.append(buf.get(), BDEV_LABEL_BLOCK_SIZE); uint32_t crc, expected_crc; auto p = bl.cbegin(); try { diff --git a/src/os/bluestore/BlueStore.h b/src/os/bluestore/BlueStore.h index d29531a021e..23f25a12b3b 100644 --- a/src/os/bluestore/BlueStore.h +++ b/src/os/bluestore/BlueStore.h @@ -2763,10 +2763,14 @@ public: return deferred_last_submitted; } - static int _write_bdev_label(CephContext* cct, - const std::string &path, bluestore_bdev_label_t label); - static int _read_bdev_label(CephContext* cct, const std::string &path, - bluestore_bdev_label_t *label); + static int _write_bdev_label( + CephContext* cct, + const std::string &path, + bluestore_bdev_label_t label, + std::vector locations = std::vector(BDEV_LABEL_POSITION)); + static int _read_bdev_label( + CephContext* cct, const std::string &path, + bluestore_bdev_label_t *label, uint64_t disk_position = BDEV_LABEL_POSITION); private: int _check_or_set_bdev_label(std::string path, uint64_t size, std::string desc, bool create); diff --git a/src/os/bluestore/bluestore_common.h b/src/os/bluestore/bluestore_common.h index 1c71c187abc..c266f25946f 100644 --- a/src/os/bluestore/bluestore_common.h +++ b/src/os/bluestore/bluestore_common.h @@ -65,7 +65,8 @@ struct Int64ArrayMergeOperator : public KeyValueDB::MergeOperator { // write a label in the first block. always use this size. note that // bluefs makes a matching assumption about the location of its // superblock (always the second block of the device). -#define BDEV_LABEL_BLOCK_SIZE 4096 +static constexpr uint64_t BDEV_LABEL_POSITION = 0; +static constexpr uint64_t BDEV_LABEL_BLOCK_SIZE = 4096; // reserved for standalone DB volume: // label (4k) + bluefs super (4k), which means we start at 8k. -- 2.39.5