]> git.proxmox.com Git - ceph.git/blob - ceph/src/mds/MDSTable.cc
import ceph pacific 16.2.5
[ceph.git] / ceph / src / mds / MDSTable.cc
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
15 #include "MDSTable.h"
16
17 #include "MDSRank.h"
18 #include "MDLog.h"
19
20 #include "osdc/Filer.h"
21
22 #include "include/types.h"
23
24 #include "common/config.h"
25 #include "common/errno.h"
26 #include "common/Finisher.h"
27
28 #include "include/ceph_assert.h"
29
30
31 #define dout_context g_ceph_context
32 #define dout_subsys ceph_subsys_mds
33 #undef dout_prefix
34 #define dout_prefix *_dout << "mds." << rank << "." << table_name << ": "
35
36
37 class MDSTableIOContext : public MDSIOContextBase
38 {
39 protected:
40 MDSTable *ida;
41 MDSRank *get_mds() override {return ida->mds;}
42 public:
43 explicit MDSTableIOContext(MDSTable *ida_) : ida(ida_) {
44 ceph_assert(ida != NULL);
45 }
46 };
47
48
49 class C_IO_MT_Save : public MDSTableIOContext {
50 version_t version;
51 public:
52 C_IO_MT_Save(MDSTable *i, version_t v) : MDSTableIOContext(i), version(v) {}
53 void finish(int r) override {
54 ida->save_2(r, version);
55 }
56 void print(ostream& out) const override {
57 out << "table_save(" << ida->table_name << ")";
58 }
59 };
60
61 void MDSTable::save(MDSContext *onfinish, version_t v)
62 {
63 if (v > 0 && v <= committing_version) {
64 dout(10) << "save v " << version << " - already saving "
65 << committing_version << " >= needed " << v << dendl;
66 if (onfinish)
67 waitfor_save[v].push_back(onfinish);
68 return;
69 }
70
71 dout(10) << "save v " << version << dendl;
72 ceph_assert(is_active());
73
74 bufferlist bl;
75 encode(version, bl);
76 encode_state(bl);
77
78 committing_version = version;
79
80 if (onfinish)
81 waitfor_save[version].push_back(onfinish);
82
83 // write (async)
84 SnapContext snapc;
85 object_t oid = get_object_name();
86 object_locator_t oloc(mds->get_metadata_pool());
87 mds->objecter->write_full(oid, oloc,
88 snapc,
89 bl, ceph::real_clock::now(), 0,
90 new C_OnFinisher(new C_IO_MT_Save(this, version),
91 mds->finisher));
92 }
93
94 void MDSTable::save_2(int r, version_t v)
95 {
96 if (r < 0) {
97 dout(1) << "save error " << r << " v " << v << dendl;
98 mds->clog->error() << "failed to store table " << table_name << " object,"
99 << " errno " << r;
100 mds->handle_write_error(r);
101 return;
102 }
103
104 dout(10) << "save_2 v " << v << dendl;
105 committed_version = v;
106
107 MDSContext::vec ls;
108 while (!waitfor_save.empty()) {
109 auto it = waitfor_save.begin();
110 if (it->first > v) break;
111 auto& v = it->second;
112 ls.insert(ls.end(), v.begin(), v.end());
113 waitfor_save.erase(it);
114 }
115 finish_contexts(g_ceph_context, ls, 0);
116 }
117
118
119 void MDSTable::reset()
120 {
121 reset_state();
122 projected_version = version;
123 state = STATE_ACTIVE;
124 }
125
126
127
128 // -----------------------
129
130 class C_IO_MT_Load : public MDSTableIOContext {
131 public:
132 Context *onfinish;
133 bufferlist bl;
134 C_IO_MT_Load(MDSTable *i, Context *o) : MDSTableIOContext(i), onfinish(o) {}
135 void finish(int r) override {
136 ida->load_2(r, bl, onfinish);
137 }
138 void print(ostream& out) const override {
139 out << "table_load(" << ida->table_name << ")";
140 }
141 };
142
143 object_t MDSTable::get_object_name() const
144 {
145 char n[50];
146 if (per_mds)
147 snprintf(n, sizeof(n), "mds%d_%s", int(rank), table_name.c_str());
148 else
149 snprintf(n, sizeof(n), "mds_%s", table_name.c_str());
150 return object_t(n);
151 }
152
153 void MDSTable::load(MDSContext *onfinish)
154 {
155 dout(10) << "load" << dendl;
156
157 ceph_assert(is_undef());
158 state = STATE_OPENING;
159
160 C_IO_MT_Load *c = new C_IO_MT_Load(this, onfinish);
161 object_t oid = get_object_name();
162 object_locator_t oloc(mds->get_metadata_pool());
163 mds->objecter->read_full(oid, oloc, CEPH_NOSNAP, &c->bl, 0,
164 new C_OnFinisher(c, mds->finisher));
165 }
166
167 void MDSTable::load_2(int r, bufferlist& bl, Context *onfinish)
168 {
169 ceph_assert(is_opening());
170 state = STATE_ACTIVE;
171 if (r == -CEPHFS_EBLOCKLISTED) {
172 mds->respawn();
173 return;
174 }
175 if (r < 0) {
176 derr << "load_2 could not read table: " << r << dendl;
177 mds->clog->error() << "error reading table object '" << get_object_name()
178 << "' " << r << " (" << cpp_strerror(r) << ")";
179 mds->damaged();
180 ceph_assert(r >= 0); // Should be unreachable because damaged() calls respawn()
181 }
182
183 dout(10) << "load_2 got " << bl.length() << " bytes" << dendl;
184 auto p = bl.cbegin();
185
186 try {
187 decode(version, p);
188 projected_version = committed_version = version;
189 dout(10) << "load_2 loaded v" << version << dendl;
190 decode_state(p);
191 } catch (buffer::error &e) {
192 mds->clog->error() << "error decoding table object '" << get_object_name()
193 << "': " << e.what();
194 mds->damaged();
195 ceph_assert(r >= 0); // Should be unreachable because damaged() calls respawn()
196 }
197
198 if (onfinish) {
199 onfinish->complete(0);
200 }
201 }