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