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