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