1    	// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
2    	// vim: ts=8 sw=2 smarttab
3    	#ifndef CEPH_INODE_BACKTRACE_H
4    	#define CEPH_INODE_BACKTRACE_H
5    	
6    	#include <string_view>
7    	
(1) Event include_recursion: #include file "../../src/mds/mdstypes.h" includes itself: mdstypes.h -> inode_backtrace.h -> mdstypes.h
(2) Event caretline: ^
8    	#include "mdstypes.h"
9    	
10   	namespace ceph {
11   	  class Formatter;
12   	}
13   	
14   	/** metadata backpointers **/
15   	
16   	/*
17   	 * - inode_backpointer_t is just the _pointer_ portion; it doesn't
18   	 *   tell us who we point _from_.
19   	 *
20   	 * - it _does_ include a version of the source object, so we can look
21   	 *   at two different pointers (from the same inode) and tell which is
22   	 *   newer.
23   	 */
24   	struct inode_backpointer_t {
25   	  inodeno_t dirino;    // containing directory ino
26   	  string dname;        // linking dentry name
27   	  version_t version;   // child's version at time of backpointer creation
28   	
29   	  inode_backpointer_t() : version(0) {}
30   	  inode_backpointer_t(inodeno_t i, std::string_view d, version_t v) : dirino(i), dname(d), version(v) {}
31   	
32   	  void encode(bufferlist& bl) const;
33   	  void decode(bufferlist::const_iterator &bl);
34   	  void decode_old(bufferlist::const_iterator &bl);
35   	  void dump(Formatter *f) const;
36   	  static void generate_test_instances(std::list<inode_backpointer_t*>& ls);
37   	};
38   	WRITE_CLASS_ENCODER(inode_backpointer_t)
39   	
40   	inline bool operator==(const inode_backpointer_t& l, const inode_backpointer_t& r) {
41   		return l.dirino == r.dirino && l.version == r.version && l.dname == r.dname;
42   	}
43   	
44   	inline ostream& operator<<(ostream& out, const inode_backpointer_t& ib) {
45   	  return out << "<" << ib.dirino << "/" << ib.dname << " v" << ib.version << ">";
46   	}
47   	
48   	/*
49   	 * inode_backtrace_t is a complete ancestor backtraces for a given inode.
50   	 * we include who _we_ are, so that the backtrace can stand alone (as, say,
51   	 * an xattr on an object).
52   	 */
53   	struct inode_backtrace_t {
54   	  inodeno_t ino;       // my ino
55   	  vector<inode_backpointer_t> ancestors;
56   	  int64_t pool;
57   	  // we use a set for old_pools to avoid duplicate entries, e.g. setlayout 0, 1, 0
58   	  set<int64_t> old_pools;
59   	
60   	  inode_backtrace_t() : pool(-1) {}
61   	
62   	  void encode(bufferlist& bl) const;
63   	  void decode(bufferlist::const_iterator &bl);
64   	  void dump(Formatter *f) const;
65   	  static void generate_test_instances(std::list<inode_backtrace_t*>& ls);
66   	
67   	  /**
68   	   * Compare two backtraces *for the same inode*.
69   	   * @pre The backtraces are for the same inode
70   	   *
71   	   * @param other The backtrace to compare ourselves with
72   	   * @param equivalent A bool pointer which will be set to true if
73   	   * the other backtrace is equivalent to our own (has the same dentries)
74   	   * @param divergent A bool pointer which will be set to true if
75   	   * the backtraces have differing entries without versions supporting them
76   	   *
77   	   * @returns 1 if we are newer than the other, 0 if equal, -1 if older
78   	   */
79   	  int compare(const inode_backtrace_t& other,
80   	               bool *equivalent, bool *divergent) const;
81   	};
82   	WRITE_CLASS_ENCODER(inode_backtrace_t)
83   	
84   	inline ostream& operator<<(ostream& out, const inode_backtrace_t& it) {
85   	  return out << "(" << it.pool << ")" << it.ino << ":" << it.ancestors << "//" << it.old_pools;
86   	}
87   	
88   	inline bool operator==(const inode_backtrace_t& l,
89   	                       const inode_backtrace_t& r) {
90   	  return l.ino == r.ino &&
91   	      l.pool == r.pool &&
92   	      l.old_pools == r.old_pools &&
93   	      l.ancestors == r.ancestors;
94   	}
95   	
96   	#endif
97   	
98