]> git.proxmox.com Git - ceph.git/blob - ceph/src/mds/CInode.h
import 15.2.0 Octopus source
[ceph.git] / ceph / src / mds / CInode.h
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 #ifndef CEPH_CINODE_H
16 #define CEPH_CINODE_H
17
18 #include <list>
19 #include <map>
20 #include <set>
21 #include <string_view>
22
23 #include "common/config.h"
24 #include "include/counter.h"
25 #include "include/elist.h"
26 #include "include/types.h"
27 #include "include/lru.h"
28 #include "include/compact_set.h"
29
30 #include "MDSCacheObject.h"
31 #include "MDSContext.h"
32 #include "flock.h"
33
34 #include "BatchOp.h"
35 #include "CDentry.h"
36 #include "SimpleLock.h"
37 #include "ScatterLock.h"
38 #include "LocalLock.h"
39 #include "Capability.h"
40 #include "SnapRealm.h"
41 #include "Mutation.h"
42
43 #include "messages/MClientCaps.h"
44
45 #define dout_context g_ceph_context
46
47 class Context;
48 class CDir;
49 class CInode;
50 class MDCache;
51 class LogSegment;
52 struct SnapRealm;
53 class Session;
54 struct ObjectOperation;
55 class EMetaBlob;
56
57 struct cinode_lock_info_t {
58 int lock;
59 int wr_caps;
60 };
61
62 /**
63 * Base class for CInode, containing the backing store data and
64 * serialization methods. This exists so that we can read and
65 * handle CInodes from the backing store without hitting all
66 * the business logic in CInode proper.
67 */
68 class InodeStoreBase {
69 public:
70 typedef inode_t<mempool::mds_co::pool_allocator> mempool_inode;
71 typedef old_inode_t<mempool::mds_co::pool_allocator> mempool_old_inode;
72 typedef mempool::mds_co::compact_map<snapid_t, mempool_old_inode> mempool_old_inode_map;
73 typedef xattr_map<mempool::mds_co::pool_allocator> mempool_xattr_map; // FIXME bufferptr not in mempool
74
75 InodeStoreBase() {}
76
77 /* Helpers */
78 bool is_file() const { return inode.is_file(); }
79 bool is_symlink() const { return inode.is_symlink(); }
80 bool is_dir() const { return inode.is_dir(); }
81 static object_t get_object_name(inodeno_t ino, frag_t fg, std::string_view suffix);
82
83 /* Full serialization for use in ".inode" root inode objects */
84 void encode(bufferlist &bl, uint64_t features, const bufferlist *snap_blob=NULL) const;
85 void decode(bufferlist::const_iterator &bl, bufferlist& snap_blob);
86
87 /* Serialization without ENCODE_START/FINISH blocks for use embedded in dentry */
88 void encode_bare(bufferlist &bl, uint64_t features, const bufferlist *snap_blob=NULL) const;
89 void decode_bare(bufferlist::const_iterator &bl, bufferlist &snap_blob, __u8 struct_v=5);
90
91 /* For test/debug output */
92 void dump(Formatter *f) const;
93
94 /* For use by offline tools */
95 __u32 hash_dentry_name(std::string_view dn);
96 frag_t pick_dirfrag(std::string_view dn);
97
98 mempool_inode inode; // the inode itself
99 mempool::mds_co::string symlink; // symlink dest, if symlink
100 mempool_xattr_map xattrs;
101 fragtree_t dirfragtree; // dir frag tree, if any. always consistent with our dirfrag map.
102 mempool_old_inode_map old_inodes; // key = last, value.first = first
103 snapid_t oldest_snap = CEPH_NOSNAP;
104 damage_flags_t damage_flags = 0;
105 };
106
107 class InodeStore : public InodeStoreBase {
108 public:
109 void encode(bufferlist &bl, uint64_t features) const {
110 InodeStoreBase::encode(bl, features, &snap_blob);
111 }
112 void decode(bufferlist::const_iterator &bl) {
113 InodeStoreBase::decode(bl, snap_blob);
114 }
115 void encode_bare(bufferlist &bl, uint64_t features) const {
116 InodeStoreBase::encode_bare(bl, features, &snap_blob);
117 }
118 void decode_bare(bufferlist::const_iterator &bl) {
119 InodeStoreBase::decode_bare(bl, snap_blob);
120 }
121
122 static void generate_test_instances(std::list<InodeStore*>& ls);
123
124 // FIXME bufferlist not part of mempool
125 bufferlist snap_blob; // Encoded copy of SnapRealm, because we can't
126 // rehydrate it without full MDCache
127 };
128 WRITE_CLASS_ENCODER_FEATURES(InodeStore)
129
130 // just for ceph-dencoder
131 class InodeStoreBare : public InodeStore {
132 public:
133 void encode(bufferlist &bl, uint64_t features) const {
134 InodeStore::encode_bare(bl, features);
135 }
136 void decode(bufferlist::const_iterator &bl) {
137 InodeStore::decode_bare(bl);
138 }
139 static void generate_test_instances(std::list<InodeStoreBare*>& ls);
140 };
141 WRITE_CLASS_ENCODER_FEATURES(InodeStoreBare)
142
143 // cached inode wrapper
144 class CInode : public MDSCacheObject, public InodeStoreBase, public Counter<CInode> {
145 public:
146 MEMPOOL_CLASS_HELPERS();
147
148 using mempool_cap_map = mempool::mds_co::map<client_t, Capability>;
149 /**
150 * @defgroup Scrubbing and fsck
151 */
152
153 /**
154 * Report the results of validation against a particular inode.
155 * Each member is a pair of bools.
156 * <member>.first represents if validation was performed against the member.
157 * <member.second represents if the member passed validation.
158 * performed_validation is set to true if the validation was actually
159 * run. It might not be run if, for instance, the inode is marked as dirty.
160 * passed_validation is set to true if everything that was checked
161 * passed its validation.
162 */
163 struct validated_data {
164 template<typename T>struct member_status {
165 bool checked = false;
166 bool passed = false;
167 bool repaired = false;
168 int ondisk_read_retval = 0;
169 T ondisk_value;
170 T memory_value;
171 std::stringstream error_str;
172 };
173
174 struct raw_stats_t {
175 frag_info_t dirstat;
176 nest_info_t rstat;
177 };
178
179 validated_data() {}
180
181 void dump(Formatter *f) const;
182
183 bool all_damage_repaired() const;
184
185 bool performed_validation = false;
186 bool passed_validation = false;
187
188 member_status<inode_backtrace_t> backtrace;
189 member_status<mempool_inode> inode; // XXX should not be in mempool; wait for pmr
190 member_status<raw_stats_t> raw_stats;
191 };
192
193 // friends
194 friend class Server;
195 friend class Locker;
196 friend class Migrator;
197 friend class MDCache;
198 friend class StrayManager;
199 friend class CDir;
200 friend ostream& operator<<(ostream&, const CInode&);
201
202 class scrub_stamp_info_t {
203 public:
204 scrub_stamp_info_t() {}
205 void reset() {
206 scrub_start_version = last_scrub_version = 0;
207 scrub_start_stamp = last_scrub_stamp = utime_t();
208 }
209 /// version we started our latest scrub (whether in-progress or finished)
210 version_t scrub_start_version = 0;
211 /// time we started our latest scrub (whether in-progress or finished)
212 utime_t scrub_start_stamp;
213 /// version we started our most recent finished scrub
214 version_t last_scrub_version = 0;
215 /// time we started our most recent finished scrub
216 utime_t last_scrub_stamp;
217 };
218
219 class scrub_info_t : public scrub_stamp_info_t {
220 public:
221 scrub_info_t() {}
222
223 CDentry *scrub_parent = nullptr;
224 MDSContext *on_finish = nullptr;
225
226 bool last_scrub_dirty = false; /// are our stamps dirty with respect to disk state?
227 bool scrub_in_progress = false; /// are we currently scrubbing?
228 bool children_scrubbed = false;
229
230 /// my own (temporary) stamps and versions for each dirfrag we have
231 std::map<frag_t, scrub_stamp_info_t> dirfrag_stamps; // XXX not part of mempool
232
233 ScrubHeaderRef header;
234 };
235
236 /**
237 * Projection methods, used to store inode changes until they have been journaled,
238 * at which point they are popped.
239 * Usage:
240 * project_inode as needed. If you're changing xattrs or sr_t, then pass true
241 * as needed then change the xattrs/snapnode member as needed. (Dirty
242 * exception: project_past_snaprealm_parent allows you to project the
243 * snapnode after doing project_inode (i.e. you don't need to pass
244 * snap=true).
245 *
246 * Then, journal. Once journaling is done, pop_and_dirty_projected_inode.
247 * This function will take care of the inode itself, the xattrs, and the snaprealm.
248 */
249
250 class projected_inode {
251 public:
252 static sr_t* const UNDEF_SRNODE;
253
254 projected_inode() = delete;
255 explicit projected_inode(const mempool_inode &in) : inode(in) {}
256
257 mempool_inode inode;
258 std::unique_ptr<mempool_xattr_map> xattrs;
259 sr_t *snapnode = UNDEF_SRNODE;
260 };
261
262 // -- pins --
263 static const int PIN_DIRFRAG = -1;
264 static const int PIN_CAPS = 2; // client caps
265 static const int PIN_IMPORTING = -4; // importing
266 static const int PIN_OPENINGDIR = 7;
267 static const int PIN_REMOTEPARENT = 8;
268 static const int PIN_BATCHOPENJOURNAL = 9;
269 static const int PIN_SCATTERED = 10;
270 static const int PIN_STICKYDIRS = 11;
271 //static const int PIN_PURGING = -12;
272 static const int PIN_FREEZING = 13;
273 static const int PIN_FROZEN = 14;
274 static const int PIN_IMPORTINGCAPS = -15;
275 static const int PIN_PASTSNAPPARENT = -16;
276 static const int PIN_OPENINGSNAPPARENTS = 17;
277 static const int PIN_TRUNCATING = 18;
278 static const int PIN_STRAY = 19; // we pin our stray inode while active
279 static const int PIN_NEEDSNAPFLUSH = 20;
280 static const int PIN_DIRTYRSTAT = 21;
281 static const int PIN_EXPORTINGCAPS = 22;
282 static const int PIN_DIRTYPARENT = 23;
283 static const int PIN_DIRWAITER = 24;
284 static const int PIN_SCRUBQUEUE = 25;
285
286 // -- dump flags --
287 static const int DUMP_INODE_STORE_BASE = (1 << 0);
288 static const int DUMP_MDS_CACHE_OBJECT = (1 << 1);
289 static const int DUMP_LOCKS = (1 << 2);
290 static const int DUMP_STATE = (1 << 3);
291 static const int DUMP_CAPS = (1 << 4);
292 static const int DUMP_PATH = (1 << 5);
293 static const int DUMP_DIRFRAGS = (1 << 6);
294 static const int DUMP_ALL = (-1);
295 static const int DUMP_DEFAULT = DUMP_ALL & (~DUMP_PATH) & (~DUMP_DIRFRAGS);
296
297 // -- state --
298 static const int STATE_EXPORTING = (1<<0); // on nonauth bystander.
299 static const int STATE_OPENINGDIR = (1<<1);
300 static const int STATE_FREEZING = (1<<2);
301 static const int STATE_FROZEN = (1<<3);
302 static const int STATE_AMBIGUOUSAUTH = (1<<4);
303 static const int STATE_EXPORTINGCAPS = (1<<5);
304 static const int STATE_NEEDSRECOVER = (1<<6);
305 static const int STATE_RECOVERING = (1<<7);
306 static const int STATE_PURGING = (1<<8);
307 static const int STATE_DIRTYPARENT = (1<<9);
308 static const int STATE_DIRTYRSTAT = (1<<10);
309 static const int STATE_STRAYPINNED = (1<<11);
310 static const int STATE_FROZENAUTHPIN = (1<<12);
311 static const int STATE_DIRTYPOOL = (1<<13);
312 static const int STATE_REPAIRSTATS = (1<<14);
313 static const int STATE_MISSINGOBJS = (1<<15);
314 static const int STATE_EVALSTALECAPS = (1<<16);
315 static const int STATE_QUEUEDEXPORTPIN = (1<<17);
316 static const int STATE_TRACKEDBYOFT = (1<<18); // tracked by open file table
317 static const int STATE_DELAYEDEXPORTPIN = (1<<19);
318 // orphan inode needs notification of releasing reference
319 static const int STATE_ORPHAN = STATE_NOTIFYREF;
320
321 static const int MASK_STATE_EXPORTED =
322 (STATE_DIRTY|STATE_NEEDSRECOVER|STATE_DIRTYPARENT|STATE_DIRTYPOOL);
323 static const int MASK_STATE_EXPORT_KEPT =
324 (STATE_FROZEN|STATE_AMBIGUOUSAUTH|STATE_EXPORTINGCAPS|
325 STATE_QUEUEDEXPORTPIN|STATE_TRACKEDBYOFT|STATE_DELAYEDEXPORTPIN);
326
327 // -- waiters --
328 static const uint64_t WAIT_DIR = (1<<0);
329 static const uint64_t WAIT_FROZEN = (1<<1);
330 static const uint64_t WAIT_TRUNC = (1<<2);
331 static const uint64_t WAIT_FLOCK = (1<<3);
332
333 static const uint64_t WAIT_ANY_MASK = (uint64_t)(-1);
334
335 // misc
336 static const unsigned EXPORT_NONCE = 1; // nonce given to replicas created by export
337
338 // ---------------------------
339 CInode() = delete;
340 CInode(MDCache *c, bool auth=true, snapid_t f=2, snapid_t l=CEPH_NOSNAP);
341 ~CInode() override {
342 close_dirfrags();
343 close_snaprealm();
344 clear_file_locks();
345 ceph_assert(num_projected_xattrs == 0);
346 ceph_assert(num_projected_srnodes == 0);
347 ceph_assert(num_caps_wanted == 0);
348 ceph_assert(num_subtree_roots == 0);
349 ceph_assert(num_exporting_dirs == 0);
350 ceph_assert(batch_ops.empty());
351 }
352
353 std::map<int, std::unique_ptr<BatchOp>> batch_ops;
354
355 std::string_view pin_name(int p) const override;
356
357 ostream& print_db_line_prefix(ostream& out) override;
358
359 const scrub_info_t *scrub_info() const{
360 if (!scrub_infop)
361 scrub_info_create();
362 return scrub_infop;
363 }
364
365 ScrubHeaderRef get_scrub_header() {
366 if (scrub_infop == nullptr) {
367 return nullptr;
368 } else {
369 return scrub_infop->header;
370 }
371 }
372
373 bool scrub_is_in_progress() const {
374 return (scrub_infop && scrub_infop->scrub_in_progress);
375 }
376 /**
377 * Start scrubbing on this inode. That could be very short if it's
378 * a file, or take a long time if we're recursively scrubbing a directory.
379 * @pre It is not currently scrubbing
380 * @post it has set up internal scrubbing state
381 * @param scrub_version What version are we scrubbing at (usually, parent
382 * directory's get_projected_version())
383 */
384 void scrub_initialize(CDentry *scrub_parent,
385 ScrubHeaderRef& header,
386 MDSContext *f);
387 /**
388 * Get the next dirfrag to scrub. Gives you a frag_t in output param which
389 * you must convert to a CDir (and possibly load off disk).
390 * @param dir A pointer to frag_t, will be filled in with the next dirfrag to
391 * scrub if there is one.
392 * @returns 0 on success, you should scrub the passed-out frag_t right now;
393 * ENOENT: There are no remaining dirfrags to scrub
394 * <0 There was some other error (It will return -ENOTDIR if not a directory)
395 */
396 int scrub_dirfrag_next(frag_t* out_dirfrag);
397 /**
398 * Get the currently scrubbing dirfrags. When returned, the
399 * passed-in list will be filled in with all frag_ts which have
400 * been returned from scrub_dirfrag_next but not sent back
401 * via scrub_dirfrag_finished.
402 */
403 void scrub_dirfrags_scrubbing(frag_vec_t *out_dirfrags);
404 /**
405 * Report to the CInode that a dirfrag it owns has been scrubbed. Call
406 * this for every frag_t returned from scrub_dirfrag_next().
407 * @param dirfrag The frag_t that was scrubbed
408 */
409 void scrub_dirfrag_finished(frag_t dirfrag);
410 /**
411 * Call this once the scrub has been completed, whether it's a full
412 * recursive scrub on a directory or simply the data on a file (or
413 * anything in between).
414 * @param c An out param which is filled in with a Context* that must
415 * be complete()ed.
416 */
417 void scrub_finished(MDSContext **c);
418
419 void scrub_aborted(MDSContext **c);
420
421 /**
422 * Report to the CInode that alldirfrags it owns have been scrubbed.
423 */
424 void scrub_children_finished() {
425 scrub_infop->children_scrubbed = true;
426 }
427 void scrub_set_finisher(MDSContext *c) {
428 ceph_assert(!scrub_infop->on_finish);
429 scrub_infop->on_finish = c;
430 }
431
432 bool is_multiversion() const {
433 return snaprealm || // other snaprealms will link to me
434 inode.is_dir() || // links to me in other snaps
435 inode.nlink > 1 || // there are remote links, possibly snapped, that will need to find me
436 !old_inodes.empty(); // once multiversion, always multiversion. until old_inodes gets cleaned out.
437 }
438 snapid_t get_oldest_snap();
439
440 bool is_dirty_rstat() {
441 return state_test(STATE_DIRTYRSTAT);
442 }
443 void mark_dirty_rstat();
444 void clear_dirty_rstat();
445
446 CInode::projected_inode &project_inode(bool xattr = false, bool snap = false);
447 void pop_and_dirty_projected_inode(LogSegment *ls);
448
449 projected_inode *get_projected_node() {
450 if (projected_nodes.empty())
451 return NULL;
452 else
453 return &projected_nodes.back();
454 }
455
456 version_t get_projected_version() const {
457 if (projected_nodes.empty())
458 return inode.version;
459 else
460 return projected_nodes.back().inode.version;
461 }
462 bool is_projected() const {
463 return !projected_nodes.empty();
464 }
465
466 const mempool_inode *get_projected_inode() const {
467 if (projected_nodes.empty())
468 return &inode;
469 else
470 return &projected_nodes.back().inode;
471 }
472 mempool_inode *get_projected_inode() {
473 if (projected_nodes.empty())
474 return &inode;
475 else
476 return &projected_nodes.back().inode;
477 }
478 mempool_inode *get_previous_projected_inode() {
479 ceph_assert(!projected_nodes.empty());
480 auto it = projected_nodes.rbegin();
481 ++it;
482 if (it != projected_nodes.rend())
483 return &it->inode;
484 else
485 return &inode;
486 }
487
488 mempool_xattr_map *get_projected_xattrs();
489 mempool_xattr_map *get_previous_projected_xattrs();
490
491 sr_t *prepare_new_srnode(snapid_t snapid);
492 void project_snaprealm(sr_t *new_srnode);
493 sr_t *project_snaprealm(snapid_t snapid=0) {
494 sr_t* new_srnode = prepare_new_srnode(snapid);
495 project_snaprealm(new_srnode);
496 return new_srnode;
497 }
498 const sr_t *get_projected_srnode() const;
499
500 void mark_snaprealm_global(sr_t *new_srnode);
501 void clear_snaprealm_global(sr_t *new_srnode);
502 bool is_projected_snaprealm_global() const;
503
504 void record_snaprealm_past_parent(sr_t *new_snap, SnapRealm *newparent);
505 void record_snaprealm_parent_dentry(sr_t *new_snap, SnapRealm *newparent,
506 CDentry *dn, bool primary_dn);
507 void project_snaprealm_past_parent(SnapRealm *newparent);
508 void early_pop_projected_snaprealm();
509
510 mempool_old_inode& cow_old_inode(snapid_t follows, bool cow_head);
511 void split_old_inode(snapid_t snap);
512 mempool_old_inode *pick_old_inode(snapid_t last);
513 void pre_cow_old_inode();
514 bool has_snap_data(snapid_t s);
515 void purge_stale_snap_data(const std::set<snapid_t>& snaps);
516
517 size_t get_num_dirfrags() const { return dirfrags.size(); }
518 CDir* get_dirfrag(frag_t fg) {
519 auto pi = dirfrags.find(fg);
520 if (pi != dirfrags.end()) {
521 //assert(g_conf()->debug_mds < 2 || dirfragtree.is_leaf(fg)); // performance hack FIXME
522 return pi->second;
523 }
524 return NULL;
525 }
526 std::pair<bool, std::vector<CDir*>> get_dirfrags_under(frag_t fg);
527 CDir* get_approx_dirfrag(frag_t fg);
528
529 template<typename Container>
530 void get_dirfrags(Container& ls) const {
531 // all dirfrags
532 if constexpr (std::is_same_v<Container, std::vector<CDir*>>)
533 ls.reserve(ls.size() + dirfrags.size());
534 for (const auto &p : dirfrags)
535 ls.push_back(p.second);
536 }
537
538 auto get_dirfrags() const {
539 std::vector<CDir*> result;
540 get_dirfrags(result);
541 return result;
542 }
543
544 void get_nested_dirfrags(std::vector<CDir*>&) const;
545 std::vector<CDir*> get_nested_dirfrags() const {
546 std::vector<CDir*> v;
547 get_nested_dirfrags(v);
548 return v;
549 }
550 void get_subtree_dirfrags(std::vector<CDir*>&) const;
551 std::vector<CDir*> get_subtree_dirfrags() const {
552 std::vector<CDir*> v;
553 get_subtree_dirfrags(v);
554 return v;
555 }
556
557 CDir *get_or_open_dirfrag(MDCache *mdcache, frag_t fg);
558 CDir *add_dirfrag(CDir *dir);
559 void close_dirfrag(frag_t fg);
560 void close_dirfrags();
561 bool has_subtree_root_dirfrag(int auth=-1);
562 bool has_subtree_or_exporting_dirfrag();
563
564 void force_dirfrags();
565 void verify_dirfrags();
566
567 void get_stickydirs();
568 void put_stickydirs();
569
570 void add_need_snapflush(CInode *snapin, snapid_t snapid, client_t client);
571 void remove_need_snapflush(CInode *snapin, snapid_t snapid, client_t client);
572 pair<bool,bool> split_need_snapflush(CInode *cowin, CInode *in);
573
574 // -- accessors --
575 bool is_root() const { return inode.ino == MDS_INO_ROOT; }
576 bool is_stray() const { return MDS_INO_IS_STRAY(inode.ino); }
577 mds_rank_t get_stray_owner() const {
578 return (mds_rank_t)MDS_INO_STRAY_OWNER(inode.ino);
579 }
580 bool is_mdsdir() const { return MDS_INO_IS_MDSDIR(inode.ino); }
581 bool is_base() const { return MDS_INO_IS_BASE(inode.ino); }
582 bool is_system() const { return inode.ino < MDS_INO_SYSTEM_BASE; }
583 bool is_normal() const { return !(is_base() || is_system() || is_stray()); }
584
585 bool is_head() const { return last == CEPH_NOSNAP; }
586
587 // note: this overloads MDSCacheObject
588 bool is_ambiguous_auth() const {
589 return state_test(STATE_AMBIGUOUSAUTH) ||
590 MDSCacheObject::is_ambiguous_auth();
591 }
592 void set_ambiguous_auth() {
593 state_set(STATE_AMBIGUOUSAUTH);
594 }
595 void clear_ambiguous_auth(MDSContext::vec& finished);
596 void clear_ambiguous_auth();
597
598 inodeno_t ino() const { return inode.ino; }
599 vinodeno_t vino() const { return vinodeno_t(inode.ino, last); }
600 int d_type() const { return IFTODT(inode.mode); }
601
602 mempool_inode& get_inode() { return inode; }
603 const mempool_inode& get_inode() const { return inode; }
604 CDentry* get_parent_dn() { return parent; }
605 const CDentry* get_parent_dn() const { return parent; }
606 CDentry* get_projected_parent_dn() { return !projected_parent.empty() ? projected_parent.back() : parent; }
607 const CDentry* get_projected_parent_dn() const { return !projected_parent.empty() ? projected_parent.back() : parent; }
608 const CDentry* get_oldest_parent_dn() const {
609 if (parent)
610 return parent;
611 return !projected_parent.empty() ? projected_parent.front(): NULL;
612 }
613 CDir *get_parent_dir();
614 const CDir *get_projected_parent_dir() const;
615 CDir *get_projected_parent_dir();
616 CInode *get_parent_inode();
617
618 bool is_lt(const MDSCacheObject *r) const override {
619 const CInode *o = static_cast<const CInode*>(r);
620 return ino() < o->ino() ||
621 (ino() == o->ino() && last < o->last);
622 }
623
624 // -- misc --
625 bool is_ancestor_of(const CInode *other) const;
626 bool is_projected_ancestor_of(const CInode *other) const;
627
628 void make_path_string(std::string& s, bool projected=false, const CDentry *use_parent=NULL) const;
629 void make_path(filepath& s, bool projected=false) const;
630 void name_stray_dentry(std::string& dname);
631
632 // -- dirtyness --
633 version_t get_version() const { return inode.version; }
634
635 version_t pre_dirty();
636 void _mark_dirty(LogSegment *ls);
637 void mark_dirty(version_t projected_dirv, LogSegment *ls);
638 void mark_clean();
639
640 void store(MDSContext *fin);
641 void _stored(int r, version_t cv, Context *fin);
642 /**
643 * Flush a CInode to disk. This includes the backtrace, the parent
644 * directory's link, and the Inode object itself (if a base directory).
645 * @pre is_auth() on both the inode and its containing directory
646 * @pre can_auth_pin()
647 * @param fin The Context to call when the flush is completed.
648 */
649 void flush(MDSContext *fin);
650 void fetch(MDSContext *fin);
651 void _fetched(bufferlist& bl, bufferlist& bl2, Context *fin);
652
653 void build_backtrace(int64_t pool, inode_backtrace_t& bt);
654 void store_backtrace(MDSContext *fin, int op_prio=-1);
655 void _stored_backtrace(int r, version_t v, Context *fin);
656 void fetch_backtrace(Context *fin, bufferlist *backtrace);
657
658 void mark_dirty_parent(LogSegment *ls, bool dirty_pool=false);
659 void clear_dirty_parent();
660 void verify_diri_backtrace(bufferlist &bl, int err);
661 bool is_dirty_parent() { return state_test(STATE_DIRTYPARENT); }
662 bool is_dirty_pool() { return state_test(STATE_DIRTYPOOL); }
663
664 void encode_snap_blob(bufferlist &bl);
665 void decode_snap_blob(const bufferlist &bl);
666 void encode_store(bufferlist& bl, uint64_t features);
667 void decode_store(bufferlist::const_iterator& bl);
668
669 void add_dir_waiter(frag_t fg, MDSContext *c);
670 void take_dir_waiting(frag_t fg, MDSContext::vec& ls);
671 bool is_waiting_for_dir(frag_t fg) {
672 return waiting_on_dir.count(fg);
673 }
674 void add_waiter(uint64_t tag, MDSContext *c) override;
675 void take_waiting(uint64_t tag, MDSContext::vec& ls) override;
676
677 // -- encode/decode helpers --
678 void _encode_base(bufferlist& bl, uint64_t features);
679 void _decode_base(bufferlist::const_iterator& p);
680 void _encode_locks_full(bufferlist& bl);
681 void _decode_locks_full(bufferlist::const_iterator& p);
682 void _encode_locks_state_for_replica(bufferlist& bl, bool need_recover);
683 void _encode_locks_state_for_rejoin(bufferlist& bl, int rep);
684 void _decode_locks_state_for_replica(bufferlist::const_iterator& p, bool is_new);
685 void _decode_locks_rejoin(bufferlist::const_iterator& p, MDSContext::vec& waiters,
686 std::list<SimpleLock*>& eval_locks, bool survivor);
687
688 // -- import/export --
689 void encode_export(bufferlist& bl);
690 void finish_export();
691 void abort_export() {
692 put(PIN_TEMPEXPORTING);
693 ceph_assert(state_test(STATE_EXPORTINGCAPS));
694 state_clear(STATE_EXPORTINGCAPS);
695 put(PIN_EXPORTINGCAPS);
696 }
697 void decode_import(bufferlist::const_iterator& p, LogSegment *ls);
698
699 // for giving to clients
700 int encode_inodestat(bufferlist& bl, Session *session, SnapRealm *realm,
701 snapid_t snapid=CEPH_NOSNAP, unsigned max_bytes=0,
702 int getattr_wants=0);
703 void encode_cap_message(const ref_t<MClientCaps> &m, Capability *cap);
704
705 SimpleLock* get_lock(int type) override;
706
707 void set_object_info(MDSCacheObjectInfo &info) override;
708
709 void encode_lock_state(int type, bufferlist& bl) override;
710 void decode_lock_state(int type, const bufferlist& bl) override;
711 void encode_lock_iauth(bufferlist& bl);
712 void decode_lock_iauth(bufferlist::const_iterator& p);
713 void encode_lock_ilink(bufferlist& bl);
714 void decode_lock_ilink(bufferlist::const_iterator& p);
715 void encode_lock_idft(bufferlist& bl);
716 void decode_lock_idft(bufferlist::const_iterator& p);
717 void encode_lock_ifile(bufferlist& bl);
718 void decode_lock_ifile(bufferlist::const_iterator& p);
719 void encode_lock_inest(bufferlist& bl);
720 void decode_lock_inest(bufferlist::const_iterator& p);
721 void encode_lock_ixattr(bufferlist& bl);
722 void decode_lock_ixattr(bufferlist::const_iterator& p);
723 void encode_lock_isnap(bufferlist& bl);
724 void decode_lock_isnap(bufferlist::const_iterator& p);
725 void encode_lock_iflock(bufferlist& bl);
726 void decode_lock_iflock(bufferlist::const_iterator& p);
727 void encode_lock_ipolicy(bufferlist& bl);
728 void decode_lock_ipolicy(bufferlist::const_iterator& p);
729
730 void _finish_frag_update(CDir *dir, MutationRef& mut);
731
732 void clear_dirty_scattered(int type) override;
733 bool is_dirty_scattered();
734 void clear_scatter_dirty(); // on rejoin ack
735
736 void start_scatter(ScatterLock *lock);
737 void finish_scatter_update(ScatterLock *lock, CDir *dir,
738 version_t inode_version, version_t dir_accounted_version);
739 void finish_scatter_gather_update(int type);
740 void finish_scatter_gather_update_accounted(int type, MutationRef& mut, EMetaBlob *metablob);
741
742 // -- snap --
743 void open_snaprealm(bool no_split=false);
744 void close_snaprealm(bool no_join=false);
745 SnapRealm *find_snaprealm() const;
746 void encode_snap(bufferlist& bl);
747 void decode_snap(bufferlist::const_iterator& p);
748
749 client_t get_loner() const { return loner_cap; }
750 client_t get_wanted_loner() const { return want_loner_cap; }
751
752 // this is the loner state our locks should aim for
753 client_t get_target_loner() const {
754 if (loner_cap == want_loner_cap)
755 return loner_cap;
756 else
757 return -1;
758 }
759
760 client_t calc_ideal_loner();
761 void set_loner_cap(client_t l);
762 bool choose_ideal_loner();
763 bool try_set_loner();
764 bool try_drop_loner();
765
766 // choose new lock state during recovery, based on issued caps
767 void choose_lock_state(SimpleLock *lock, int allissued);
768 void choose_lock_states(int dirty_caps);
769
770 int count_nonstale_caps();
771 bool multiple_nonstale_caps();
772
773 bool is_any_caps() { return !client_caps.empty(); }
774 bool is_any_nonstale_caps() { return count_nonstale_caps(); }
775
776 const mempool::mds_co::compact_map<int32_t,int32_t>& get_mds_caps_wanted() const { return mds_caps_wanted; }
777 void set_mds_caps_wanted(mempool::mds_co::compact_map<int32_t,int32_t>& m);
778 void set_mds_caps_wanted(mds_rank_t mds, int32_t wanted);
779
780 const mempool_cap_map& get_client_caps() const { return client_caps; }
781 Capability *get_client_cap(client_t client) {
782 auto client_caps_entry = client_caps.find(client);
783 if (client_caps_entry != client_caps.end())
784 return &client_caps_entry->second;
785 return 0;
786 }
787 int get_client_cap_pending(client_t client) const {
788 auto client_caps_entry = client_caps.find(client);
789 if (client_caps_entry != client_caps.end()) {
790 return client_caps_entry->second.pending();
791 } else {
792 return 0;
793 }
794 }
795
796 int get_num_caps_wanted() const { return num_caps_wanted; }
797 void adjust_num_caps_wanted(int d);
798
799 Capability *add_client_cap(client_t client, Session *session,
800 SnapRealm *conrealm=nullptr, bool new_inode=false);
801 void remove_client_cap(client_t client);
802 void move_to_realm(SnapRealm *realm);
803
804 Capability *reconnect_cap(client_t client, const cap_reconnect_t& icr, Session *session);
805 void clear_client_caps_after_export();
806 void export_client_caps(std::map<client_t,Capability::Export>& cl);
807
808 // caps allowed
809 int get_caps_liked() const;
810 int get_caps_allowed_ever() const;
811 int get_caps_allowed_by_type(int type) const;
812 int get_caps_careful() const;
813 int get_xlocker_mask(client_t client) const;
814 int get_caps_allowed_for_client(Session *s, Capability *cap, mempool_inode *file_i) const;
815
816 // caps issued, wanted
817 int get_caps_issued(int *ploner = 0, int *pother = 0, int *pxlocker = 0,
818 int shift = 0, int mask = -1);
819 bool is_any_caps_wanted() const;
820 int get_caps_wanted(int *ploner = 0, int *pother = 0, int shift = 0, int mask = -1) const;
821 bool issued_caps_need_gather(SimpleLock *lock);
822
823 // -- authority --
824 mds_authority_t authority() const override;
825
826 // -- auth pins --
827 bool can_auth_pin(int *err_ret=nullptr) const override;
828 void auth_pin(void *by) override;
829 void auth_unpin(void *by) override;
830
831 // -- freeze --
832 bool is_freezing_inode() const { return state_test(STATE_FREEZING); }
833 bool is_frozen_inode() const { return state_test(STATE_FROZEN); }
834 bool is_frozen_auth_pin() const { return state_test(STATE_FROZENAUTHPIN); }
835 bool is_frozen() const override;
836 bool is_frozen_dir() const;
837 bool is_freezing() const override;
838
839 /* Freeze the inode. auth_pin_allowance lets the caller account for any
840 * auth_pins it is itself holding/responsible for. */
841 bool freeze_inode(int auth_pin_allowance=0);
842 void unfreeze_inode(MDSContext::vec& finished);
843 void unfreeze_inode();
844
845 void freeze_auth_pin();
846 void unfreeze_auth_pin();
847
848 // -- reference counting --
849 void bad_put(int by) override {
850 generic_dout(0) << " bad put " << *this << " by " << by << " " << pin_name(by) << " was " << ref
851 #ifdef MDS_REF_SET
852 << " (" << ref_map << ")"
853 #endif
854 << dendl;
855 #ifdef MDS_REF_SET
856 ceph_assert(ref_map[by] > 0);
857 #endif
858 ceph_assert(ref > 0);
859 }
860 void bad_get(int by) override {
861 generic_dout(0) << " bad get " << *this << " by " << by << " " << pin_name(by) << " was " << ref
862 #ifdef MDS_REF_SET
863 << " (" << ref_map << ")"
864 #endif
865 << dendl;
866 #ifdef MDS_REF_SET
867 ceph_assert(ref_map[by] >= 0);
868 #endif
869 }
870 void first_get() override;
871 void last_put() override;
872 void _put() override;
873
874 // -- hierarchy stuff --
875 void set_primary_parent(CDentry *p) {
876 ceph_assert(parent == 0 ||
877 g_conf().get_val<bool>("mds_hack_allow_loading_invalid_metadata"));
878 parent = p;
879 }
880 void remove_primary_parent(CDentry *dn) {
881 ceph_assert(dn == parent);
882 parent = 0;
883 }
884 void add_remote_parent(CDentry *p);
885 void remove_remote_parent(CDentry *p);
886 int num_remote_parents() {
887 return remote_parents.size();
888 }
889
890 void push_projected_parent(CDentry *dn) {
891 projected_parent.push_back(dn);
892 }
893 void pop_projected_parent() {
894 ceph_assert(projected_parent.size());
895 parent = projected_parent.front();
896 projected_parent.pop_front();
897 }
898 bool is_parent_projected() const {
899 return !projected_parent.empty();
900 }
901
902 void maybe_export_pin(bool update=false);
903 void set_export_pin(mds_rank_t rank);
904 mds_rank_t get_export_pin(bool inherit=true) const;
905 bool is_exportable(mds_rank_t dest) const;
906
907 void print(ostream& out) override;
908 void dump(Formatter *f, int flags = DUMP_DEFAULT) const;
909
910 /**
911 * Validate that the on-disk state of an inode matches what
912 * we expect from our memory state. Currently this checks that:
913 * 1) The backtrace associated with the file data exists and is correct
914 * 2) For directories, the actual inode metadata matches our memory state,
915 * 3) For directories, the rstats match
916 *
917 * @param results A freshly-created validated_data struct, with values set
918 * as described in the struct documentation.
919 * @param mdr The request to be responeded upon the completion of the
920 * validation (or NULL)
921 * @param fin Context to call back on completion (or NULL)
922 */
923 void validate_disk_state(validated_data *results,
924 MDSContext *fin);
925 static void dump_validation_results(const validated_data& results,
926 Formatter *f);
927
928 //bool hack_accessed = false;
929 //utime_t hack_load_stamp;
930
931 MDCache *mdcache;
932
933 SnapRealm *snaprealm = nullptr;
934 SnapRealm *containing_realm = nullptr;
935 snapid_t first, last;
936 mempool::mds_co::compact_set<snapid_t> dirty_old_rstats;
937
938 uint64_t last_journaled = 0; // log offset for the last time i was journaled
939 //loff_t last_open_journaled; // log offset for the last journaled EOpen
940 utime_t last_dirstat_prop;
941
942 // list item node for when we have unpropagated rstat data
943 elist<CInode*>::item dirty_rstat_item;
944
945 mempool::mds_co::set<client_t> client_snap_caps;
946 mempool::mds_co::compact_map<snapid_t, mempool::mds_co::set<client_t> > client_need_snapflush;
947
948 // LogSegment lists i (may) belong to
949 elist<CInode*>::item item_dirty;
950 elist<CInode*>::item item_caps;
951 elist<CInode*>::item item_open_file;
952 elist<CInode*>::item item_dirty_parent;
953 elist<CInode*>::item item_dirty_dirfrag_dir;
954 elist<CInode*>::item item_dirty_dirfrag_nest;
955 elist<CInode*>::item item_dirty_dirfrag_dirfragtree;
956 elist<CInode*>::item item_scrub;
957
958 // also update RecoveryQueue::RecoveryQueue() if you change this
959 elist<CInode*>::item& item_recover_queue = item_dirty_dirfrag_dir;
960 elist<CInode*>::item& item_recover_queue_front = item_dirty_dirfrag_nest;
961
962 inode_load_vec_t pop;
963 elist<CInode*>::item item_pop_lru;
964
965 // -- locks --
966 static LockType versionlock_type;
967 static LockType authlock_type;
968 static LockType linklock_type;
969 static LockType dirfragtreelock_type;
970 static LockType filelock_type;
971 static LockType xattrlock_type;
972 static LockType snaplock_type;
973 static LockType nestlock_type;
974 static LockType flocklock_type;
975 static LockType policylock_type;
976
977 // FIXME not part of mempool
978 LocalLock versionlock;
979 SimpleLock authlock;
980 SimpleLock linklock;
981 ScatterLock dirfragtreelock;
982 ScatterLock filelock;
983 SimpleLock xattrlock;
984 SimpleLock snaplock;
985 ScatterLock nestlock;
986 SimpleLock flocklock;
987 SimpleLock policylock;
988
989 // -- caps -- (new)
990 // client caps
991 client_t loner_cap = -1, want_loner_cap = -1;
992
993 protected:
994 ceph_lock_state_t *get_fcntl_lock_state() {
995 if (!fcntl_locks)
996 fcntl_locks = new ceph_lock_state_t(g_ceph_context, CEPH_LOCK_FCNTL);
997 return fcntl_locks;
998 }
999 void clear_fcntl_lock_state() {
1000 delete fcntl_locks;
1001 fcntl_locks = NULL;
1002 }
1003 ceph_lock_state_t *get_flock_lock_state() {
1004 if (!flock_locks)
1005 flock_locks = new ceph_lock_state_t(g_ceph_context, CEPH_LOCK_FLOCK);
1006 return flock_locks;
1007 }
1008 void clear_flock_lock_state() {
1009 delete flock_locks;
1010 flock_locks = NULL;
1011 }
1012 void clear_file_locks() {
1013 clear_fcntl_lock_state();
1014 clear_flock_lock_state();
1015 }
1016 void _encode_file_locks(bufferlist& bl) const {
1017 using ceph::encode;
1018 bool has_fcntl_locks = fcntl_locks && !fcntl_locks->empty();
1019 encode(has_fcntl_locks, bl);
1020 if (has_fcntl_locks)
1021 encode(*fcntl_locks, bl);
1022 bool has_flock_locks = flock_locks && !flock_locks->empty();
1023 encode(has_flock_locks, bl);
1024 if (has_flock_locks)
1025 encode(*flock_locks, bl);
1026 }
1027 void _decode_file_locks(bufferlist::const_iterator& p) {
1028 using ceph::decode;
1029 bool has_fcntl_locks;
1030 decode(has_fcntl_locks, p);
1031 if (has_fcntl_locks)
1032 decode(*get_fcntl_lock_state(), p);
1033 else
1034 clear_fcntl_lock_state();
1035 bool has_flock_locks;
1036 decode(has_flock_locks, p);
1037 if (has_flock_locks)
1038 decode(*get_flock_lock_state(), p);
1039 else
1040 clear_flock_lock_state();
1041 }
1042
1043 /**
1044 * Return the pool ID where we currently write backtraces for
1045 * this inode (in addition to inode.old_pools)
1046 *
1047 * @returns a pool ID >=0
1048 */
1049 int64_t get_backtrace_pool() const;
1050
1051 // parent dentries in cache
1052 CDentry *parent = nullptr; // primary link
1053 mempool::mds_co::compact_set<CDentry*> remote_parents; // if hard linked
1054
1055 mempool::mds_co::list<CDentry*> projected_parent; // for in-progress rename, (un)link, etc.
1056
1057 mds_authority_t inode_auth = CDIR_AUTH_DEFAULT;
1058
1059 // -- distributed state --
1060 // file capabilities
1061 mempool_cap_map client_caps; // client -> caps
1062 mempool::mds_co::compact_map<int32_t, int32_t> mds_caps_wanted; // [auth] mds -> caps wanted
1063 int replica_caps_wanted = 0; // [replica] what i've requested from auth
1064 int num_caps_wanted = 0;
1065
1066 ceph_lock_state_t *fcntl_locks = nullptr;
1067 ceph_lock_state_t *flock_locks = nullptr;
1068
1069 // -- waiting --
1070 mempool::mds_co::compact_map<frag_t, MDSContext::vec > waiting_on_dir;
1071
1072
1073 // -- freezing inode --
1074 int auth_pin_freeze_allowance = 0;
1075 elist<CInode*>::item item_freezing_inode;
1076 void maybe_finish_freeze_inode();
1077 private:
1078
1079 friend class ValidationContinuation;
1080
1081 /**
1082 * Create a scrub_info_t struct for the scrub_infop pointer.
1083 */
1084 void scrub_info_create() const;
1085 /**
1086 * Delete the scrub_info_t struct if it's not got any useful data
1087 */
1088 void scrub_maybe_delete_info();
1089
1090 void pop_projected_snaprealm(sr_t *next_snaprealm, bool early);
1091
1092 bool _validate_disk_state(class ValidationContinuation *c,
1093 int rval, int stage);
1094
1095 mempool::mds_co::list<projected_inode> projected_nodes; // projected values (only defined while dirty)
1096 size_t num_projected_xattrs = 0;
1097 size_t num_projected_srnodes = 0;
1098
1099 // -- cache infrastructure --
1100 mempool::mds_co::compact_map<frag_t,CDir*> dirfrags; // cached dir fragments under this Inode
1101
1102 //for the purpose of quickly determining whether there's a subtree root or exporting dir
1103 int num_subtree_roots = 0;
1104 int num_exporting_dirs = 0;
1105
1106 int stickydir_ref = 0;
1107 scrub_info_t *scrub_infop = nullptr;
1108 /** @} Scrubbing and fsck */
1109 };
1110
1111 ostream& operator<<(ostream& out, const CInode& in);
1112 ostream& operator<<(ostream& out, const CInode::scrub_stamp_info_t& si);
1113
1114 extern cinode_lock_info_t cinode_lock_info[];
1115 extern int num_cinode_locks;
1116 #undef dout_context
1117 #endif