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