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/Mutex.h"
24 #include "common/Cond.h"
25 #include "common/config.h"
26 #include "common/debug.h"
27 #include "include/buffer.h"
29 #include "IndexManager.h"
30 #include "HashIndex.h"
31 #include "CollectionIndex.h"
33 #include "chain_xattr.h"
35 static int set_version(const char *path
, uint32_t version
) {
38 return chain_setxattr
<true, true>(
39 path
, "user.cephos.collection_version", bl
.c_str(),
43 static int get_version(const char *path
, uint32_t *version
) {
44 bufferptr
bp(PATH_MAX
);
45 int r
= chain_getxattr(path
, "user.cephos.collection_version",
46 bp
.c_str(), bp
.length());
63 IndexManager::~IndexManager() {
65 for (ceph::unordered_map
<coll_t
, CollectionIndex
* > ::iterator it
= col_indices
.begin();
66 it
!= col_indices
.end(); ++it
) {
75 int IndexManager::init_index(coll_t c
, const char *path
, uint32_t version
) {
76 RWLock::WLocker
l(lock
);
77 int r
= set_version(path
, version
);
80 HashIndex
index(cct
, c
, path
, cct
->_conf
->filestore_merge_threshold
,
81 cct
->_conf
->filestore_split_multiple
,
83 cct
->_conf
->filestore_index_retry_probability
);
87 return index
.read_settings();
90 int IndexManager::build_index(coll_t c
, const char *path
, CollectionIndex
**index
) {
92 // Need to check the collection generation
95 r
= get_version(path
, &version
);
100 case CollectionIndex::FLAT_INDEX_TAG
:
101 case CollectionIndex::HASH_INDEX_TAG
: // fall through
102 case CollectionIndex::HASH_INDEX_TAG_2
: // fall through
103 case CollectionIndex::HOBJECT_WITH_POOL
: {
104 // Must be a HashIndex
105 *index
= new HashIndex(cct
, c
, path
,
106 cct
->_conf
->filestore_merge_threshold
,
107 cct
->_conf
->filestore_split_multiple
,
109 return (*index
)->read_settings();
111 default: ceph_abort();
116 *index
= new HashIndex(cct
, c
, path
, cct
->_conf
->filestore_merge_threshold
,
117 cct
->_conf
->filestore_split_multiple
,
118 CollectionIndex::HOBJECT_WITH_POOL
,
119 cct
->_conf
->filestore_index_retry_probability
);
120 return (*index
)->read_settings();
124 bool IndexManager::get_index_optimistic(coll_t c
, Index
*index
) {
125 RWLock::RLocker
l(lock
);
126 ceph::unordered_map
<coll_t
, CollectionIndex
* > ::iterator it
= col_indices
.find(c
);
127 if (it
== col_indices
.end())
129 index
->index
= it
->second
;
133 int IndexManager::get_index(coll_t c
, const string
& baseDir
, Index
*index
) {
134 if (get_index_optimistic(c
, index
))
136 RWLock::WLocker
l(lock
);
137 ceph::unordered_map
<coll_t
, CollectionIndex
* > ::iterator it
= col_indices
.find(c
);
138 if (it
== col_indices
.end()) {
140 snprintf(path
, sizeof(path
), "%s/current/%s", baseDir
.c_str(), c
.to_str().c_str());
141 CollectionIndex
* colIndex
= NULL
;
142 int r
= build_index(c
, path
, &colIndex
);
145 col_indices
[c
] = colIndex
;
146 index
->index
= colIndex
;
148 index
->index
= it
->second
;