]> git.proxmox.com Git - ceph.git/blame - ceph/src/mds/Mutation.cc
update download target update for octopus release
[ceph.git] / ceph / src / mds / Mutation.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 "Mutation.h"
16#include "ScatterLock.h"
17#include "CDir.h"
18
7c673cae
FG
19// MutationImpl
20
21void MutationImpl::pin(MDSCacheObject *o)
22{
23 if (pins.count(o) == 0) {
24 o->get(MDSCacheObject::PIN_REQUEST);
25 pins.insert(o);
26 }
27}
28
29void MutationImpl::unpin(MDSCacheObject *o)
30{
11fdf7f2 31 ceph_assert(pins.count(o));
7c673cae
FG
32 o->put(MDSCacheObject::PIN_REQUEST);
33 pins.erase(o);
34}
35
36void MutationImpl::set_stickydirs(CInode *in)
37{
11fdf7f2 38 if (!stickydiri || stickydiri != in) {
7c673cae 39 in->get_stickydirs();
11fdf7f2
TL
40 if (stickydiri)
41 stickydiri->put_stickydirs();
42 stickydiri = in;
43 }
44}
45
46void MutationImpl::put_stickydirs()
47{
48 if (stickydiri) {
49 stickydiri->put_stickydirs();
50 stickydiri = nullptr;
51
7c673cae
FG
52 }
53}
54
55void MutationImpl::drop_pins()
56{
11fdf7f2
TL
57 for (auto& o : pins)
58 o->put(MDSCacheObject::PIN_REQUEST);
7c673cae
FG
59 pins.clear();
60}
61
62void MutationImpl::start_locking(SimpleLock *lock, int target)
63{
11fdf7f2 64 ceph_assert(locking == NULL);
7c673cae
FG
65 pin(lock->get_parent());
66 locking = lock;
67 locking_target_mds = target;
68}
69
70void MutationImpl::finish_locking(SimpleLock *lock)
71{
11fdf7f2 72 ceph_assert(locking == lock);
7c673cae
FG
73 locking = NULL;
74 locking_target_mds = -1;
75}
76
11fdf7f2
TL
77void MutationImpl::LockOpVec::erase_rdlock(SimpleLock* lock)
78{
79 for (int i = size() - 1; i >= 0; --i) {
80 auto& op = (*this)[i];
81 if (op.lock == lock && op.is_rdlock()) {
82 erase(begin() + i);
83 return;
84 }
85 }
86}
87
88void MutationImpl::LockOpVec::sort_and_merge()
89{
90 std::sort(begin(), end(), SimpleLock::ptr_lt());
91 // merge ops on the same lock
92 for (auto i = end() - 1; i > begin(); ) {
93 auto j = i;
94 while (--j >= begin()) {
95 if (i->lock != j->lock)
96 break;
97 }
98 if (i - j == 1) {
99 i = j;
100 continue;
101 }
102
103 // merge
104 ++j;
105 for (auto k = i; k > j; --k) {
106 if (k->is_remote_wrlock()) {
107 ceph_assert(!j->is_remote_wrlock());
108 j->wrlock_target = k->wrlock_target;
109 }
110 j->flags |= k->flags;
111 }
112 if (j->is_xlock()) {
113 // xlock overwrites other types
114 ceph_assert(!j->is_remote_wrlock());
115 j->flags = MutationImpl::LockOp::XLOCK;
116 }
117 erase(j + 1, i + 1);
118 i = j - 1;
119 }
120}
7c673cae
FG
121
122// auth pins
123bool MutationImpl::is_auth_pinned(MDSCacheObject *object) const
124{
125 return auth_pins.count(object) || remote_auth_pins.count(object);
126}
127
128void MutationImpl::auth_pin(MDSCacheObject *object)
129{
130 if (!is_auth_pinned(object)) {
131 object->auth_pin(this);
132 auth_pins.insert(object);
133 }
134}
135
136void MutationImpl::auth_unpin(MDSCacheObject *object)
137{
11fdf7f2 138 ceph_assert(auth_pins.count(object));
7c673cae
FG
139 object->auth_unpin(this);
140 auth_pins.erase(object);
141}
142
143void MutationImpl::drop_local_auth_pins()
144{
11fdf7f2
TL
145 for (const auto& p : auth_pins) {
146 ceph_assert(p->is_auth());
147 p->auth_unpin(this);
7c673cae
FG
148 }
149 auth_pins.clear();
150}
151
152void MutationImpl::add_projected_inode(CInode *in)
153{
154 projected_inodes.push_back(in);
155}
156
157void MutationImpl::pop_and_dirty_projected_inodes()
158{
159 while (!projected_inodes.empty()) {
160 CInode *in = projected_inodes.front();
161 projected_inodes.pop_front();
162 in->pop_and_dirty_projected_inode(ls);
163 }
164}
165
166void MutationImpl::add_projected_fnode(CDir *dir)
167{
168 projected_fnodes.push_back(dir);
169}
170
171void MutationImpl::pop_and_dirty_projected_fnodes()
172{
173 while (!projected_fnodes.empty()) {
174 CDir *dir = projected_fnodes.front();
175 projected_fnodes.pop_front();
176 dir->pop_and_dirty_projected_fnode(ls);
177 }
178}
179
180void MutationImpl::add_updated_lock(ScatterLock *lock)
181{
182 updated_locks.push_back(lock);
183}
184
185void MutationImpl::add_cow_inode(CInode *in)
186{
187 pin(in);
188 dirty_cow_inodes.push_back(in);
189}
190
191void MutationImpl::add_cow_dentry(CDentry *dn)
192{
193 pin(dn);
194 dirty_cow_dentries.push_back(pair<CDentry*,version_t>(dn, dn->get_projected_version()));
195}
196
197void MutationImpl::apply()
198{
199 pop_and_dirty_projected_inodes();
200 pop_and_dirty_projected_fnodes();
201
202 for (list<CInode*>::iterator p = dirty_cow_inodes.begin();
203 p != dirty_cow_inodes.end();
204 ++p)
205 (*p)->_mark_dirty(ls);
206 for (list<pair<CDentry*,version_t> >::iterator p = dirty_cow_dentries.begin();
207 p != dirty_cow_dentries.end();
208 ++p)
209 p->first->mark_dirty(p->second, ls);
210
211 for (list<ScatterLock*>::iterator p = updated_locks.begin();
212 p != updated_locks.end();
213 ++p)
214 (*p)->mark_dirty();
215}
216
217void MutationImpl::cleanup()
218{
219 drop_local_auth_pins();
220 drop_pins();
221}
222
223void MutationImpl::_dump_op_descriptor_unlocked(ostream& stream) const
224{
225 stream << "Mutation";
226}
227
228// MDRequestImpl
229
230MDRequestImpl::~MDRequestImpl()
231{
7c673cae
FG
232 delete _more;
233}
234
235MDRequestImpl::More* MDRequestImpl::more()
236{
237 if (!_more)
238 _more = new More();
239 return _more;
240}
241
242bool MDRequestImpl::has_more() const
243{
244 return _more != nullptr;
245}
246
247bool MDRequestImpl::has_witnesses()
248{
249 return (_more != nullptr) && (!_more->witnessed.empty());
250}
251
252bool MDRequestImpl::slave_did_prepare()
253{
254 return has_more() && more()->slave_commit;
255}
256
257bool MDRequestImpl::slave_rolling_back()
258{
259 return has_more() && more()->slave_rolling_back;
260}
261
262bool MDRequestImpl::did_ino_allocation() const
263{
264 return alloc_ino || used_prealloc_ino || prealloc_inos.size();
265}
266
267bool MDRequestImpl::freeze_auth_pin(CInode *inode)
268{
11fdf7f2 269 ceph_assert(!more()->rename_inode || more()->rename_inode == inode);
7c673cae
FG
270 more()->rename_inode = inode;
271 more()->is_freeze_authpin = true;
272 auth_pin(inode);
273 if (!inode->freeze_inode(1)) {
274 return false;
275 }
276 inode->freeze_auth_pin();
277 inode->unfreeze_inode();
278 return true;
279}
280
281void MDRequestImpl::unfreeze_auth_pin(bool clear_inode)
282{
11fdf7f2 283 ceph_assert(more()->is_freeze_authpin);
7c673cae
FG
284 CInode *inode = more()->rename_inode;
285 if (inode->is_frozen_auth_pin())
286 inode->unfreeze_auth_pin();
287 else
288 inode->unfreeze_inode();
289 more()->is_freeze_authpin = false;
290 if (clear_inode)
291 more()->rename_inode = NULL;
292}
293
294void MDRequestImpl::set_remote_frozen_auth_pin(CInode *inode)
295{
296 more()->rename_inode = inode;
297 more()->is_remote_frozen_authpin = true;
298}
299
300void MDRequestImpl::set_ambiguous_auth(CInode *inode)
301{
11fdf7f2
TL
302 ceph_assert(!more()->rename_inode || more()->rename_inode == inode);
303 ceph_assert(!more()->is_ambiguous_auth);
7c673cae
FG
304
305 inode->set_ambiguous_auth();
306 more()->rename_inode = inode;
307 more()->is_ambiguous_auth = true;
308}
309
310void MDRequestImpl::clear_ambiguous_auth()
311{
312 CInode *inode = more()->rename_inode;
11fdf7f2 313 ceph_assert(inode && more()->is_ambiguous_auth);
7c673cae
FG
314 inode->clear_ambiguous_auth();
315 more()->is_ambiguous_auth = false;
316}
317
318bool MDRequestImpl::can_auth_pin(MDSCacheObject *object)
319{
320 return object->can_auth_pin() ||
321 (is_auth_pinned(object) && has_more() &&
322 more()->is_freeze_authpin &&
323 more()->rename_inode == object);
324}
325
326void MDRequestImpl::drop_local_auth_pins()
327{
328 if (has_more() && more()->is_freeze_authpin)
329 unfreeze_auth_pin(true);
330 MutationImpl::drop_local_auth_pins();
331}
332
333const filepath& MDRequestImpl::get_filepath()
334{
335 if (client_request)
336 return client_request->get_filepath();
337 return more()->filepath1;
338}
339
340const filepath& MDRequestImpl::get_filepath2()
341{
342 if (client_request)
343 return client_request->get_filepath2();
344 return more()->filepath2;
345}
346
347void MDRequestImpl::set_filepath(const filepath& fp)
348{
11fdf7f2 349 ceph_assert(!client_request);
7c673cae
FG
350 more()->filepath1 = fp;
351}
352
353void MDRequestImpl::set_filepath2(const filepath& fp)
354{
11fdf7f2 355 ceph_assert(!client_request);
7c673cae
FG
356 more()->filepath2 = fp;
357}
358
b32b8144 359bool MDRequestImpl::is_queued_for_replay() const
7c673cae 360{
b32b8144 361 return client_request ? client_request->is_queued_for_replay() : false;
7c673cae
FG
362}
363
11fdf7f2 364MClientRequest::const_ref MDRequestImpl::release_client_request()
91327a77
AA
365{
366 msg_lock.lock();
11fdf7f2
TL
367 MClientRequest::const_ref req;
368 req.swap(client_request);
91327a77
AA
369 msg_lock.unlock();
370 return req;
371}
372
11fdf7f2 373void MDRequestImpl::reset_slave_request(const MMDSSlaveRequest::const_ref& req)
91327a77
AA
374{
375 msg_lock.lock();
11fdf7f2
TL
376 MMDSSlaveRequest::const_ref old;
377 old.swap(slave_request);
91327a77
AA
378 slave_request = req;
379 msg_lock.unlock();
11fdf7f2 380 old.reset();
91327a77
AA
381}
382
7c673cae
FG
383void MDRequestImpl::print(ostream &out) const
384{
385 out << "request(" << reqid;
386 //if (request) out << " " << *request;
387 if (is_slave()) out << " slave_to mds." << slave_to_mds;
388 if (client_request) out << " cr=" << client_request;
389 if (slave_request) out << " sr=" << slave_request;
390 out << ")";
391}
392
393void MDRequestImpl::dump(Formatter *f) const
394{
395 _dump(f);
396}
397
398void MDRequestImpl::_dump(Formatter *f) const
399{
400 f->dump_string("flag_point", state_string());
401 f->dump_stream("reqid") << reqid;
402 {
91327a77 403 msg_lock.lock();
11fdf7f2
TL
404 auto _client_request = client_request;
405 auto _slave_request =slave_request;
91327a77
AA
406 msg_lock.unlock();
407
408 if (_client_request) {
7c673cae
FG
409 f->dump_string("op_type", "client_request");
410 f->open_object_section("client_info");
91327a77
AA
411 f->dump_stream("client") << _client_request->get_orig_source();
412 f->dump_int("tid", _client_request->get_tid());
7c673cae 413 f->close_section(); // client_info
91327a77 414 } else if (is_slave() && _slave_request) { // replies go to an existing mdr
7c673cae
FG
415 f->dump_string("op_type", "slave_request");
416 f->open_object_section("master_info");
91327a77 417 f->dump_stream("master") << _slave_request->get_orig_source();
7c673cae
FG
418 f->close_section(); // master_info
419
420 f->open_object_section("request_info");
91327a77 421 f->dump_int("attempt", _slave_request->get_attempt());
7c673cae 422 f->dump_string("op_type",
91327a77
AA
423 MMDSSlaveRequest::get_opname(_slave_request->get_op()));
424 f->dump_int("lock_type", _slave_request->get_lock_type());
425 f->dump_stream("object_info") << _slave_request->get_object_info();
426 f->dump_stream("srcdnpath") << _slave_request->srcdnpath;
427 f->dump_stream("destdnpath") << _slave_request->destdnpath;
428 f->dump_stream("witnesses") << _slave_request->witnesses;
7c673cae 429 f->dump_bool("has_inode_export",
91327a77
AA
430 _slave_request->inode_export_v != 0);
431 f->dump_int("inode_export_v", _slave_request->inode_export_v);
432 f->dump_stream("op_stamp") << _slave_request->op_stamp;
7c673cae
FG
433 f->close_section(); // request_info
434 }
435 else if (internal_op != -1) { // internal request
436 f->dump_string("op_type", "internal_op");
437 f->dump_int("internal_op", internal_op);
438 f->dump_string("op_name", ceph_mds_op_name(internal_op));
439 }
440 else {
441 f->dump_string("op_type", "no_available_op_found");
442 }
443 }
444 {
445 f->open_array_section("events");
11fdf7f2 446 std::lock_guard l(lock);
7c673cae
FG
447 for (auto& i : events) {
448 f->dump_object("event", i);
449 }
450 f->close_section(); // events
451 }
452}
453
454void MDRequestImpl::_dump_op_descriptor_unlocked(ostream& stream) const
455{
91327a77 456 msg_lock.lock();
11fdf7f2
TL
457 auto _client_request = client_request;
458 auto _slave_request = slave_request;
91327a77
AA
459 msg_lock.unlock();
460
461 if (_client_request) {
462 _client_request->print(stream);
463 } else if (_slave_request) {
464 _slave_request->print(stream);
7c673cae
FG
465 } else if (internal_op >= 0) {
466 stream << "internal op " << ceph_mds_op_name(internal_op) << ":" << reqid;
467 } else {
468 // drat, it's triggered by a slave request, but we don't have a message
469 // FIXME
470 stream << "rejoin:" << reqid;
471 }
472}