caching/superblock.{h,cc}
This commit is contained in:
parent
500e508c6d
commit
1e925d4cf1
@ -48,7 +48,7 @@ PDATA_SOURCE=\
|
|||||||
SOURCE=\
|
SOURCE=\
|
||||||
$(PDATA_SOURCE) \
|
$(PDATA_SOURCE) \
|
||||||
\
|
\
|
||||||
cache/metadata_disk_structures.cc \
|
caching/superblock.cc \
|
||||||
\
|
\
|
||||||
thin-provisioning/device_tree.cc \
|
thin-provisioning/device_tree.cc \
|
||||||
thin-provisioning/file_utils.cc \
|
thin-provisioning/file_utils.cc \
|
||||||
@ -66,7 +66,7 @@ SOURCE=\
|
|||||||
PDATA_OBJECTS=$(subst .cc,.o,$(SOURCE))
|
PDATA_OBJECTS=$(subst .cc,.o,$(SOURCE))
|
||||||
|
|
||||||
CXX_PROGRAM_SOURCE=\
|
CXX_PROGRAM_SOURCE=\
|
||||||
cache/check.cc \
|
caching/check.cc \
|
||||||
\
|
\
|
||||||
thin-provisioning/thin_check.cc \
|
thin-provisioning/thin_check.cc \
|
||||||
thin-provisioning/thin_dump.cc \
|
thin-provisioning/thin_dump.cc \
|
||||||
@ -228,11 +228,11 @@ CACHE_CHECK_SOURCE=\
|
|||||||
persistent-data/space-maps/recursive.cc \
|
persistent-data/space-maps/recursive.cc \
|
||||||
persistent-data/space-maps/careful_alloc.cc \
|
persistent-data/space-maps/careful_alloc.cc \
|
||||||
persistent-data/transaction_manager.cc \
|
persistent-data/transaction_manager.cc \
|
||||||
cache/metadata_disk_structures.cc
|
caching/superblock.cc
|
||||||
|
|
||||||
CACHE_CHECK_OBJECTS=$(subst .cc,.o,$(CACHE_CHECK_SOURCE))
|
CACHE_CHECK_OBJECTS=$(subst .cc,.o,$(CACHE_CHECK_SOURCE))
|
||||||
|
|
||||||
cache_check: $(CACHE_CHECK_OBJECTS) cache/check.o
|
cache_check: $(CACHE_CHECK_OBJECTS) caching/check.o
|
||||||
@echo " [LD] $@"
|
@echo " [LD] $@"
|
||||||
$(V) $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $+ $(LIBS)
|
$(V) $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $+ $(LIBS)
|
||||||
|
|
||||||
|
120
cache/metadata_disk_structures.h
vendored
120
cache/metadata_disk_structures.h
vendored
@ -1,120 +0,0 @@
|
|||||||
// Copyright (C) 2012 Red Hat, Inc. All rights reserved.
|
|
||||||
//
|
|
||||||
// This file is part of the thin-provisioning-tools source.
|
|
||||||
//
|
|
||||||
// thin-provisioning-tools is free software: you can redistribute it
|
|
||||||
// and/or modify it under the terms of the GNU General Public License
|
|
||||||
// as published by the Free Software Foundation, either version 3 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// thin-provisioning-tools is distributed in the hope that it will be
|
|
||||||
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
|
||||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License along
|
|
||||||
// with thin-provisioning-tools. If not, see
|
|
||||||
// <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#ifndef CACHE_METADATA_DISK_STRUCTURES_H
|
|
||||||
#define CACHE_METADATA_DISK_STRUCTURES_H
|
|
||||||
|
|
||||||
#include "persistent-data/endian_utils.h"
|
|
||||||
#include "persistent-data/data-structures/btree.h"
|
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
|
||||||
|
|
||||||
// FIXME: rename to just METADATA_DISK_STRUCTURES
|
|
||||||
namespace cache_tools {
|
|
||||||
using namespace base; // FIXME: don't use namespaces in headers.
|
|
||||||
|
|
||||||
unsigned const SPACE_MAP_ROOT_SIZE = 128;
|
|
||||||
unsigned const CACHE_POLICY_NAME_SIZE = 16;
|
|
||||||
unsigned const CACHE_POLICY_VERSION_SIZE = 3;
|
|
||||||
|
|
||||||
typedef unsigned char __u8;
|
|
||||||
|
|
||||||
struct superblock_disk {
|
|
||||||
le32 csum;
|
|
||||||
le32 flags;
|
|
||||||
le64 blocknr;
|
|
||||||
|
|
||||||
__u8 uuid[16];
|
|
||||||
le64 magic;
|
|
||||||
le32 version;
|
|
||||||
|
|
||||||
__u8 policy_name[CACHE_POLICY_NAME_SIZE];
|
|
||||||
le32 policy_version[CACHE_POLICY_VERSION_SIZE];
|
|
||||||
le32 policy_hint_size;
|
|
||||||
|
|
||||||
__u8 metadata_space_map_root[SPACE_MAP_ROOT_SIZE];
|
|
||||||
|
|
||||||
le64 mapping_root;
|
|
||||||
le64 hint_root;
|
|
||||||
|
|
||||||
le64 discard_root;
|
|
||||||
le64 discard_block_size;
|
|
||||||
le64 discard_nr_blocks;
|
|
||||||
|
|
||||||
le32 data_block_size; /* in 512-byte sectors */
|
|
||||||
le32 metadata_block_size; /* in 512-byte sectors */
|
|
||||||
le32 cache_blocks;
|
|
||||||
|
|
||||||
le32 compat_flags;
|
|
||||||
le32 compat_ro_flags;
|
|
||||||
le32 incompat_flags;
|
|
||||||
|
|
||||||
le32 read_hits;
|
|
||||||
le32 read_misses;
|
|
||||||
le32 write_hits;
|
|
||||||
le32 write_misses;
|
|
||||||
} __attribute__ ((packed));
|
|
||||||
|
|
||||||
struct superblock {
|
|
||||||
uint32_t csum;
|
|
||||||
uint32_t flags;
|
|
||||||
uint64_t blocknr;
|
|
||||||
|
|
||||||
__u8 uuid[16];
|
|
||||||
uint64_t magic;
|
|
||||||
uint32_t version;
|
|
||||||
|
|
||||||
__u8 policy_name[CACHE_POLICY_NAME_SIZE];
|
|
||||||
uint32_t policy_version[CACHE_POLICY_VERSION_SIZE];
|
|
||||||
uint32_t policy_hint_size;
|
|
||||||
|
|
||||||
__u8 metadata_space_map_root[SPACE_MAP_ROOT_SIZE];
|
|
||||||
|
|
||||||
uint64_t mapping_root;
|
|
||||||
uint64_t hint_root;
|
|
||||||
|
|
||||||
uint64_t discard_root;
|
|
||||||
uint64_t discard_block_size;
|
|
||||||
uint64_t discard_nr_blocks;
|
|
||||||
|
|
||||||
uint32_t data_block_size; /* in 512-byte sectors */
|
|
||||||
uint32_t metadata_block_size; /* in 512-byte sectors */
|
|
||||||
uint32_t cache_blocks;
|
|
||||||
|
|
||||||
uint32_t compat_flags;
|
|
||||||
uint32_t compat_ro_flags;
|
|
||||||
uint32_t incompat_flags;
|
|
||||||
|
|
||||||
uint32_t read_hits;
|
|
||||||
uint32_t read_misses;
|
|
||||||
uint32_t write_hits;
|
|
||||||
uint32_t write_misses;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct superblock_traits {
|
|
||||||
typedef superblock_disk disk_type;
|
|
||||||
typedef superblock value_type;
|
|
||||||
|
|
||||||
static void unpack(superblock_disk const &disk, superblock &value);
|
|
||||||
static void pack(superblock const &value, superblock_disk &disk);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
|
||||||
|
|
||||||
#endif
|
|
28
caching/metadata_disk_structures.cc
Normal file
28
caching/metadata_disk_structures.cc
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Copyright (C) 2012 Red Hat, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of the thin-provisioning-tools source.
|
||||||
|
//
|
||||||
|
// thin-provisioning-tools is free software: you can redistribute it
|
||||||
|
// and/or modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation, either version 3 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// thin-provisioning-tools is distributed in the hope that it will be
|
||||||
|
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||||
|
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License along
|
||||||
|
// with thin-provisioning-tools. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "metadata_disk_structures.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
using namespace cache_tools;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
35
caching/metadata_disk_structures.h
Normal file
35
caching/metadata_disk_structures.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// Copyright (C) 2012 Red Hat, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of the thin-provisioning-tools source.
|
||||||
|
//
|
||||||
|
// thin-provisioning-tools is free software: you can redistribute it
|
||||||
|
// and/or modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation, either version 3 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// thin-provisioning-tools is distributed in the hope that it will be
|
||||||
|
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||||
|
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License along
|
||||||
|
// with thin-provisioning-tools. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef CACHE_METADATA_DISK_STRUCTURES_H
|
||||||
|
#define CACHE_METADATA_DISK_STRUCTURES_H
|
||||||
|
|
||||||
|
#include "persistent-data/endian_utils.h"
|
||||||
|
#include "persistent-data/data-structures/btree.h"
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
|
// FIXME: rename to just METADATA_DISK_STRUCTURES
|
||||||
|
namespace cache_tools {
|
||||||
|
using namespace base; // FIXME: don't use namespaces in headers.
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
|
#endif
|
@ -1,26 +1,7 @@
|
|||||||
// Copyright (C) 2012 Red Hat, Inc. All rights reserved.
|
#include "caching/superblock.h"
|
||||||
//
|
|
||||||
// This file is part of the thin-provisioning-tools source.
|
|
||||||
//
|
|
||||||
// thin-provisioning-tools is free software: you can redistribute it
|
|
||||||
// and/or modify it under the terms of the GNU General Public License
|
|
||||||
// as published by the Free Software Foundation, either version 3 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// thin-provisioning-tools is distributed in the hope that it will be
|
|
||||||
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
|
||||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License along
|
|
||||||
// with thin-provisioning-tools. If not, see
|
|
||||||
// <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#include "metadata_disk_structures.h"
|
using namespace caching;
|
||||||
|
using namespace superblock_detail;
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
using namespace cache_tools;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
@ -110,4 +91,87 @@ superblock_traits::pack(superblock const &core, superblock_disk &disk)
|
|||||||
disk.write_misses = to_disk<le32>(core.write_misses);
|
disk.write_misses = to_disk<le32>(core.write_misses);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------
|
||||||
|
|
||||||
|
superblock_corruption::superblock_corruption(std::string const &desc)
|
||||||
|
: desc_(desc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
superblock_corruption::visit(damage_visitor &v) const
|
||||||
|
{
|
||||||
|
v.visit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
using namespace persistent_data;
|
||||||
|
using namespace superblock_detail;
|
||||||
|
|
||||||
|
uint32_t const VERSION = 1;
|
||||||
|
unsigned const SECTOR_TO_BLOCK_SHIFT = 3;
|
||||||
|
uint32_t const SUPERBLOCK_CSUM_SEED = 9031977;
|
||||||
|
|
||||||
|
struct sb_validator : public block_manager<>::validator {
|
||||||
|
virtual void check(buffer<> const &b, block_address location) const {
|
||||||
|
superblock_disk const *sbd = reinterpret_cast<superblock_disk const *>(&b);
|
||||||
|
crc32c sum(SUPERBLOCK_CSUM_SEED);
|
||||||
|
sum.append(&sbd->flags, MD_BLOCK_SIZE - sizeof(uint32_t));
|
||||||
|
if (sum.get_sum() != to_cpu<uint32_t>(sbd->csum))
|
||||||
|
throw checksum_error("bad checksum in superblock");
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void prepare(buffer<> &b, block_address location) const {
|
||||||
|
superblock_disk *sbd = reinterpret_cast<superblock_disk *>(&b);
|
||||||
|
crc32c sum(SUPERBLOCK_CSUM_SEED);
|
||||||
|
sum.append(&sbd->flags, MD_BLOCK_SIZE - sizeof(uint32_t));
|
||||||
|
sbd->csum = to_disk<base::le32>(sum.get_sum());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
persistent_data::block_manager<>::validator::ptr
|
||||||
|
caching::superblock_validator()
|
||||||
|
{
|
||||||
|
return block_manager<>::validator::ptr(new sb_validator);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------
|
||||||
|
|
||||||
|
superblock_detail::superblock
|
||||||
|
caching::read_superblock(persistent_data::block_manager<>::ptr bm,
|
||||||
|
persistent_data::block_address location)
|
||||||
|
{
|
||||||
|
using namespace superblock_detail;
|
||||||
|
|
||||||
|
superblock sb;
|
||||||
|
block_manager<>::read_ref r = bm->read_lock(location, superblock_validator());
|
||||||
|
superblock_disk const *sbd = reinterpret_cast<superblock_disk const *>(&r.data());
|
||||||
|
superblock_traits::unpack(*sbd, sb);
|
||||||
|
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
superblock_detail::superblock
|
||||||
|
caching::read_superblock(persistent_data::block_manager<>::ptr bm)
|
||||||
|
{
|
||||||
|
return read_superblock(bm, SUPERBLOCK_LOCATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
caching::check_superblock(persistent_data::block_manager<>::ptr bm,
|
||||||
|
superblock_detail::damage_visitor &visitor)
|
||||||
|
{
|
||||||
|
using namespace superblock_detail;
|
||||||
|
|
||||||
|
try {
|
||||||
|
bm->read_lock(SUPERBLOCK_LOCATION, superblock_validator());
|
||||||
|
|
||||||
|
} catch (std::exception const &e) {
|
||||||
|
visitor.visit(superblock_corruption(e.what()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
139
caching/superblock.h
Normal file
139
caching/superblock.h
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
#ifndef CACHE_SUPERBLOCK_H
|
||||||
|
#define CACHE_SUPERBLOCK_H
|
||||||
|
|
||||||
|
#include "persistent-data/endian_utils.h"
|
||||||
|
#include "persistent-data/data-structures/btree.h"
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace caching {
|
||||||
|
namespace superblock_detail {
|
||||||
|
using namespace base;
|
||||||
|
|
||||||
|
unsigned const SPACE_MAP_ROOT_SIZE = 128;
|
||||||
|
unsigned const CACHE_POLICY_NAME_SIZE = 16;
|
||||||
|
unsigned const CACHE_POLICY_VERSION_SIZE = 3;
|
||||||
|
|
||||||
|
typedef unsigned char __u8;
|
||||||
|
|
||||||
|
struct superblock_disk {
|
||||||
|
le32 csum;
|
||||||
|
le32 flags;
|
||||||
|
le64 blocknr;
|
||||||
|
|
||||||
|
__u8 uuid[16];
|
||||||
|
le64 magic;
|
||||||
|
le32 version;
|
||||||
|
|
||||||
|
__u8 policy_name[CACHE_POLICY_NAME_SIZE];
|
||||||
|
le32 policy_version[CACHE_POLICY_VERSION_SIZE];
|
||||||
|
le32 policy_hint_size;
|
||||||
|
|
||||||
|
__u8 metadata_space_map_root[SPACE_MAP_ROOT_SIZE];
|
||||||
|
|
||||||
|
le64 mapping_root;
|
||||||
|
le64 hint_root;
|
||||||
|
|
||||||
|
le64 discard_root;
|
||||||
|
le64 discard_block_size;
|
||||||
|
le64 discard_nr_blocks;
|
||||||
|
|
||||||
|
le32 data_block_size; /* in 512-byte sectors */
|
||||||
|
le32 metadata_block_size; /* in 512-byte sectors */
|
||||||
|
le32 cache_blocks;
|
||||||
|
|
||||||
|
le32 compat_flags;
|
||||||
|
le32 compat_ro_flags;
|
||||||
|
le32 incompat_flags;
|
||||||
|
|
||||||
|
le32 read_hits;
|
||||||
|
le32 read_misses;
|
||||||
|
le32 write_hits;
|
||||||
|
le32 write_misses;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct superblock {
|
||||||
|
uint32_t csum;
|
||||||
|
uint32_t flags;
|
||||||
|
uint64_t blocknr;
|
||||||
|
|
||||||
|
__u8 uuid[16];
|
||||||
|
uint64_t magic;
|
||||||
|
uint32_t version;
|
||||||
|
|
||||||
|
__u8 policy_name[CACHE_POLICY_NAME_SIZE];
|
||||||
|
uint32_t policy_version[CACHE_POLICY_VERSION_SIZE];
|
||||||
|
uint32_t policy_hint_size;
|
||||||
|
|
||||||
|
__u8 metadata_space_map_root[SPACE_MAP_ROOT_SIZE];
|
||||||
|
|
||||||
|
uint64_t mapping_root;
|
||||||
|
uint64_t hint_root;
|
||||||
|
|
||||||
|
uint64_t discard_root;
|
||||||
|
uint64_t discard_block_size;
|
||||||
|
uint64_t discard_nr_blocks;
|
||||||
|
|
||||||
|
uint32_t data_block_size; /* in 512-byte sectors */
|
||||||
|
uint32_t metadata_block_size; /* in 512-byte sectors */
|
||||||
|
uint32_t cache_blocks;
|
||||||
|
|
||||||
|
uint32_t compat_flags;
|
||||||
|
uint32_t compat_ro_flags;
|
||||||
|
uint32_t incompat_flags;
|
||||||
|
|
||||||
|
uint32_t read_hits;
|
||||||
|
uint32_t read_misses;
|
||||||
|
uint32_t write_hits;
|
||||||
|
uint32_t write_misses;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct superblock_traits {
|
||||||
|
typedef superblock_disk disk_type;
|
||||||
|
typedef superblock value_type;
|
||||||
|
|
||||||
|
static void unpack(superblock_disk const &disk, superblock &value);
|
||||||
|
static void pack(superblock const &value, superblock_disk &disk);
|
||||||
|
};
|
||||||
|
|
||||||
|
block_address const SUPERBLOCK_LOCATION = 0;
|
||||||
|
uint32_t const SUPERBLOCK_MAGIC = 06142003;
|
||||||
|
|
||||||
|
//--------------------------------
|
||||||
|
|
||||||
|
class damage_visitor;
|
||||||
|
|
||||||
|
struct damage {
|
||||||
|
virtual ~damage() {}
|
||||||
|
virtual void visit(damage_visitor &v) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct superblock_corruption : public damage {
|
||||||
|
superblock_corruption(std::string const &desc);
|
||||||
|
void visit(damage_visitor &v) const;
|
||||||
|
|
||||||
|
std::string desc_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class damage_visitor {
|
||||||
|
public:
|
||||||
|
virtual ~damage_visitor() {}
|
||||||
|
|
||||||
|
void visit(damage const &d);
|
||||||
|
|
||||||
|
virtual void visit(superblock_corruption const &d) = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
persistent_data::block_manager<>::validator::ptr superblock_validator();
|
||||||
|
|
||||||
|
superblock_detail::superblock read_superblock(persistent_data::block_manager<>::ptr bm);
|
||||||
|
superblock_detail::superblock read_superblock(persistent_data::block_manager<>::ptr bm,
|
||||||
|
persistent_data::block_address location);
|
||||||
|
void check_superblock(persistent_data::block_manager<>::ptr bm,
|
||||||
|
superblock_detail::damage_visitor &visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user