]> git.proxmox.com Git - ceph.git/blame - ceph/src/mds/MDSTable.cc
import ceph pacific 16.2.5
[ceph.git] / ceph / src / mds / MDSTable.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
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
11fdf7f2 28#include "include/ceph_assert.h"
7c673cae
FG
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
37class 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_) {
11fdf7f2 44 ceph_assert(ida != NULL);
7c673cae
FG
45 }
46};
47
48
49class C_IO_MT_Save : public MDSTableIOContext {
50 version_t version;
51public:
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 }
91327a77
AA
56 void print(ostream& out) const override {
57 out << "table_save(" << ida->table_name << ")";
58 }
7c673cae
FG
59};
60
11fdf7f2 61void MDSTable::save(MDSContext *onfinish, version_t v)
7c673cae
FG
62{
63 if (v > 0 && v <= committing_version) {
64 dout(10) << "save v " << version << " - already saving "
65 << committing_version << " >= needed " << v << dendl;
11fdf7f2
TL
66 if (onfinish)
67 waitfor_save[v].push_back(onfinish);
7c673cae
FG
68 return;
69 }
70
71 dout(10) << "save v " << version << dendl;
11fdf7f2 72 ceph_assert(is_active());
7c673cae
FG
73
74 bufferlist bl;
11fdf7f2 75 encode(version, bl);
7c673cae
FG
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();
b3b6e05e 86 object_locator_t oloc(mds->get_metadata_pool());
7c673cae
FG
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
94void 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
11fdf7f2 107 MDSContext::vec ls;
7c673cae 108 while (!waitfor_save.empty()) {
11fdf7f2
TL
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);
7c673cae 114 }
11fdf7f2 115 finish_contexts(g_ceph_context, ls, 0);
7c673cae
FG
116}
117
118
119void MDSTable::reset()
120{
121 reset_state();
11fdf7f2 122 projected_version = version;
7c673cae
FG
123 state = STATE_ACTIVE;
124}
125
126
127
128// -----------------------
129
130class C_IO_MT_Load : public MDSTableIOContext {
131public:
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 }
91327a77
AA
138 void print(ostream& out) const override {
139 out << "table_load(" << ida->table_name << ")";
140 }
7c673cae
FG
141};
142
143object_t MDSTable::get_object_name() const
144{
145 char n[50];
146 if (per_mds)
11fdf7f2 147 snprintf(n, sizeof(n), "mds%d_%s", int(rank), table_name.c_str());
7c673cae 148 else
11fdf7f2 149 snprintf(n, sizeof(n), "mds_%s", table_name.c_str());
7c673cae
FG
150 return object_t(n);
151}
152
11fdf7f2 153void MDSTable::load(MDSContext *onfinish)
7c673cae
FG
154{
155 dout(10) << "load" << dendl;
156
11fdf7f2 157 ceph_assert(is_undef());
7c673cae
FG
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();
b3b6e05e 162 object_locator_t oloc(mds->get_metadata_pool());
7c673cae
FG
163 mds->objecter->read_full(oid, oloc, CEPH_NOSNAP, &c->bl, 0,
164 new C_OnFinisher(c, mds->finisher));
165}
166
167void MDSTable::load_2(int r, bufferlist& bl, Context *onfinish)
168{
11fdf7f2 169 ceph_assert(is_opening());
7c673cae 170 state = STATE_ACTIVE;
f67539c2 171 if (r == -CEPHFS_EBLOCKLISTED) {
7c673cae
FG
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();
11fdf7f2 180 ceph_assert(r >= 0); // Should be unreachable because damaged() calls respawn()
7c673cae
FG
181 }
182
183 dout(10) << "load_2 got " << bl.length() << " bytes" << dendl;
11fdf7f2 184 auto p = bl.cbegin();
7c673cae
FG
185
186 try {
11fdf7f2 187 decode(version, p);
7c673cae
FG
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();
11fdf7f2 195 ceph_assert(r >= 0); // Should be unreachable because damaged() calls respawn()
7c673cae
FG
196 }
197
198 if (onfinish) {
199 onfinish->complete(0);
200 }
201}