Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / mds / SnapRealm.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_MDS_SNAPREALM_H
16 #define CEPH_MDS_SNAPREALM_H
17
18 #include "mdstypes.h"
19 #include "snap.h"
20 #include "include/xlist.h"
21 #include "include/elist.h"
22 #include "common/snap_types.h"
23
24 class MDSInternalContextBase;
25
26 struct SnapRealm {
27 protected:
28   // cache
29   mutable snapid_t cached_seq;           // max seq over self and all past+present parents.
30   mutable snapid_t cached_last_created;  // max last_created over all past+present parents
31   mutable snapid_t cached_last_destroyed;
32   mutable set<snapid_t> cached_snaps;
33   mutable SnapContext cached_snap_context;
34   mutable bufferlist cached_snap_trace;
35
36   void check_cache() const;
37
38 public:
39   // realm state
40   sr_t srnode;
41
42   // in-memory state
43   MDCache *mdcache;
44   CInode *inode;
45
46   bool open;                        // set to true once all past_parents are opened
47   SnapRealm *parent;
48   set<SnapRealm*> open_children;    // active children that are currently open
49   set<SnapRealm*> open_past_children;  // past children who has pinned me
50   map<inodeno_t, pair<SnapRealm*, set<snapid_t> > > open_past_parents;  // these are explicitly pinned.
51   unsigned num_open_past_parents;
52
53
54
55   elist<CInode*> inodes_with_caps;             // for efficient realm splits
56   map<client_t, xlist<Capability*>* > client_caps;   // to identify clients who need snap notifications
57
58   SnapRealm(MDCache *c, CInode *in) : 
59     srnode(),
60     mdcache(c), inode(in),
61     open(false), parent(0),
62     num_open_past_parents(0),
63     inodes_with_caps(0) 
64   { }
65
66   bool exists(const string &name) const {
67     for (map<snapid_t,SnapInfo>::const_iterator p = srnode.snaps.begin();
68          p != srnode.snaps.end();
69          ++p) {
70       if (p->second.name == name)
71         return true;
72     }
73     return false;
74   }
75
76   bool is_open() const { return open; }
77   void _close_parents() { open = false; }
78   bool _open_parents(MDSInternalContextBase *retryorfinish, snapid_t first=1, snapid_t last=CEPH_NOSNAP);
79   bool open_parents(MDSInternalContextBase *retryorfinish);
80   void _remove_missing_parent(snapid_t snapid, inodeno_t parent, int err);
81   bool have_past_parents_open(snapid_t first=1, snapid_t last=CEPH_NOSNAP);
82   void add_open_past_parent(SnapRealm *parent, snapid_t last);
83   void remove_open_past_parent(inodeno_t ino, snapid_t last);
84   void close_parents();
85
86   void prune_past_parents();
87   bool has_past_parents() const { return !srnode.past_parents.empty(); }
88
89   void build_snap_set(set<snapid_t>& s, 
90                       snapid_t& max_seq, snapid_t& max_last_created, snapid_t& max_last_destroyed,
91                       snapid_t first, snapid_t last) const;
92   void get_snap_info(map<snapid_t,SnapInfo*>& infomap, snapid_t first=0, snapid_t last=CEPH_NOSNAP);
93
94   const bufferlist& get_snap_trace();
95   void build_snap_trace(bufferlist& snapbl) const;
96
97   const string& get_snapname(snapid_t snapid, inodeno_t atino);
98   snapid_t resolve_snapname(const string &name, inodeno_t atino, snapid_t first=0, snapid_t last=CEPH_NOSNAP);
99
100   const set<snapid_t>& get_snaps() const;
101   const SnapContext& get_snap_context() const;
102   void invalidate_cached_snaps() {
103     cached_seq = 0;
104   }
105   snapid_t get_last_created() {
106     check_cache();
107     return cached_last_created;
108   }
109   snapid_t get_last_destroyed() {
110     check_cache();
111     return cached_last_destroyed;
112   }
113   snapid_t get_newest_snap() {
114     check_cache();
115     if (cached_snaps.empty())
116       return 0;
117     else
118       return *cached_snaps.rbegin();
119   }
120   snapid_t get_newest_seq() {
121     check_cache();
122     return cached_seq;
123   }
124
125   snapid_t get_snap_following(snapid_t follows) {
126     check_cache();
127     const set<snapid_t>& s = get_snaps();
128     set<snapid_t>::const_iterator p = s.upper_bound(follows);
129     if (p != s.end())
130       return *p;
131     return CEPH_NOSNAP;
132   }
133
134   bool has_snaps_in_range(snapid_t first, snapid_t last) {
135     check_cache();
136     const set<snapid_t>& s = get_snaps();
137     set<snapid_t>::const_iterator p = s.lower_bound(first);
138     return (p != s.end() && *p <= last);
139   }
140
141   void adjust_parent();
142
143   void split_at(SnapRealm *child);
144   void join(SnapRealm *child);
145
146   void add_cap(client_t client, Capability *cap) {
147     auto client_caps_entry = client_caps.find(client);
148     if (client_caps_entry == client_caps.end())
149       client_caps_entry = client_caps.emplace(client,
150                                               new xlist<Capability*>).first;
151     client_caps_entry->second->push_back(&cap->item_snaprealm_caps);
152   }
153   void remove_cap(client_t client, Capability *cap) {
154     cap->item_snaprealm_caps.remove_myself();
155     if (client_caps[client]->empty()) {
156       delete client_caps[client];
157       client_caps.erase(client);
158     }
159   }
160
161 };
162
163 ostream& operator<<(ostream& out, const SnapRealm &realm);
164
165 #endif