]> git.proxmox.com Git - ceph.git/blame - ceph/src/os/memstore/MemStore.h
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / os / memstore / MemStore.h
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) 2013- Sage Weil <sage@inktank.com>
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
15
16#ifndef CEPH_MEMSTORE_H
17#define CEPH_MEMSTORE_H
18
19#include <mutex>
20#include <boost/intrusive_ptr.hpp>
21
22#include "include/unordered_map.h"
7c673cae
FG
23#include "common/Finisher.h"
24#include "common/RefCountedObj.h"
25#include "common/RWLock.h"
26#include "os/ObjectStore.h"
27#include "PageSet.h"
11fdf7f2 28#include "include/ceph_assert.h"
7c673cae
FG
29
30class MemStore : public ObjectStore {
31public:
32 struct Object : public RefCountedObject {
11fdf7f2
TL
33 ceph::mutex xattr_mutex{ceph::make_mutex("MemStore::Object::xattr_mutex")};
34 ceph::mutex omap_mutex{ceph::make_mutex("MemStore::Object::omap_mutex")};
7c673cae
FG
35 map<string,bufferptr> xattr;
36 bufferlist omap_header;
37 map<string,bufferlist> omap;
38
39 typedef boost::intrusive_ptr<Object> Ref;
40 friend void intrusive_ptr_add_ref(Object *o) { o->get(); }
41 friend void intrusive_ptr_release(Object *o) { o->put(); }
42
43 Object() : RefCountedObject(nullptr, 0) {}
44 // interface for object data
45 virtual size_t get_size() const = 0;
46 virtual int read(uint64_t offset, uint64_t len, bufferlist &bl) = 0;
47 virtual int write(uint64_t offset, const bufferlist &bl) = 0;
48 virtual int clone(Object *src, uint64_t srcoff, uint64_t len,
49 uint64_t dstoff) = 0;
50 virtual int truncate(uint64_t offset) = 0;
51 virtual void encode(bufferlist& bl) const = 0;
11fdf7f2 52 virtual void decode(bufferlist::const_iterator& p) = 0;
7c673cae
FG
53
54 void encode_base(bufferlist& bl) const {
11fdf7f2
TL
55 using ceph::encode;
56 encode(xattr, bl);
57 encode(omap_header, bl);
58 encode(omap, bl);
7c673cae 59 }
11fdf7f2
TL
60 void decode_base(bufferlist::const_iterator& p) {
61 using ceph::decode;
62 decode(xattr, p);
63 decode(omap_header, p);
64 decode(omap, p);
7c673cae
FG
65 }
66
67 void dump(Formatter *f) const {
68 f->dump_int("data_len", get_size());
69 f->dump_int("omap_header_len", omap_header.length());
70
71 f->open_array_section("xattrs");
72 for (map<string,bufferptr>::const_iterator p = xattr.begin();
73 p != xattr.end();
74 ++p) {
75 f->open_object_section("xattr");
76 f->dump_string("name", p->first);
77 f->dump_int("length", p->second.length());
78 f->close_section();
79 }
80 f->close_section();
81
82 f->open_array_section("omap");
83 for (map<string,bufferlist>::const_iterator p = omap.begin();
84 p != omap.end();
85 ++p) {
86 f->open_object_section("pair");
87 f->dump_string("key", p->first);
88 f->dump_int("length", p->second.length());
89 f->close_section();
90 }
91 f->close_section();
92 }
93 };
94 typedef Object::Ref ObjectRef;
95
96 struct PageSetObject;
97 struct Collection : public CollectionImpl {
11fdf7f2 98 int bits = 0;
7c673cae
FG
99 CephContext *cct;
100 bool use_page_set;
101 ceph::unordered_map<ghobject_t, ObjectRef> object_hash; ///< for lookup
102 map<ghobject_t, ObjectRef> object_map; ///< for iteration
103 map<string,bufferptr> xattr;
11fdf7f2
TL
104 /// for object_{map,hash}
105 ceph::shared_mutex lock{
106 ceph::make_shared_mutex("MemStore::Collection::lock", true, false)};
107
108 bool exists = true;
109 ceph::mutex sequencer_mutex{
110 ceph::make_mutex("MemStore::Collection::sequencer_mutex")};
7c673cae
FG
111
112 typedef boost::intrusive_ptr<Collection> Ref;
113 friend void intrusive_ptr_add_ref(Collection *c) { c->get(); }
114 friend void intrusive_ptr_release(Collection *c) { c->put(); }
115
7c673cae
FG
116 ObjectRef create_object() const;
117
118 // NOTE: The lock only needs to protect the object_map/hash, not the
119 // contents of individual objects. The osd is already sequencing
120 // reads and writes, so we will never see them concurrently at this
121 // level.
122
123 ObjectRef get_object(ghobject_t oid) {
11fdf7f2 124 std::shared_lock l{lock};
7c673cae
FG
125 auto o = object_hash.find(oid);
126 if (o == object_hash.end())
127 return ObjectRef();
128 return o->second;
129 }
130
131 ObjectRef get_or_create_object(ghobject_t oid) {
11fdf7f2 132 std::lock_guard l{lock};
7c673cae
FG
133 auto result = object_hash.emplace(oid, ObjectRef());
134 if (result.second)
135 object_map[oid] = result.first->second = create_object();
136 return result.first->second;
137 }
138
139 void encode(bufferlist& bl) const {
140 ENCODE_START(1, 1, bl);
11fdf7f2
TL
141 encode(xattr, bl);
142 encode(use_page_set, bl);
7c673cae 143 uint32_t s = object_map.size();
11fdf7f2 144 encode(s, bl);
7c673cae
FG
145 for (map<ghobject_t, ObjectRef>::const_iterator p = object_map.begin();
146 p != object_map.end();
147 ++p) {
11fdf7f2 148 encode(p->first, bl);
7c673cae
FG
149 p->second->encode(bl);
150 }
151 ENCODE_FINISH(bl);
152 }
11fdf7f2 153 void decode(bufferlist::const_iterator& p) {
7c673cae 154 DECODE_START(1, p);
11fdf7f2
TL
155 decode(xattr, p);
156 decode(use_page_set, p);
7c673cae 157 uint32_t s;
11fdf7f2 158 decode(s, p);
7c673cae
FG
159 while (s--) {
160 ghobject_t k;
11fdf7f2 161 decode(k, p);
7c673cae
FG
162 auto o = create_object();
163 o->decode(p);
164 object_map.insert(make_pair(k, o));
165 object_hash.insert(make_pair(k, o));
166 }
167 DECODE_FINISH(p);
168 }
169
170 uint64_t used_bytes() const {
171 uint64_t result = 0;
172 for (map<ghobject_t, ObjectRef>::const_iterator p = object_map.begin();
173 p != object_map.end();
174 ++p) {
175 result += p->second->get_size();
176 }
177
178 return result;
179 }
180
11fdf7f2
TL
181 void flush() override {
182 }
183 bool flush_commit(Context *c) override {
184 return true;
185 }
186
7c673cae 187 explicit Collection(CephContext *cct, coll_t c)
11fdf7f2 188 : CollectionImpl(c),
7c673cae 189 cct(cct),
11fdf7f2 190 use_page_set(cct->_conf->memstore_page_set) {}
7c673cae
FG
191 };
192 typedef Collection::Ref CollectionRef;
193
194private:
195 class OmapIteratorImpl;
196
197
198 ceph::unordered_map<coll_t, CollectionRef> coll_map;
11fdf7f2
TL
199 /// rwlock to protect coll_map
200 ceph::shared_mutex coll_lock{
201 ceph::make_shared_mutex("MemStore::coll_lock")};
202 map<coll_t,CollectionRef> new_coll_map;
7c673cae
FG
203
204 CollectionRef get_collection(const coll_t& cid);
205
206 Finisher finisher;
207
208 uint64_t used_bytes;
209
210 void _do_transaction(Transaction& t);
211
212 int _touch(const coll_t& cid, const ghobject_t& oid);
213 int _write(const coll_t& cid, const ghobject_t& oid, uint64_t offset, size_t len,
214 const bufferlist& bl, uint32_t fadvise_flags = 0);
215 int _zero(const coll_t& cid, const ghobject_t& oid, uint64_t offset, size_t len);
216 int _truncate(const coll_t& cid, const ghobject_t& oid, uint64_t size);
217 int _remove(const coll_t& cid, const ghobject_t& oid);
218 int _setattrs(const coll_t& cid, const ghobject_t& oid, map<string,bufferptr>& aset);
219 int _rmattr(const coll_t& cid, const ghobject_t& oid, const char *name);
220 int _rmattrs(const coll_t& cid, const ghobject_t& oid);
221 int _clone(const coll_t& cid, const ghobject_t& oldoid, const ghobject_t& newoid);
222 int _clone_range(const coll_t& cid, const ghobject_t& oldoid,
223 const ghobject_t& newoid,
224 uint64_t srcoff, uint64_t len, uint64_t dstoff);
225 int _omap_clear(const coll_t& cid, const ghobject_t &oid);
226 int _omap_setkeys(const coll_t& cid, const ghobject_t &oid, bufferlist& aset_bl);
227 int _omap_rmkeys(const coll_t& cid, const ghobject_t &oid, bufferlist& keys_bl);
228 int _omap_rmkeyrange(const coll_t& cid, const ghobject_t &oid,
229 const string& first, const string& last);
230 int _omap_setheader(const coll_t& cid, const ghobject_t &oid, const bufferlist &bl);
231
232 int _collection_hint_expected_num_objs(const coll_t& cid, uint32_t pg_num,
233 uint64_t num_objs) const { return 0; }
234 int _create_collection(const coll_t& c, int bits);
235 int _destroy_collection(const coll_t& c);
236 int _collection_add(const coll_t& cid, const coll_t& ocid, const ghobject_t& oid);
237 int _collection_move_rename(const coll_t& oldcid, const ghobject_t& oldoid,
238 coll_t cid, const ghobject_t& o);
239 int _split_collection(const coll_t& cid, uint32_t bits, uint32_t rem, coll_t dest);
11fdf7f2 240 int _merge_collection(const coll_t& cid, uint32_t bits, coll_t dest);
7c673cae
FG
241
242 int _save();
243 int _load();
244
245 void dump(Formatter *f);
246 void dump_all();
247
248public:
249 MemStore(CephContext *cct, const string& path)
250 : ObjectStore(cct, path),
7c673cae
FG
251 finisher(cct),
252 used_bytes(0) {}
253 ~MemStore() override { }
254
255 string get_type() override {
256 return "memstore";
257 }
258
259 bool test_mount_in_use() override {
260 return false;
261 }
262
263 int mount() override;
264 int umount() override;
265
266 int fsck(bool deep) override {
267 return 0;
268 }
269
270 int validate_hobject_key(const hobject_t &obj) const override {
271 return 0;
272 }
273 unsigned get_max_attr_name_length() override {
274 return 256; // arbitrary; there is no real limit internally
275 }
276
277 int mkfs() override;
278 int mkjournal() override {
279 return 0;
280 }
281 bool wants_journal() override {
282 return false;
283 }
284 bool allows_journal() override {
285 return false;
286 }
287 bool needs_journal() override {
288 return false;
289 }
290
11fdf7f2
TL
291 int get_devices(set<string> *ls) override {
292 // no devices for us!
293 return 0;
294 }
295
296 int statfs(struct store_statfs_t *buf,
297 osd_alert_list_t* alerts = nullptr) override;
298 int pool_statfs(uint64_t pool_id, struct store_statfs_t *buf) override;
7c673cae 299
7c673cae 300 bool exists(CollectionHandle &c, const ghobject_t& oid) override;
7c673cae
FG
301 int stat(CollectionHandle &c, const ghobject_t& oid,
302 struct stat *st, bool allow_eio = false) override;
303 int set_collection_opts(
11fdf7f2 304 CollectionHandle& c,
7c673cae 305 const pool_opts_t& opts) override;
7c673cae
FG
306 int read(
307 CollectionHandle &c,
308 const ghobject_t& oid,
309 uint64_t offset,
310 size_t len,
311 bufferlist& bl,
224ce89b 312 uint32_t op_flags = 0) override;
7c673cae 313 using ObjectStore::fiemap;
11fdf7f2
TL
314 int fiemap(CollectionHandle& c, const ghobject_t& oid,
315 uint64_t offset, size_t len, bufferlist& bl) override;
316 int fiemap(CollectionHandle& c, const ghobject_t& oid, uint64_t offset,
317 size_t len, map<uint64_t, uint64_t>& destmap) override;
7c673cae
FG
318 int getattr(CollectionHandle &c, const ghobject_t& oid, const char *name,
319 bufferptr& value) override;
7c673cae
FG
320 int getattrs(CollectionHandle &c, const ghobject_t& oid,
321 map<string,bufferptr>& aset) override;
322
323 int list_collections(vector<coll_t>& ls) override;
324
325 CollectionHandle open_collection(const coll_t& c) override {
326 return get_collection(c);
327 }
11fdf7f2
TL
328 CollectionHandle create_new_collection(const coll_t& c) override;
329
330 void set_collection_commit_queue(const coll_t& cid,
331 ContextQueue *commit_queue) override {
332 }
333
7c673cae 334 bool collection_exists(const coll_t& c) override;
11fdf7f2
TL
335 int collection_empty(CollectionHandle& c, bool *empty) override;
336 int collection_bits(CollectionHandle& c) override;
337 int collection_list(CollectionHandle& cid,
7c673cae
FG
338 const ghobject_t& start, const ghobject_t& end, int max,
339 vector<ghobject_t> *ls, ghobject_t *next) override;
340
341 using ObjectStore::omap_get;
342 int omap_get(
11fdf7f2 343 CollectionHandle& c, ///< [in] Collection containing oid
7c673cae
FG
344 const ghobject_t &oid, ///< [in] Object containing omap
345 bufferlist *header, ///< [out] omap header
346 map<string, bufferlist> *out /// < [out] Key to value map
347 ) override;
348
349 using ObjectStore::omap_get_header;
350 /// Get omap header
351 int omap_get_header(
11fdf7f2 352 CollectionHandle& c, ///< [in] Collection containing oid
7c673cae
FG
353 const ghobject_t &oid, ///< [in] Object containing omap
354 bufferlist *header, ///< [out] omap header
355 bool allow_eio = false ///< [in] don't assert on eio
356 ) override;
357
358 using ObjectStore::omap_get_keys;
359 /// Get keys defined on oid
360 int omap_get_keys(
11fdf7f2 361 CollectionHandle& c, ///< [in] Collection containing oid
7c673cae
FG
362 const ghobject_t &oid, ///< [in] Object containing omap
363 set<string> *keys ///< [out] Keys defined on oid
364 ) override;
365
366 using ObjectStore::omap_get_values;
367 /// Get key values
368 int omap_get_values(
11fdf7f2 369 CollectionHandle& c, ///< [in] Collection containing oid
7c673cae
FG
370 const ghobject_t &oid, ///< [in] Object containing omap
371 const set<string> &keys, ///< [in] Keys to get
372 map<string, bufferlist> *out ///< [out] Returned keys and values
373 ) override;
374
375 using ObjectStore::omap_check_keys;
376 /// Filters keys into out which are defined on oid
377 int omap_check_keys(
11fdf7f2 378 CollectionHandle& c, ///< [in] Collection containing oid
7c673cae
FG
379 const ghobject_t &oid, ///< [in] Object containing omap
380 const set<string> &keys, ///< [in] Keys to check
381 set<string> *out ///< [out] Subset of keys defined on oid
382 ) override;
383
384 using ObjectStore::get_omap_iterator;
385 ObjectMap::ObjectMapIterator get_omap_iterator(
11fdf7f2 386 CollectionHandle& c, ///< [in] collection
7c673cae
FG
387 const ghobject_t &oid ///< [in] object
388 ) override;
389
390 void set_fsid(uuid_d u) override;
391 uuid_d get_fsid() override;
392
393 uint64_t estimate_objects_overhead(uint64_t num_objects) override {
394 return 0; //do not care
395 }
396
397 objectstore_perf_stat_t get_cur_stats() override;
398
399 const PerfCounters* get_perf_counters() const override {
400 return nullptr;
401 }
402
403
404 int queue_transactions(
11fdf7f2
TL
405 CollectionHandle& ch,
406 vector<Transaction>& tls,
7c673cae
FG
407 TrackedOpRef op = TrackedOpRef(),
408 ThreadPool::TPHandle *handle = NULL) override;
409};
410
411
412
413
414#endif