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