]> git.proxmox.com Git - ceph.git/blob - ceph/src/mds/StrayManager.h
import 15.2.0 Octopus source
[ceph.git] / ceph / src / mds / StrayManager.h
1 // vim: ts=8 sw=2 smarttab
2 /*
3 * Ceph - scalable distributed file system
4 *
5 * Copyright (C) 2015 Red Hat
6 *
7 * This is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License version 2.1, as published by the Free Software
10 * Foundation. See file COPYING.
11 *
12 */
13
14 #ifndef STRAY_MANAGER_H
15 #define STRAY_MANAGER_H
16
17 #include "include/common_fwd.h"
18 #include "include/elist.h"
19 #include <list>
20 #include "mds/PurgeQueue.h"
21
22 class MDSRank;
23 class CInode;
24 class CDentry;
25
26 class StrayManager
27 {
28 // My public interface is for consumption by MDCache
29 public:
30 explicit StrayManager(MDSRank *mds, PurgeQueue &purge_queue_);
31 void set_logger(PerfCounters *l) {logger = l;}
32 void activate();
33
34 bool eval_stray(CDentry *dn);
35
36 void set_num_strays(uint64_t num);
37 uint64_t get_num_strays() const { return num_strays; }
38
39 /**
40 * Queue dentry for later evaluation. (evaluate it while not in the
41 * middle of another metadata operation)
42 */
43 void queue_delayed(CDentry *dn);
44
45 /**
46 * Eval strays in the delayed_eval_stray list
47 */
48 void advance_delayed();
49
50 /**
51 * Remote dentry potentially points to a stray. When it is touched,
52 * call in here to evaluate it for migration (move a stray residing
53 * on another MDS to this MDS) or reintegration (move a stray dentry's
54 * inode into a non-stray hardlink dentry and clean up the stray).
55 *
56 * @param stray_dn a stray dentry whose inode has been referenced
57 * by a remote dentry
58 * @param remote_dn (optional) which remote dentry was touched
59 * in an operation that led us here: this is used
60 * as a hint for which remote to reintegrate into
61 * if there are multiple remotes.
62 */
63 void eval_remote(CDentry *remote_dn);
64
65 /**
66 * Given a dentry within one of my stray directories,
67 * send it off to a stray directory in another MDS.
68 *
69 * This is for use:
70 * * Case A: when shutting down a rank, we migrate strays
71 * away from ourselves rather than waiting for purge
72 * * Case B: when a client request has a trace that refers to
73 * a stray inode on another MDS, we migrate that inode from
74 * there to here, in order that we can later re-integrate it
75 * here.
76 *
77 * In case B, the receiver should be calling into eval_stray
78 * on completion of mv (i.e. inode put), resulting in a subsequent
79 * reintegration.
80 */
81 void migrate_stray(CDentry *dn, mds_rank_t dest);
82
83 /**
84 * Update stats to reflect a newly created stray dentry. Needed
85 * because stats on strays live here, but creation happens
86 * in Server or MDCache. For our purposes "creation" includes
87 * loading a stray from a dirfrag and migrating a stray from
88 * another MDS, in addition to creations per-se.
89 */
90 void notify_stray_created();
91
92 /**
93 * Update stats to reflect a removed stray dentry. Needed because
94 * stats on strays live here, but removal happens in Server or
95 * MDCache. Also includes migration (rename) of strays from
96 * this MDS to another MDS.
97 */
98 void notify_stray_removed();
99
100 protected:
101 friend class StrayManagerIOContext;
102 friend class StrayManagerLogContext;
103 friend class StrayManagerContext;
104
105 friend class C_StraysFetched;
106 friend class C_OpenSnapParents;
107 friend class C_PurgeStrayLogged;
108 friend class C_TruncateStrayLogged;
109 friend class C_IO_PurgeStrayPurged;
110
111 void truncate(CDentry *dn);
112
113 /**
114 * Purge a dentry from a stray directory. This function
115 * is called once eval_stray is satisfied and StrayManager
116 * throttling is also satisfied. There is no going back
117 * at this stage!
118 */
119 void purge(CDentry *dn);
120
121 /**
122 * Completion handler for a Filer::purge on a stray inode.
123 */
124 void _purge_stray_purged(CDentry *dn, bool only_head);
125
126 void _purge_stray_logged(CDentry *dn, version_t pdv, LogSegment *ls);
127
128 /**
129 * Callback: we have logged the update to an inode's metadata
130 * reflecting it's newly-zeroed length.
131 */
132 void _truncate_stray_logged(CDentry *dn, LogSegment *ls);
133 /**
134 * Call this on a dentry that has been identified as
135 * eligible for purging. It will be passed on to PurgeQueue.
136 */
137 void enqueue(CDentry *dn, bool trunc);
138 /**
139 * Final part of enqueue() which we may have to retry
140 * after opening snap parents.
141 */
142 void _enqueue(CDentry *dn, bool trunc);
143
144 /**
145 * When hard links exist to an inode whose primary dentry
146 * is unlinked, the inode gets a stray primary dentry.
147 *
148 * We may later "reintegrate" the inode into a remaining
149 * non-stray dentry (one of what was previously a remote
150 * dentry) by issuing a rename from the stray to the other
151 * dentry.
152 */
153 void reintegrate_stray(CDentry *dn, CDentry *rlink);
154
155 /**
156 * Evaluate a stray dentry for purging or reintegration.
157 *
158 * purging: If the inode has no linkage, and no more references, then
159 * we may decide to purge it.
160 *
161 * reintegration: If the inode still has linkage, then it means someone else
162 * (a hard link) is still referring to it, and we should
163 * think about reintegrating that inode into the remote dentry.
164 *
165 * @returns true if the dentry will be purged (caller should never
166 * take more refs after this happens), else false.
167 */
168 bool _eval_stray(CDentry *dn);
169
170 void _eval_stray_remote(CDentry *stray_dn, CDentry *remote_dn);
171
172 // Has passed through eval_stray and still has refs
173 elist<CDentry*> delayed_eval_stray;
174
175 // strays that have been trimmed from cache
176 std::set<std::string> trimmed_strays;
177
178 // Global references for doing I/O
179 MDSRank *mds;
180 PerfCounters *logger = nullptr;
181
182 bool started = false;
183
184 // Stray dentries for this rank (including those not in cache)
185 uint64_t num_strays = 0;
186
187 // Stray dentries
188 uint64_t num_strays_delayed = 0;
189 /**
190 * Entries that have entered enqueue() but not been persistently
191 * recorded by PurgeQueue yet
192 */
193 uint64_t num_strays_enqueuing = 0;
194
195 PurgeQueue &purge_queue;
196 };
197 #endif // STRAY_MANAGER_H