0001
0002 #ifndef _FS_CEPH_MDS_CLIENT_H
0003 #define _FS_CEPH_MDS_CLIENT_H
0004
0005 #include <linux/completion.h>
0006 #include <linux/kref.h>
0007 #include <linux/list.h>
0008 #include <linux/mutex.h>
0009 #include <linux/rbtree.h>
0010 #include <linux/spinlock.h>
0011 #include <linux/refcount.h>
0012 #include <linux/utsname.h>
0013 #include <linux/ktime.h>
0014
0015 #include <linux/ceph/types.h>
0016 #include <linux/ceph/messenger.h>
0017 #include <linux/ceph/mdsmap.h>
0018 #include <linux/ceph/auth.h>
0019
0020 #include "metric.h"
0021 #include "super.h"
0022
0023
0024 enum ceph_feature_type {
0025 CEPHFS_FEATURE_MIMIC = 8,
0026 CEPHFS_FEATURE_REPLY_ENCODING,
0027 CEPHFS_FEATURE_RECLAIM_CLIENT,
0028 CEPHFS_FEATURE_LAZY_CAP_WANTED,
0029 CEPHFS_FEATURE_MULTI_RECONNECT,
0030 CEPHFS_FEATURE_DELEG_INO,
0031 CEPHFS_FEATURE_METRIC_COLLECT,
0032 CEPHFS_FEATURE_ALTERNATE_NAME,
0033 CEPHFS_FEATURE_NOTIFY_SESSION_STATE,
0034
0035 CEPHFS_FEATURE_MAX = CEPHFS_FEATURE_NOTIFY_SESSION_STATE,
0036 };
0037
0038 #define CEPHFS_FEATURES_CLIENT_SUPPORTED { \
0039 0, 1, 2, 3, 4, 5, 6, 7, \
0040 CEPHFS_FEATURE_MIMIC, \
0041 CEPHFS_FEATURE_REPLY_ENCODING, \
0042 CEPHFS_FEATURE_LAZY_CAP_WANTED, \
0043 CEPHFS_FEATURE_MULTI_RECONNECT, \
0044 CEPHFS_FEATURE_DELEG_INO, \
0045 CEPHFS_FEATURE_METRIC_COLLECT, \
0046 CEPHFS_FEATURE_NOTIFY_SESSION_STATE, \
0047 }
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063 struct ceph_fs_client;
0064 struct ceph_cap;
0065
0066
0067
0068
0069
0070 struct ceph_mds_reply_info_in {
0071 struct ceph_mds_reply_inode *in;
0072 struct ceph_dir_layout dir_layout;
0073 u32 symlink_len;
0074 char *symlink;
0075 u32 xattr_len;
0076 char *xattr_data;
0077 u64 inline_version;
0078 u32 inline_len;
0079 char *inline_data;
0080 u32 pool_ns_len;
0081 char *pool_ns_data;
0082 u64 max_bytes;
0083 u64 max_files;
0084 s32 dir_pin;
0085 struct ceph_timespec btime;
0086 struct ceph_timespec snap_btime;
0087 u64 rsnaps;
0088 u64 change_attr;
0089 };
0090
0091 struct ceph_mds_reply_dir_entry {
0092 char *name;
0093 u32 name_len;
0094 struct ceph_mds_reply_lease *lease;
0095 struct ceph_mds_reply_info_in inode;
0096 loff_t offset;
0097 };
0098
0099 struct ceph_mds_reply_xattr {
0100 char *xattr_value;
0101 size_t xattr_value_len;
0102 };
0103
0104
0105
0106
0107
0108
0109
0110 struct ceph_mds_reply_info_parsed {
0111 struct ceph_mds_reply_head *head;
0112
0113
0114 struct ceph_mds_reply_info_in diri, targeti;
0115 struct ceph_mds_reply_dirfrag *dirfrag;
0116 char *dname;
0117 u32 dname_len;
0118 struct ceph_mds_reply_lease *dlease;
0119 struct ceph_mds_reply_xattr xattr_info;
0120
0121
0122 union {
0123
0124 struct ceph_filelock *filelock_reply;
0125
0126
0127 struct {
0128 struct ceph_mds_reply_dirfrag *dir_dir;
0129 size_t dir_buf_size;
0130 int dir_nr;
0131 bool dir_end;
0132 bool dir_complete;
0133 bool hash_order;
0134 bool offset_hash;
0135 struct ceph_mds_reply_dir_entry *dir_entries;
0136 };
0137
0138
0139 struct {
0140 bool has_create_ino;
0141 u64 ino;
0142 };
0143 };
0144
0145
0146
0147 void *snapblob;
0148 int snapblob_len;
0149 };
0150
0151
0152
0153
0154
0155
0156
0157
0158 #define CEPH_CAPS_PER_RELEASE ((PAGE_SIZE - sizeof(u32) - \
0159 sizeof(struct ceph_mds_cap_release)) / \
0160 sizeof(struct ceph_mds_cap_item))
0161
0162
0163
0164
0165
0166 enum {
0167 CEPH_MDS_SESSION_NEW = 1,
0168 CEPH_MDS_SESSION_OPENING = 2,
0169 CEPH_MDS_SESSION_OPEN = 3,
0170 CEPH_MDS_SESSION_HUNG = 4,
0171 CEPH_MDS_SESSION_RESTARTING = 5,
0172 CEPH_MDS_SESSION_RECONNECTING = 6,
0173 CEPH_MDS_SESSION_CLOSING = 7,
0174 CEPH_MDS_SESSION_CLOSED = 8,
0175 CEPH_MDS_SESSION_REJECTED = 9,
0176 };
0177
0178 struct ceph_mds_session {
0179 struct ceph_mds_client *s_mdsc;
0180 int s_mds;
0181 int s_state;
0182 unsigned long s_ttl;
0183 unsigned long s_features;
0184 u64 s_seq;
0185 struct mutex s_mutex;
0186
0187 struct ceph_connection s_con;
0188
0189 struct ceph_auth_handshake s_auth;
0190
0191 atomic_t s_cap_gen;
0192 unsigned long s_cap_ttl;
0193
0194
0195 spinlock_t s_cap_lock;
0196 refcount_t s_ref;
0197 struct list_head s_caps;
0198 struct ceph_cap *s_cap_iterator;
0199 int s_nr_caps;
0200 int s_num_cap_releases;
0201 int s_cap_reconnect;
0202 int s_readonly;
0203 struct list_head s_cap_releases;
0204 struct work_struct s_cap_release_work;
0205
0206
0207 struct list_head s_cap_dirty;
0208
0209
0210 struct list_head s_cap_flushing;
0211
0212 unsigned long s_renew_requested;
0213 u64 s_renew_seq;
0214
0215 struct list_head s_waiting;
0216 struct list_head s_unsafe;
0217 struct xarray s_delegated_inos;
0218 };
0219
0220
0221
0222
0223 enum {
0224 USE_ANY_MDS,
0225 USE_RANDOM_MDS,
0226 USE_AUTH_MDS,
0227 };
0228
0229 struct ceph_mds_request;
0230 struct ceph_mds_client;
0231
0232
0233
0234
0235 typedef void (*ceph_mds_request_callback_t) (struct ceph_mds_client *mdsc,
0236 struct ceph_mds_request *req);
0237
0238
0239
0240 typedef int (*ceph_mds_request_wait_callback_t) (struct ceph_mds_client *mdsc,
0241 struct ceph_mds_request *req);
0242
0243
0244
0245
0246 struct ceph_mds_request {
0247 u64 r_tid;
0248 struct rb_node r_node;
0249 struct ceph_mds_client *r_mdsc;
0250
0251 struct kref r_kref;
0252 int r_op;
0253
0254
0255 struct inode *r_inode;
0256 struct dentry *r_dentry;
0257 struct dentry *r_old_dentry;
0258 struct inode *r_old_dentry_dir;
0259 char *r_path1, *r_path2;
0260 struct ceph_vino r_ino1, r_ino2;
0261
0262 struct inode *r_parent;
0263 struct inode *r_target_inode;
0264
0265 #define CEPH_MDS_R_DIRECT_IS_HASH (1)
0266 #define CEPH_MDS_R_ABORTED (2)
0267 #define CEPH_MDS_R_GOT_UNSAFE (3)
0268 #define CEPH_MDS_R_GOT_SAFE (4)
0269 #define CEPH_MDS_R_GOT_RESULT (5)
0270 #define CEPH_MDS_R_DID_PREPOPULATE (6)
0271 #define CEPH_MDS_R_PARENT_LOCKED (7)
0272 #define CEPH_MDS_R_ASYNC (8)
0273 unsigned long r_req_flags;
0274
0275 struct mutex r_fill_mutex;
0276
0277 union ceph_mds_request_args r_args;
0278 int r_fmode;
0279 int r_request_release_offset;
0280 const struct cred *r_cred;
0281 struct timespec64 r_stamp;
0282
0283
0284 int r_direct_mode;
0285 u32 r_direct_hash;
0286
0287
0288 struct ceph_pagelist *r_pagelist;
0289
0290
0291 int r_inode_drop, r_inode_unless;
0292 int r_dentry_drop, r_dentry_unless;
0293 int r_old_dentry_drop, r_old_dentry_unless;
0294 struct inode *r_old_inode;
0295 int r_old_inode_drop, r_old_inode_unless;
0296
0297 struct ceph_msg *r_request;
0298 struct ceph_msg *r_reply;
0299 struct ceph_mds_reply_info_parsed r_reply_info;
0300 int r_err;
0301 u32 r_readdir_offset;
0302
0303 struct page *r_locked_page;
0304 int r_dir_caps;
0305 int r_num_caps;
0306
0307 unsigned long r_timeout;
0308 unsigned long r_started;
0309 unsigned long r_start_latency;
0310 unsigned long r_end_latency;
0311 unsigned long r_request_started;
0312
0313
0314
0315 struct inode *r_unsafe_dir;
0316 struct list_head r_unsafe_dir_item;
0317
0318
0319 struct list_head r_unsafe_target_item;
0320
0321 struct ceph_mds_session *r_session;
0322
0323 int r_attempts;
0324 int r_num_fwd;
0325 int r_resend_mds;
0326 u32 r_sent_on_mseq;
0327 u64 r_deleg_ino;
0328
0329 struct list_head r_wait;
0330 struct completion r_completion;
0331 struct completion r_safe_completion;
0332 ceph_mds_request_callback_t r_callback;
0333 struct list_head r_unsafe_item;
0334
0335 long long r_dir_release_cnt;
0336 long long r_dir_ordered_cnt;
0337 int r_readdir_cache_idx;
0338
0339 struct ceph_cap_reservation r_caps_reservation;
0340 };
0341
0342 struct ceph_pool_perm {
0343 struct rb_node node;
0344 int perm;
0345 s64 pool;
0346 size_t pool_ns_len;
0347 char pool_ns[];
0348 };
0349
0350 struct ceph_snapid_map {
0351 struct rb_node node;
0352 struct list_head lru;
0353 atomic_t ref;
0354 u64 snap;
0355 dev_t dev;
0356 unsigned long last_used;
0357 };
0358
0359
0360
0361
0362
0363 struct ceph_quotarealm_inode {
0364 struct rb_node node;
0365 u64 ino;
0366 unsigned long timeout;
0367 struct mutex mutex;
0368 struct inode *inode;
0369 };
0370
0371 struct cap_wait {
0372 struct list_head list;
0373 u64 ino;
0374 pid_t tgid;
0375 int need;
0376 int want;
0377 };
0378
0379
0380
0381
0382 struct ceph_mds_client {
0383 struct ceph_fs_client *fsc;
0384 struct mutex mutex;
0385
0386 struct ceph_mdsmap *mdsmap;
0387 struct completion safe_umount_waiters;
0388 wait_queue_head_t session_close_wq;
0389 struct list_head waiting_for_map;
0390 int mdsmap_err;
0391
0392 struct ceph_mds_session **sessions;
0393 atomic_t num_sessions;
0394 int max_sessions;
0395 int stopping;
0396
0397 atomic64_t quotarealms_count;
0398
0399
0400
0401
0402 struct rb_root quotarealms_inodes;
0403 struct mutex quotarealms_inodes_mutex;
0404
0405
0406
0407
0408
0409
0410
0411
0412 u64 last_snap_seq;
0413 struct rw_semaphore snap_rwsem;
0414 struct rb_root snap_realms;
0415 struct list_head snap_empty;
0416 int num_snap_realms;
0417 spinlock_t snap_empty_lock;
0418
0419 u64 last_tid;
0420 u64 oldest_tid;
0421
0422 struct rb_root request_tree;
0423 struct delayed_work delayed_work;
0424 unsigned long last_renew_caps;
0425 struct list_head cap_delay_list;
0426 spinlock_t cap_delay_lock;
0427 struct list_head snap_flush_list;
0428 spinlock_t snap_flush_lock;
0429
0430 u64 last_cap_flush_tid;
0431 struct list_head cap_flush_list;
0432 struct list_head cap_dirty_migrating;
0433 int num_cap_flushing;
0434 spinlock_t cap_dirty_lock;
0435 wait_queue_head_t cap_flushing_wq;
0436
0437 struct work_struct cap_reclaim_work;
0438 atomic_t cap_reclaim_pending;
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451 spinlock_t caps_list_lock;
0452 struct list_head caps_list;
0453
0454 struct list_head cap_wait_list;
0455 int caps_total_count;
0456 int caps_use_count;
0457 int caps_use_max;
0458 int caps_reserve_count;
0459 int caps_avail_count;
0460 int caps_min_count;
0461
0462 spinlock_t dentry_list_lock;
0463 struct list_head dentry_leases;
0464 struct list_head dentry_dir_leases;
0465
0466 struct ceph_client_metric metric;
0467
0468 spinlock_t snapid_map_lock;
0469 struct rb_root snapid_map_tree;
0470 struct list_head snapid_map_lru;
0471
0472 struct rw_semaphore pool_perm_rwsem;
0473 struct rb_root pool_perm_tree;
0474
0475 char nodename[__NEW_UTS_LEN + 1];
0476 };
0477
0478 extern const char *ceph_mds_op_name(int op);
0479
0480 extern bool check_session_state(struct ceph_mds_session *s);
0481 void inc_session_sequence(struct ceph_mds_session *s);
0482
0483 extern struct ceph_mds_session *
0484 __ceph_lookup_mds_session(struct ceph_mds_client *, int mds);
0485
0486 extern const char *ceph_session_state_name(int s);
0487
0488 extern struct ceph_mds_session *
0489 ceph_get_mds_session(struct ceph_mds_session *s);
0490 extern void ceph_put_mds_session(struct ceph_mds_session *s);
0491
0492 extern int ceph_send_msg_mds(struct ceph_mds_client *mdsc,
0493 struct ceph_msg *msg, int mds);
0494
0495 extern int ceph_mdsc_init(struct ceph_fs_client *fsc);
0496 extern void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc);
0497 extern void ceph_mdsc_force_umount(struct ceph_mds_client *mdsc);
0498 extern void ceph_mdsc_destroy(struct ceph_fs_client *fsc);
0499
0500 extern void ceph_mdsc_sync(struct ceph_mds_client *mdsc);
0501
0502 extern void ceph_invalidate_dir_request(struct ceph_mds_request *req);
0503 extern int ceph_alloc_readdir_reply_buffer(struct ceph_mds_request *req,
0504 struct inode *dir);
0505 extern struct ceph_mds_request *
0506 ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode);
0507 extern int ceph_mdsc_submit_request(struct ceph_mds_client *mdsc,
0508 struct inode *dir,
0509 struct ceph_mds_request *req);
0510 int ceph_mdsc_wait_request(struct ceph_mds_client *mdsc,
0511 struct ceph_mds_request *req,
0512 ceph_mds_request_wait_callback_t wait_func);
0513 extern int ceph_mdsc_do_request(struct ceph_mds_client *mdsc,
0514 struct inode *dir,
0515 struct ceph_mds_request *req);
0516 extern void ceph_mdsc_release_dir_caps(struct ceph_mds_request *req);
0517 extern void ceph_mdsc_release_dir_caps_no_check(struct ceph_mds_request *req);
0518 static inline void ceph_mdsc_get_request(struct ceph_mds_request *req)
0519 {
0520 kref_get(&req->r_kref);
0521 }
0522 extern void ceph_mdsc_release_request(struct kref *kref);
0523 static inline void ceph_mdsc_put_request(struct ceph_mds_request *req)
0524 {
0525 kref_put(&req->r_kref, ceph_mdsc_release_request);
0526 }
0527
0528 extern void send_flush_mdlog(struct ceph_mds_session *s);
0529 extern void ceph_mdsc_iterate_sessions(struct ceph_mds_client *mdsc,
0530 void (*cb)(struct ceph_mds_session *),
0531 bool check_state);
0532 extern struct ceph_msg *ceph_create_session_msg(u32 op, u64 seq);
0533 extern void __ceph_queue_cap_release(struct ceph_mds_session *session,
0534 struct ceph_cap *cap);
0535 extern void ceph_flush_cap_releases(struct ceph_mds_client *mdsc,
0536 struct ceph_mds_session *session);
0537 extern void ceph_queue_cap_reclaim_work(struct ceph_mds_client *mdsc);
0538 extern void ceph_reclaim_caps_nr(struct ceph_mds_client *mdsc, int nr);
0539 extern int ceph_iterate_session_caps(struct ceph_mds_session *session,
0540 int (*cb)(struct inode *,
0541 struct ceph_cap *, void *),
0542 void *arg);
0543 extern void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc);
0544
0545 static inline void ceph_mdsc_free_path(char *path, int len)
0546 {
0547 if (!IS_ERR_OR_NULL(path))
0548 __putname(path - (PATH_MAX - 1 - len));
0549 }
0550
0551 extern char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base,
0552 int stop_on_nosnap);
0553
0554 extern void __ceph_mdsc_drop_dentry_lease(struct dentry *dentry);
0555 extern void ceph_mdsc_lease_send_msg(struct ceph_mds_session *session,
0556 struct dentry *dentry, char action,
0557 u32 seq);
0558
0559 extern void ceph_mdsc_handle_mdsmap(struct ceph_mds_client *mdsc,
0560 struct ceph_msg *msg);
0561 extern void ceph_mdsc_handle_fsmap(struct ceph_mds_client *mdsc,
0562 struct ceph_msg *msg);
0563
0564 extern struct ceph_mds_session *
0565 ceph_mdsc_open_export_target_session(struct ceph_mds_client *mdsc, int target);
0566 extern void ceph_mdsc_open_export_target_sessions(struct ceph_mds_client *mdsc,
0567 struct ceph_mds_session *session);
0568
0569 extern int ceph_trim_caps(struct ceph_mds_client *mdsc,
0570 struct ceph_mds_session *session,
0571 int max_caps);
0572
0573 static inline int ceph_wait_on_async_create(struct inode *inode)
0574 {
0575 struct ceph_inode_info *ci = ceph_inode(inode);
0576
0577 return wait_on_bit(&ci->i_ceph_flags, CEPH_ASYNC_CREATE_BIT,
0578 TASK_KILLABLE);
0579 }
0580
0581 extern int ceph_wait_on_conflict_unlink(struct dentry *dentry);
0582 extern u64 ceph_get_deleg_ino(struct ceph_mds_session *session);
0583 extern int ceph_restore_deleg_ino(struct ceph_mds_session *session, u64 ino);
0584 #endif