]>
git.proxmox.com Git - ceph.git/blob - ceph/src/mds/Mutation.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
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.
16 #include "ScatterLock.h"
21 void MutationImpl::pin(MDSCacheObject
*o
)
23 if (pins
.count(o
) == 0) {
24 o
->get(MDSCacheObject::PIN_REQUEST
);
29 void MutationImpl::unpin(MDSCacheObject
*o
)
31 ceph_assert(pins
.count(o
));
32 o
->put(MDSCacheObject::PIN_REQUEST
);
36 void MutationImpl::set_stickydirs(CInode
*in
)
38 if (!stickydiri
|| stickydiri
!= in
) {
41 stickydiri
->put_stickydirs();
46 void MutationImpl::put_stickydirs()
49 stickydiri
->put_stickydirs();
55 void MutationImpl::drop_pins()
58 o
->put(MDSCacheObject::PIN_REQUEST
);
62 void MutationImpl::start_locking(SimpleLock
*lock
, int target
)
64 ceph_assert(locking
== NULL
);
65 pin(lock
->get_parent());
67 locking_target_mds
= target
;
70 void MutationImpl::finish_locking(SimpleLock
*lock
)
72 ceph_assert(locking
== lock
);
74 locking_target_mds
= -1;
77 void MutationImpl::LockOpVec::erase_rdlock(SimpleLock
* lock
)
79 for (int i
= size() - 1; i
>= 0; --i
) {
80 auto& op
= (*this)[i
];
81 if (op
.lock
== lock
&& op
.is_rdlock()) {
88 void MutationImpl::LockOpVec::sort_and_merge()
90 std::sort(begin(), end(), SimpleLock::ptr_lt());
91 // merge ops on the same lock
92 for (auto i
= end() - 1; i
> begin(); ) {
94 while (--j
>= begin()) {
95 if (i
->lock
!= j
->lock
)
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
;
110 j
->flags
|= k
->flags
;
113 // xlock overwrites other types
114 ceph_assert(!j
->is_remote_wrlock());
115 j
->flags
= MutationImpl::LockOp::XLOCK
;
123 bool MutationImpl::is_auth_pinned(MDSCacheObject
*object
) const
125 return auth_pins
.count(object
) || remote_auth_pins
.count(object
);
128 void MutationImpl::auth_pin(MDSCacheObject
*object
)
130 if (!is_auth_pinned(object
)) {
131 object
->auth_pin(this);
132 auth_pins
.insert(object
);
136 void MutationImpl::auth_unpin(MDSCacheObject
*object
)
138 ceph_assert(auth_pins
.count(object
));
139 object
->auth_unpin(this);
140 auth_pins
.erase(object
);
143 void MutationImpl::drop_local_auth_pins()
145 for (const auto& p
: auth_pins
) {
146 ceph_assert(p
->is_auth());
152 void MutationImpl::add_projected_inode(CInode
*in
)
154 projected_inodes
.push_back(in
);
157 void MutationImpl::pop_and_dirty_projected_inodes()
159 while (!projected_inodes
.empty()) {
160 CInode
*in
= projected_inodes
.front();
161 projected_inodes
.pop_front();
162 in
->pop_and_dirty_projected_inode(ls
);
166 void MutationImpl::add_projected_fnode(CDir
*dir
)
168 projected_fnodes
.push_back(dir
);
171 void MutationImpl::pop_and_dirty_projected_fnodes()
173 while (!projected_fnodes
.empty()) {
174 CDir
*dir
= projected_fnodes
.front();
175 projected_fnodes
.pop_front();
176 dir
->pop_and_dirty_projected_fnode(ls
);
180 void MutationImpl::add_updated_lock(ScatterLock
*lock
)
182 updated_locks
.push_back(lock
);
185 void MutationImpl::add_cow_inode(CInode
*in
)
188 dirty_cow_inodes
.push_back(in
);
191 void MutationImpl::add_cow_dentry(CDentry
*dn
)
194 dirty_cow_dentries
.push_back(pair
<CDentry
*,version_t
>(dn
, dn
->get_projected_version()));
197 void MutationImpl::apply()
199 pop_and_dirty_projected_inodes();
200 pop_and_dirty_projected_fnodes();
202 for (list
<CInode
*>::iterator p
= dirty_cow_inodes
.begin();
203 p
!= dirty_cow_inodes
.end();
205 (*p
)->_mark_dirty(ls
);
206 for (list
<pair
<CDentry
*,version_t
> >::iterator p
= dirty_cow_dentries
.begin();
207 p
!= dirty_cow_dentries
.end();
209 p
->first
->mark_dirty(p
->second
, ls
);
211 for (list
<ScatterLock
*>::iterator p
= updated_locks
.begin();
212 p
!= updated_locks
.end();
217 void MutationImpl::cleanup()
219 drop_local_auth_pins();
223 void MutationImpl::_dump_op_descriptor_unlocked(ostream
& stream
) const
225 stream
<< "Mutation";
230 MDRequestImpl::~MDRequestImpl()
235 MDRequestImpl::More
* MDRequestImpl::more()
242 bool MDRequestImpl::has_more() const
244 return _more
!= nullptr;
247 bool MDRequestImpl::has_witnesses()
249 return (_more
!= nullptr) && (!_more
->witnessed
.empty());
252 bool MDRequestImpl::slave_did_prepare()
254 return has_more() && more()->slave_commit
;
257 bool MDRequestImpl::slave_rolling_back()
259 return has_more() && more()->slave_rolling_back
;
262 bool MDRequestImpl::did_ino_allocation() const
264 return alloc_ino
|| used_prealloc_ino
|| prealloc_inos
.size();
267 bool MDRequestImpl::freeze_auth_pin(CInode
*inode
)
269 ceph_assert(!more()->rename_inode
|| more()->rename_inode
== inode
);
270 more()->rename_inode
= inode
;
271 more()->is_freeze_authpin
= true;
273 if (!inode
->freeze_inode(1)) {
276 inode
->freeze_auth_pin();
277 inode
->unfreeze_inode();
281 void MDRequestImpl::unfreeze_auth_pin(bool clear_inode
)
283 ceph_assert(more()->is_freeze_authpin
);
284 CInode
*inode
= more()->rename_inode
;
285 if (inode
->is_frozen_auth_pin())
286 inode
->unfreeze_auth_pin();
288 inode
->unfreeze_inode();
289 more()->is_freeze_authpin
= false;
291 more()->rename_inode
= NULL
;
294 void MDRequestImpl::set_remote_frozen_auth_pin(CInode
*inode
)
296 more()->rename_inode
= inode
;
297 more()->is_remote_frozen_authpin
= true;
300 void MDRequestImpl::set_ambiguous_auth(CInode
*inode
)
302 ceph_assert(!more()->rename_inode
|| more()->rename_inode
== inode
);
303 ceph_assert(!more()->is_ambiguous_auth
);
305 inode
->set_ambiguous_auth();
306 more()->rename_inode
= inode
;
307 more()->is_ambiguous_auth
= true;
310 void MDRequestImpl::clear_ambiguous_auth()
312 CInode
*inode
= more()->rename_inode
;
313 ceph_assert(inode
&& more()->is_ambiguous_auth
);
314 inode
->clear_ambiguous_auth();
315 more()->is_ambiguous_auth
= false;
318 bool MDRequestImpl::can_auth_pin(MDSCacheObject
*object
)
320 return object
->can_auth_pin() ||
321 (is_auth_pinned(object
) && has_more() &&
322 more()->is_freeze_authpin
&&
323 more()->rename_inode
== object
);
326 void MDRequestImpl::drop_local_auth_pins()
328 if (has_more() && more()->is_freeze_authpin
)
329 unfreeze_auth_pin(true);
330 MutationImpl::drop_local_auth_pins();
333 const filepath
& MDRequestImpl::get_filepath()
336 return client_request
->get_filepath();
337 return more()->filepath1
;
340 const filepath
& MDRequestImpl::get_filepath2()
343 return client_request
->get_filepath2();
344 return more()->filepath2
;
347 void MDRequestImpl::set_filepath(const filepath
& fp
)
349 ceph_assert(!client_request
);
350 more()->filepath1
= fp
;
353 void MDRequestImpl::set_filepath2(const filepath
& fp
)
355 ceph_assert(!client_request
);
356 more()->filepath2
= fp
;
359 bool MDRequestImpl::is_queued_for_replay() const
361 return client_request
? client_request
->is_queued_for_replay() : false;
364 MClientRequest::const_ref
MDRequestImpl::release_client_request()
367 MClientRequest::const_ref req
;
368 req
.swap(client_request
);
373 void MDRequestImpl::reset_slave_request(const MMDSSlaveRequest::const_ref
& req
)
376 MMDSSlaveRequest::const_ref old
;
377 old
.swap(slave_request
);
383 void MDRequestImpl::print(ostream
&out
) const
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
;
393 void MDRequestImpl::dump(Formatter
*f
) const
398 void MDRequestImpl::_dump(Formatter
*f
) const
400 f
->dump_string("flag_point", state_string());
401 f
->dump_stream("reqid") << reqid
;
404 auto _client_request
= client_request
;
405 auto _slave_request
=slave_request
;
408 if (_client_request
) {
409 f
->dump_string("op_type", "client_request");
410 f
->open_object_section("client_info");
411 f
->dump_stream("client") << _client_request
->get_orig_source();
412 f
->dump_int("tid", _client_request
->get_tid());
413 f
->close_section(); // client_info
414 } else if (is_slave() && _slave_request
) { // replies go to an existing mdr
415 f
->dump_string("op_type", "slave_request");
416 f
->open_object_section("master_info");
417 f
->dump_stream("master") << _slave_request
->get_orig_source();
418 f
->close_section(); // master_info
420 f
->open_object_section("request_info");
421 f
->dump_int("attempt", _slave_request
->get_attempt());
422 f
->dump_string("op_type",
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
;
429 f
->dump_bool("has_inode_export",
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
;
433 f
->close_section(); // request_info
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
));
441 f
->dump_string("op_type", "no_available_op_found");
445 f
->open_array_section("events");
446 std::lock_guard
l(lock
);
447 for (auto& i
: events
) {
448 f
->dump_object("event", i
);
450 f
->close_section(); // events
454 void MDRequestImpl::_dump_op_descriptor_unlocked(ostream
& stream
) const
457 auto _client_request
= client_request
;
458 auto _slave_request
= slave_request
;
461 if (_client_request
) {
462 _client_request
->print(stream
);
463 } else if (_slave_request
) {
464 _slave_request
->print(stream
);
465 } else if (internal_op
>= 0) {
466 stream
<< "internal op " << ceph_mds_op_name(internal_op
) << ":" << reqid
;
468 // drat, it's triggered by a slave request, but we don't have a message
470 stream
<< "rejoin:" << reqid
;