return res;
}
-int BlueStore::_set_bdev_label_size(const string& path, uint64_t size)
-{
- bluestore_bdev_label_t label;
- int r = _read_bdev_label(cct, path, &label);
- if (r < 0) {
- derr << "unable to read label for " << path << ": "
- << cpp_strerror(r) << dendl;
- } else {
- label.size = size;
- r = _write_bdev_label(cct, path, label);
- if (r < 0) {
- derr << "unable to write label for " << path << ": "
- << cpp_strerror(r) << dendl;
- }
- }
- return r;
-}
-
int BlueStore::expand_devices(ostream& out)
{
int r = _open_db_and_around(true);
ceph_assert(r == 0);
bluefs->dump_block_extents(out);
out << "Expanding DB/WAL..." << std::endl;
+ // updating dedicated devices first
for (auto devid : { BlueFS::BDEV_WAL, BlueFS::BDEV_DB}) {
- if (devid == bluefs_layout.shared_bdev ) {
+ if (devid == bluefs_layout.shared_bdev) {
continue;
}
uint64_t size = bluefs->get_block_device_size(devid);
// no bdev
continue;
}
-
- out << devid
- <<" : expanding " << " to 0x" << size << std::dec << std::endl;
- string p = get_device_path(devid);
- const char* path = p.c_str();
- if (path == nullptr) {
- derr << devid
- <<": can't find device path " << dendl;
- continue;
- }
if (bluefs->bdev_support_label(devid)) {
- if (_set_bdev_label_size(p, size) >= 0) {
- out << devid
- << " : size label updated to " << size
- << std::endl;
+ string my_path = get_device_path(devid);
+ bluestore_bdev_label_t my_label;
+ int r = _read_bdev_label(cct, my_path, &my_label);
+ if (r < 0) {
+ derr << "unable to read label for " << my_path << ": "
+ << cpp_strerror(r) << dendl;
+ continue;
+ } else {
+ if (size == my_label.size) {
+ // no need to expand
+ out << devid
+ << " : nothing to do, skipped"
+ << std::endl;
+ continue;
+ } else if (size < my_label.size) {
+ // something weird in bdev label
+ out << devid
+ <<" : ERROR: bdev label is above device size, skipped"
+ << std::endl;
+ continue;
+ } else {
+ my_label.size = size;
+ out << devid
+ << " : Expanding to 0x" << std::hex << size
+ << std::dec << "(" << byte_u_t(size) << ")"
+ << std::endl;
+ r = _write_bdev_label(cct, my_path, my_label);
+ if (r < 0) {
+ derr << "unable to write label for " << my_path << ": "
+ << cpp_strerror(r) << dendl;
+ } else {
+ out << devid
+ << " : size updated to 0x" << std::hex << size
+ << std::dec << "(" << byte_u_t(size) << ")"
+ << std::endl;
+ }
+ }
}
}
}
+ // now proceed with a shared device
uint64_t size0 = fm->get_size();
uint64_t size = bdev->get_size();
- if (size0 < size) {
- out << bluefs_layout.shared_bdev
- << " : expanding " << " from 0x" << std::hex
- << size0 << " to 0x" << size << std::dec << std::endl;
- _write_out_fm_meta(size);
- string p = get_device_path(bluefs_layout.shared_bdev);
- if (bdev->supported_bdev_label()) {
- if (_set_bdev_label_size(p, size) >= 0) {
- out << bluefs_layout.shared_bdev
- << " : size label updated to " << size
- << std::endl;
+ auto devid = bluefs_layout.shared_bdev;
+ auto aligned_size = p2align(size, min_alloc_size);
+ if (aligned_size == size0) {
+ // no need to expand
+ out << devid
+ << " : nothing to do, skipped"
+ << std::endl;
+ } else if (aligned_size < size0) {
+ // something weird in bdev label
+ out << devid
+ << " : ERROR: previous device size is above the current one, skipped"
+ << std::endl;
+ } else {
+ auto my_path = get_device_path(devid);
+ out << devid
+ <<" : Expanding to 0x" << std::hex << size
+ << std::dec << "(" << byte_u_t(size) << ")"
+ << std::endl;
+ r = _write_out_fm_meta(size);
+ if (r != 0) {
+ derr << "unable to write out fm meta for " << my_path << ": "
+ << cpp_strerror(r) << dendl;
+ } else if (bdev->supported_bdev_label()) {
+ bluestore_bdev_label_t my_label;
+ int r = _read_bdev_label(cct, my_path, &my_label);
+ if (r < 0) {
+ derr << "unable to read label for " << my_path << ": "
+ << cpp_strerror(r) << dendl;
+ } else {
+ my_label.size = size;
+ r = _write_bdev_label(cct, my_path, my_label);
+ if (r < 0) {
+ derr << "unable to write label(s) for " << my_path << ": "
+ << cpp_strerror(r) << dendl;
+ }
}
}
- _close_db_and_around();
+ if (r == 0) {
+ out << devid
+ << " : size updated to 0x" << std::hex << size
+ << std::dec << "(" << byte_u_t(size) << ")"
+ << std::endl;
+ _close_db_and_around();
- // mount in read/write to sync expansion changes
- 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);
- need_to_destage_allocation_file = true;
+ // mount in read/write to sync expansion changes
+ r = _open_db_and_around(false);
+ 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);
+ need_to_destage_allocation_file = true;
+ }
}
- umount();
- } else {
- _close_db_and_around();
}
+ _close_db_and_around();
return r;
}