]> git.proxmox.com Git - ceph.git/blame - ceph/src/mds/CDentry.h
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / mds / CDentry.h
CommitLineData
7c673cae
FG
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
16
17#ifndef CEPH_CDENTRY_H
18#define CEPH_CDENTRY_H
19
20#include <string>
11fdf7f2 21#include <string_view>
7c673cae
FG
22#include <set>
23
24#include "include/counter.h"
25#include "include/types.h"
26#include "include/buffer_fwd.h"
27#include "include/lru.h"
28#include "include/elist.h"
29#include "include/filepath.h"
30
31#include "MDSCacheObject.h"
11fdf7f2 32#include "MDSContext.h"
7c673cae
FG
33#include "SimpleLock.h"
34#include "LocalLock.h"
35#include "ScrubHeader.h"
36
37class CInode;
38class CDir;
39class Locker;
7c673cae
FG
40class CDentry;
41class LogSegment;
42
43class Session;
44
45
46
47// define an ordering
48bool operator<(const CDentry& l, const CDentry& r);
49
50// dentry
51class CDentry : public MDSCacheObject, public LRUObject, public Counter<CDentry> {
52public:
181888fb 53 MEMPOOL_CLASS_HELPERS();
7c673cae
FG
54 friend class CDir;
55
56 struct linkage_t {
94b18763
FG
57 CInode *inode = nullptr;
58 inodeno_t remote_ino = 0;
59 unsigned char remote_d_type = 0;
7c673cae 60
94b18763 61 linkage_t() {}
7c673cae
FG
62
63 // dentry type is primary || remote || null
64 // inode ptr is required for primary, optional for remote, undefined for null
65 bool is_primary() const { return remote_ino == 0 && inode != 0; }
66 bool is_remote() const { return remote_ino > 0; }
67 bool is_null() const { return remote_ino == 0 && inode == 0; }
68
69 CInode *get_inode() { return inode; }
70 const CInode *get_inode() const { return inode; }
71 inodeno_t get_remote_ino() const { return remote_ino; }
72 unsigned char get_remote_d_type() const { return remote_d_type; }
73 std::string get_remote_d_type_string() const;
74
75 void set_remote(inodeno_t ino, unsigned char d_type) {
76 remote_ino = ino;
77 remote_d_type = d_type;
78 inode = 0;
79 }
80 void link_remote(CInode *in);
81 };
82
83
84 // -- state --
85 static const int STATE_NEW = (1<<0);
86 static const int STATE_FRAGMENTING = (1<<1);
87 static const int STATE_PURGING = (1<<2);
88 static const int STATE_BADREMOTEINO = (1<<3);
89 static const int STATE_EVALUATINGSTRAY = (1<<4);
90 static const int STATE_PURGINGPINNED = (1<<5);
31f18b77 91 static const int STATE_BOTTOMLRU = (1<<6);
7c673cae
FG
92 // stray dentry needs notification of releasing reference
93 static const int STATE_STRAY = STATE_NOTIFYREF;
31f18b77 94 static const int MASK_STATE_IMPORT_KEPT = STATE_BOTTOMLRU;
7c673cae
FG
95
96 // -- pins --
97 static const int PIN_INODEPIN = 1; // linked inode is pinned
98 static const int PIN_FRAGMENTING = -2; // containing dir is refragmenting
99 static const int PIN_PURGING = 3;
100 static const int PIN_SCRUBPARENT = 4;
101
102 static const unsigned EXPORT_NONCE = 1;
103
104
11fdf7f2 105 CDentry(std::string_view n, __u32 h,
7c673cae 106 snapid_t f, snapid_t l) :
94b18763 107 hash(h),
7c673cae
FG
108 first(f), last(l),
109 item_dirty(this),
110 lock(this, &lock_type),
111 versionlock(this, &versionlock_type),
94b18763
FG
112 name(n)
113 {}
11fdf7f2 114 CDentry(std::string_view n, __u32 h, inodeno_t ino, unsigned char dt,
7c673cae 115 snapid_t f, snapid_t l) :
94b18763 116 hash(h),
7c673cae
FG
117 first(f), last(l),
118 item_dirty(this),
119 lock(this, &lock_type),
120 versionlock(this, &versionlock_type),
94b18763
FG
121 name(n)
122 {
7c673cae
FG
123 linkage.remote_ino = ino;
124 linkage.remote_d_type = dt;
125 }
126
11fdf7f2 127 std::string_view pin_name(int p) const override {
7c673cae
FG
128 switch (p) {
129 case PIN_INODEPIN: return "inodepin";
130 case PIN_FRAGMENTING: return "fragmenting";
131 case PIN_PURGING: return "purging";
132 case PIN_SCRUBPARENT: return "scrubparent";
133 default: return generic_pin_name(p);
134 }
135 }
136
137 // -- wait --
138 //static const int WAIT_LOCK_OFFSET = 8;
139
11fdf7f2 140 void add_waiter(uint64_t tag, MDSContext *c) override;
7c673cae
FG
141
142 bool is_lt(const MDSCacheObject *r) const override {
143 return *this < *static_cast<const CDentry*>(r);
144 }
145
146 dentry_key_t key() {
147 return dentry_key_t(last, name.c_str(), hash);
148 }
149
150 const CDir *get_dir() const { return dir; }
151 CDir *get_dir() { return dir; }
11fdf7f2 152 std::string_view get_name() const { return std::string_view(name); }
7c673cae
FG
153
154 __u32 get_hash() const { return hash; }
155
156 // linkage
157 const linkage_t *get_linkage() const { return &linkage; }
158 linkage_t *get_linkage() { return &linkage; }
159
160 linkage_t *_project_linkage() {
161 projected.push_back(linkage_t());
162 return &projected.back();
163 }
164 void push_projected_linkage();
165 void push_projected_linkage(inodeno_t ino, char d_type) {
166 linkage_t *p = _project_linkage();
167 p->remote_ino = ino;
168 p->remote_d_type = d_type;
169 }
170 void push_projected_linkage(CInode *inode);
171 linkage_t *pop_projected_linkage();
172
173 bool is_projected() const { return !projected.empty(); }
174
175 linkage_t *get_projected_linkage() {
176 if (!projected.empty())
177 return &projected.back();
178 return &linkage;
179 }
180
181 const linkage_t *get_projected_linkage() const {
182 if (!projected.empty())
183 return &projected.back();
184 return &linkage;
185 }
186
187 CInode *get_projected_inode() {
188 return get_projected_linkage()->inode;
189 }
190
191 bool use_projected(client_t client, const MutationRef& mut) const {
192 return lock.can_read_projected(client) ||
193 lock.get_xlock_by() == mut;
194 }
195 linkage_t *get_linkage(client_t client, const MutationRef& mut) {
196 return use_projected(client, mut) ? get_projected_linkage() : get_linkage();
197 }
198
199 // ref counts: pin ourselves in the LRU when we're pinned.
200 void first_get() override {
201 lru_pin();
202 }
203 void last_put() override {
204 lru_unpin();
205 }
206 void _put() override;
207
208 // auth pins
91327a77 209 bool can_auth_pin(int *err_ret=nullptr) const override;
7c673cae
FG
210 void auth_pin(void *by) override;
211 void auth_unpin(void *by) override;
11fdf7f2 212 void adjust_nested_auth_pins(int diradj, void *by);
7c673cae
FG
213 bool is_frozen() const override;
214 bool is_freezing() const override;
215 int get_num_dir_auth_pins() const;
216
217 // remote links
218 void link_remote(linkage_t *dnl, CInode *in);
219 void unlink_remote(linkage_t *dnl);
220
221 // copy cons
222 CDentry(const CDentry& m);
223 const CDentry& operator= (const CDentry& right);
224
225 // misc
226 void make_path_string(std::string& s, bool projected=false) const;
227 void make_path(filepath& fp, bool projected=false) const;
228
229 // -- version --
230 version_t get_version() const { return version; }
231 void set_version(version_t v) { projected_version = version = v; }
232 version_t get_projected_version() const { return projected_version; }
233 void set_projected_version(version_t v) { projected_version = v; }
234
235 mds_authority_t authority() const override;
236
237 version_t pre_dirty(version_t min=0);
238 void _mark_dirty(LogSegment *ls);
239 void mark_dirty(version_t projected_dirv, LogSegment *ls);
240 void mark_clean();
241
242 void mark_new();
243 bool is_new() const { return state_test(STATE_NEW); }
244 void clear_new() { state_clear(STATE_NEW); }
245
246 // -- replication
b32b8144 247 void encode_replica(mds_rank_t mds, bufferlist& bl, bool need_recover) {
7c673cae 248 __u32 nonce = add_replica(mds);
11fdf7f2
TL
249 encode(nonce, bl);
250 encode(first, bl);
251 encode(linkage.remote_ino, bl);
252 encode(linkage.remote_d_type, bl);
b32b8144 253 lock.encode_state_for_replica(bl);
11fdf7f2 254 encode(need_recover, bl);
7c673cae 255 }
11fdf7f2 256 void decode_replica(bufferlist::const_iterator& p, bool is_new);
7c673cae
FG
257
258 // -- exporting
259 // note: this assumes the dentry already exists.
260 // i.e., the name is already extracted... so we just need the other state.
261 void encode_export(bufferlist& bl) {
11fdf7f2
TL
262 encode(first, bl);
263 encode(state, bl);
264 encode(version, bl);
265 encode(projected_version, bl);
266 encode(lock, bl);
267 encode(get_replicas(), bl);
7c673cae
FG
268 get(PIN_TEMPEXPORTING);
269 }
270 void finish_export() {
271 // twiddle
272 clear_replica_map();
273 replica_nonce = EXPORT_NONCE;
274 state_clear(CDentry::STATE_AUTH);
275 if (is_dirty())
276 mark_clean();
277 put(PIN_TEMPEXPORTING);
278 }
279 void abort_export() {
280 put(PIN_TEMPEXPORTING);
281 }
11fdf7f2
TL
282 void decode_import(bufferlist::const_iterator& blp, LogSegment *ls) {
283 decode(first, blp);
7c673cae 284 __u32 nstate;
11fdf7f2
TL
285 decode(nstate, blp);
286 decode(version, blp);
287 decode(projected_version, blp);
288 decode(lock, blp);
289 decode(get_replicas(), blp);
7c673cae
FG
290
291 // twiddle
31f18b77 292 state &= MASK_STATE_IMPORT_KEPT;
7c673cae
FG
293 state_set(CDentry::STATE_AUTH);
294 if (nstate & STATE_DIRTY)
295 _mark_dirty(ls);
181888fb 296 if (is_replicated())
7c673cae
FG
297 get(PIN_REPLICATED);
298 replica_nonce = 0;
299 }
300
301 // -- locking --
302 SimpleLock* get_lock(int type) override {
11fdf7f2 303 ceph_assert(type == CEPH_LOCK_DN);
7c673cae
FG
304 return &lock;
305 }
306 void set_object_info(MDSCacheObjectInfo &info) override;
307 void encode_lock_state(int type, bufferlist& bl) override;
11fdf7f2 308 void decode_lock_state(int type, const bufferlist& bl) override;
7c673cae
FG
309
310 // ---------------------------------------------
311 // replicas (on clients)
312
313 bool is_any_leases() const {
314 return !client_lease_map.empty();
315 }
316 const ClientLease *get_client_lease(client_t c) const {
317 if (client_lease_map.count(c))
318 return client_lease_map.find(c)->second;
319 return 0;
320 }
321 ClientLease *get_client_lease(client_t c) {
322 if (client_lease_map.count(c))
323 return client_lease_map.find(c)->second;
324 return 0;
325 }
326 bool have_client_lease(client_t c) const {
327 const ClientLease *l = get_client_lease(c);
328 if (l)
329 return true;
330 else
331 return false;
332 }
333
334 ClientLease *add_client_lease(client_t c, Session *session);
335 void remove_client_lease(ClientLease *r, Locker *locker); // returns remaining mask (if any), and kicks locker eval_gathers
336 void remove_client_leases(Locker *locker);
337
338 ostream& print_db_line_prefix(ostream& out) override;
339 void print(ostream& out) override;
340 void dump(Formatter *f) const;
341
342
7c673cae
FG
343 __u32 hash;
344 snapid_t first, last;
345
b32b8144 346 elist<CDentry*>::item item_dirty, item_dir_dirty;
7c673cae
FG
347 elist<CDentry*>::item item_stray;
348
349 // lock
350 static LockType lock_type;
351 static LockType versionlock_type;
352
94b18763
FG
353 SimpleLock lock; // FIXME referenced containers not in mempool
354 LocalLock versionlock; // FIXME referenced containers not in mempool
7c673cae 355
94b18763 356 mempool::mds_co::map<client_t,ClientLease*> client_lease_map;
7c673cae
FG
357
358
359protected:
360 friend class Migrator;
361 friend class Locker;
362 friend class MDCache;
363 friend class StrayManager;
364 friend class CInode;
365 friend class C_MDC_XlockRequest;
366
94b18763 367 CDir *dir = nullptr; // containing dirfrag
7c673cae 368 linkage_t linkage;
94b18763
FG
369 mempool::mds_co::list<linkage_t> projected;
370
371 version_t version = 0; // dir version when last touched.
372 version_t projected_version = 0; // what it will be when i unlock/commit.
7c673cae 373
94b18763
FG
374private:
375 mempool::mds_co::string name;
7c673cae
FG
376};
377
378ostream& operator<<(ostream& out, const CDentry& dn);
379
380
381#endif