]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: Fix CBT bluefs-bdev-expand 60363/head
authorAdam Kupczyk <akupczyk@ibm.com>
Wed, 16 Oct 2024 13:43:23 +0000 (13:43 +0000)
committerAdam Kupczyk <akupczyk@ibm.com>
Wed, 16 Oct 2024 19:08:24 +0000 (19:08 +0000)
There was a problem when expansion of 'block' device crossed location
of bdev label copy. The extra label that did not exist before and now
exist was not initialized.

Also changed logic of 'bluestore_bdev_label_require_all'.
Previously label locations 0..bdev->size() were taken in to account.
Now labels in range bdev_label.size..bdev->size() are excluded.

Fixes: https://tracker.ceph.com/issues/68577
Signed-off-by: Adam Kupczyk <akupczyk@ibm.com>
src/os/bluestore/BlueStore.cc

index 44a171873c08cdb4ca8b6e7478df074fccaa9b37..6e284298d0a1c0af6b787bff1b352764a328a088 100644 (file)
@@ -6912,8 +6912,19 @@ int BlueStore::_check_main_bdev_label()
     return -EIO;
   }
   if (bluestore_bdev_label_require_all && r != 0) {
-    derr << __func__ << " not all labels read properly" << dendl;
-    return -EIO;
+    // We are about to complain that some labels failed.
+    // But in case if we expanded block device some labels will not be good.
+    uint64_t lsize = std::max(BDEV_LABEL_BLOCK_SIZE, min_alloc_size);
+    uint32_t valid_locations = 0;
+    for (uint64_t loc : bdev_label_positions) {
+      if (loc + lsize <= bdev_label.size) {
+        ++valid_locations;
+      }
+    }
+    if (valid_locations != bdev_label_valid_locations.size()) {
+      derr << __func__ << " not all labels read properly" << dendl;
+      return -EIO;
+    }
   }
   return 0;
 }
@@ -8949,11 +8960,25 @@ int BlueStore::expand_devices(ostream& out)
     _close_db_and_around();
 
     // mount in read/write to sync expansion changes
+    if (bdev_label_multi) {
+      // We need not do fsck, because we can be broken - size is increased,
+      // but we might not have labels set.
+      cct->_conf.set_val_or_die("bluestore_fsck_on_mount", "false");
+    }
     r = _mount();
     ceph_assert(r == 0);
     if (fm && fm->is_null_manager()) {
       // we grow the allocation range, must reflect it in the allocation file
       alloc->init_add_free(size0, size - size0);
+      if (bdev_label_multi) {
+        uint64_t lsize = std::max(BDEV_LABEL_BLOCK_SIZE, min_alloc_size);
+        for (uint64_t loc : bdev_label_positions) {
+          if ((loc >= size0) && (loc + lsize <= size)) {
+            bdev_label_valid_locations.push_back(loc);
+          }
+        }
+        _write_bdev_label(cct, bdev, path + "/block", bdev_label, bdev_label_valid_locations);
+      }
       need_to_destage_allocation_file = true;
     }
     umount();