diff options
Diffstat (limited to 'src/os/FileStore.cc')
-rw-r--r-- | src/os/FileStore.cc | 392 |
1 files changed, 273 insertions, 119 deletions
diff --git a/src/os/FileStore.cc b/src/os/FileStore.cc index 5d9e9d1482d..cd8a8e50658 100644 --- a/src/os/FileStore.cc +++ b/src/os/FileStore.cc @@ -86,6 +86,23 @@ using ceph::crypto::SHA1; #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 + compat.incompat.insert(CEPH_FS_FEATURE_INCOMPAT_SHARDS); + return compat; +} + void FileStore::FSPerfTracker::update_from_perfcounters( PerfCounters &logger) @@ -124,12 +141,12 @@ int FileStore::init_index(coll_t cid) { char path[PATH_MAX]; get_cdir(cid, path, sizeof(path)); - int r = index_manager.init_index(cid, path, on_disk_version); + int r = index_manager.init_index(cid, path, target_version); assert(!m_filestore_fail_eio || r != -EIO); return r; } -int FileStore::lfn_find(coll_t cid, const hobject_t& oid, IndexedPath *path) +int FileStore::lfn_find(coll_t cid, const ghobject_t& oid, IndexedPath *path) { Index index; int r, exist; @@ -147,20 +164,25 @@ int FileStore::lfn_find(coll_t cid, const hobject_t& oid, IndexedPath *path) return 0; } -int FileStore::lfn_truncate(coll_t cid, const hobject_t& oid, off_t length) +int FileStore::lfn_truncate(coll_t cid, const ghobject_t& oid, off_t length) { IndexedPath path; - int r = lfn_find(cid, oid, &path); + FDRef fd; + int r = lfn_open(cid, oid, false, &fd, &path); if (r < 0) return r; - r = ::truncate(path->path(), length); + r = ::ftruncate(**fd, length); if (r < 0) r = -errno; + if (r >= 0 && m_filestore_sloppy_crc) { + int rc = backend->_crc_update_truncate(**fd, length); + assert(rc >= 0); + } assert(!m_filestore_fail_eio || r != -EIO); return r; } -int FileStore::lfn_stat(coll_t cid, const hobject_t& oid, struct stat *buf) +int FileStore::lfn_stat(coll_t cid, const ghobject_t& oid, struct stat *buf) { IndexedPath path; int r = lfn_find(cid, oid, &path); @@ -173,12 +195,13 @@ int FileStore::lfn_stat(coll_t cid, const hobject_t& oid, struct stat *buf) } int FileStore::lfn_open(coll_t cid, - const hobject_t& oid, + const ghobject_t& oid, bool create, FDRef *outfd, IndexedPath *path, Index *index) { + assert(get_allow_sharded_objects() || oid.shard_id == ghobject_t::NO_SHARD); assert(outfd); int flags = O_RDWR; if (create) @@ -246,7 +269,7 @@ void FileStore::lfn_close(FDRef fd) { } -int FileStore::lfn_link(coll_t c, coll_t newcid, const hobject_t& o, const hobject_t& newoid) +int FileStore::lfn_link(coll_t c, coll_t newcid, const ghobject_t& o, const ghobject_t& newoid) { Index index_new, index_old; IndexedPath path_new, path_old; @@ -298,7 +321,7 @@ int FileStore::lfn_link(coll_t c, coll_t newcid, const hobject_t& o, const hobje return 0; } -int FileStore::lfn_unlink(coll_t cid, const hobject_t& o, +int FileStore::lfn_unlink(coll_t cid, const ghobject_t& o, const SequencerPosition &spos, bool force_clear_omap) { @@ -324,7 +347,8 @@ int FileStore::lfn_unlink(coll_t cid, const hobject_t& o, assert(!m_filestore_fail_eio || r != -EIO); return r; } - force_clear_omap = true; + if (st.st_nlink == 1) + force_clear_omap = true; } if (force_clear_omap) { dout(20) << __func__ << ": clearing omap on " << o @@ -396,7 +420,9 @@ FileStore::FileStore(const std::string &base, const std::string &jdev, const cha m_filestore_queue_committing_max_ops(g_conf->filestore_queue_committing_max_ops), m_filestore_queue_committing_max_bytes(g_conf->filestore_queue_committing_max_bytes), m_filestore_do_dump(false), - m_filestore_dump_fmt(true) + m_filestore_dump_fmt(true), + m_filestore_sloppy_crc(g_conf->filestore_sloppy_crc), + m_filestore_sloppy_crc_block_size(g_conf->filestore_sloppy_crc_block_size) { m_filestore_kill_at.set(g_conf->filestore_kill_at); @@ -446,6 +472,8 @@ FileStore::FileStore(const std::string &base, const std::string &jdev, const cha generic_backend = new GenericFileStoreBackend(this); backend = generic_backend; + + superblock.compat_features = get_fs_initial_compat_set(); } FileStore::~FileStore() @@ -591,6 +619,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) { @@ -916,6 +951,49 @@ int FileStore::_sanity_check_fs() return 0; } +int FileStore::write_superblock() +{ + bufferlist bl; + ::encode(superblock, bl); + return safe_write_file(basedir.c_str(), "superblock", + bl.c_str(), bl.length()); +} + +int FileStore::read_superblock() +{ + bufferptr bp(PATH_MAX); + int ret = safe_read_file(basedir.c_str(), "superblock", + bp.c_str(), bp.length()); + if (ret < 0) { + if (ret == -ENOENT) { + // If the file doesn't exist write initial CompatSet + return write_superblock(); + } + 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(); @@ -923,25 +1001,19 @@ int FileStore::update_version_stamp() int FileStore::version_stamp_is_valid(uint32_t *version) { - char fn[PATH_MAX]; - snprintf(fn, sizeof(fn), "%s/store_version", basedir.c_str()); - int fd = ::open(fn, O_RDONLY, 0644); - if (fd < 0) { - if (errno == ENOENT) + bufferptr bp(PATH_MAX); + int ret = safe_read_file(basedir.c_str(), "store_version", + bp.c_str(), bp.length()); + if (ret < 0) { + if (ret == -ENOENT) return 0; - else - return -errno; + return ret; } - bufferptr bp(PATH_MAX); - int ret = safe_read(fd, bp.c_str(), bp.length()); - TEMP_FAILURE_RETRY(::close(fd)); - if (ret < 0) - return -errno; bufferlist bl; bl.push_back(bp); bufferlist::iterator i = bl.begin(); ::decode(*version, i); - if (*version == on_disk_version) + if (*version == target_version) return 1; else return 0; @@ -949,19 +1021,11 @@ int FileStore::version_stamp_is_valid(uint32_t *version) int FileStore::write_version_stamp() { - char fn[PATH_MAX]; - snprintf(fn, sizeof(fn), "%s/store_version", basedir.c_str()); - int fd = ::open(fn, O_WRONLY|O_CREAT|O_TRUNC, 0644); - if (fd < 0) - return -errno; bufferlist bl; - ::encode(on_disk_version, bl); - - int ret = safe_write(fd, bl.c_str(), bl.length()); - TEMP_FAILURE_RETRY(::close(fd)); - if (ret < 0) - return -errno; - return 0; + ::encode(target_version, bl); + + return safe_write_file(basedir.c_str(), "store_version", + bl.c_str(), bl.length()); } int FileStore::read_op_seq(uint64_t *seq) @@ -1003,6 +1067,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; @@ -1057,12 +1122,26 @@ int FileStore::mount() ret = -EINVAL; derr << "FileStore::mount : stale version stamp " << version_stamp << ". Please run the FileStore update script before starting the " - << "OSD, or set filestore_update_to to " << on_disk_version + << "OSD, or set filestore_update_to to " << target_version << dendl; goto close_fsid_fd; } } + 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) { @@ -1710,7 +1789,7 @@ int FileStore::_do_transactions( for (list<Transaction*>::iterator p = tls.begin(); p != tls.end(); ++p, trans_num++) { - r = _do_transaction(**p, op_seq, trans_num); + r = _do_transaction(**p, op_seq, trans_num, handle); if (r < 0) break; if (handle) @@ -1812,7 +1891,7 @@ void FileStore::_set_replay_guard(coll_t cid, void FileStore::_set_replay_guard(int fd, const SequencerPosition& spos, - const hobject_t *hoid, + const ghobject_t *hoid, bool in_progress) { if (backend->can_checkpoint()) @@ -1893,7 +1972,7 @@ void FileStore::_close_replay_guard(int fd, const SequencerPosition& spos) dout(10) << "_close_replay_guard " << spos << " done" << dendl; } -int FileStore::_check_replay_guard(coll_t cid, hobject_t oid, const SequencerPosition& spos) +int FileStore::_check_replay_guard(coll_t cid, ghobject_t oid, const SequencerPosition& spos) { if (!replaying || backend->can_checkpoint()) return 1; @@ -1972,7 +2051,9 @@ int FileStore::_check_replay_guard(int fd, const SequencerPosition& spos) } } -unsigned FileStore::_do_transaction(Transaction& t, uint64_t op_seq, int trans_num) +unsigned FileStore::_do_transaction( + Transaction& t, uint64_t op_seq, int trans_num, + ThreadPool::TPHandle *handle) { dout(10) << "_do_transaction on " << &t << dendl; @@ -1980,6 +2061,9 @@ unsigned FileStore::_do_transaction(Transaction& t, uint64_t op_seq, int trans_n SequencerPosition spos(op_seq, trans_num, 0); while (i.have_op()) { + if (handle) + handle->reset_tp_timeout(); + int op = i.get_op(); int r = 0; @@ -1991,7 +2075,7 @@ unsigned FileStore::_do_transaction(Transaction& t, uint64_t op_seq, int trans_n case Transaction::OP_TOUCH: { coll_t cid = i.get_cid(); - hobject_t oid = i.get_oid(); + ghobject_t oid = i.get_oid(); if (_check_replay_guard(cid, oid, spos) > 0) r = _touch(cid, oid); } @@ -2000,7 +2084,7 @@ unsigned FileStore::_do_transaction(Transaction& t, uint64_t op_seq, int trans_n case Transaction::OP_WRITE: { coll_t cid = i.get_cid(); - hobject_t oid = i.get_oid(); + ghobject_t oid = i.get_oid(); uint64_t off = i.get_length(); uint64_t len = i.get_length(); bool replica = i.get_replica(); @@ -2014,7 +2098,7 @@ unsigned FileStore::_do_transaction(Transaction& t, uint64_t op_seq, int trans_n case Transaction::OP_ZERO: { coll_t cid = i.get_cid(); - hobject_t oid = i.get_oid(); + ghobject_t oid = i.get_oid(); uint64_t off = i.get_length(); uint64_t len = i.get_length(); if (_check_replay_guard(cid, oid, spos) > 0) @@ -2035,7 +2119,7 @@ unsigned FileStore::_do_transaction(Transaction& t, uint64_t op_seq, int trans_n case Transaction::OP_TRUNCATE: { coll_t cid = i.get_cid(); - hobject_t oid = i.get_oid(); + ghobject_t oid = i.get_oid(); uint64_t off = i.get_length(); if (_check_replay_guard(cid, oid, spos) > 0) r = _truncate(cid, oid, off); @@ -2045,7 +2129,7 @@ unsigned FileStore::_do_transaction(Transaction& t, uint64_t op_seq, int trans_n case Transaction::OP_REMOVE: { coll_t cid = i.get_cid(); - hobject_t oid = i.get_oid(); + ghobject_t oid = i.get_oid(); if (_check_replay_guard(cid, oid, spos) > 0) r = _remove(cid, oid, spos); } @@ -2054,7 +2138,7 @@ unsigned FileStore::_do_transaction(Transaction& t, uint64_t op_seq, int trans_n case Transaction::OP_SETATTR: { coll_t cid = i.get_cid(); - hobject_t oid = i.get_oid(); + ghobject_t oid = i.get_oid(); string name = i.get_attrname(); bufferlist bl; i.get_bl(bl); @@ -2072,7 +2156,7 @@ unsigned FileStore::_do_transaction(Transaction& t, uint64_t op_seq, int trans_n case Transaction::OP_SETATTRS: { coll_t cid = i.get_cid(); - hobject_t oid = i.get_oid(); + ghobject_t oid = i.get_oid(); map<string, bufferptr> aset; i.get_attrset(aset); if (_check_replay_guard(cid, oid, spos) > 0) @@ -2085,7 +2169,7 @@ unsigned FileStore::_do_transaction(Transaction& t, uint64_t op_seq, int trans_n case Transaction::OP_RMATTR: { coll_t cid = i.get_cid(); - hobject_t oid = i.get_oid(); + ghobject_t oid = i.get_oid(); string name = i.get_attrname(); if (_check_replay_guard(cid, oid, spos) > 0) r = _rmattr(cid, oid, name.c_str(), spos); @@ -2095,7 +2179,7 @@ unsigned FileStore::_do_transaction(Transaction& t, uint64_t op_seq, int trans_n case Transaction::OP_RMATTRS: { coll_t cid = i.get_cid(); - hobject_t oid = i.get_oid(); + ghobject_t oid = i.get_oid(); if (_check_replay_guard(cid, oid, spos) > 0) r = _rmattrs(cid, oid, spos); } @@ -2104,8 +2188,8 @@ unsigned FileStore::_do_transaction(Transaction& t, uint64_t op_seq, int trans_n case Transaction::OP_CLONE: { coll_t cid = i.get_cid(); - hobject_t oid = i.get_oid(); - hobject_t noid = i.get_oid(); + ghobject_t oid = i.get_oid(); + ghobject_t noid = i.get_oid(); r = _clone(cid, oid, noid, spos); } break; @@ -2113,8 +2197,8 @@ unsigned FileStore::_do_transaction(Transaction& t, uint64_t op_seq, int trans_n case Transaction::OP_CLONERANGE: { coll_t cid = i.get_cid(); - hobject_t oid = i.get_oid(); - hobject_t noid = i.get_oid(); + ghobject_t oid = i.get_oid(); + ghobject_t noid = i.get_oid(); uint64_t off = i.get_length(); uint64_t len = i.get_length(); r = _clone_range(cid, oid, noid, off, len, off, spos); @@ -2124,8 +2208,8 @@ unsigned FileStore::_do_transaction(Transaction& t, uint64_t op_seq, int trans_n case Transaction::OP_CLONERANGE2: { coll_t cid = i.get_cid(); - hobject_t oid = i.get_oid(); - hobject_t noid = i.get_oid(); + ghobject_t oid = i.get_oid(); + ghobject_t noid = i.get_oid(); uint64_t srcoff = i.get_length(); uint64_t len = i.get_length(); uint64_t dstoff = i.get_length(); @@ -2153,7 +2237,7 @@ unsigned FileStore::_do_transaction(Transaction& t, uint64_t op_seq, int trans_n { coll_t ncid = i.get_cid(); coll_t ocid = i.get_cid(); - hobject_t oid = i.get_oid(); + ghobject_t oid = i.get_oid(); r = _collection_add(ncid, ocid, oid, spos); } break; @@ -2161,7 +2245,7 @@ unsigned FileStore::_do_transaction(Transaction& t, uint64_t op_seq, int trans_n case Transaction::OP_COLL_REMOVE: { coll_t cid = i.get_cid(); - hobject_t oid = i.get_oid(); + ghobject_t oid = i.get_oid(); if (_check_replay_guard(cid, oid, spos) > 0) r = _remove(cid, oid, spos); } @@ -2172,7 +2256,7 @@ unsigned FileStore::_do_transaction(Transaction& t, uint64_t op_seq, int trans_n // WARNING: this is deprecated and buggy; only here to replay old journals. coll_t ocid = i.get_cid(); coll_t ncid = i.get_cid(); - hobject_t oid = i.get_oid(); + ghobject_t oid = i.get_oid(); r = _collection_add(ocid, ncid, oid, spos); if (r == 0 && (_check_replay_guard(ocid, oid, spos) > 0)) @@ -2183,9 +2267,9 @@ unsigned FileStore::_do_transaction(Transaction& t, uint64_t op_seq, int trans_n case Transaction::OP_COLL_MOVE_RENAME: { coll_t oldcid = i.get_cid(); - hobject_t oldoid = i.get_oid(); + ghobject_t oldoid = i.get_oid(); coll_t newcid = i.get_cid(); - hobject_t newoid = i.get_oid(); + ghobject_t newoid = i.get_oid(); r = _collection_move_rename(oldcid, oldoid, newcid, newoid, spos); } break; @@ -2225,14 +2309,14 @@ unsigned FileStore::_do_transaction(Transaction& t, uint64_t op_seq, int trans_n case Transaction::OP_OMAP_CLEAR: { coll_t cid(i.get_cid()); - hobject_t oid = i.get_oid(); + ghobject_t oid = i.get_oid(); r = _omap_clear(cid, oid, spos); } break; case Transaction::OP_OMAP_SETKEYS: { coll_t cid(i.get_cid()); - hobject_t oid = i.get_oid(); + ghobject_t oid = i.get_oid(); map<string, bufferlist> aset; i.get_attrset(aset); r = _omap_setkeys(cid, oid, aset, spos); @@ -2241,7 +2325,7 @@ unsigned FileStore::_do_transaction(Transaction& t, uint64_t op_seq, int trans_n case Transaction::OP_OMAP_RMKEYS: { coll_t cid(i.get_cid()); - hobject_t oid = i.get_oid(); + ghobject_t oid = i.get_oid(); set<string> keys; i.get_keyset(keys); r = _omap_rmkeys(cid, oid, keys, spos); @@ -2250,7 +2334,7 @@ unsigned FileStore::_do_transaction(Transaction& t, uint64_t op_seq, int trans_n case Transaction::OP_OMAP_RMKEYRANGE: { coll_t cid(i.get_cid()); - hobject_t oid = i.get_oid(); + ghobject_t oid = i.get_oid(); string first, last; first = i.get_key(); last = i.get_key(); @@ -2260,7 +2344,7 @@ unsigned FileStore::_do_transaction(Transaction& t, uint64_t op_seq, int trans_n case Transaction::OP_OMAP_SETHEADER: { coll_t cid(i.get_cid()); - hobject_t oid = i.get_oid(); + ghobject_t oid = i.get_oid(); bufferlist bl; i.get_bl(bl); r = _omap_setheader(cid, oid, bl, spos); @@ -2380,7 +2464,7 @@ unsigned FileStore::_do_transaction(Transaction& t, uint64_t op_seq, int trans_n // -------------------- // objects -bool FileStore::exists(coll_t cid, const hobject_t& oid) +bool FileStore::exists(coll_t cid, const ghobject_t& oid) { struct stat st; if (stat(cid, oid, &st) == 0) @@ -2390,7 +2474,7 @@ bool FileStore::exists(coll_t cid, const hobject_t& oid) } int FileStore::stat( - coll_t cid, const hobject_t& oid, struct stat *st, bool allow_eio) + coll_t cid, const ghobject_t& oid, struct stat *st, bool allow_eio) { int r = lfn_stat(cid, oid, st); assert(allow_eio || !m_filestore_fail_eio || r != -EIO); @@ -2412,7 +2496,7 @@ int FileStore::stat( int FileStore::read( coll_t cid, - const hobject_t& oid, + const ghobject_t& oid, uint64_t offset, size_t len, bufferlist& bl, @@ -2448,6 +2532,17 @@ int FileStore::read( } bptr.set_length(got); // properly size the buffer bl.push_back(bptr); // put it in the target bufferlist + + if (m_filestore_sloppy_crc && (!replaying || backend->can_checkpoint())) { + ostringstream ss; + int errors = backend->_crc_verify_read(**fd, offset, got, bl, &ss); + if (errors > 0) { + dout(0) << "FileStore::read " << cid << "/" << oid << " " << offset << "~" + << got << " ... BAD CRC:\n" << ss.str() << dendl; + assert(0 == "bad crc on read"); + } + } + lfn_close(fd); dout(10) << "FileStore::read " << cid << "/" << oid << " " << offset << "~" @@ -2460,7 +2555,7 @@ int FileStore::read( } } -int FileStore::fiemap(coll_t cid, const hobject_t& oid, +int FileStore::fiemap(coll_t cid, const ghobject_t& oid, uint64_t offset, size_t len, bufferlist& bl) { @@ -2538,7 +2633,7 @@ done: } -int FileStore::_remove(coll_t cid, const hobject_t& oid, +int FileStore::_remove(coll_t cid, const ghobject_t& oid, const SequencerPosition &spos) { dout(15) << "remove " << cid << "/" << oid << dendl; @@ -2547,7 +2642,7 @@ int FileStore::_remove(coll_t cid, const hobject_t& oid, return r; } -int FileStore::_truncate(coll_t cid, const hobject_t& oid, uint64_t size) +int FileStore::_truncate(coll_t cid, const ghobject_t& oid, uint64_t size) { dout(15) << "truncate " << cid << "/" << oid << " size " << size << dendl; int r = lfn_truncate(cid, oid, size); @@ -2556,7 +2651,7 @@ int FileStore::_truncate(coll_t cid, const hobject_t& oid, uint64_t size) } -int FileStore::_touch(coll_t cid, const hobject_t& oid) +int FileStore::_touch(coll_t cid, const ghobject_t& oid) { dout(15) << "touch " << cid << "/" << oid << dendl; @@ -2571,7 +2666,7 @@ int FileStore::_touch(coll_t cid, const hobject_t& oid) return r; } -int FileStore::_write(coll_t cid, const hobject_t& oid, +int FileStore::_write(coll_t cid, const ghobject_t& oid, uint64_t offset, size_t len, const bufferlist& bl, bool replica) { @@ -2609,6 +2704,11 @@ int FileStore::_write(coll_t cid, const hobject_t& oid, if (r == 0) r = bl.length(); + if (r >= 0 && m_filestore_sloppy_crc) { + int rc = backend->_crc_update_write(**fd, offset, len, bl); + assert(rc >= 0); + } + // flush? if (!replaying && g_conf->filestore_wbthrottle_enable) @@ -2620,7 +2720,7 @@ int FileStore::_write(coll_t cid, const hobject_t& oid, return r; } -int FileStore::_zero(coll_t cid, const hobject_t& oid, uint64_t offset, size_t len) +int FileStore::_zero(coll_t cid, const ghobject_t& oid, uint64_t offset, size_t len) { dout(15) << "zero " << cid << "/" << oid << " " << offset << "~" << len << dendl; int ret = 0; @@ -2640,6 +2740,11 @@ int FileStore::_zero(coll_t cid, const hobject_t& oid, uint64_t offset, size_t l ret = -errno; lfn_close(fd); + if (ret >= 0 && m_filestore_sloppy_crc) { + int rc = backend->_crc_update_zero(**fd, offset, len); + assert(rc >= 0); + } + if (ret == 0) goto out; // yay! if (ret != -EOPNOTSUPP) @@ -2663,7 +2768,7 @@ int FileStore::_zero(coll_t cid, const hobject_t& oid, uint64_t offset, size_t l return ret; } -int FileStore::_clone(coll_t cid, const hobject_t& oldoid, const hobject_t& newoid, +int FileStore::_clone(coll_t cid, const ghobject_t& oldoid, const ghobject_t& newoid, const SequencerPosition& spos) { dout(15) << "clone " << cid << "/" << oldoid << " -> " << cid << "/" << newoid << dendl; @@ -2793,11 +2898,15 @@ int FileStore::_do_copy_range(int from, int to, uint64_t srcoff, uint64_t len, u break; pos += r; } + if (r >= 0 && m_filestore_sloppy_crc) { + int rc = backend->_crc_update_clone_range(from, to, srcoff, len, dstoff); + assert(rc >= 0); + } dout(20) << "_do_copy_range " << srcoff << "~" << len << " to " << dstoff << " = " << r << dendl; return r; } -int FileStore::_clone_range(coll_t cid, const hobject_t& oldoid, const hobject_t& newoid, +int FileStore::_clone_range(coll_t cid, const ghobject_t& oldoid, const ghobject_t& newoid, uint64_t srcoff, uint64_t len, uint64_t dstoff, const SequencerPosition& spos) { @@ -3238,23 +3347,23 @@ int FileStore::_fsetattrs(int fd, map<string, bufferptr> &aset) } // debug EIO injection -void FileStore::inject_data_error(const hobject_t &oid) { +void FileStore::inject_data_error(const ghobject_t &oid) { Mutex::Locker l(read_error_lock); dout(10) << __func__ << ": init error on " << oid << dendl; data_error_set.insert(oid); } -void FileStore::inject_mdata_error(const hobject_t &oid) { +void FileStore::inject_mdata_error(const ghobject_t &oid) { Mutex::Locker l(read_error_lock); dout(10) << __func__ << ": init error on " << oid << dendl; mdata_error_set.insert(oid); } -void FileStore::debug_obj_on_delete(const hobject_t &oid) { +void FileStore::debug_obj_on_delete(const ghobject_t &oid) { Mutex::Locker l(read_error_lock); dout(10) << __func__ << ": clear error on " << oid << dendl; data_error_set.erase(oid); mdata_error_set.erase(oid); } -bool FileStore::debug_data_eio(const hobject_t &oid) { +bool FileStore::debug_data_eio(const ghobject_t &oid) { Mutex::Locker l(read_error_lock); if (data_error_set.count(oid)) { dout(10) << __func__ << ": inject error on " << oid << dendl; @@ -3263,7 +3372,7 @@ bool FileStore::debug_data_eio(const hobject_t &oid) { return false; } } -bool FileStore::debug_mdata_eio(const hobject_t &oid) { +bool FileStore::debug_mdata_eio(const ghobject_t &oid) { Mutex::Locker l(read_error_lock); if (mdata_error_set.count(oid)) { dout(10) << __func__ << ": inject error on " << oid << dendl; @@ -3276,7 +3385,7 @@ bool FileStore::debug_mdata_eio(const hobject_t &oid) { // objects -int FileStore::getattr(coll_t cid, const hobject_t& oid, const char *name, bufferptr &bp) +int FileStore::getattr(coll_t cid, const ghobject_t& oid, const char *name, bufferptr &bp) { dout(15) << "getattr " << cid << "/" << oid << " '" << name << "'" << dendl; FDRef fd; @@ -3322,7 +3431,7 @@ int FileStore::getattr(coll_t cid, const hobject_t& oid, const char *name, buffe } } -int FileStore::getattrs(coll_t cid, const hobject_t& oid, map<string,bufferptr>& aset, bool user_only) +int FileStore::getattrs(coll_t cid, const ghobject_t& oid, map<string,bufferptr>& aset, bool user_only) { dout(15) << "getattrs " << cid << "/" << oid << dendl; FDRef fd; @@ -3381,7 +3490,7 @@ int FileStore::getattrs(coll_t cid, const hobject_t& oid, map<string,bufferptr>& } } -int FileStore::_setattrs(coll_t cid, const hobject_t& oid, map<string,bufferptr>& aset, +int FileStore::_setattrs(coll_t cid, const ghobject_t& oid, map<string,bufferptr>& aset, const SequencerPosition &spos) { map<string, bufferlist> omap_set; @@ -3466,7 +3575,7 @@ int FileStore::_setattrs(coll_t cid, const hobject_t& oid, map<string,bufferptr> } -int FileStore::_rmattr(coll_t cid, const hobject_t& oid, const char *name, +int FileStore::_rmattr(coll_t cid, const ghobject_t& oid, const char *name, const SequencerPosition &spos) { dout(15) << "rmattr " << cid << "/" << oid << " '" << name << "'" << dendl; @@ -3501,7 +3610,7 @@ int FileStore::_rmattr(coll_t cid, const hobject_t& oid, const char *name, return r; } -int FileStore::_rmattrs(coll_t cid, const hobject_t& oid, +int FileStore::_rmattrs(coll_t cid, const ghobject_t& oid, const SequencerPosition &spos) { dout(15) << "rmattrs " << cid << "/" << oid << dendl; @@ -3697,14 +3806,14 @@ int FileStore::_collection_remove_recursive(const coll_t &cid, return r; } - vector<hobject_t> objects; - hobject_t max; + vector<ghobject_t> objects; + ghobject_t max; r = 0; while (!max.is_max()) { r = collection_list_partial(cid, max, 200, 300, 0, &objects, &max); if (r < 0) return r; - for (vector<hobject_t>::iterator i = objects.begin(); + for (vector<ghobject_t>::iterator i = objects.begin(); i != objects.end(); ++i) { assert(_check_replay_guard(cid, *i, spos)); @@ -3776,7 +3885,7 @@ int FileStore::collection_version_current(coll_t c, uint32_t *version) if (r < 0) return r; *version = index->collection_version(); - if (*version == on_disk_version) + if (*version == target_version) return 1; else return 0; @@ -3869,9 +3978,9 @@ bool FileStore::collection_empty(coll_t c) int r = get_index(c, &index); if (r < 0) return false; - vector<hobject_t> ls; + vector<ghobject_t> ls; collection_list_handle_t handle; - r = index->collection_list_partial(hobject_t(), 1, 1, 0, &ls, NULL); + r = index->collection_list_partial(ghobject_t(), 1, 1, 0, &ls, NULL); if (r < 0) { assert(!m_filestore_fail_eio || r != -EIO); return false; @@ -3879,14 +3988,14 @@ bool FileStore::collection_empty(coll_t c) return ls.empty(); } -int FileStore::collection_list_range(coll_t c, hobject_t start, hobject_t end, - snapid_t seq, vector<hobject_t> *ls) +int FileStore::collection_list_range(coll_t c, ghobject_t start, ghobject_t end, + snapid_t seq, vector<ghobject_t> *ls) { bool done = false; - hobject_t next = start; + ghobject_t next = start; while (!done) { - vector<hobject_t> next_objects; + vector<ghobject_t> next_objects; int r = collection_list_partial(c, next, get_ideal_list_min(), get_ideal_list_max(), seq, &next_objects, &next); @@ -3913,10 +4022,11 @@ int FileStore::collection_list_range(coll_t c, hobject_t start, hobject_t end, return 0; } -int FileStore::collection_list_partial(coll_t c, hobject_t start, +int FileStore::collection_list_partial(coll_t c, ghobject_t start, int min, int max, snapid_t seq, - vector<hobject_t> *ls, hobject_t *next) + vector<ghobject_t> *ls, ghobject_t *next) { + dout(10) << "collection_list_partial: " << c << dendl; Index index; int r = get_index(c, &index); if (r < 0) @@ -3928,10 +4038,12 @@ int FileStore::collection_list_partial(coll_t c, hobject_t start, assert(!m_filestore_fail_eio || r != -EIO); return r; } + if (ls) + dout(20) << "objects: " << *ls << dendl; return 0; } -int FileStore::collection_list(coll_t c, vector<hobject_t>& ls) +int FileStore::collection_list(coll_t c, vector<ghobject_t>& ls) { Index index; int r = get_index(c, &index); @@ -3942,7 +4054,7 @@ int FileStore::collection_list(coll_t c, vector<hobject_t>& ls) return r; } -int FileStore::omap_get(coll_t c, const hobject_t &hoid, +int FileStore::omap_get(coll_t c, const ghobject_t &hoid, bufferlist *header, map<string, bufferlist> *out) { @@ -3961,7 +4073,7 @@ int FileStore::omap_get(coll_t c, const hobject_t &hoid, int FileStore::omap_get_header( coll_t c, - const hobject_t &hoid, + const ghobject_t &hoid, bufferlist *bl, bool allow_eio) { @@ -3978,7 +4090,7 @@ int FileStore::omap_get_header( return 0; } -int FileStore::omap_get_keys(coll_t c, const hobject_t &hoid, set<string> *keys) +int FileStore::omap_get_keys(coll_t c, const ghobject_t &hoid, set<string> *keys) { dout(15) << __func__ << " " << c << "/" << hoid << dendl; IndexedPath path; @@ -3993,7 +4105,7 @@ int FileStore::omap_get_keys(coll_t c, const hobject_t &hoid, set<string> *keys) return 0; } -int FileStore::omap_get_values(coll_t c, const hobject_t &hoid, +int FileStore::omap_get_values(coll_t c, const ghobject_t &hoid, const set<string> &keys, map<string, bufferlist> *out) { @@ -4010,7 +4122,7 @@ int FileStore::omap_get_values(coll_t c, const hobject_t &hoid, return 0; } -int FileStore::omap_check_keys(coll_t c, const hobject_t &hoid, +int FileStore::omap_check_keys(coll_t c, const ghobject_t &hoid, const set<string> &keys, set<string> *out) { @@ -4028,7 +4140,7 @@ int FileStore::omap_check_keys(coll_t c, const hobject_t &hoid, } ObjectMap::ObjectMapIterator FileStore::get_omap_iterator(coll_t c, - const hobject_t &hoid) + const ghobject_t &hoid) { dout(15) << __func__ << " " << c << "/" << hoid << dendl; IndexedPath path; @@ -4099,7 +4211,7 @@ int FileStore::_destroy_collection(coll_t c) } -int FileStore::_collection_add(coll_t c, coll_t oldcid, const hobject_t& o, +int FileStore::_collection_add(coll_t c, coll_t oldcid, const ghobject_t& o, const SequencerPosition& spos) { dout(15) << "collection_add " << c << "/" << o << " from " << oldcid << "/" << o << dendl; @@ -4147,8 +4259,8 @@ int FileStore::_collection_add(coll_t c, coll_t oldcid, const hobject_t& o, return r; } -int FileStore::_collection_move_rename(coll_t oldcid, const hobject_t& oldoid, - coll_t c, const hobject_t& o, +int FileStore::_collection_move_rename(coll_t oldcid, const ghobject_t& oldoid, + coll_t c, const ghobject_t& o, const SequencerPosition& spos) { dout(15) << __func__ << " " << c << "/" << o << " from " << oldcid << "/" << oldoid << dendl; @@ -4227,7 +4339,7 @@ void FileStore::_inject_failure() } } -int FileStore::_omap_clear(coll_t cid, const hobject_t &hoid, +int FileStore::_omap_clear(coll_t cid, const ghobject_t &hoid, const SequencerPosition &spos) { dout(15) << __func__ << " " << cid << "/" << hoid << dendl; IndexedPath path; @@ -4240,7 +4352,7 @@ int FileStore::_omap_clear(coll_t cid, const hobject_t &hoid, return 0; } -int FileStore::_omap_setkeys(coll_t cid, const hobject_t &hoid, +int FileStore::_omap_setkeys(coll_t cid, const ghobject_t &hoid, const map<string, bufferlist> &aset, const SequencerPosition &spos) { dout(15) << __func__ << " " << cid << "/" << hoid << dendl; @@ -4251,7 +4363,7 @@ int FileStore::_omap_setkeys(coll_t cid, const hobject_t &hoid, return object_map->set_keys(hoid, aset, &spos); } -int FileStore::_omap_rmkeys(coll_t cid, const hobject_t &hoid, +int FileStore::_omap_rmkeys(coll_t cid, const ghobject_t &hoid, const set<string> &keys, const SequencerPosition &spos) { dout(15) << __func__ << " " << cid << "/" << hoid << dendl; @@ -4265,7 +4377,7 @@ int FileStore::_omap_rmkeys(coll_t cid, const hobject_t &hoid, return 0; } -int FileStore::_omap_rmkeyrange(coll_t cid, const hobject_t &hoid, +int FileStore::_omap_rmkeyrange(coll_t cid, const ghobject_t &hoid, const string& first, const string& last, const SequencerPosition &spos) { dout(15) << __func__ << " " << cid << "/" << hoid << " [" << first << "," << last << "]" << dendl; @@ -4282,7 +4394,7 @@ int FileStore::_omap_rmkeyrange(coll_t cid, const hobject_t &hoid, return _omap_rmkeys(cid, hoid, keys, spos); } -int FileStore::_omap_setheader(coll_t cid, const hobject_t &hoid, +int FileStore::_omap_setheader(coll_t cid, const ghobject_t &hoid, const bufferlist &bl, const SequencerPosition &spos) { @@ -4342,8 +4454,8 @@ int FileStore::_split_collection(coll_t cid, _close_replay_guard(dest, spos); } if (g_conf->filestore_debug_verify_split) { - vector<hobject_t> objects; - hobject_t next; + vector<ghobject_t> objects; + ghobject_t next; while (1) { collection_list_partial( cid, @@ -4353,7 +4465,7 @@ int FileStore::_split_collection(coll_t cid, &next); if (objects.empty()) break; - for (vector<hobject_t>::iterator i = objects.begin(); + for (vector<ghobject_t>::iterator i = objects.begin(); i != objects.end(); ++i) { dout(20) << __func__ << ": " << *i << " still in source " @@ -4362,7 +4474,7 @@ int FileStore::_split_collection(coll_t cid, } objects.clear(); } - next = hobject_t(); + next = ghobject_t(); while (1) { collection_list_partial( dest, @@ -4372,7 +4484,7 @@ int FileStore::_split_collection(coll_t cid, &next); if (objects.empty()) break; - for (vector<hobject_t>::iterator i = objects.begin(); + for (vector<ghobject_t>::iterator i = objects.begin(); i != objects.end(); ++i) { dout(20) << __func__ << ": " << *i << " now in dest " @@ -4438,6 +4550,8 @@ const char** FileStore::get_tracked_conf_keys() const "filestore_kill_at", "filestore_fail_eio", "filestore_replica_fadvise", + "filestore_sloppy_crc", + "filestore_sloppy_crc_block_size", NULL }; return KEYS; @@ -4454,6 +4568,8 @@ void FileStore::handle_conf_change(const struct md_config_t *conf, changed.count("filestore_queue_committing_max_bytes") || changed.count("filestore_kill_at") || changed.count("filestore_fail_eio") || + changed.count("filestore_sloppy_crc") || + changed.count("filestore_sloppy_crc_block_size") || changed.count("filestore_replica_fadvise")) { Mutex::Locker l(lock); m_filestore_min_sync_interval = conf->filestore_min_sync_interval; @@ -4465,6 +4581,8 @@ void FileStore::handle_conf_change(const struct md_config_t *conf, m_filestore_kill_at.set(conf->filestore_kill_at); m_filestore_fail_eio = conf->filestore_fail_eio; m_filestore_replica_fadvise = conf->filestore_replica_fadvise; + m_filestore_sloppy_crc = conf->filestore_sloppy_crc; + m_filestore_sloppy_crc_block_size = conf->filestore_sloppy_crc_block_size; } if (changed.count("filestore_commit_timeout")) { Mutex::Locker l(sync_entry_timeo_lock); @@ -4520,3 +4638,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)); +} |