return snprintf(s, len, "%s/current/%s", basedir.c_str(), cid_str.c_str());
}
-Index FileStore::get_index(coll_t cid)
+int FileStore::get_index(coll_t cid, Index *index)
{
char path[PATH_MAX];
get_cdir(cid, path, sizeof(path));
- return index_manager.get_index(cid, path);
+ return index_manager.get_index(cid, path, index);
+}
+
+int FileStore::init_index(coll_t cid)
+{
+ char path[PATH_MAX];
+ get_cdir(cid, path, sizeof(path));
+ return index_manager.init_index(cid, path, on_disk_version);
}
int FileStore::lfn_find(coll_t cid, const hobject_t& oid, IndexedPath *path)
{
- Index index = get_index(cid);
+ Index index;
int r, exist;
+ r = get_index(cid, &index);
+ if (r < 0)
+ return r;
+
r = index->lookup(oid, path, &exist);
-
if (r < 0)
return r;
if (!exist)
int FileStore::lfn_open(coll_t cid, const hobject_t& oid, int flags, mode_t mode)
{
- Index index = get_index(cid);
+ Index index;
IndexedPath path;
int r, fd, exist;
+ r = get_index(cid, &index);
+ if (r < 0)
+ return r;
r = index->lookup(oid, &path, &exist);
if (r < 0) {
return r;
int exist;
int r;
if (c < cid) {
- index_new = get_index(cid);
- index_old = get_index(c);
+ r = get_index(cid, &index_new);
+ if (r < 0)
+ return r;
+ r = get_index(c, &index_old);
+ if (r < 0)
+ return r;
} else {
- index_old = get_index(c);
- index_new = get_index(cid);
+ r = get_index(c, &index_old);
+ if (r < 0)
+ return r;
+ r = get_index(cid, &index_new);
+ if (r < 0)
+ return r;
}
r = index_old->lookup(o, &path_old, &exist);
int FileStore::lfn_unlink(coll_t cid, const hobject_t& o)
{
- Index index = get_index(cid);
+ Index index;
+ int r = get_index(cid, &index);
+ if (r < 0)
+ return r;
return index->unlink(o);
}
fsid_fd = -1;
dout(10) << "mkfs fsid is " << fsid << dendl;
+ ret = write_version_stamp();
+ if (ret < 0) {
+ derr << "Firestore::mkfs: write_version_stamp() failed: "
+ << cpp_strerror(ret) << dendl;
+ goto close_fsid_fd;
+ }
+
// current
memset(&volargs, 0, sizeof(volargs));
basedir_fd = ::open(basedir.c_str(), O_RDONLY);
return ret;
}
-
int FileStore::lock_fsid()
{
struct flock l;
return 0;
}
+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)
+ return 0;
+ else
+ return -errno;
+ }
+ bufferptr bp(PATH_MAX);
+ int ret = safe_read(fd, bp.c_str(), bp.length());
+ TEMP_FAILURE_RETRY(::close(op_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)
+ return 1;
+ else
+ return 0;
+}
+
+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(op_fd));
+ if (ret < 0)
+ return -errno;
+ return 0;
+}
int FileStore::read_op_seq(const char *fn, uint64_t *seq)
{
if (ret)
goto done;
+ uint32_t version_stamp;
+ ret = version_stamp_is_valid(&version_stamp);
+ if (ret < 0) {
+ derr << "FileStore::mount : error in version_stamp_is_valid: "
+ << cpp_strerror(ret) << dendl;
+ goto done;
+ } else if (ret == 0) {
+ if (g_conf->filestore_update_collections) {
+ derr << "FileStore::mount : stale version stamp detected: "
+ << version_stamp
+ << ". Proceeding, g_conf->filestore_update_collections "
+ << "is set, DO NOT USE THIS OPTION IF YOU DO NOT KNOW WHAT IT DOES."
+ << " More details can be found on the wiki."
+ << dendl;
+ } else {
+ ret = -EINVAL;
+ derr << "FileStore::mount : stale version stamp " << version_stamp
+ << ". Please run the FileStore update script before starting the "
+ << "OSD."
+ << dendl;
+ goto done;
+ }
+ }
+
// get fsid
snprintf(buf, sizeof(buf), "%s/fsid", basedir.c_str());
fsid_fd = ::open(buf, O_RDWR|O_CREAT, 0644);
// --------------------------
// collections
+int FileStore::collection_version_current(coll_t c, uint32_t *version)
+{
+ Index index;
+ int r = get_index(c, &index);
+ if (r < 0)
+ return r;
+ *version = index->collection_version();
+ if (*version == on_disk_version)
+ return 1;
+ else
+ return 0;
+}
+
int FileStore::list_collections(vector<coll_t>& ls)
{
if (fake_collections) return collections.list_collections(ls);
collection_list_handle_t *handle)
{
if (fake_collections) return collections.collection_list(c, ls);
- Index index = get_index(c);
- int r = index->collection_list_partial(seq, max_count, &ls, handle);
+ Index index;
+ int r = get_index(c, &index);
+ if (r < 0)
+ return r;
+ r = index->collection_list_partial(seq, max_count, &ls, handle);
if (r < 0)
return r;
return 0;
int FileStore::collection_list(coll_t c, vector<hobject_t>& ls)
{
if (fake_collections) return collections.collection_list(c, ls);
- Index index = get_index(c);
+ Index index;
+ int r = get_index(c, &index);
+ if (r < 0)
+ return r;
return index->collection_list(&ls);
}
dout(10) << "create_collection " << fn << " = " << r << dendl;
if (r < 0) return r;
- Index index = get_index(c);
- return index->init();
+ return init_index(c);
}
int FileStore::_destroy_collection(coll_t c)
// fake attributes in memory, if we need to.
class FileStore : public JournalingObjectStore {
+ static const uint32_t on_disk_version = 1;
string basedir, journalpath;
std::string current_fn;
std::string current_op_seq_fn;
// Indexed Collections
IndexManager index_manager;
- Index get_index(coll_t c);
+ int get_index(coll_t c, Index *index);
+ int init_index(coll_t c);
Finisher ondisk_finisher;
int _sanity_check_fs();
bool test_mount_in_use();
+ int write_version_stamp();
+ int version_stamp_is_valid(uint32_t *version);
int read_op_seq(const char *fn, uint64_t *seq);
int write_op_seq(int, uint64_t seq);
int mount();
// collections
int list_collections(vector<coll_t>& ls);
+ int collection_version_current(coll_t c, uint32_t *version);
int collection_stat(coll_t c, struct stat *st);
bool collection_exists(coll_t c);
bool collection_empty(coll_t c);