From 1ba0bc39801e5b3faf9206db39244490a789f7b5 Mon Sep 17 00:00:00 2001 From: sageweil Date: Fri, 14 Dec 2007 20:06:35 +0000 Subject: [PATCH] superblock checksums git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@2210 29311d96-e01e-0410-9327-a35deaab8ce9 --- branches/ebofs/ebofs/BufferCache.cc | 18 ++++++++++++++---- branches/ebofs/ebofs/BufferCache.h | 6 ++++-- branches/ebofs/ebofs/Ebofs.cc | 16 +++++++++++----- branches/ebofs/ebofs/types.h | 16 ++++++++++++++++ 4 files changed, 45 insertions(+), 11 deletions(-) diff --git a/branches/ebofs/ebofs/BufferCache.cc b/branches/ebofs/ebofs/BufferCache.cc index c9c8dafca164b..84c82aeb48c9a 100644 --- a/branches/ebofs/ebofs/BufferCache.cc +++ b/branches/ebofs/ebofs/BufferCache.cc @@ -1387,7 +1387,9 @@ void BufferCache::bh_queue_partial_write(Onode *on, BufferHead *bh) // copy map state, queue for this block assert(bh->rx_from.length == 1); - queue_partial( bh->rx_from.start, bh->partial_tx_to, bh->partial, bh->partial_tx_epoch ); + csum_t csum = *on->get_extent_csum_ptr(bh->start(), 1); + queue_partial(on, bh->start(), csum, + bh->rx_from.start, bh->partial_tx_to, bh->partial, bh->partial_tx_epoch ); } void BufferCache::bh_cancel_partial_write(BufferHead *bh) @@ -1399,10 +1401,13 @@ void BufferCache::bh_cancel_partial_write(BufferHead *bh) } -void BufferCache::queue_partial(block_t from, block_t to, - map& partial, version_t epoch) +void BufferCache::queue_partial(Onode *on, block_t opos, csum_t csum, + block_t from, block_t to, + map& partial, + version_t epoch) { - dout(10) << "queue_partial " << from << " -> " << to + dout(10) << "queue_partial " << on->object_id << " at " << opos + << " from disk " << from << " -> " << to << " in epoch " << epoch << dendl; @@ -1414,6 +1419,10 @@ void BufferCache::queue_partial(block_t from, block_t to, inc_unflushed( EBOFS_BC_FLUSH_PARTIAL, epoch ); } + on->get(); // one ref for each pair. + partial_write[from].on = on; + partial_write[from].csum = csum; + partial_write[from].opos = opos; partial_write[from].writes[to].partial = partial; partial_write[from].writes[to].epoch = epoch; } @@ -1429,6 +1438,7 @@ void BufferCache::cancel_partial(block_t from, block_t to, version_t epoch) << dendl; partial_write[from].writes.erase(to); + partial_write[from].on->put(); // one ref per pair. if (partial_write[from].writes.empty()) partial_write.erase(from); diff --git a/branches/ebofs/ebofs/BufferCache.h b/branches/ebofs/ebofs/BufferCache.h index 3959a7e644090..12f3cde28704c 100644 --- a/branches/ebofs/ebofs/BufferCache.h +++ b/branches/ebofs/ebofs/BufferCache.h @@ -431,7 +431,9 @@ class BufferCache { version_t epoch; }; struct PartialWriteSet { - csum_t csum; // expected csum + Onode *on; // object + block_t opos; // block in object + csum_t csum; // expected csum map writes; }; @@ -595,7 +597,7 @@ class BufferCache { void bh_queue_partial_write(Onode *on, BufferHead *bh); void bh_cancel_partial_write(BufferHead *bh); - void queue_partial(block_t from, block_t to, map& partial, version_t epoch); + void queue_partial(Onode *on, block_t opos, csum_t csum, block_t from, block_t to, map& partial, version_t epoch); void cancel_partial(block_t from, block_t to, version_t epoch); void add_shadow_partial(block_t from, BufferHead *bh); diff --git a/branches/ebofs/ebofs/Ebofs.cc b/branches/ebofs/ebofs/Ebofs.cc index e8bacbe6989bb..deae741ec865c 100644 --- a/branches/ebofs/ebofs/Ebofs.cc +++ b/branches/ebofs/ebofs/Ebofs.cc @@ -70,13 +70,16 @@ int Ebofs::mount() struct ebofs_super *sb2 = (struct ebofs_super*)bp2.c_str(); // valid superblocks? - if (sb1->s_magic != EBOFS_MAGIC || - sb2->s_magic != EBOFS_MAGIC) { + if (!sb1->is_valid_magic() && !sb2->is_valid_magic()) { derr(0) << "mount bad magic, not a valid EBOFS file system" << dendl; return -EINVAL; } - if (sb1->num_blocks > dev.get_num_blocks() || - sb2->num_blocks > dev.get_num_blocks()) { + if (sb1->is_corrupt() && sb2->is_corrupt()) { + derr(0) << "mount both superblocks are corrupt (bad csum)" << dendl; + return -EINVAL; + } + if ((sb1->is_valid() && sb1->num_blocks > dev.get_num_blocks()) || + (sb2->is_valid() && sb2->num_blocks > dev.get_num_blocks())) { derr(0) << "mount superblock size exceeds actual device size" << dendl; return -EINVAL; } @@ -374,7 +377,6 @@ void Ebofs::prepare_super(version_t epoch, bufferptr& bp) sb.free_blocks = free_blocks; sb.limbo_blocks = limbo_blocks; - // tables sb.object_tab.num_keys = object_tab->get_num_keys(); sb.object_tab.root = object_tab->get_root(); @@ -408,6 +410,10 @@ void Ebofs::prepare_super(version_t epoch, bufferptr& bp) } sb.nodepool.node_usemap_even = nodepool.usemap_even; sb.nodepool.node_usemap_odd = nodepool.usemap_odd; + + // csum + sb.super_csum = sb.calc_csum(); + dout(20) << "super csum is " << sb.super_csum << " " << sb.calc_csum() << dendl; // put in a buffer bp = buffer::create_page_aligned(EBOFS_BLOCK_SIZE); diff --git a/branches/ebofs/ebofs/types.h b/branches/ebofs/ebofs/types.h index 6645881e355e5..c853d0605cdb6 100644 --- a/branches/ebofs/ebofs/types.h +++ b/branches/ebofs/ebofs/types.h @@ -161,6 +161,22 @@ struct ebofs_super { struct ebofs_table object_tab; // object directory struct ebofs_table collection_tab; // collection directory struct ebofs_table co_tab; + + csum_t super_csum; + + csum_t calc_csum() { + return ::calc_csum((char*)this, (unsigned long)&super_csum-(unsigned long)this); + } + bool is_corrupt() { + csum_t actual = calc_csum(); + if (actual != super_csum) { + cout << "actual " << actual << " expected " << super_csum << std::endl; + return true; + } + return false; + } + bool is_valid_magic() { return s_magic == EBOFS_MAGIC; } + bool is_valid() { return is_valid_magic() && !is_corrupt(); } }; -- 2.39.5