]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: Modify read/write_bdev_label functions
authorAdam Kupczyk <akupczyk@ibm.com>
Mon, 29 Jan 2024 15:34:18 +0000 (15:34 +0000)
committerPere Diaz Bou <pere-altea@hotmail.com>
Fri, 23 Aug 2024 09:49:23 +0000 (11:49 +0200)
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 <akupczyk@ibm.com>
(cherry picked from commit 8e7b9deb65347b80b5c1ab895654bce6681741ab)

src/os/bluestore/BlueStore.cc
src/os/bluestore/BlueStore.h
src/os/bluestore/bluestore_common.h

index ad2d2bad3930a31bc51f111a4fd9e3287933872e..1b942e9b515c492052cbbd8cd17bd28b0052aa69 100644 (file)
@@ -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<uint64_t> 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<char> 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 {
index d29531a021e9361b17e08b3b57f4a7a35caec249..23f25a12b3b15967a7c5eb50f9a01ece93ef2188 100644 (file)
@@ -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<uint64_t> locations = std::vector<uint64_t>(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);
index 1c71c187abcc04010469337efbd5f1dd64219feb..c266f25946f54a31b51b1b22eb9a8d0b3ff5c454 100644 (file)
@@ -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.