diff options
Diffstat (limited to 'src/os/FileStore.cc')
-rw-r--r-- | src/os/FileStore.cc | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/src/os/FileStore.cc b/src/os/FileStore.cc index 7418039ece6..a6f330bc3ea 100644 --- a/src/os/FileStore.cc +++ b/src/os/FileStore.cc @@ -101,6 +101,22 @@ static const __SWORD_TYPE XFS_SUPER_MAGIC(0x58465342); #define REPLAY_GUARD_XATTR "user.cephos.seq" #define GLOBAL_REPLAY_GUARD_XATTR "user.cephos.gseq" +//Initial features in new superblock. +static CompatSet get_fs_initial_compat_set() { + CompatSet::FeatureSet ceph_osd_feature_compat; + CompatSet::FeatureSet ceph_osd_feature_ro_compat; + CompatSet::FeatureSet ceph_osd_feature_incompat; + return CompatSet(ceph_osd_feature_compat, ceph_osd_feature_ro_compat, + ceph_osd_feature_incompat); +} + +//Features are added here that this FileStore supports. +static CompatSet get_fs_supported_compat_set() { + CompatSet compat = get_fs_initial_compat_set(); + //Any features here can be set in code, but not in initial superblock + return compat; +} + /* * long file names will have the following format: * @@ -478,6 +494,8 @@ FileStore::FileStore(const std::string &base, const std::string &jdev, const cha g_ceph_context->get_perfcounters_collection()->add(logger); g_ceph_context->_conf->add_observer(this); + + superblock.compat_features = get_fs_initial_compat_set(); } FileStore::~FileStore() @@ -679,6 +697,13 @@ int FileStore::mkfs() goto close_fsid_fd; } + ret = write_superblock(); + if (ret < 0) { + derr << "mkfs: write_superblock() failed: " + << cpp_strerror(ret) << dendl; + goto close_fsid_fd; + } + struct statfs basefs; ret = ::fstatfs(basedir_fd, &basefs); if (ret < 0) { @@ -1339,6 +1364,67 @@ int FileStore::_sanity_check_fs() return 0; } +int FileStore::write_superblock() +{ + char fn[PATH_MAX]; + snprintf(fn, sizeof(fn), "%s/superblock", basedir.c_str()); + int fd = ::open(fn, O_WRONLY|O_CREAT|O_TRUNC, 0644); + if (fd < 0) + return -errno; + bufferlist bl; + ::encode(superblock, bl); + + int ret = safe_write(fd, bl.c_str(), bl.length()); + if (ret < 0) + goto out; + ret = ::fsync(fd); + if (ret < 0) + ret = -errno; + // XXX: fsync() man page says I need to sync containing directory +out: + TEMP_FAILURE_RETRY(::close(fd)); + return ret; +} + +int FileStore::read_superblock() +{ + char fn[PATH_MAX]; + snprintf(fn, sizeof(fn), "%s/superblock", basedir.c_str()); + int fd = ::open(fn, O_RDONLY, 0644); + if (fd < 0) { + if (errno == ENOENT) { + // If the file doesn't exist write initial CompatSet + return write_superblock(); + } else + return -errno; + } + bufferptr bp(PATH_MAX); + int ret = safe_read(fd, bp.c_str(), bp.length()); + TEMP_FAILURE_RETRY(::close(fd)); + if (ret < 0) + return ret; + bufferlist bl; + bl.push_back(bp); + bufferlist::iterator i = bl.begin(); + ::decode(superblock, i); + return 0; +} + +void FileStore::set_allow_sharded_objects() +{ + if (!get_allow_sharded_objects()) { + superblock.compat_features.incompat.insert(CEPH_FS_FEATURE_INCOMPAT_SHARDS); + int ret = write_superblock(); + assert(ret == 0); //Should we return error and make caller handle it? + } + return; +} + +bool FileStore::get_allow_sharded_objects() +{ + return superblock.compat_features.incompat.contains(CEPH_FS_FEATURE_INCOMPAT_SHARDS); +} + int FileStore::update_version_stamp() { return write_version_stamp(); @@ -1426,6 +1512,7 @@ int FileStore::mount() char buf[PATH_MAX]; uint64_t initial_op_seq; set<string> cluster_snaps; + CompatSet supported_compat_set = get_fs_supported_compat_set(); dout(5) << "basedir " << basedir << " journal " << journalpath << dendl; @@ -1490,6 +1577,20 @@ int FileStore::mount() } } + ret = read_superblock(); + if (ret < 0) { + ret = -EINVAL; + goto close_fsid_fd; + } + + // Check if this FileStore supports all the necessary features to mount + if (supported_compat_set.compare(superblock.compat_features) == -1) { + derr << "FileStore::mount : Incompatible features set " + << superblock.compat_features << dendl; + ret = -EINVAL; + goto close_fsid_fd; + } + // open some dir handles basedir_fd = ::open(basedir.c_str(), O_RDONLY); if (basedir_fd < 0) { @@ -5037,3 +5138,39 @@ void FileStore::dump_transactions(list<ObjectStore::Transaction*>& ls, uint64_t m_filestore_dump_fmt.flush(m_filestore_dump); m_filestore_dump.flush(); } + +// -- FSSuperblock -- + +void FSSuperblock::encode(bufferlist &bl) const +{ + ENCODE_START(1, 1, bl); + compat_features.encode(bl); + ENCODE_FINISH(bl); +} + +void FSSuperblock::decode(bufferlist::iterator &bl) +{ + DECODE_START(1, bl); + compat_features.decode(bl); + DECODE_FINISH(bl); +} + +void FSSuperblock::dump(Formatter *f) const +{ + f->open_object_section("compat"); + compat_features.dump(f); + f->close_section(); +} + +void FSSuperblock::generate_test_instances(list<FSSuperblock*>& o) +{ + FSSuperblock z; + o.push_back(new FSSuperblock(z)); + CompatSet::FeatureSet feature_compat; + CompatSet::FeatureSet feature_ro_compat; + CompatSet::FeatureSet feature_incompat; + feature_incompat.insert(CEPH_FS_FEATURE_INCOMPAT_SHARDS); + z.compat_features = CompatSet(feature_compat, feature_ro_compat, + feature_incompat); + o.push_back(new FSSuperblock(z)); +} |