1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
15 #include "include/unordered_map.h"
17 #if defined(__FreeBSD__)
18 #include <sys/param.h>
23 #include "common/Cond.h"
24 #include "common/config.h"
25 #include "common/debug.h"
26 #include "include/buffer.h"
28 #include "IndexManager.h"
29 #include "HashIndex.h"
30 #include "CollectionIndex.h"
32 #include "chain_xattr.h"
36 using ceph::bufferlist
;
37 using ceph::bufferptr
;
41 static int set_version(const char *path
, uint32_t version
) {
44 return chain_setxattr
<true, true>(
45 path
, "user.cephos.collection_version", bl
.c_str(),
49 static int get_version(const char *path
, uint32_t *version
) {
50 bufferptr
bp(PATH_MAX
);
51 int r
= chain_getxattr(path
, "user.cephos.collection_version",
52 bp
.c_str(), bp
.length());
69 IndexManager::~IndexManager() {
71 for (ceph::unordered_map
<coll_t
, CollectionIndex
* > ::iterator it
= col_indices
.begin();
72 it
!= col_indices
.end(); ++it
) {
81 int IndexManager::init_index(coll_t c
, const char *path
, uint32_t version
) {
82 std::unique_lock l
{lock
};
83 int r
= set_version(path
, version
);
86 HashIndex
index(cct
, c
, path
, cct
->_conf
->filestore_merge_threshold
,
87 cct
->_conf
->filestore_split_multiple
,
89 cct
->_conf
->filestore_index_retry_probability
);
93 return index
.read_settings();
96 int IndexManager::build_index(coll_t c
, const char *path
, CollectionIndex
**index
) {
98 // Need to check the collection generation
100 uint32_t version
= 0;
101 r
= get_version(path
, &version
);
106 case CollectionIndex::FLAT_INDEX_TAG
:
107 case CollectionIndex::HASH_INDEX_TAG
: // fall through
108 case CollectionIndex::HASH_INDEX_TAG_2
: // fall through
109 case CollectionIndex::HOBJECT_WITH_POOL
: {
110 // Must be a HashIndex
111 *index
= new HashIndex(cct
, c
, path
,
112 cct
->_conf
->filestore_merge_threshold
,
113 cct
->_conf
->filestore_split_multiple
,
115 return (*index
)->read_settings();
117 default: ceph_abort();
122 *index
= new HashIndex(cct
, c
, path
, cct
->_conf
->filestore_merge_threshold
,
123 cct
->_conf
->filestore_split_multiple
,
124 CollectionIndex::HOBJECT_WITH_POOL
,
125 cct
->_conf
->filestore_index_retry_probability
);
126 return (*index
)->read_settings();
130 bool IndexManager::get_index_optimistic(coll_t c
, Index
*index
) {
131 std::shared_lock l
{lock
};
132 ceph::unordered_map
<coll_t
, CollectionIndex
* > ::iterator it
= col_indices
.find(c
);
133 if (it
== col_indices
.end())
135 index
->index
= it
->second
;
139 int IndexManager::get_index(coll_t c
, const string
& baseDir
, Index
*index
) {
140 if (get_index_optimistic(c
, index
))
142 std::unique_lock l
{lock
};
143 ceph::unordered_map
<coll_t
, CollectionIndex
* > ::iterator it
= col_indices
.find(c
);
144 if (it
== col_indices
.end()) {
146 snprintf(path
, sizeof(path
), "%s/current/%s", baseDir
.c_str(), c
.to_str().c_str());
147 CollectionIndex
* colIndex
= NULL
;
148 int r
= build_index(c
, path
, &colIndex
);
151 col_indices
[c
] = colIndex
;
152 index
->index
= colIndex
;
154 index
->index
= it
->second
;