]> git.proxmox.com Git - ceph.git/blame - ceph/src/client/Client.h
import ceph quincy 17.2.4
[ceph.git] / ceph / src / client / Client.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#ifndef CEPH_CLIENT_H
17#define CEPH_CLIENT_H
18
11fdf7f2
TL
19#include "common/CommandTable.h"
20#include "common/Finisher.h"
11fdf7f2 21#include "common/Timer.h"
9f95a23c 22#include "common/ceph_mutex.h"
11fdf7f2
TL
23#include "common/cmdparse.h"
24#include "common/compiler_extensions.h"
9f95a23c 25#include "include/common_fwd.h"
e306af50 26#include "include/cephfs/ceph_ll_client.h"
7c673cae
FG
27#include "include/filepath.h"
28#include "include/interval_set.h"
29#include "include/lru.h"
11fdf7f2
TL
30#include "include/types.h"
31#include "include/unordered_map.h"
32#include "include/unordered_set.h"
f67539c2 33#include "include/cephfs/metrics/Types.h"
7c673cae
FG
34#include "mds/mdstypes.h"
35#include "msg/Dispatcher.h"
11fdf7f2 36#include "msg/MessageRef.h"
7c673cae 37#include "msg/Messenger.h"
7c673cae
FG
38#include "osdc/ObjectCacher.h"
39
f67539c2 40#include "RWRef.h"
7c673cae 41#include "InodeRef.h"
11fdf7f2 42#include "MetaSession.h"
7c673cae 43#include "UserPerm.h"
11fdf7f2
TL
44
45#include <fstream>
46#include <map>
47#include <memory>
48#include <set>
49#include <string>
f67539c2 50#include <thread>
11fdf7f2
TL
51
52using std::set;
53using std::map;
54using std::fstream;
7c673cae
FG
55
56class FSMap;
57class FSMapUser;
58class MonClient;
59
7c673cae
FG
60
61struct DirStat;
62struct LeaseStat;
63struct InodeStat;
64
65class Filer;
66class Objecter;
67class WritebackHandler;
68
7c673cae
FG
69class MDSMap;
70class Message;
f67539c2 71class destructive_lock_ref_t;
7c673cae
FG
72
73enum {
74 l_c_first = 20000,
75 l_c_reply,
76 l_c_lat,
77 l_c_wrlat,
11fdf7f2
TL
78 l_c_read,
79 l_c_fsync,
2a845540
TL
80 l_c_md_avg,
81 l_c_md_sqsum,
82 l_c_md_ops,
83 l_c_rd_avg,
84 l_c_rd_sqsum,
85 l_c_rd_ops,
86 l_c_wr_avg,
87 l_c_wr_sqsum,
88 l_c_wr_ops,
7c673cae
FG
89 l_c_last,
90};
91
92
93class MDSCommandOp : public CommandOp
94{
95 public:
96 mds_gid_t mds_gid;
97
11fdf7f2 98 explicit MDSCommandOp(ceph_tid_t t) : CommandOp(t) {}
7c673cae
FG
99};
100
101/* error code for ceph_fuse */
28e407b8
AA
102#define CEPH_FUSE_NO_MDS_UP -((1<<16)+0) /* no mds up deteced in ceph_fuse */
103#define CEPH_FUSE_LAST -((1<<16)+1) /* (unused) */
7c673cae
FG
104
105// ============================================
106// types for my local metadata cache
107/* basic structure:
108
109 - Dentries live in an LRU loop. they get expired based on last access.
110 see include/lru.h. items can be bumped to "mid" or "top" of list, etc.
111 - Inode has ref count for each Fh, Dir, or Dentry that points to it.
112 - when Inode ref goes to 0, it's expired.
113 - when Dir is empty, it's removed (and it's Inode ref--)
114
115*/
116
117/* getdir result */
118struct DirEntry {
20effc67
TL
119 explicit DirEntry(const std::string &s) : d_name(s), stmask(0) {}
120 DirEntry(const std::string &n, struct stat& s, int stm)
121 : d_name(n), st(s), stmask(stm) {}
11fdf7f2 122
20effc67 123 std::string d_name;
7c673cae
FG
124 struct stat st;
125 int stmask;
7c673cae
FG
126};
127
128struct Cap;
129class Dir;
130class Dentry;
131struct SnapRealm;
132struct Fh;
133struct CapSnap;
134
7c673cae
FG
135struct MetaRequest;
136class ceph_lock_state_t;
137
7c673cae
FG
138// ========================================================
139// client interface
140
141struct dir_result_t {
142 static const int SHIFT = 28;
143 static const int64_t MASK = (1 << SHIFT) - 1;
144 static const int64_t HASH = 0xFFULL << (SHIFT + 24); // impossible frag bits
145 static const loff_t END = 1ULL << (SHIFT + 32);
146
11fdf7f2
TL
147 struct dentry {
148 int64_t offset;
f67539c2
TL
149 std::string name;
150 std::string alternate_name;
11fdf7f2
TL
151 InodeRef inode;
152 explicit dentry(int64_t o) : offset(o) {}
f67539c2
TL
153 dentry(int64_t o, std::string n, std::string an, InodeRef in) :
154 offset(o), name(std::move(n)), alternate_name(std::move(an)), inode(std::move(in)) {}
11fdf7f2
TL
155 };
156 struct dentry_off_lt {
157 bool operator()(const dentry& d, int64_t off) const {
158 return dir_result_t::fpos_cmp(d.offset, off) < 0;
159 }
160 };
161
162
163 explicit dir_result_t(Inode *in, const UserPerm& perms);
164
165
7c673cae
FG
166 static uint64_t make_fpos(unsigned h, unsigned l, bool hash) {
167 uint64_t v = ((uint64_t)h<< SHIFT) | (uint64_t)l;
168 if (hash)
169 v |= HASH;
170 else
11fdf7f2 171 ceph_assert((v & HASH) != HASH);
7c673cae
FG
172 return v;
173 }
174 static unsigned fpos_high(uint64_t p) {
175 unsigned v = (p & (END-1)) >> SHIFT;
176 if ((p & HASH) == HASH)
177 return ceph_frag_value(v);
178 return v;
179 }
180 static unsigned fpos_low(uint64_t p) {
181 return p & MASK;
182 }
183 static int fpos_cmp(uint64_t l, uint64_t r) {
184 int c = ceph_frag_compare(fpos_high(l), fpos_high(r));
185 if (c)
186 return c;
187 if (fpos_low(l) == fpos_low(r))
188 return 0;
189 return fpos_low(l) < fpos_low(r) ? -1 : 1;
190 }
191
7c673cae
FG
192 unsigned offset_high() { return fpos_high(offset); }
193 unsigned offset_low() { return fpos_low(offset); }
194
195 void set_end() { offset |= END; }
196 bool at_end() { return (offset & END); }
197
198 void set_hash_order() { offset |= HASH; }
199 bool hash_order() { return (offset & HASH) == HASH; }
200
201 bool is_cached() {
202 if (buffer.empty())
203 return false;
204 if (hash_order()) {
205 return buffer_frag.contains(offset_high());
206 } else {
207 return buffer_frag == frag_t(offset_high());
208 }
209 }
210
211 void reset() {
212 last_name.clear();
213 next_offset = 2;
214 offset = 0;
215 ordered_count = 0;
216 cache_index = 0;
217 buffer.clear();
218 }
11fdf7f2
TL
219
220 InodeRef inode;
221 int64_t offset; // hash order:
222 // (0xff << 52) | ((24 bits hash) << 28) |
223 // (the nth entry has hash collision);
224 // frag+name order;
225 // ((frag value) << 28) | (the nth entry in frag);
226
227 unsigned next_offset; // offset of next chunk (last_name's + 1)
20effc67 228 std::string last_name; // last entry in previous chunk
11fdf7f2
TL
229
230 uint64_t release_count;
231 uint64_t ordered_count;
232 unsigned cache_index;
233 int start_shared_gen; // dir shared_gen at start of readdir
234 UserPerm perms;
235
236 frag_t buffer_frag;
237
20effc67 238 std::vector<dentry> buffer;
f91f0fd5 239 struct dirent de;
7c673cae
FG
240};
241
242class Client : public Dispatcher, public md_config_obs_t {
11fdf7f2
TL
243public:
244 friend class C_Block_Sync; // Calls block map and protected helpers
245 friend class C_Client_CacheInvalidate; // calls ino_invalidate_cb
246 friend class C_Client_DentryInvalidate; // calls dentry_invalidate_cb
247 friend class C_Client_FlushComplete; // calls put_inode()
248 friend class C_Client_Remount;
249 friend class C_Client_RequestInterrupt;
250 friend class C_Deleg_Timeout; // Asserts on client_lock, called when a delegation is unreturned
e306af50 251 friend class C_Client_CacheRelease; // Asserts on client_lock
11fdf7f2
TL
252 friend class SyntheticClient;
253 friend void intrusive_ptr_release(Inode *in);
f67539c2
TL
254 template <typename T> friend struct RWRefState;
255 template <typename T> friend class RWRef;
11fdf7f2 256
7c673cae 257 using Dispatcher::cct;
f67539c2 258 using clock = ceph::coarse_mono_clock;
7c673cae 259
11fdf7f2 260 typedef int (*add_dirent_cb_t)(void *p, struct dirent *de, struct ceph_statx *stx, off_t off, Inode *in);
7c673cae 261
f67539c2
TL
262 struct walk_dentry_result {
263 InodeRef in;
264 std::string alternate_name;
265 };
266
7c673cae 267 class CommandHook : public AdminSocketHook {
7c673cae
FG
268 public:
269 explicit CommandHook(Client *client);
9f95a23c
TL
270 int call(std::string_view command, const cmdmap_t& cmdmap,
271 Formatter *f,
272 std::ostream& errss,
273 bufferlist& out) override;
11fdf7f2
TL
274 private:
275 Client *m_client;
7c673cae 276 };
7c673cae 277
f67539c2
TL
278 // snapshot info returned via get_snap_info(). nothing to do
279 // with SnapInfo on the MDS.
280 struct SnapInfo {
281 snapid_t id;
282 std::map<std::string, std::string> metadata;
283 };
284
11fdf7f2
TL
285 Client(Messenger *m, MonClient *mc, Objecter *objecter_);
286 Client(const Client&) = delete;
287 Client(const Client&&) = delete;
288 virtual ~Client() override;
7c673cae 289
11fdf7f2
TL
290 static UserPerm pick_my_perms(CephContext *c) {
291 uid_t uid = c->_conf->client_mount_uid >= 0 ? c->_conf->client_mount_uid : -1;
292 gid_t gid = c->_conf->client_mount_gid >= 0 ? c->_conf->client_mount_gid : -1;
293 return UserPerm(uid, gid);
294 }
7c673cae
FG
295 UserPerm pick_my_perms() {
296 uid_t uid = user_id >= 0 ? user_id : -1;
297 gid_t gid = group_id >= 0 ? group_id : -1;
298 return UserPerm(uid, gid);
299 }
300
11fdf7f2
TL
301 int mount(const std::string &mount_root, const UserPerm& perms,
302 bool require_mds=false, const std::string &fs_name="");
303 void unmount();
f67539c2
TL
304 bool is_unmounting() const {
305 return mount_state.check_current_state(CLIENT_UNMOUNTING);
306 }
307 bool is_mounted() const {
308 return mount_state.check_current_state(CLIENT_MOUNTED);
309 }
310 bool is_mounting() const {
311 return mount_state.check_current_state(CLIENT_MOUNTING);
312 }
313 bool is_initialized() const {
314 return initialize_state.check_current_state(CLIENT_INITIALIZED);
315 }
11fdf7f2 316 void abort_conn();
7c673cae 317
11fdf7f2
TL
318 void set_uuid(const std::string& uuid);
319 void set_session_timeout(unsigned timeout);
320 int start_reclaim(const std::string& uuid, unsigned flags,
321 const std::string& fs_name);
322 void finish_reclaim();
7c673cae 323
11fdf7f2
TL
324 fs_cluster_id_t get_fs_cid() {
325 return fscid;
326 }
7c673cae 327
11fdf7f2
TL
328 int mds_command(
329 const std::string &mds_spec,
330 const std::vector<std::string>& cmd,
331 const bufferlist& inbl,
332 bufferlist *poutbl, std::string *prs, Context *onfinish);
7c673cae 333
11fdf7f2
TL
334 // these should (more or less) mirror the actual system calls.
335 int statfs(const char *path, struct statvfs *stbuf, const UserPerm& perms);
7c673cae 336
11fdf7f2
TL
337 // crap
338 int chdir(const char *s, std::string &new_cwd, const UserPerm& perms);
339 void _getcwd(std::string& cwd, const UserPerm& perms);
340 void getcwd(std::string& cwd, const UserPerm& perms);
7c673cae 341
11fdf7f2
TL
342 // namespace ops
343 int opendir(const char *name, dir_result_t **dirpp, const UserPerm& perms);
b3b6e05e 344 int fdopendir(int dirfd, dir_result_t **dirpp, const UserPerm& perms);
11fdf7f2 345 int closedir(dir_result_t *dirp);
7c673cae 346
11fdf7f2
TL
347 /**
348 * Fill a directory listing from dirp, invoking cb for each entry
349 * with the given pointer, the dirent, the struct stat, the stmask,
350 * and the offset.
351 *
352 * Returns 0 if it reached the end of the directory.
353 * If @a cb returns a negative error code, stop and return that.
354 */
355 int readdir_r_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p,
2a845540 356 unsigned want=0, unsigned flags=AT_STATX_DONT_SYNC,
11fdf7f2 357 bool getref=false);
7c673cae 358
11fdf7f2
TL
359 struct dirent * readdir(dir_result_t *d);
360 int readdir_r(dir_result_t *dirp, struct dirent *de);
361 int readdirplus_r(dir_result_t *dirp, struct dirent *de, struct ceph_statx *stx, unsigned want, unsigned flags, Inode **out);
7c673cae 362
20effc67 363 int getdir(const char *relpath, std::list<std::string>& names,
11fdf7f2 364 const UserPerm& perms); // get the whole dir at once.
7c673cae 365
11fdf7f2
TL
366 /**
367 * Returns the length of the buffer that got filled in, or -errno.
f67539c2 368 * If it returns -CEPHFS_ERANGE you just need to increase the size of the
11fdf7f2
TL
369 * buffer and try again.
370 */
371 int _getdents(dir_result_t *dirp, char *buf, int buflen, bool ful); // get a bunch of dentries at once
372 int getdents(dir_result_t *dirp, char *buf, int buflen) {
373 return _getdents(dirp, buf, buflen, true);
374 }
375 int getdnames(dir_result_t *dirp, char *buf, int buflen) {
376 return _getdents(dirp, buf, buflen, false);
377 }
7c673cae 378
11fdf7f2
TL
379 void rewinddir(dir_result_t *dirp);
380 loff_t telldir(dir_result_t *dirp);
381 void seekdir(dir_result_t *dirp, loff_t offset);
7c673cae 382
f67539c2
TL
383 int may_delete(const char *relpath, const UserPerm& perms);
384 int link(const char *existing, const char *newname, const UserPerm& perm, std::string alternate_name="");
11fdf7f2 385 int unlink(const char *path, const UserPerm& perm);
b3b6e05e 386 int unlinkat(int dirfd, const char *relpath, int flags, const UserPerm& perm);
f67539c2 387 int rename(const char *from, const char *to, const UserPerm& perm, std::string alternate_name="");
11fdf7f2
TL
388
389 // dirs
f67539c2 390 int mkdir(const char *path, mode_t mode, const UserPerm& perm, std::string alternate_name="");
b3b6e05e
TL
391 int mkdirat(int dirfd, const char *relpath, mode_t mode, const UserPerm& perm,
392 std::string alternate_name="");
11fdf7f2
TL
393 int mkdirs(const char *path, mode_t mode, const UserPerm& perms);
394 int rmdir(const char *path, const UserPerm& perms);
395
396 // symlinks
397 int readlink(const char *path, char *buf, loff_t size, const UserPerm& perms);
b3b6e05e 398 int readlinkat(int dirfd, const char *relpath, char *buf, loff_t size, const UserPerm& perms);
11fdf7f2 399
f67539c2 400 int symlink(const char *existing, const char *newname, const UserPerm& perms, std::string alternate_name="");
b3b6e05e
TL
401 int symlinkat(const char *target, int dirfd, const char *relpath, const UserPerm& perms,
402 std::string alternate_name="");
f67539c2
TL
403
404 // path traversal for high-level interface
405 int walk(std::string_view path, struct walk_dentry_result* result, const UserPerm& perms, bool followsym=true);
11fdf7f2
TL
406
407 // inode stuff
408 unsigned statx_to_mask(unsigned int flags, unsigned int want);
409 int stat(const char *path, struct stat *stbuf, const UserPerm& perms,
410 frag_info_t *dirstat=0, int mask=CEPH_STAT_CAP_INODE_ALL);
411 int statx(const char *path, struct ceph_statx *stx,
412 const UserPerm& perms,
413 unsigned int want, unsigned int flags);
414 int lstat(const char *path, struct stat *stbuf, const UserPerm& perms,
415 frag_info_t *dirstat=0, int mask=CEPH_STAT_CAP_INODE_ALL);
416
417 int setattr(const char *relpath, struct stat *attr, int mask,
418 const UserPerm& perms);
419 int setattrx(const char *relpath, struct ceph_statx *stx, int mask,
420 const UserPerm& perms, int flags=0);
421 int fsetattr(int fd, struct stat *attr, int mask, const UserPerm& perms);
422 int fsetattrx(int fd, struct ceph_statx *stx, int mask, const UserPerm& perms);
423 int chmod(const char *path, mode_t mode, const UserPerm& perms);
424 int fchmod(int fd, mode_t mode, const UserPerm& perms);
b3b6e05e 425 int chmodat(int dirfd, const char *relpath, mode_t mode, int flags, const UserPerm& perms);
11fdf7f2
TL
426 int lchmod(const char *path, mode_t mode, const UserPerm& perms);
427 int chown(const char *path, uid_t new_uid, gid_t new_gid,
428 const UserPerm& perms);
429 int fchown(int fd, uid_t new_uid, gid_t new_gid, const UserPerm& perms);
430 int lchown(const char *path, uid_t new_uid, gid_t new_gid,
431 const UserPerm& perms);
b3b6e05e
TL
432 int chownat(int dirfd, const char *relpath, uid_t new_uid, gid_t new_gid,
433 int flags, const UserPerm& perms);
11fdf7f2
TL
434 int utime(const char *path, struct utimbuf *buf, const UserPerm& perms);
435 int lutime(const char *path, struct utimbuf *buf, const UserPerm& perms);
436 int futime(int fd, struct utimbuf *buf, const UserPerm& perms);
437 int utimes(const char *relpath, struct timeval times[2], const UserPerm& perms);
438 int lutimes(const char *relpath, struct timeval times[2], const UserPerm& perms);
439 int futimes(int fd, struct timeval times[2], const UserPerm& perms);
440 int futimens(int fd, struct timespec times[2], const UserPerm& perms);
b3b6e05e
TL
441 int utimensat(int dirfd, const char *relpath, struct timespec times[2], int flags,
442 const UserPerm& perms);
11fdf7f2
TL
443 int flock(int fd, int operation, uint64_t owner);
444 int truncate(const char *path, loff_t size, const UserPerm& perms);
445
446 // file ops
447 int mknod(const char *path, mode_t mode, const UserPerm& perms, dev_t rdev=0);
b3b6e05e 448
20effc67
TL
449 int create_and_open(int dirfd, const char *relpath, int flags, const UserPerm& perms,
450 mode_t mode, int stripe_unit, int stripe_count, int object_size,
451 const char *data_pool, std::string alternate_name);
f67539c2
TL
452 int open(const char *path, int flags, const UserPerm& perms, mode_t mode=0, std::string alternate_name="") {
453 return open(path, flags, perms, mode, 0, 0, 0, NULL, alternate_name);
454 }
11fdf7f2
TL
455 int open(const char *path, int flags, const UserPerm& perms,
456 mode_t mode, int stripe_unit, int stripe_count, int object_size,
f67539c2 457 const char *data_pool, std::string alternate_name="");
b3b6e05e
TL
458 int openat(int dirfd, const char *relpath, int flags, const UserPerm& perms,
459 mode_t mode, int stripe_unit, int stripe_count,
460 int object_size, const char *data_pool, std::string alternate_name);
461 int openat(int dirfd, const char *path, int flags, const UserPerm& perms, mode_t mode=0,
462 std::string alternate_name="") {
463 return openat(dirfd, path, flags, perms, mode, 0, 0, 0, NULL, alternate_name);
464 }
465
11fdf7f2
TL
466 int lookup_hash(inodeno_t ino, inodeno_t dirino, const char *name,
467 const UserPerm& perms);
468 int lookup_ino(inodeno_t ino, const UserPerm& perms, Inode **inode=NULL);
11fdf7f2 469 int lookup_name(Inode *in, Inode *parent, const UserPerm& perms);
b3b6e05e 470 int _close(int fd);
11fdf7f2
TL
471 int close(int fd);
472 loff_t lseek(int fd, loff_t offset, int whence);
473 int read(int fd, char *buf, loff_t size, loff_t offset=-1);
474 int preadv(int fd, const struct iovec *iov, int iovcnt, loff_t offset=-1);
475 int write(int fd, const char *buf, loff_t size, loff_t offset=-1);
476 int pwritev(int fd, const struct iovec *iov, int iovcnt, loff_t offset=-1);
477 int fake_write_size(int fd, loff_t size);
478 int ftruncate(int fd, loff_t size, const UserPerm& perms);
479 int fsync(int fd, bool syncdataonly);
480 int fstat(int fd, struct stat *stbuf, const UserPerm& perms,
481 int mask=CEPH_STAT_CAP_INODE_ALL);
482 int fstatx(int fd, struct ceph_statx *stx, const UserPerm& perms,
483 unsigned int want, unsigned int flags);
b3b6e05e
TL
484 int statxat(int dirfd, const char *relpath,
485 struct ceph_statx *stx, const UserPerm& perms,
486 unsigned int want, unsigned int flags);
11fdf7f2
TL
487 int fallocate(int fd, int mode, loff_t offset, loff_t length);
488
489 // full path xattr ops
490 int getxattr(const char *path, const char *name, void *value, size_t size,
491 const UserPerm& perms);
492 int lgetxattr(const char *path, const char *name, void *value, size_t size,
493 const UserPerm& perms);
494 int fgetxattr(int fd, const char *name, void *value, size_t size,
495 const UserPerm& perms);
496 int listxattr(const char *path, char *list, size_t size, const UserPerm& perms);
497 int llistxattr(const char *path, char *list, size_t size, const UserPerm& perms);
498 int flistxattr(int fd, char *list, size_t size, const UserPerm& perms);
499 int removexattr(const char *path, const char *name, const UserPerm& perms);
500 int lremovexattr(const char *path, const char *name, const UserPerm& perms);
501 int fremovexattr(int fd, const char *name, const UserPerm& perms);
502 int setxattr(const char *path, const char *name, const void *value,
503 size_t size, int flags, const UserPerm& perms);
504 int lsetxattr(const char *path, const char *name, const void *value,
505 size_t size, int flags, const UserPerm& perms);
506 int fsetxattr(int fd, const char *name, const void *value, size_t size,
507 int flags, const UserPerm& perms);
508
509 int sync_fs();
510 int64_t drop_caches();
511
f67539c2
TL
512 int get_snap_info(const char *path, const UserPerm &perms, SnapInfo *snap_info);
513
11fdf7f2
TL
514 // hpc lazyio
515 int lazyio(int fd, int enable);
92f5a8d4 516 int lazyio_propagate(int fd, loff_t offset, size_t count);
11fdf7f2
TL
517 int lazyio_synchronize(int fd, loff_t offset, size_t count);
518
519 // expose file layout
520 int describe_layout(const char *path, file_layout_t* layout,
521 const UserPerm& perms);
522 int fdescribe_layout(int fd, file_layout_t* layout);
20effc67
TL
523 int get_file_stripe_address(int fd, loff_t offset, std::vector<entity_addr_t>& address);
524 int get_file_extent_osds(int fd, loff_t off, loff_t *len, std::vector<int>& osds);
11fdf7f2
TL
525 int get_osd_addr(int osd, entity_addr_t& addr);
526
527 // expose mdsmap
528 int64_t get_default_pool_id();
529
530 // expose osdmap
531 int get_local_osd();
532 int get_pool_replication(int64_t pool);
533 int64_t get_pool_id(const char *pool_name);
20effc67
TL
534 std::string get_pool_name(int64_t pool);
535 int get_osd_crush_location(int id, std::vector<std::pair<std::string, std::string> >& path);
11fdf7f2 536
20effc67 537 int enumerate_layout(int fd, std::vector<ObjectExtent>& result,
11fdf7f2
TL
538 loff_t length, loff_t offset);
539
f67539c2
TL
540 int mksnap(const char *path, const char *name, const UserPerm& perm,
541 mode_t mode=0, const std::map<std::string, std::string> &metadata={});
542 int rmsnap(const char *path, const char *name, const UserPerm& perm, bool check_perms=false);
11fdf7f2
TL
543
544 // Inode permission checking
545 int inode_permission(Inode *in, const UserPerm& perms, unsigned want);
546
547 // expose caps
548 int get_caps_issued(int fd);
549 int get_caps_issued(const char *path, const UserPerm& perms);
550
551 snapid_t ll_get_snapid(Inode *in);
552 vinodeno_t ll_get_vino(Inode *in) {
553 std::lock_guard lock(client_lock);
554 return _get_vino(in);
555 }
556 // get inode from faked ino
557 Inode *ll_get_inode(ino_t ino);
558 Inode *ll_get_inode(vinodeno_t vino);
559 int ll_lookup(Inode *parent, const char *name, struct stat *attr,
560 Inode **out, const UserPerm& perms);
561 int ll_lookup_inode(struct inodeno_t ino, const UserPerm& perms, Inode **inode);
f67539c2 562 int ll_lookup_vino(vinodeno_t vino, const UserPerm& perms, Inode **inode);
11fdf7f2
TL
563 int ll_lookupx(Inode *parent, const char *name, Inode **out,
564 struct ceph_statx *stx, unsigned want, unsigned flags,
565 const UserPerm& perms);
494da23a 566 bool ll_forget(Inode *in, uint64_t count);
11fdf7f2
TL
567 bool ll_put(Inode *in);
568 int ll_get_snap_ref(snapid_t snap);
569
570 int ll_getattr(Inode *in, struct stat *st, const UserPerm& perms);
571 int ll_getattrx(Inode *in, struct ceph_statx *stx, unsigned int want,
572 unsigned int flags, const UserPerm& perms);
573 int ll_setattrx(Inode *in, struct ceph_statx *stx, int mask,
574 const UserPerm& perms);
575 int ll_setattr(Inode *in, struct stat *st, int mask,
576 const UserPerm& perms);
577 int ll_getxattr(Inode *in, const char *name, void *value, size_t size,
578 const UserPerm& perms);
579 int ll_setxattr(Inode *in, const char *name, const void *value, size_t size,
580 int flags, const UserPerm& perms);
581 int ll_removexattr(Inode *in, const char *name, const UserPerm& perms);
582 int ll_listxattr(Inode *in, char *list, size_t size, const UserPerm& perms);
583 int ll_opendir(Inode *in, int flags, dir_result_t **dirpp,
584 const UserPerm& perms);
585 int ll_releasedir(dir_result_t* dirp);
586 int ll_fsyncdir(dir_result_t* dirp);
587 int ll_readlink(Inode *in, char *buf, size_t bufsize, const UserPerm& perms);
588 int ll_mknod(Inode *in, const char *name, mode_t mode, dev_t rdev,
589 struct stat *attr, Inode **out, const UserPerm& perms);
590 int ll_mknodx(Inode *parent, const char *name, mode_t mode, dev_t rdev,
591 Inode **out, struct ceph_statx *stx, unsigned want,
592 unsigned flags, const UserPerm& perms);
593 int ll_mkdir(Inode *in, const char *name, mode_t mode, struct stat *attr,
594 Inode **out, const UserPerm& perm);
595 int ll_mkdirx(Inode *parent, const char *name, mode_t mode, Inode **out,
596 struct ceph_statx *stx, unsigned want, unsigned flags,
597 const UserPerm& perms);
598 int ll_symlink(Inode *in, const char *name, const char *value,
599 struct stat *attr, Inode **out, const UserPerm& perms);
600 int ll_symlinkx(Inode *parent, const char *name, const char *value,
601 Inode **out, struct ceph_statx *stx, unsigned want,
602 unsigned flags, const UserPerm& perms);
603 int ll_unlink(Inode *in, const char *name, const UserPerm& perm);
604 int ll_rmdir(Inode *in, const char *name, const UserPerm& perms);
605 int ll_rename(Inode *parent, const char *name, Inode *newparent,
606 const char *newname, const UserPerm& perm);
607 int ll_link(Inode *in, Inode *newparent, const char *newname,
608 const UserPerm& perm);
609 int ll_open(Inode *in, int flags, Fh **fh, const UserPerm& perms);
610 int _ll_create(Inode *parent, const char *name, mode_t mode,
611 int flags, InodeRef *in, int caps, Fh **fhp,
612 const UserPerm& perms);
613 int ll_create(Inode *parent, const char *name, mode_t mode, int flags,
614 struct stat *attr, Inode **out, Fh **fhp,
615 const UserPerm& perms);
616 int ll_createx(Inode *parent, const char *name, mode_t mode,
617 int oflags, Inode **outp, Fh **fhp,
618 struct ceph_statx *stx, unsigned want, unsigned lflags,
619 const UserPerm& perms);
620 int ll_read_block(Inode *in, uint64_t blockid, char *buf, uint64_t offset,
621 uint64_t length, file_layout_t* layout);
622
623 int ll_write_block(Inode *in, uint64_t blockid,
624 char* buf, uint64_t offset,
625 uint64_t length, file_layout_t* layout,
626 uint64_t snapseq, uint32_t sync);
627 int ll_commit_blocks(Inode *in, uint64_t offset, uint64_t length);
628
629 int ll_statfs(Inode *in, struct statvfs *stbuf, const UserPerm& perms);
630 int ll_walk(const char* name, Inode **i, struct ceph_statx *stx,
631 unsigned int want, unsigned int flags, const UserPerm& perms);
632 uint32_t ll_stripe_unit(Inode *in);
633 int ll_file_layout(Inode *in, file_layout_t *layout);
634 uint64_t ll_snap_seq(Inode *in);
635
636 int ll_read(Fh *fh, loff_t off, loff_t len, bufferlist *bl);
637 int ll_write(Fh *fh, loff_t off, loff_t len, const char *data);
638 int64_t ll_readv(struct Fh *fh, const struct iovec *iov, int iovcnt, int64_t off);
639 int64_t ll_writev(struct Fh *fh, const struct iovec *iov, int iovcnt, int64_t off);
640 loff_t ll_lseek(Fh *fh, loff_t offset, int whence);
641 int ll_flush(Fh *fh);
642 int ll_fsync(Fh *fh, bool syncdataonly);
643 int ll_sync_inode(Inode *in, bool syncdataonly);
644 int ll_fallocate(Fh *fh, int mode, int64_t offset, int64_t length);
645 int ll_release(Fh *fh);
646 int ll_getlk(Fh *fh, struct flock *fl, uint64_t owner);
647 int ll_setlk(Fh *fh, struct flock *fl, uint64_t owner, int sleep);
648 int ll_flock(Fh *fh, int cmd, uint64_t owner);
649 int ll_lazyio(Fh *fh, int enable);
650 int ll_file_layout(Fh *fh, file_layout_t *layout);
651 void ll_interrupt(void *d);
652 bool ll_handle_umask() {
653 return acl_type != NO_ACL;
654 }
655
656 int ll_get_stripe_osd(struct Inode *in, uint64_t blockno,
657 file_layout_t* layout);
658 uint64_t ll_get_internal_offset(struct Inode *in, uint64_t blockno);
659
660 int ll_num_osds(void);
661 int ll_osdaddr(int osd, uint32_t *addr);
662 int ll_osdaddr(int osd, char* buf, size_t size);
663
20effc67
TL
664 void _ll_register_callbacks(struct ceph_client_callback_args *args);
665 void ll_register_callbacks(struct ceph_client_callback_args *args); // deprecated
666 int ll_register_callbacks2(struct ceph_client_callback_args *args);
1d09f67e 667 std::pair<int, bool> test_dentry_handling(bool can_invalidate);
11fdf7f2
TL
668
669 const char** get_tracked_conf_keys() const override;
670 void handle_conf_change(const ConfigProxy& conf,
671 const std::set <std::string> &changed) override;
672 uint32_t get_deleg_timeout() { return deleg_timeout; }
673 int set_deleg_timeout(uint32_t timeout);
674 int ll_delegation(Fh *fh, unsigned cmd, ceph_deleg_cb_t cb, void *priv);
675
676 entity_name_t get_myname() { return messenger->get_myname(); }
9f95a23c
TL
677 void wait_on_list(std::list<ceph::condition_variable*>& ls);
678 void signal_cond_list(std::list<ceph::condition_variable*>& ls);
11fdf7f2
TL
679
680 void set_filer_flags(int flags);
681 void clear_filer_flags(int flags);
682
683 void tear_down_cache();
684
685 void update_metadata(std::string const &k, std::string const &v);
686
687 client_t get_nodeid() { return whoami; }
688
689 inodeno_t get_root_ino();
690 Inode *get_root();
691
692 virtual int init();
693 virtual void shutdown();
694
695 // messaging
f67539c2 696 void cancel_commands(const MDSMap& newmap);
11fdf7f2
TL
697 void handle_mds_map(const MConstRef<MMDSMap>& m);
698 void handle_fs_map(const MConstRef<MFSMap>& m);
699 void handle_fs_map_user(const MConstRef<MFSMapUser>& m);
700 void handle_osd_map(const MConstRef<MOSDMap>& m);
701
702 void handle_lease(const MConstRef<MClientLease>& m);
703
704 // inline data
705 int uninline_data(Inode *in, Context *onfinish);
706
707 // file caps
708 void check_cap_issue(Inode *in, unsigned issued);
709 void add_update_cap(Inode *in, MetaSession *session, uint64_t cap_id,
710 unsigned issued, unsigned wanted, unsigned seq, unsigned mseq,
711 inodeno_t realm, int flags, const UserPerm& perms);
712 void remove_cap(Cap *cap, bool queue_release);
713 void remove_all_caps(Inode *in);
f6b5b4d7 714 void remove_session_caps(MetaSession *session, int err);
11fdf7f2
TL
715 int mark_caps_flushing(Inode *in, ceph_tid_t *ptid);
716 void adjust_session_flushing_caps(Inode *in, MetaSession *old_s, MetaSession *new_s);
717 void flush_caps_sync();
eafe8130 718 void kick_flushing_caps(Inode *in, MetaSession *session);
11fdf7f2
TL
719 void kick_flushing_caps(MetaSession *session);
720 void early_kick_flushing_caps(MetaSession *session);
f6b5b4d7 721 int get_caps(Fh *fh, int need, int want, int *have, loff_t endoff);
11fdf7f2
TL
722 int get_caps_used(Inode *in);
723
724 void maybe_update_snaprealm(SnapRealm *realm, snapid_t snap_created, snapid_t snap_highwater,
20effc67 725 std::vector<snapid_t>& snaps);
11fdf7f2
TL
726
727 void handle_quota(const MConstRef<MClientQuota>& m);
728 void handle_snap(const MConstRef<MClientSnap>& m);
729 void handle_caps(const MConstRef<MClientCaps>& m);
730 void handle_cap_import(MetaSession *session, Inode *in, const MConstRef<MClientCaps>& m);
731 void handle_cap_export(MetaSession *session, Inode *in, const MConstRef<MClientCaps>& m);
732 void handle_cap_trunc(MetaSession *session, Inode *in, const MConstRef<MClientCaps>& m);
733 void handle_cap_flush_ack(MetaSession *session, Inode *in, Cap *cap, const MConstRef<MClientCaps>& m);
734 void handle_cap_flushsnap_ack(MetaSession *session, Inode *in, const MConstRef<MClientCaps>& m);
735 void handle_cap_grant(MetaSession *session, Inode *in, Cap *cap, const MConstRef<MClientCaps>& m);
736 void cap_delay_requeue(Inode *in);
eafe8130
TL
737
738 void send_cap(Inode *in, MetaSession *session, Cap *cap, int flags,
11fdf7f2
TL
739 int used, int want, int retain, int flush,
740 ceph_tid_t flush_tid);
741
eafe8130
TL
742 void send_flush_snap(Inode *in, MetaSession *session, snapid_t follows, CapSnap& capsnap);
743
744 void flush_snaps(Inode *in);
11fdf7f2
TL
745 void get_cap_ref(Inode *in, int cap);
746 void put_cap_ref(Inode *in, int cap);
11fdf7f2
TL
747 void wait_sync_caps(Inode *in, ceph_tid_t want);
748 void wait_sync_caps(ceph_tid_t want);
749 void queue_cap_snap(Inode *in, SnapContext &old_snapc);
750 void finish_cap_snap(Inode *in, CapSnap &capsnap, int used);
11fdf7f2
TL
751
752 void _schedule_invalidate_dentry_callback(Dentry *dn, bool del);
20effc67 753 void _async_dentry_invalidate(vinodeno_t dirino, vinodeno_t ino, std::string& name);
11fdf7f2
TL
754 void _try_to_trim_inode(Inode *in, bool sched_inval);
755
756 void _schedule_invalidate_callback(Inode *in, int64_t off, int64_t len);
757 void _invalidate_inode_cache(Inode *in);
758 void _invalidate_inode_cache(Inode *in, int64_t off, int64_t len);
759 void _async_invalidate(vinodeno_t ino, int64_t off, int64_t len);
e306af50
TL
760
761 void _schedule_ino_release_callback(Inode *in);
762 void _async_inode_release(vinodeno_t ino);
763
11fdf7f2
TL
764 bool _release(Inode *in);
765
766 /**
767 * Initiate a flush of the data associated with the given inode.
768 * If you specify a Context, you are responsible for holding an inode
769 * reference for the duration of the flush. If not, _flush() will
770 * take the reference for you.
771 * @param in The Inode whose data you wish to flush.
772 * @param c The Context you wish us to complete once the data is
773 * flushed. If already flushed, this will be called in-line.
774 *
775 * @returns true if the data was already flushed, false otherwise.
776 */
777 bool _flush(Inode *in, Context *c);
778 void _flush_range(Inode *in, int64_t off, uint64_t size);
779 void _flushed(Inode *in);
780 void flush_set_callback(ObjectCacher::ObjectSet *oset);
781
782 void close_release(Inode *in);
783 void close_safe(Inode *in);
784
785 void lock_fh_pos(Fh *f);
786 void unlock_fh_pos(Fh *f);
787
788 // metadata cache
522d829b 789 void update_dir_dist(Inode *in, DirStat *st, mds_rank_t from);
11fdf7f2
TL
790
791 void clear_dir_complete_and_ordered(Inode *diri, bool complete);
792 void insert_readdir_results(MetaRequest *request, MetaSession *session, Inode *diri);
793 Inode* insert_trace(MetaRequest *request, MetaSession *session);
794 void update_inode_file_size(Inode *in, int issued, uint64_t size,
795 uint64_t truncate_seq, uint64_t truncate_size);
796 void update_inode_file_time(Inode *in, int issued, uint64_t time_warp_seq,
797 utime_t ctime, utime_t mtime, utime_t atime);
798
799 Inode *add_update_inode(InodeStat *st, utime_t ttl, MetaSession *session,
800 const UserPerm& request_perms);
20effc67 801 Dentry *insert_dentry_inode(Dir *dir, const std::string& dname, LeaseStat *dlease,
11fdf7f2
TL
802 Inode *in, utime_t from, MetaSession *session,
803 Dentry *old_dentry = NULL);
804 void update_dentry_lease(Dentry *dn, LeaseStat *dlease, utime_t from, MetaSession *session);
805
806 bool use_faked_inos() { return _use_faked_inos; }
807 vinodeno_t map_faked_ino(ino_t ino);
808
809 //notify the mds to flush the mdlog
522d829b 810 void flush_mdlog_sync(Inode *in);
11fdf7f2
TL
811 void flush_mdlog_sync();
812 void flush_mdlog(MetaSession *session);
813
814 void renew_caps();
815 void renew_caps(MetaSession *session);
816 void flush_cap_releases();
f67539c2 817 void renew_and_flush_cap_releases();
11fdf7f2 818 void tick();
f67539c2
TL
819 void start_tick_thread();
820
a4b75251
TL
821 void update_read_io_size(size_t size) {
822 total_read_ops++;
823 total_read_size += size;
824 }
825
826 void update_write_io_size(size_t size) {
827 total_write_ops++;
828 total_write_size += size;
829 }
830
f67539c2
TL
831 void inc_dentry_nr() {
832 ++dentry_nr;
833 }
834 void dec_dentry_nr() {
835 --dentry_nr;
836 }
837 void dlease_hit() {
838 ++dlease_hits;
839 }
840 void dlease_miss() {
841 ++dlease_misses;
842 }
843 std::tuple<uint64_t, uint64_t, uint64_t> get_dlease_hit_rates() {
844 return std::make_tuple(dlease_hits, dlease_misses, dentry_nr);
845 }
846
847 void cap_hit() {
848 ++cap_hits;
849 }
850 void cap_miss() {
851 ++cap_misses;
852 }
853 std::pair<uint64_t, uint64_t> get_cap_hit_rates() {
854 return std::make_pair(cap_hits, cap_misses);
855 }
856
857 void inc_opened_files() {
858 ++opened_files;
859 }
860 void dec_opened_files() {
861 --opened_files;
862 }
863 std::pair<uint64_t, uint64_t> get_opened_files_rates() {
864 return std::make_pair(opened_files, inode_map.size());
865 }
866
867 void inc_pinned_icaps() {
868 ++pinned_icaps;
869 }
870 void dec_pinned_icaps(uint64_t nr=1) {
871 pinned_icaps -= nr;
872 }
873 std::pair<uint64_t, uint64_t> get_pinned_icaps_rates() {
874 return std::make_pair(pinned_icaps, inode_map.size());
875 }
876
877 void inc_opened_inodes() {
878 ++opened_inodes;
879 }
880 void dec_opened_inodes() {
881 --opened_inodes;
882 }
883 std::pair<uint64_t, uint64_t> get_opened_inodes_rates() {
884 return std::make_pair(opened_inodes, inode_map.size());
885 }
11fdf7f2 886
f67539c2
TL
887 /* timer_lock for 'timer' */
888 ceph::mutex timer_lock = ceph::make_mutex("Client::timer_lock");
11fdf7f2
TL
889 SafeTimer timer;
890
f67539c2
TL
891 /* tick thread */
892 std::thread upkeeper;
893 ceph::condition_variable upkeep_cond;
894 bool tick_thread_stopped = false;
895
11fdf7f2
TL
896 std::unique_ptr<PerfCounters> logger;
897 std::unique_ptr<MDSMap> mdsmap;
898
92f5a8d4 899 bool fuse_default_permissions;
33c7a0ef 900 bool _collect_and_send_global_metrics;
11fdf7f2
TL
901
902protected:
903 /* Flags for check_caps() */
904 static const unsigned CHECK_CAPS_NODELAY = 0x1;
905 static const unsigned CHECK_CAPS_SYNCHRONOUS = 0x2;
906
11fdf7f2
TL
907 void check_caps(Inode *in, unsigned flags);
908
909 void set_cap_epoch_barrier(epoch_t e);
910
911 void handle_command_reply(const MConstRef<MCommandReply>& m);
912 int fetch_fsmap(bool user);
913 int resolve_mds(
914 const std::string &mds_spec,
915 std::vector<mds_gid_t> *targets);
916
917 void get_session_metadata(std::map<std::string, std::string> *meta) const;
918 bool have_open_session(mds_rank_t mds);
919 void got_mds_push(MetaSession *s);
20effc67
TL
920 MetaSessionRef _get_mds_session(mds_rank_t mds, Connection *con); ///< return session for mds *and* con; null otherwise
921 MetaSessionRef _get_or_open_mds_session(mds_rank_t mds);
922 MetaSessionRef _open_mds_session(mds_rank_t mds);
11fdf7f2 923 void _close_mds_session(MetaSession *s);
f6b5b4d7 924 void _closed_mds_session(MetaSession *s, int err=0, bool rejected=false);
11fdf7f2
TL
925 bool _any_stale_sessions() const;
926 void _kick_stale_sessions();
927 void handle_client_session(const MConstRef<MClientSession>& m);
928 void send_reconnect(MetaSession *s);
929 void resend_unsafe_requests(MetaSession *s);
930 void wait_unsafe_requests();
931
11fdf7f2 932 void dump_mds_requests(Formatter *f);
adb31ebb 933 void dump_mds_sessions(Formatter *f, bool cap_dump=false);
11fdf7f2
TL
934
935 int make_request(MetaRequest *req, const UserPerm& perms,
936 InodeRef *ptarget = 0, bool *pcreated = 0,
937 mds_rank_t use_mds=-1, bufferlist *pdirbl=0);
938 void put_request(MetaRequest *request);
939 void unregister_request(MetaRequest *request);
940
9f95a23c
TL
941 int verify_reply_trace(int r, MetaSession *session, MetaRequest *request,
942 const MConstRef<MClientReply>& reply,
11fdf7f2
TL
943 InodeRef *ptarget, bool *pcreated,
944 const UserPerm& perms);
945 void encode_cap_releases(MetaRequest *request, mds_rank_t mds);
946 int encode_inode_release(Inode *in, MetaRequest *req,
7c673cae
FG
947 mds_rank_t mds, int drop,
948 int unless,int force=0);
949 void encode_dentry_release(Dentry *dn, MetaRequest *req,
950 mds_rank_t mds, int drop, int unless);
951 mds_rank_t choose_target_mds(MetaRequest *req, Inode** phash_diri=NULL);
952 void connect_mds_targets(mds_rank_t mds);
953 void send_request(MetaRequest *request, MetaSession *session,
954 bool drop_cap_releases=false);
11fdf7f2 955 MRef<MClientRequest> build_client_request(MetaRequest *request);
7c673cae
FG
956 void kick_requests(MetaSession *session);
957 void kick_requests_closed(MetaSession *session);
11fdf7f2
TL
958 void handle_client_request_forward(const MConstRef<MClientRequestForward>& reply);
959 void handle_client_reply(const MConstRef<MClientReply>& reply);
7c673cae
FG
960 bool is_dir_operation(MetaRequest *request);
961
b3b6e05e
TL
962 int path_walk(const filepath& fp, struct walk_dentry_result* result, const UserPerm& perms, bool followsym=true, int mask=0,
963 InodeRef dirinode=nullptr);
f67539c2 964 int path_walk(const filepath& fp, InodeRef *end, const UserPerm& perms,
b3b6e05e 965 bool followsym=true, int mask=0, InodeRef dirinode=nullptr);
f67539c2 966
7c673cae 967 // fake inode number for 32-bits ino_t
7c673cae 968 void _assign_faked_ino(Inode *in);
11fdf7f2 969 void _assign_faked_root(Inode *in);
7c673cae 970 void _release_faked_ino(Inode *in);
7c673cae
FG
971 void _reset_faked_inos();
972 vinodeno_t _map_faked_ino(ino_t ino);
973
7c673cae 974 // Optional extra metadata about me to send to the MDS
7c673cae
FG
975 void populate_metadata(const std::string &mount_root);
976
7c673cae
FG
977 SnapRealm *get_snap_realm(inodeno_t r);
978 SnapRealm *get_snap_realm_maybe(inodeno_t r);
979 void put_snap_realm(SnapRealm *realm);
980 bool adjust_realm_parent(SnapRealm *realm, inodeno_t parent);
11fdf7f2 981 void update_snap_trace(const bufferlist& bl, SnapRealm **realm_ret, bool must_flush=true);
7c673cae
FG
982 void invalidate_snaprealm_and_children(SnapRealm *realm);
983
984 Inode *open_snapdir(Inode *diri);
985
7c673cae
FG
986 int get_fd() {
987 int fd = free_fd_set.range_start();
988 free_fd_set.erase(fd, 1);
989 return fd;
990 }
991 void put_fd(int fd) {
992 free_fd_set.insert(fd, 1);
993 }
994
995 /*
996 * Resolve file descriptor, or return NULL.
997 */
998 Fh *get_filehandle(int fd) {
f67539c2
TL
999 auto it = fd_map.find(fd);
1000 if (it == fd_map.end())
7c673cae 1001 return NULL;
f67539c2 1002 return it->second;
7c673cae 1003 }
b3b6e05e 1004 int get_fd_inode(int fd, InodeRef *in);
7c673cae 1005
7c673cae 1006 // helpers
a8e16298 1007 void wake_up_session_caps(MetaSession *s, bool reconnect);
7c673cae 1008
20effc67
TL
1009 void wait_on_context_list(std::list<Context*>& ls);
1010 void signal_context_list(std::list<Context*>& ls);
7c673cae
FG
1011
1012 // -- metadata cache stuff
1013
1014 // decrease inode ref. delete if dangling.
f67539c2
TL
1015 void _put_inode(Inode *in, int n);
1016 void delay_put_inodes(bool wakeup=false);
7c673cae
FG
1017 void put_inode(Inode *in, int n=1);
1018 void close_dir(Dir *dir);
1019
11fdf7f2 1020 int subscribe_mdsmap(const std::string &fs_name="");
b32b8144 1021
11fdf7f2
TL
1022 void _abort_mds_sessions(int err);
1023
1024 // same as unmount() but for when the client_lock is already held
1025 void _unmount(bool abort);
7c673cae
FG
1026
1027 //int get_cache_size() { return lru.lru_get_size(); }
7c673cae
FG
1028
1029 /**
1030 * Don't call this with in==NULL, use get_or_create for that
1031 * leave dn set to default NULL unless you're trying to add
1032 * a new inode to a pre-created Dentry
1033 */
20effc67 1034 Dentry* link(Dir *dir, const std::string& name, Inode *in, Dentry *dn);
7c673cae
FG
1035 void unlink(Dentry *dn, bool keepdir, bool keepdentry);
1036
7c673cae
FG
1037 int fill_stat(Inode *in, struct stat *st, frag_info_t *dirstat=0, nest_info_t *rstat=0);
1038 int fill_stat(InodeRef& in, struct stat *st, frag_info_t *dirstat=0, nest_info_t *rstat=0) {
1039 return fill_stat(in.get(), st, dirstat, rstat);
1040 }
1041
1042 void fill_statx(Inode *in, unsigned int mask, struct ceph_statx *stx);
1043 void fill_statx(InodeRef& in, unsigned int mask, struct ceph_statx *stx) {
1044 return fill_statx(in.get(), mask, stx);
1045 }
1046
1047 void touch_dn(Dentry *dn);
1048
1049 // trim cache.
1050 void trim_cache(bool trim_kernel_dcache=false);
1051 void trim_cache_for_reconnect(MetaSession *s);
1052 void trim_dentry(Dentry *dn);
28e407b8 1053 void trim_caps(MetaSession *s, uint64_t max);
7c673cae 1054 void _invalidate_kernel_dcache();
91327a77 1055 void _trim_negative_child_dentries(InodeRef& in);
11fdf7f2 1056
7c673cae
FG
1057 void dump_inode(Formatter *f, Inode *in, set<Inode*>& did, bool disconnected);
1058 void dump_cache(Formatter *f); // debug
1059
1060 // force read-only
1061 void force_session_readonly(MetaSession *s);
1062
1063 void dump_status(Formatter *f); // debug
7c673cae 1064
11fdf7f2 1065 bool ms_dispatch2(const MessageRef& m) override;
7c673cae
FG
1066
1067 void ms_handle_connect(Connection *con) override;
1068 bool ms_handle_reset(Connection *con) override;
1069 void ms_handle_remote_reset(Connection *con) override;
1070 bool ms_handle_refused(Connection *con) override;
7c673cae
FG
1071
1072 int authenticate();
1073
1074 Inode* get_quota_root(Inode *in, const UserPerm& perms);
1075 bool check_quota_condition(Inode *in, const UserPerm& perms,
1076 std::function<bool (const Inode &)> test);
1077 bool is_quota_files_exceeded(Inode *in, const UserPerm& perms);
1078 bool is_quota_bytes_exceeded(Inode *in, int64_t new_bytes,
11fdf7f2
TL
1079 const UserPerm& perms);
1080 bool is_quota_bytes_approaching(Inode *in, const UserPerm& perms);
7c673cae 1081
7c673cae
FG
1082 int check_pool_perm(Inode *in, int need);
1083
11fdf7f2
TL
1084 void handle_client_reclaim_reply(const MConstRef<MClientReclaimReply>& reply);
1085
7c673cae
FG
1086 /**
1087 * Call this when an OSDMap is seen with a full flag (global or per pool)
1088 * set.
1089 *
1090 * @param pool the pool ID affected, or -1 if all.
1091 */
1092 void _handle_full_flag(int64_t pool);
1093
1094 void _close_sessions();
1095
e306af50
TL
1096 void _pre_init();
1097
7c673cae
FG
1098 /**
1099 * The basic housekeeping parts of init (perf counters, admin socket)
1100 * that is independent of how objecters/monclient/messengers are
1101 * being set up.
1102 */
1103 void _finish_init();
1104
11fdf7f2
TL
1105 // global client lock
1106 // - protects Client and buffer cache both!
9f95a23c 1107 ceph::mutex client_lock = ceph::make_mutex("Client::client_lock");
7c673cae 1108
11fdf7f2 1109 std::map<snapid_t, int> ll_snap_ref;
7c673cae 1110
b3b6e05e 1111 InodeRef root = nullptr;
11fdf7f2
TL
1112 map<Inode*, InodeRef> root_parents;
1113 Inode* root_ancestor = nullptr;
1114 LRU lru; // lru list of Dentry's in our local metadata cache.
7c673cae 1115
11fdf7f2 1116 InodeRef cwd;
7c673cae 1117
11fdf7f2
TL
1118 std::unique_ptr<Filer> filer;
1119 std::unique_ptr<ObjectCacher> objectcacher;
1120 std::unique_ptr<WritebackHandler> writeback_handler;
7c673cae 1121
11fdf7f2
TL
1122 Messenger *messenger;
1123 MonClient *monclient;
1124 Objecter *objecter;
7c673cae 1125
11fdf7f2 1126 client_t whoami;
7c673cae 1127
f67539c2
TL
1128 /* The state migration mechanism */
1129 enum _state {
1130 /* For the initialize_state */
1131 CLIENT_NEW, // The initial state for the initialize_state or after Client::shutdown()
1132 CLIENT_INITIALIZING, // At the beginning of the Client::init()
1133 CLIENT_INITIALIZED, // At the end of CLient::init()
1134
1135 /* For the mount_state */
1136 CLIENT_UNMOUNTED, // The initial state for the mount_state or after unmounted
1137 CLIENT_MOUNTING, // At the beginning of Client::mount()
1138 CLIENT_MOUNTED, // At the end of Client::mount()
1139 CLIENT_UNMOUNTING, // At the beginning of the Client::_unmout()
1140 };
1141
1142 typedef enum _state state_t;
1143 using RWRef_t = RWRef<state_t>;
1144
1145 struct mount_state_t : public RWRefState<state_t> {
1146 public:
1147 bool is_valid_state(state_t state) const override {
1148 switch (state) {
1149 case Client::CLIENT_MOUNTING:
1150 case Client::CLIENT_MOUNTED:
1151 case Client::CLIENT_UNMOUNTING:
1152 case Client::CLIENT_UNMOUNTED:
1153 return true;
1154 default:
1155 return false;
1156 }
1157 }
1158
1159 int check_reader_state(state_t require) const override {
1160 if (require == Client::CLIENT_MOUNTING &&
1161 (state == Client::CLIENT_MOUNTING || state == Client::CLIENT_MOUNTED))
1162 return true;
1163 else
1164 return false;
1165 }
1166
1167 /* The state migration check */
1168 int check_writer_state(state_t require) const override {
1169 if (require == Client::CLIENT_MOUNTING &&
1170 state == Client::CLIENT_UNMOUNTED)
1171 return true;
1172 else if (require == Client::CLIENT_MOUNTED &&
1173 state == Client::CLIENT_MOUNTING)
1174 return true;
1175 else if (require == Client::CLIENT_UNMOUNTING &&
1176 state == Client::CLIENT_MOUNTED)
1177 return true;
1178 else if (require == Client::CLIENT_UNMOUNTED &&
1179 state == Client::CLIENT_UNMOUNTING)
1180 return true;
1181 else
1182 return false;
1183 }
1184
1185 mount_state_t(state_t state, const char *lockname, uint64_t reader_cnt=0)
1186 : RWRefState (state, lockname, reader_cnt) {}
1187 ~mount_state_t() {}
1188 };
1189
1190 struct initialize_state_t : public RWRefState<state_t> {
1191 public:
1192 bool is_valid_state(state_t state) const override {
1193 switch (state) {
1194 case Client::CLIENT_NEW:
1195 case Client::CLIENT_INITIALIZING:
1196 case Client::CLIENT_INITIALIZED:
1197 return true;
1198 default:
1199 return false;
1200 }
1201 }
1202
1203 int check_reader_state(state_t require) const override {
1204 if (require == Client::CLIENT_INITIALIZED &&
1205 state >= Client::CLIENT_INITIALIZED)
1206 return true;
1207 else
1208 return false;
1209 }
1210
1211 /* The state migration check */
1212 int check_writer_state(state_t require) const override {
1213 if (require == Client::CLIENT_INITIALIZING &&
1214 (state == Client::CLIENT_NEW))
1215 return true;
1216 else if (require == Client::CLIENT_INITIALIZED &&
1217 (state == Client::CLIENT_INITIALIZING))
1218 return true;
1219 else if (require == Client::CLIENT_NEW &&
1220 (state == Client::CLIENT_INITIALIZED))
1221 return true;
1222 else
1223 return false;
1224 }
1225
1226 initialize_state_t(state_t state, const char *lockname, uint64_t reader_cnt=0)
1227 : RWRefState (state, lockname, reader_cnt) {}
1228 ~initialize_state_t() {}
1229 };
1230
1231 struct mount_state_t mount_state;
1232 struct initialize_state_t initialize_state;
7c673cae 1233
11fdf7f2
TL
1234private:
1235 struct C_Readahead : public Context {
1236 C_Readahead(Client *c, Fh *f);
1237 ~C_Readahead() override;
1238 void finish(int r) override;
7c673cae 1239
11fdf7f2
TL
1240 Client *client;
1241 Fh *f;
1242 };
7c673cae 1243
11fdf7f2
TL
1244 /*
1245 * These define virtual xattrs exposing the recursive directory
1246 * statistics and layout metadata.
1247 */
1248 struct VXattr {
20effc67
TL
1249 const std::string name;
1250 size_t (Client::*getxattr_cb)(Inode *in, char *val, size_t size);
1251 bool readonly;
1252 bool (Client::*exists_cb)(Inode *in);
1253 unsigned int flags;
11fdf7f2 1254 };
7c673cae 1255
11fdf7f2
TL
1256 enum {
1257 NO_ACL = 0,
1258 POSIX_ACL,
1259 };
7c673cae 1260
11fdf7f2
TL
1261 enum {
1262 MAY_EXEC = 1,
1263 MAY_WRITE = 2,
1264 MAY_READ = 4,
1265 };
7c673cae 1266
f67539c2 1267 std::unique_ptr<CephContext, std::function<void(CephContext*)>> cct_deleter;
7c673cae 1268
11fdf7f2
TL
1269 /* Flags for VXattr */
1270 static const unsigned VXATTR_RSTAT = 0x1;
adb31ebb 1271 static const unsigned VXATTR_DIRSTAT = 0x2;
7c673cae 1272
11fdf7f2
TL
1273 static const VXattr _dir_vxattrs[];
1274 static const VXattr _file_vxattrs[];
adb31ebb 1275 static const VXattr _common_vxattrs[];
1adf2230 1276
7c673cae 1277
b3b6e05e 1278 bool is_reserved_vino(vinodeno_t &vino);
7c673cae
FG
1279
1280 void fill_dirent(struct dirent *de, const char *name, int type, uint64_t ino, loff_t next_off);
1281
7c673cae
FG
1282 int _opendir(Inode *in, dir_result_t **dirpp, const UserPerm& perms);
1283 void _readdir_drop_dirp_buffer(dir_result_t *dirp);
1284 bool _readdir_have_frag(dir_result_t *dirp);
1285 void _readdir_next_frag(dir_result_t *dirp);
1286 void _readdir_rechoose_frag(dir_result_t *dirp);
1287 int _readdir_get_frag(dir_result_t *dirp);
1288 int _readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p, int caps, bool getref);
1289 void _closedir(dir_result_t *dirp);
1290
1291 // other helpers
1292 void _fragmap_remove_non_leaves(Inode *in);
1293 void _fragmap_remove_stopped_mds(Inode *in, mds_rank_t mds);
1294
1295 void _ll_get(Inode *in);
494da23a 1296 int _ll_put(Inode *in, uint64_t num);
7c673cae
FG
1297 void _ll_drop_pins();
1298
1299 Fh *_create_fh(Inode *in, int flags, int cmode, const UserPerm& perms);
1300 int _release_fh(Fh *fh);
1301 void _put_fh(Fh *fh);
1302
1d09f67e 1303 std::pair<int, bool> _do_remount(bool retry_on_error);
7c673cae
FG
1304
1305 int _read_sync(Fh *f, uint64_t off, uint64_t len, bufferlist *bl, bool *checkeof);
1306 int _read_async(Fh *f, uint64_t off, uint64_t len, bufferlist *bl);
1307
f67539c2
TL
1308 bool _dentry_valid(const Dentry *dn);
1309
7c673cae
FG
1310 // internal interface
1311 // call these with client_lock held!
20effc67 1312 int _do_lookup(Inode *dir, const std::string& name, int mask, InodeRef *target,
7c673cae
FG
1313 const UserPerm& perms);
1314
20effc67 1315 int _lookup(Inode *dir, const std::string& dname, int mask, InodeRef *target,
f67539c2 1316 const UserPerm& perm, std::string* alternate_name=nullptr);
7c673cae 1317
f67539c2 1318 int _link(Inode *in, Inode *dir, const char *name, const UserPerm& perm, std::string alternate_name,
7c673cae
FG
1319 InodeRef *inp = 0);
1320 int _unlink(Inode *dir, const char *name, const UserPerm& perm);
f67539c2 1321 int _rename(Inode *olddir, const char *oname, Inode *ndir, const char *nname, const UserPerm& perm, std::string alternate_name);
7c673cae 1322 int _mkdir(Inode *dir, const char *name, mode_t mode, const UserPerm& perm,
f67539c2
TL
1323 InodeRef *inp = 0, const std::map<std::string, std::string> &metadata={},
1324 std::string alternate_name="");
7c673cae
FG
1325 int _rmdir(Inode *dir, const char *name, const UserPerm& perms);
1326 int _symlink(Inode *dir, const char *name, const char *target,
f67539c2 1327 const UserPerm& perms, std::string alternate_name, InodeRef *inp = 0);
7c673cae
FG
1328 int _mknod(Inode *dir, const char *name, mode_t mode, dev_t rdev,
1329 const UserPerm& perms, InodeRef *inp = 0);
1330 int _do_setattr(Inode *in, struct ceph_statx *stx, int mask,
1331 const UserPerm& perms, InodeRef *inp);
1332 void stat_to_statx(struct stat *st, struct ceph_statx *stx);
1333 int __setattrx(Inode *in, struct ceph_statx *stx, int mask,
1334 const UserPerm& perms, InodeRef *inp = 0);
1335 int _setattrx(InodeRef &in, struct ceph_statx *stx, int mask,
1336 const UserPerm& perms);
1337 int _setattr(InodeRef &in, struct stat *attr, int mask,
1338 const UserPerm& perms);
1339 int _ll_setattrx(Inode *in, struct ceph_statx *stx, int mask,
1340 const UserPerm& perms, InodeRef *inp = 0);
1341 int _getattr(Inode *in, int mask, const UserPerm& perms, bool force=false);
1342 int _getattr(InodeRef &in, int mask, const UserPerm& perms, bool force=false) {
1343 return _getattr(in.get(), mask, perms, force);
1344 }
1345 int _readlink(Inode *in, char *buf, size_t size);
1346 int _getxattr(Inode *in, const char *name, void *value, size_t len,
1347 const UserPerm& perms);
1348 int _getxattr(InodeRef &in, const char *name, void *value, size_t len,
1349 const UserPerm& perms);
1d09f67e
TL
1350 int _getvxattr(Inode *in, const UserPerm& perms, const char *attr_name,
1351 ssize_t size, void *value, mds_rank_t rank);
7c673cae
FG
1352 int _listxattr(Inode *in, char *names, size_t len, const UserPerm& perms);
1353 int _do_setxattr(Inode *in, const char *name, const void *value, size_t len,
1354 int flags, const UserPerm& perms);
1355 int _setxattr(Inode *in, const char *name, const void *value, size_t len,
1356 int flags, const UserPerm& perms);
1357 int _setxattr(InodeRef &in, const char *name, const void *value, size_t len,
1358 int flags, const UserPerm& perms);
20effc67 1359 int _setxattr_check_data_pool(std::string& name, std::string& value, const OSDMap *osdmap);
7c673cae
FG
1360 void _setxattr_maybe_wait_for_osdmap(const char *name, const void *value, size_t len);
1361 int _removexattr(Inode *in, const char *nm, const UserPerm& perms);
1362 int _removexattr(InodeRef &in, const char *nm, const UserPerm& perms);
1363 int _open(Inode *in, int flags, mode_t mode, Fh **fhp,
1364 const UserPerm& perms);
1365 int _renew_caps(Inode *in);
1366 int _create(Inode *in, const char *name, int flags, mode_t mode, InodeRef *inp,
1367 Fh **fhp, int stripe_unit, int stripe_count, int object_size,
f67539c2
TL
1368 const char *data_pool, bool *created, const UserPerm &perms,
1369 std::string alternate_name);
7c673cae
FG
1370
1371 loff_t _lseek(Fh *fh, loff_t offset, int whence);
11fdf7f2
TL
1372 int64_t _read(Fh *fh, int64_t offset, uint64_t size, bufferlist *bl);
1373 int64_t _write(Fh *fh, int64_t offset, uint64_t size, const char *buf,
7c673cae 1374 const struct iovec *iov, int iovcnt);
f67539c2
TL
1375 int64_t _preadv_pwritev_locked(Fh *fh, const struct iovec *iov,
1376 unsigned iovcnt, int64_t offset,
20effc67
TL
1377 bool write, bool clamp_to_int);
1378 int _preadv_pwritev(int fd, const struct iovec *iov, unsigned iovcnt,
1379 int64_t offset, bool write);
7c673cae
FG
1380 int _flush(Fh *fh);
1381 int _fsync(Fh *fh, bool syncdataonly);
1382 int _fsync(Inode *in, bool syncdataonly);
1383 int _sync_fs();
1384 int _fallocate(Fh *fh, int mode, int64_t offset, int64_t length);
1385 int _getlk(Fh *fh, struct flock *fl, uint64_t owner);
1386 int _setlk(Fh *fh, struct flock *fl, uint64_t owner, int sleep);
1387 int _flock(Fh *fh, int cmd, uint64_t owner);
11fdf7f2 1388 int _lazyio(Fh *fh, int enable);
7c673cae
FG
1389
1390 int get_or_create(Inode *dir, const char* name,
1391 Dentry **pdn, bool expect_null=false);
1392
7c673cae
FG
1393 int xattr_permission(Inode *in, const char *name, unsigned want,
1394 const UserPerm& perms);
1395 int may_setattr(Inode *in, struct ceph_statx *stx, int mask,
1396 const UserPerm& perms);
1397 int may_open(Inode *in, int flags, const UserPerm& perms);
1398 int may_lookup(Inode *dir, const UserPerm& perms);
1399 int may_create(Inode *dir, const UserPerm& perms);
1400 int may_delete(Inode *dir, const char *name, const UserPerm& perms);
1401 int may_hardlink(Inode *in, const UserPerm& perms);
1402
1403 int _getattr_for_perm(Inode *in, const UserPerm& perms);
7c673cae
FG
1404
1405 vinodeno_t _get_vino(Inode *in);
28e407b8 1406
7c673cae
FG
1407 bool _vxattrcb_quota_exists(Inode *in);
1408 size_t _vxattrcb_quota(Inode *in, char *val, size_t size);
1409 size_t _vxattrcb_quota_max_bytes(Inode *in, char *val, size_t size);
1410 size_t _vxattrcb_quota_max_files(Inode *in, char *val, size_t size);
1411
1412 bool _vxattrcb_layout_exists(Inode *in);
1413 size_t _vxattrcb_layout(Inode *in, char *val, size_t size);
1414 size_t _vxattrcb_layout_stripe_unit(Inode *in, char *val, size_t size);
1415 size_t _vxattrcb_layout_stripe_count(Inode *in, char *val, size_t size);
1416 size_t _vxattrcb_layout_object_size(Inode *in, char *val, size_t size);
1417 size_t _vxattrcb_layout_pool(Inode *in, char *val, size_t size);
1418 size_t _vxattrcb_layout_pool_namespace(Inode *in, char *val, size_t size);
1419 size_t _vxattrcb_dir_entries(Inode *in, char *val, size_t size);
1420 size_t _vxattrcb_dir_files(Inode *in, char *val, size_t size);
1421 size_t _vxattrcb_dir_subdirs(Inode *in, char *val, size_t size);
1422 size_t _vxattrcb_dir_rentries(Inode *in, char *val, size_t size);
1423 size_t _vxattrcb_dir_rfiles(Inode *in, char *val, size_t size);
1424 size_t _vxattrcb_dir_rsubdirs(Inode *in, char *val, size_t size);
f67539c2 1425 size_t _vxattrcb_dir_rsnaps(Inode *in, char *val, size_t size);
7c673cae
FG
1426 size_t _vxattrcb_dir_rbytes(Inode *in, char *val, size_t size);
1427 size_t _vxattrcb_dir_rctime(Inode *in, char *val, size_t size);
7c673cae 1428
11fdf7f2
TL
1429 bool _vxattrcb_dir_pin_exists(Inode *in);
1430 size_t _vxattrcb_dir_pin(Inode *in, char *val, size_t size);
1431
81eedcae
TL
1432 bool _vxattrcb_snap_btime_exists(Inode *in);
1433 size_t _vxattrcb_snap_btime(Inode *in, char *val, size_t size);
7c673cae 1434
20effc67
TL
1435 size_t _vxattrcb_caps(Inode *in, char *val, size_t size);
1436
f67539c2
TL
1437 bool _vxattrcb_mirror_info_exists(Inode *in);
1438 size_t _vxattrcb_mirror_info(Inode *in, char *val, size_t size);
1439
adb31ebb
TL
1440 size_t _vxattrcb_cluster_fsid(Inode *in, char *val, size_t size);
1441 size_t _vxattrcb_client_id(Inode *in, char *val, size_t size);
1442
7c673cae
FG
1443 static const VXattr *_get_vxattrs(Inode *in);
1444 static const VXattr *_match_vxattr(Inode *in, const char *name);
1445
7c673cae
FG
1446 int _do_filelock(Inode *in, Fh *fh, int lock_type, int op, int sleep,
1447 struct flock *fl, uint64_t owner, bool removing=false);
1448 int _interrupt_filelock(MetaRequest *req);
1449 void _encode_filelocks(Inode *in, bufferlist& bl);
1450 void _release_filelocks(Fh *fh);
1451 void _update_lock_state(struct flock *fl, uint64_t owner, ceph_lock_state_t *lock_state);
1452
1453 int _posix_acl_create(Inode *dir, mode_t *mode, bufferlist& xattrs_bl,
1454 const UserPerm& perms);
1455 int _posix_acl_chmod(Inode *in, mode_t mode, const UserPerm& perms);
1456 int _posix_acl_permission(Inode *in, const UserPerm& perms, unsigned want);
1457
1458 mds_rank_t _get_random_up_mds() const;
1459
1460 int _ll_getattr(Inode *in, int caps, const UserPerm& perms);
1adf2230
AA
1461 int _lookup_parent(Inode *in, const UserPerm& perms, Inode **parent=NULL);
1462 int _lookup_name(Inode *in, Inode *parent, const UserPerm& perms);
f67539c2 1463 int _lookup_vino(vinodeno_t ino, const UserPerm& perms, Inode **inode=NULL);
494da23a 1464 bool _ll_forget(Inode *in, uint64_t count);
7c673cae 1465
f67539c2
TL
1466 void collect_and_send_metrics();
1467 void collect_and_send_global_metrics();
7c673cae 1468
2a845540
TL
1469 void update_io_stat_metadata(utime_t latency);
1470 void update_io_stat_read(utime_t latency);
1471 void update_io_stat_write(utime_t latency);
1472
11fdf7f2 1473 uint32_t deleg_timeout = 0;
7c673cae 1474
11fdf7f2
TL
1475 client_switch_interrupt_callback_t switch_interrupt_cb = nullptr;
1476 client_remount_callback_t remount_cb = nullptr;
1477 client_ino_callback_t ino_invalidate_cb = nullptr;
1478 client_dentry_callback_t dentry_invalidate_cb = nullptr;
1479 client_umask_callback_t umask_cb = nullptr;
e306af50 1480 client_ino_release_t ino_release_cb = nullptr;
11fdf7f2
TL
1481 void *callback_handle = nullptr;
1482 bool can_invalidate_dentries = false;
7c673cae 1483
11fdf7f2
TL
1484 Finisher async_ino_invalidator;
1485 Finisher async_dentry_invalidator;
1486 Finisher interrupt_finisher;
1487 Finisher remount_finisher;
e306af50 1488 Finisher async_ino_releasor;
11fdf7f2 1489 Finisher objecter_finisher;
7c673cae 1490
2a845540 1491 ceph::coarse_mono_time last_cap_renew;
7c673cae 1492
11fdf7f2 1493 CommandHook m_command_hook;
7c673cae 1494
11fdf7f2
TL
1495 int user_id, group_id;
1496 int acl_type = NO_ACL;
7c673cae 1497
11fdf7f2 1498 epoch_t cap_epoch_barrier = 0;
7c673cae 1499
11fdf7f2 1500 // mds sessions
20effc67 1501 map<mds_rank_t, MetaSessionRef> mds_sessions; // mds -> push seq
f6b5b4d7 1502 std::set<mds_rank_t> mds_ranks_closing; // mds ranks currently tearing down sessions
9f95a23c 1503 std::list<ceph::condition_variable*> waiting_for_mdsmap;
7c673cae 1504
11fdf7f2 1505 // FSMap, for when using mds_command
9f95a23c 1506 std::list<ceph::condition_variable*> waiting_for_fsmap;
11fdf7f2
TL
1507 std::unique_ptr<FSMap> fsmap;
1508 std::unique_ptr<FSMapUser> fsmap_user;
7c673cae 1509
f67539c2
TL
1510 // This mutex only protects command_table
1511 ceph::mutex command_lock = ceph::make_mutex("Client::command_lock");
11fdf7f2
TL
1512 // MDS command state
1513 CommandTable<MDSCommandOp> command_table;
7c673cae 1514
11fdf7f2 1515 bool _use_faked_inos;
7c673cae 1516
11fdf7f2
TL
1517 // Cluster fsid
1518 fs_cluster_id_t fscid;
7c673cae 1519
11fdf7f2
TL
1520 // file handles, etc.
1521 interval_set<int> free_fd_set; // unused fds
1522 ceph::unordered_map<int, Fh*> fd_map;
1523 set<Fh*> ll_unclosed_fh_set;
1524 ceph::unordered_set<dir_result_t*> opened_dirs;
f6b5b4d7 1525 uint64_t fd_gen = 1;
7c673cae 1526
f67539c2
TL
1527 bool mount_aborted = false;
1528 bool blocklisted = false;
28e407b8 1529
11fdf7f2
TL
1530 ceph::unordered_map<vinodeno_t, Inode*> inode_map;
1531 ceph::unordered_map<ino_t, vinodeno_t> faked_ino_map;
1532 interval_set<ino_t> free_faked_inos;
1533 ino_t last_used_faked_ino;
1534 ino_t last_used_faked_root;
7c673cae 1535
f67539c2 1536 int local_osd = -CEPHFS_ENXIO;
11fdf7f2 1537 epoch_t local_osd_epoch = 0;
7c673cae 1538
11fdf7f2
TL
1539 // mds requests
1540 ceph_tid_t last_tid = 0;
1541 ceph_tid_t oldest_tid = 0; // oldest incomplete mds request, excluding setfilelock requests
1542 map<ceph_tid_t, MetaRequest*> mds_requests;
7c673cae 1543
11fdf7f2
TL
1544 // cap flushing
1545 ceph_tid_t last_flush_tid = 1;
7c673cae 1546
20effc67 1547 xlist<Inode*> delayed_list;
11fdf7f2
TL
1548 int num_flushing_caps = 0;
1549 ceph::unordered_map<inodeno_t,SnapRealm*> snap_realms;
1550 std::map<std::string, std::string> metadata;
7c673cae 1551
2a845540
TL
1552 ceph::coarse_mono_time last_auto_reconnect;
1553 std::chrono::seconds caps_release_delay, mount_timeout;
11fdf7f2 1554 // trace generation
20effc67 1555 std::ofstream traceout;
7c673cae 1556
9f95a23c 1557 ceph::condition_variable mount_cond, sync_cond;
11fdf7f2
TL
1558
1559 std::map<std::pair<int64_t,std::string>, int> pool_perms;
9f95a23c 1560 std::list<ceph::condition_variable*> waiting_for_pool_perm;
91327a77 1561
91327a77 1562 uint64_t retries_on_invalidate = 0;
11fdf7f2
TL
1563
1564 // state reclaim
9f95a23c 1565 std::list<ceph::condition_variable*> waiting_for_reclaim;
11fdf7f2
TL
1566 int reclaim_errno = 0;
1567 epoch_t reclaim_osd_epoch = 0;
1568 entity_addrvec_t reclaim_target_addrs;
f67539c2
TL
1569
1570 // dentry lease metrics
1571 uint64_t dentry_nr = 0;
1572 uint64_t dlease_hits = 0;
1573 uint64_t dlease_misses = 0;
1574
1575 uint64_t cap_hits = 0;
1576 uint64_t cap_misses = 0;
1577
1578 uint64_t opened_files = 0;
1579 uint64_t pinned_icaps = 0;
1580 uint64_t opened_inodes = 0;
1581
a4b75251
TL
1582 uint64_t total_read_ops = 0;
1583 uint64_t total_read_size = 0;
1584
1585 uint64_t total_write_ops = 0;
1586 uint64_t total_write_size = 0;
1587
f67539c2
TL
1588 ceph::spinlock delay_i_lock;
1589 std::map<Inode*,int> delay_i_release;
2a845540
TL
1590
1591 uint64_t nr_metadata_request = 0;
1592 uint64_t nr_read_request = 0;
1593 uint64_t nr_write_request = 0;
7c673cae
FG
1594};
1595
1596/**
1597 * Specialization of Client that manages its own Objecter instance
1598 * and handles init/shutdown of messenger/monclient
1599 */
1600class StandaloneClient : public Client
1601{
11fdf7f2 1602public:
f67539c2 1603 StandaloneClient(Messenger *m, MonClient *mc, boost::asio::io_context& ictx);
7c673cae
FG
1604
1605 ~StandaloneClient() override;
1606
1607 int init() override;
1608 void shutdown() override;
1609};
1610
1611#endif