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