summaryrefslogtreecommitdiffstats
path: root/src/tools/cephfs/DataScan.cc
diff options
context:
space:
mode:
authorJohn Spray <john.spray@redhat.com>2015-08-03 15:54:37 +0200
committerJohn Spray <john.spray@redhat.com>2015-08-13 15:28:53 +0200
commit773b43129b1b1741ac3937d5411bad5e9f7dd471 (patch)
tree0afa276b4fbdac3c8198fd803d58875ecf6737dd /src/tools/cephfs/DataScan.cc
parenttools/cephfs: pass layouts around in DataScan (diff)
downloadceph-773b43129b1b1741ac3937d5411bad5e9f7dd471.tar.xz
ceph-773b43129b1b1741ac3937d5411bad5e9f7dd471.zip
tools/cephfs: use xattr layout if present+valid
So that in cases where files had an unguessable (e.g. striped) layout, but they were lucky enough to have the layout stashed in their xattr, we can provide the correct layout on recovery. Signed-off-by: John Spray <john.spray@redhat.com>
Diffstat (limited to 'src/tools/cephfs/DataScan.cc')
-rw-r--r--src/tools/cephfs/DataScan.cc34
1 files changed, 32 insertions, 2 deletions
diff --git a/src/tools/cephfs/DataScan.cc b/src/tools/cephfs/DataScan.cc
index 8269c088003..4fc563c9fcf 100644
--- a/src/tools/cephfs/DataScan.cc
+++ b/src/tools/cephfs/DataScan.cc
@@ -491,12 +491,17 @@ int DataScan::scan_inodes()
AccumulateResult accum_res;
inode_backtrace_t backtrace;
+ ceph_file_layout loaded_layout = g_default_file_layout;
int r = ClsCephFSClient::fetch_inode_accumulate_result(
- data_io, oid, &backtrace, &accum_res);
+ data_io, oid, &backtrace, &loaded_layout, &accum_res);
if (r < 0) {
dout(4) << "Unexpected error loading accumulated metadata from '"
<< oid << "': " << cpp_strerror(r) << dendl;
+ // FIXME: this creates situation where if a client has a corrupt
+ // backtrace/layout, we will fail to inject it. We should (optionally)
+ // proceed if the backtrace/layout is corrupt but we have valid
+ // accumulated metadata.
continue;
}
@@ -505,6 +510,11 @@ int DataScan::scan_inodes()
uint32_t chunk_size = g_default_file_layout.fl_object_size;
bool have_backtrace = !(backtrace.ancestors.empty());
+ // This is the layout we will use for injection, populated either
+ // from loaded_layout or from best guesses
+ ceph_file_layout guessed_layout;
+ guessed_layout.fl_pg_pool = data_pool_id;
+
// Calculate file_size, guess chunk_size
if (accum_res.ceiling_obj_index > 0) {
// When there are multiple objects, the largest object probably
@@ -515,7 +525,27 @@ int DataScan::scan_inodes()
chunk_size = accum_res.max_obj_size;
}
- file_size = chunk_size * accum_res.ceiling_obj_index
+ if (loaded_layout.fl_pg_pool == uint32_t(-1)) {
+ // If no stashed layout was found, guess it
+ guessed_layout.fl_object_size = chunk_size;
+ guessed_layout.fl_stripe_unit = chunk_size;
+ } else if (loaded_layout.fl_object_size < accum_res.max_obj_size) {
+ // If the max size seen exceeds what the stashed layout claims, then
+ // disbelieve it. Guess instead.
+ dout(4) << "bogus xattr layout on 0x" << std::hex << obj_name_ino
+ << std::dec << ", ignoring in favour of best guess" << dendl;
+ guessed_layout.fl_object_size = chunk_size;
+ guessed_layout.fl_stripe_unit = chunk_size;
+ } else {
+ // We have a stashed layout that we can't disprove, so apply it
+ guessed_layout = loaded_layout;
+ // User might have transplanted files from a pool with a different
+ // ID, so whatever the loaded_layout says, we'll force the injected
+ // layout to point to the pool we really read from
+ guessed_layout.fl_pg_pool = data_pool_id;
+ }
+
+ file_size = guessed_layout.fl_object_size * accum_res.ceiling_obj_index
+ accum_res.ceiling_obj_size;
} else {
file_size = accum_res.ceiling_obj_size;