]> git.proxmox.com Git - ceph.git/blame - ceph/src/os/filestore/IndexManager.cc
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / os / filestore / IndexManager.cc
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3/*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
7 *
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.
12 *
13 */
14
7c673cae
FG
15#include "include/unordered_map.h"
16
17#if defined(__FreeBSD__)
18#include <sys/param.h>
19#endif
20
21#include <errno.h>
22
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"
28
29#include "IndexManager.h"
30#include "HashIndex.h"
31#include "CollectionIndex.h"
32
33#include "chain_xattr.h"
34
35static int set_version(const char *path, uint32_t version) {
36 bufferlist bl;
11fdf7f2 37 encode(version, bl);
7c673cae
FG
38 return chain_setxattr<true, true>(
39 path, "user.cephos.collection_version", bl.c_str(),
40 bl.length());
41}
42
43static 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());
47 if (r < 0) {
48 if (r != -ENOENT) {
49 *version = 0;
50 return 0;
51 } else {
52 return r;
53 }
54 }
55 bp.set_length(r);
56 bufferlist bl;
57 bl.push_back(bp);
11fdf7f2
TL
58 auto i = bl.cbegin();
59 decode(*version, i);
7c673cae
FG
60 return 0;
61}
62
63IndexManager::~IndexManager() {
64
65 for (ceph::unordered_map<coll_t, CollectionIndex* > ::iterator it = col_indices.begin();
66 it != col_indices.end(); ++it) {
67
68 delete it->second;
69 it->second = NULL;
70 }
71 col_indices.clear();
72}
73
74
75int IndexManager::init_index(coll_t c, const char *path, uint32_t version) {
76 RWLock::WLocker l(lock);
77 int r = set_version(path, version);
78 if (r < 0)
79 return r;
80 HashIndex index(cct, c, path, cct->_conf->filestore_merge_threshold,
81 cct->_conf->filestore_split_multiple,
82 version,
83 cct->_conf->filestore_index_retry_probability);
224ce89b
WB
84 r = index.init();
85 if (r < 0)
86 return r;
87 return index.read_settings();
7c673cae
FG
88}
89
90int IndexManager::build_index(coll_t c, const char *path, CollectionIndex **index) {
91 if (upgrade) {
92 // Need to check the collection generation
93 int r;
94 uint32_t version = 0;
95 r = get_version(path, &version);
96 if (r < 0)
97 return r;
98
99 switch (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,
224ce89b
WB
107 cct->_conf->filestore_split_multiple,
108 version);
109 return (*index)->read_settings();
7c673cae
FG
110 }
111 default: ceph_abort();
112 }
113
114 } else {
115 // No need to check
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);
224ce89b 120 return (*index)->read_settings();
7c673cae
FG
121 }
122}
123
124bool 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())
128 return false;
129 index->index = it->second;
130 return true;
131}
132
133int IndexManager::get_index(coll_t c, const string& baseDir, Index *index) {
134 if (get_index_optimistic(c, index))
135 return 0;
136 RWLock::WLocker l(lock);
137 ceph::unordered_map<coll_t, CollectionIndex* > ::iterator it = col_indices.find(c);
138 if (it == col_indices.end()) {
139 char path[PATH_MAX];
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);
143 if (r < 0)
144 return r;
145 col_indices[c] = colIndex;
146 index->index = colIndex;
147 } else {
148 index->index = it->second;
149 }
150 return 0;
151}