]>
Commit | Line | Data |
---|---|---|
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 | #ifndef CEPH_MDS_SERVER_H | |
16 | #define CEPH_MDS_SERVER_H | |
17 | ||
11fdf7f2 | 18 | #include <string_view> |
94b18763 | 19 | |
a8e16298 TL |
20 | #include <common/DecayCounter.h> |
21 | ||
9f95a23c TL |
22 | #include "include/common_fwd.h" |
23 | ||
11fdf7f2 TL |
24 | #include "messages/MClientReconnect.h" |
25 | #include "messages/MClientReply.h" | |
26 | #include "messages/MClientRequest.h" | |
27 | #include "messages/MClientSession.h" | |
28 | #include "messages/MClientSnap.h" | |
29 | #include "messages/MClientReclaim.h" | |
30 | #include "messages/MClientReclaimReply.h" | |
31 | #include "messages/MLock.h" | |
32 | ||
f67539c2 | 33 | #include "CInode.h" |
7c673cae FG |
34 | #include "MDSRank.h" |
35 | #include "Mutation.h" | |
11fdf7f2 | 36 | #include "MDSContext.h" |
7c673cae FG |
37 | |
38 | class OSDMap; | |
7c673cae FG |
39 | class LogEvent; |
40 | class EMetaBlob; | |
41 | class EUpdate; | |
7c673cae | 42 | class MDLog; |
11fdf7f2 | 43 | struct SnapInfo; |
f67539c2 | 44 | class MetricsHandler; |
7c673cae FG |
45 | |
46 | enum { | |
47 | l_mdss_first = 1000, | |
d2e6a577 | 48 | l_mdss_dispatch_client_request, |
f67539c2 | 49 | l_mdss_dispatch_peer_request, |
7c673cae | 50 | l_mdss_handle_client_request, |
7c673cae | 51 | l_mdss_handle_client_session, |
f67539c2 | 52 | l_mdss_handle_peer_request, |
91327a77 AA |
53 | l_mdss_req_create_latency, |
54 | l_mdss_req_getattr_latency, | |
55 | l_mdss_req_getfilelock_latency, | |
56 | l_mdss_req_link_latency, | |
57 | l_mdss_req_lookup_latency, | |
58 | l_mdss_req_lookuphash_latency, | |
59 | l_mdss_req_lookupino_latency, | |
60 | l_mdss_req_lookupname_latency, | |
61 | l_mdss_req_lookupparent_latency, | |
62 | l_mdss_req_lookupsnap_latency, | |
63 | l_mdss_req_lssnap_latency, | |
64 | l_mdss_req_mkdir_latency, | |
65 | l_mdss_req_mknod_latency, | |
66 | l_mdss_req_mksnap_latency, | |
67 | l_mdss_req_open_latency, | |
68 | l_mdss_req_readdir_latency, | |
69 | l_mdss_req_rename_latency, | |
70 | l_mdss_req_renamesnap_latency, | |
71 | l_mdss_req_rmdir_latency, | |
72 | l_mdss_req_rmsnap_latency, | |
73 | l_mdss_req_rmxattr_latency, | |
74 | l_mdss_req_setattr_latency, | |
75 | l_mdss_req_setdirlayout_latency, | |
76 | l_mdss_req_setfilelock_latency, | |
77 | l_mdss_req_setlayout_latency, | |
78 | l_mdss_req_setxattr_latency, | |
79 | l_mdss_req_symlink_latency, | |
80 | l_mdss_req_unlink_latency, | |
81 | l_mdss_cap_revoke_eviction, | |
adb31ebb | 82 | l_mdss_cap_acquisition_throttle, |
1d09f67e | 83 | l_mdss_req_getvxattr_latency, |
7c673cae FG |
84 | l_mdss_last, |
85 | }; | |
86 | ||
87 | class Server { | |
91327a77 AA |
88 | public: |
89 | using clock = ceph::coarse_mono_clock; | |
90 | using time = ceph::coarse_mono_time; | |
91 | ||
9f95a23c TL |
92 | enum class RecallFlags : uint64_t { |
93 | NONE = 0, | |
94 | STEADY = (1<<0), | |
95 | ENFORCE_MAX = (1<<1), | |
96 | TRIM = (1<<2), | |
97 | ENFORCE_LIVENESS = (1<<3), | |
98 | }; | |
1d09f67e | 99 | |
f67539c2 | 100 | explicit Server(MDSRank *m, MetricsHandler *metrics_handler); |
7c673cae FG |
101 | ~Server() { |
102 | g_ceph_context->get_perfcounters_collection()->remove(logger); | |
103 | delete logger; | |
104 | delete reconnect_done; | |
105 | } | |
106 | ||
107 | void create_logger(); | |
108 | ||
109 | // message handler | |
9f95a23c | 110 | void dispatch(const cref_t<Message> &m); |
7c673cae FG |
111 | |
112 | void handle_osd_map(); | |
113 | ||
114 | // -- sessions and recovery -- | |
7c673cae FG |
115 | bool waiting_for_reconnect(client_t c) const; |
116 | void dump_reconnect_status(Formatter *f) const; | |
117 | ||
a8e16298 TL |
118 | time last_recalled() const { |
119 | return last_recall_state; | |
120 | } | |
11fdf7f2 | 121 | |
9f95a23c | 122 | void handle_client_session(const cref_t<MClientSession> &m); |
f67539c2 TL |
123 | void _session_logged(Session *session, uint64_t state_seq, bool open, version_t pv, |
124 | const interval_set<inodeno_t>& inos_to_free, version_t piv, | |
125 | const interval_set<inodeno_t>& inos_to_purge, LogSegment *ls); | |
20effc67 TL |
126 | version_t prepare_force_open_sessions(std::map<client_t,entity_inst_t> &cm, |
127 | std::map<client_t,client_metadata_t>& cmm, | |
128 | std::map<client_t,std::pair<Session*,uint64_t> >& smap); | |
129 | void finish_force_open_sessions(const std::map<client_t,std::pair<Session*,uint64_t> >& smap, | |
7c673cae | 130 | bool dec_import=true); |
20effc67 | 131 | void flush_client_sessions(std::set<client_t>& client_set, MDSGatherBuilder& gather); |
7c673cae FG |
132 | void finish_flush_session(Session *session, version_t seq); |
133 | void terminate_sessions(); | |
134 | void find_idle_sessions(); | |
f67539c2 TL |
135 | |
136 | void kill_session(Session *session, Context *on_safe); | |
137 | size_t apply_blocklist(const std::set<entity_addr_t> &blocklist); | |
138 | void journal_close_session(Session *session, int state, Context *on_safe); | |
11fdf7f2 | 139 | |
11fdf7f2 TL |
140 | size_t get_num_pending_reclaim() const { return client_reclaim_gather.size(); } |
141 | Session *find_session_by_uuid(std::string_view uuid); | |
9f95a23c TL |
142 | void reclaim_session(Session *session, const cref_t<MClientReclaim> &m); |
143 | void finish_reclaim_session(Session *session, const ref_t<MClientReclaimReply> &reply=nullptr); | |
144 | void handle_client_reclaim(const cref_t<MClientReclaim> &m); | |
11fdf7f2 TL |
145 | |
146 | void reconnect_clients(MDSContext *reconnect_done_); | |
9f95a23c | 147 | void handle_client_reconnect(const cref_t<MClientReconnect> &m); |
11fdf7f2 TL |
148 | void infer_supported_features(Session *session, client_metadata_t& client_metadata); |
149 | void update_required_client_features(); | |
150 | ||
7c673cae FG |
151 | //void process_reconnect_cap(CInode *in, int from, ceph_mds_cap_reconnect& capinfo); |
152 | void reconnect_gather_finish(); | |
153 | void reconnect_tick(); | |
154 | void recover_filelocks(CInode *in, bufferlist locks, int64_t client); | |
155 | ||
92f5a8d4 | 156 | std::pair<bool, uint64_t> recall_client_state(MDSGatherBuilder* gather, RecallFlags=RecallFlags::NONE); |
7c673cae FG |
157 | void force_clients_readonly(); |
158 | ||
159 | // -- requests -- | |
9f95a23c | 160 | void handle_client_request(const cref_t<MClientRequest> &m); |
7c673cae FG |
161 | |
162 | void journal_and_reply(MDRequestRef& mdr, CInode *tracei, CDentry *tracedn, | |
163 | LogEvent *le, MDSLogContextBase *fin); | |
164 | void submit_mdlog_entry(LogEvent *le, MDSLogContextBase *fin, | |
11fdf7f2 | 165 | MDRequestRef& mdr, std::string_view event); |
7c673cae | 166 | void dispatch_client_request(MDRequestRef& mdr); |
9f95a23c | 167 | void perf_gather_op_latency(const cref_t<MClientRequest> &req, utime_t lat); |
7c673cae FG |
168 | void early_reply(MDRequestRef& mdr, CInode *tracei, CDentry *tracedn); |
169 | void respond_to_request(MDRequestRef& mdr, int r = 0); | |
9f95a23c | 170 | void set_trace_dist(const ref_t<MClientReply> &reply, CInode *in, CDentry *dn, |
7c673cae FG |
171 | MDRequestRef& mdr); |
172 | ||
f67539c2 TL |
173 | void handle_peer_request(const cref_t<MMDSPeerRequest> &m); |
174 | void handle_peer_request_reply(const cref_t<MMDSPeerRequest> &m); | |
175 | void dispatch_peer_request(MDRequestRef& mdr); | |
176 | void handle_peer_auth_pin(MDRequestRef& mdr); | |
177 | void handle_peer_auth_pin_ack(MDRequestRef& mdr, const cref_t<MMDSPeerRequest> &ack); | |
7c673cae FG |
178 | |
179 | // some helpers | |
180 | bool check_fragment_space(MDRequestRef& mdr, CDir *in); | |
20effc67 | 181 | bool check_dir_max_entries(MDRequestRef& mdr, CDir *in); |
7c673cae FG |
182 | bool check_access(MDRequestRef& mdr, CInode *in, unsigned mask); |
183 | bool _check_access(Session *session, CInode *in, unsigned mask, int caller_uid, int caller_gid, int setattr_uid, int setattr_gid); | |
7c673cae FG |
184 | CDentry *prepare_stray_dentry(MDRequestRef& mdr, CInode *in); |
185 | CInode* prepare_new_inode(MDRequestRef& mdr, CDir *dir, inodeno_t useino, unsigned mode, | |
f67539c2 | 186 | const file_layout_t *layout=nullptr); |
7c673cae FG |
187 | void journal_allocated_inos(MDRequestRef& mdr, EMetaBlob *blob); |
188 | void apply_allocated_inos(MDRequestRef& mdr, Session *session); | |
189 | ||
9f95a23c TL |
190 | CInode* rdlock_path_pin_ref(MDRequestRef& mdr, bool want_auth, |
191 | bool no_want_auth=false); | |
192 | CDentry* rdlock_path_xlock_dentry(MDRequestRef& mdr, bool create, | |
193 | bool okexist=false, bool want_layout=false); | |
194 | std::pair<CDentry*, CDentry*> | |
195 | rdlock_two_paths_xlock_destdn(MDRequestRef& mdr, bool xlock_srcdn); | |
7c673cae FG |
196 | |
197 | CDir* try_open_auth_dirfrag(CInode *diri, frag_t fg, MDRequestRef& mdr); | |
198 | ||
7c673cae FG |
199 | // requests on existing inodes. |
200 | void handle_client_getattr(MDRequestRef& mdr, bool is_lookup); | |
201 | void handle_client_lookup_ino(MDRequestRef& mdr, | |
202 | bool want_parent, bool want_dentry); | |
11fdf7f2 | 203 | void _lookup_snap_ino(MDRequestRef& mdr); |
7c673cae FG |
204 | void _lookup_ino_2(MDRequestRef& mdr, int r); |
205 | void handle_client_readdir(MDRequestRef& mdr); | |
206 | void handle_client_file_setlock(MDRequestRef& mdr); | |
207 | void handle_client_file_readlock(MDRequestRef& mdr); | |
208 | ||
9f95a23c TL |
209 | bool xlock_policylock(MDRequestRef& mdr, CInode *in, |
210 | bool want_layout=false, bool xlock_snaplock=false); | |
211 | CInode* try_get_auth_inode(MDRequestRef& mdr, inodeno_t ino); | |
7c673cae FG |
212 | void handle_client_setattr(MDRequestRef& mdr); |
213 | void handle_client_setlayout(MDRequestRef& mdr); | |
214 | void handle_client_setdirlayout(MDRequestRef& mdr); | |
215 | ||
20effc67 | 216 | int parse_quota_vxattr(std::string name, std::string value, quota_info_t *quota); |
11fdf7f2 | 217 | void create_quota_realm(CInode *in); |
1d09f67e TL |
218 | int parse_layout_vxattr_json(std::string name, std::string value, |
219 | const OSDMap& osdmap, file_layout_t *layout); | |
220 | int parse_layout_vxattr_string(std::string name, std::string value, const OSDMap& osdmap, | |
221 | file_layout_t *layout); | |
20effc67 | 222 | int parse_layout_vxattr(std::string name, std::string value, const OSDMap& osdmap, |
7c673cae | 223 | file_layout_t *layout, bool validate=true); |
7c673cae | 224 | int check_layout_vxattr(MDRequestRef& mdr, |
20effc67 TL |
225 | std::string name, |
226 | std::string value, | |
7c673cae | 227 | file_layout_t *layout); |
9f95a23c TL |
228 | void handle_set_vxattr(MDRequestRef& mdr, CInode *cur); |
229 | void handle_remove_vxattr(MDRequestRef& mdr, CInode *cur); | |
1d09f67e | 230 | void handle_client_getvxattr(MDRequestRef& mdr); |
7c673cae FG |
231 | void handle_client_setxattr(MDRequestRef& mdr); |
232 | void handle_client_removexattr(MDRequestRef& mdr); | |
233 | ||
234 | void handle_client_fsync(MDRequestRef& mdr); | |
235 | ||
236 | // open | |
237 | void handle_client_open(MDRequestRef& mdr); | |
238 | void handle_client_openc(MDRequestRef& mdr); // O_CREAT variant. | |
239 | void do_open_truncate(MDRequestRef& mdr, int cmode); // O_TRUNC variant. | |
240 | ||
241 | // namespace changes | |
242 | void handle_client_mknod(MDRequestRef& mdr); | |
243 | void handle_client_mkdir(MDRequestRef& mdr); | |
244 | void handle_client_symlink(MDRequestRef& mdr); | |
245 | ||
246 | // link | |
247 | void handle_client_link(MDRequestRef& mdr); | |
adb31ebb | 248 | void _link_local(MDRequestRef& mdr, CDentry *dn, CInode *targeti, SnapRealm *target_realm); |
11fdf7f2 TL |
249 | void _link_local_finish(MDRequestRef& mdr, CDentry *dn, CInode *targeti, |
250 | version_t, version_t, bool); | |
7c673cae FG |
251 | |
252 | void _link_remote(MDRequestRef& mdr, bool inc, CDentry *dn, CInode *targeti); | |
253 | void _link_remote_finish(MDRequestRef& mdr, bool inc, CDentry *dn, CInode *targeti, | |
254 | version_t); | |
255 | ||
f67539c2 TL |
256 | void handle_peer_link_prep(MDRequestRef& mdr); |
257 | void _logged_peer_link(MDRequestRef& mdr, CInode *targeti, bool adjust_realm); | |
258 | void _commit_peer_link(MDRequestRef& mdr, int r, CInode *targeti); | |
259 | void _committed_peer(MDRequestRef& mdr); // use for rename, too | |
260 | void handle_peer_link_prep_ack(MDRequestRef& mdr, const cref_t<MMDSPeerRequest> &m); | |
261 | void do_link_rollback(bufferlist &rbl, mds_rank_t leader, MDRequestRef& mdr); | |
11fdf7f2 | 262 | void _link_rollback_finish(MutationRef& mut, MDRequestRef& mdr, |
20effc67 | 263 | std::map<client_t,ref_t<MClientSnap>>& split); |
7c673cae FG |
264 | |
265 | // unlink | |
266 | void handle_client_unlink(MDRequestRef& mdr); | |
267 | bool _dir_is_nonempty_unlocked(MDRequestRef& mdr, CInode *rmdiri); | |
268 | bool _dir_is_nonempty(MDRequestRef& mdr, CInode *rmdiri); | |
269 | void _unlink_local(MDRequestRef& mdr, CDentry *dn, CDentry *straydn); | |
270 | void _unlink_local_finish(MDRequestRef& mdr, | |
271 | CDentry *dn, CDentry *straydn, | |
272 | version_t); | |
20effc67 | 273 | bool _rmdir_prepare_witness(MDRequestRef& mdr, mds_rank_t who, std::vector<CDentry*>& trace, CDentry *straydn); |
f67539c2 TL |
274 | void handle_peer_rmdir_prep(MDRequestRef& mdr); |
275 | void _logged_peer_rmdir(MDRequestRef& mdr, CDentry *srcdn, CDentry *straydn); | |
276 | void _commit_peer_rmdir(MDRequestRef& mdr, int r, CDentry *straydn); | |
277 | void handle_peer_rmdir_prep_ack(MDRequestRef& mdr, const cref_t<MMDSPeerRequest> &ack); | |
278 | void do_rmdir_rollback(bufferlist &rbl, mds_rank_t leader, MDRequestRef& mdr); | |
7c673cae FG |
279 | void _rmdir_rollback_finish(MDRequestRef& mdr, metareqid_t reqid, CDentry *dn, CDentry *straydn); |
280 | ||
281 | // rename | |
282 | void handle_client_rename(MDRequestRef& mdr); | |
283 | void _rename_finish(MDRequestRef& mdr, | |
284 | CDentry *srcdn, CDentry *destdn, CDentry *straydn); | |
285 | ||
286 | void handle_client_lssnap(MDRequestRef& mdr); | |
287 | void handle_client_mksnap(MDRequestRef& mdr); | |
288 | void _mksnap_finish(MDRequestRef& mdr, CInode *diri, SnapInfo &info); | |
289 | void handle_client_rmsnap(MDRequestRef& mdr); | |
290 | void _rmsnap_finish(MDRequestRef& mdr, CInode *diri, snapid_t snapid); | |
291 | void handle_client_renamesnap(MDRequestRef& mdr); | |
292 | void _renamesnap_finish(MDRequestRef& mdr, CInode *diri, snapid_t snapid); | |
293 | ||
7c673cae | 294 | // helpers |
20effc67 TL |
295 | bool _rename_prepare_witness(MDRequestRef& mdr, mds_rank_t who, std::set<mds_rank_t> &witnesse, |
296 | std::vector<CDentry*>& srctrace, std::vector<CDentry*>& dsttrace, CDentry *straydn); | |
7c673cae FG |
297 | version_t _rename_prepare_import(MDRequestRef& mdr, CDentry *srcdn, bufferlist *client_map_bl); |
298 | bool _need_force_journal(CInode *diri, bool empty); | |
299 | void _rename_prepare(MDRequestRef& mdr, | |
300 | EMetaBlob *metablob, bufferlist *client_map_bl, | |
f67539c2 TL |
301 | CDentry *srcdn, CDentry *destdn, std::string_view alternate_name, |
302 | CDentry *straydn); | |
7c673cae FG |
303 | /* set not_journaling=true if you're going to discard the results -- |
304 | * this bypasses the asserts to make sure we're journaling the right | |
305 | * things on the right nodes */ | |
306 | void _rename_apply(MDRequestRef& mdr, CDentry *srcdn, CDentry *destdn, CDentry *straydn); | |
307 | ||
308 | // slaving | |
f67539c2 TL |
309 | void handle_peer_rename_prep(MDRequestRef& mdr); |
310 | void handle_peer_rename_prep_ack(MDRequestRef& mdr, const cref_t<MMDSPeerRequest> &m); | |
311 | void handle_peer_rename_notify_ack(MDRequestRef& mdr, const cref_t<MMDSPeerRequest> &m); | |
312 | void _peer_rename_sessions_flushed(MDRequestRef& mdr); | |
313 | void _logged_peer_rename(MDRequestRef& mdr, CDentry *srcdn, CDentry *destdn, CDentry *straydn); | |
314 | void _commit_peer_rename(MDRequestRef& mdr, int r, CDentry *srcdn, CDentry *destdn, CDentry *straydn); | |
315 | void do_rename_rollback(bufferlist &rbl, mds_rank_t leader, MDRequestRef& mdr, bool finish_mdr=false); | |
7c673cae | 316 | void _rename_rollback_finish(MutationRef& mut, MDRequestRef& mdr, CDentry *srcdn, version_t srcdnpv, |
20effc67 | 317 | CDentry *destdn, CDentry *staydn, std::map<client_t,ref_t<MClientSnap>> splits[2], |
11fdf7f2 | 318 | bool finish_mdr); |
7c673cae | 319 | |
91327a77 | 320 | void evict_cap_revoke_non_responders(); |
92f5a8d4 | 321 | void handle_conf_change(const std::set<std::string>& changed); |
91327a77 | 322 | |
9f95a23c TL |
323 | bool terminating_sessions = false; |
324 | ||
20effc67 | 325 | std::set<client_t> client_reclaim_gather; |
9f95a23c | 326 | |
7c673cae | 327 | private: |
9f95a23c TL |
328 | friend class MDSContinuation; |
329 | friend class ServerContext; | |
330 | friend class ServerLogContext; | |
331 | friend class Batch_Getattr_Lookup; | |
332 | ||
f67539c2 TL |
333 | // placeholder for validation handler to store xattr specific |
334 | // data | |
335 | struct XattrInfo { | |
336 | virtual ~XattrInfo() { | |
337 | } | |
338 | }; | |
339 | ||
340 | struct MirrorXattrInfo : XattrInfo { | |
341 | std::string cluster_id; | |
342 | std::string fs_id; | |
343 | ||
344 | static const std::string MIRROR_INFO_REGEX; | |
345 | static const std::string CLUSTER_ID; | |
346 | static const std::string FS_ID; | |
347 | ||
348 | MirrorXattrInfo(std::string_view cluster_id, | |
349 | std::string_view fs_id) | |
350 | : cluster_id(cluster_id), | |
351 | fs_id(fs_id) { | |
352 | } | |
353 | }; | |
354 | ||
355 | struct XattrOp { | |
356 | int op; | |
357 | std::string xattr_name; | |
358 | const bufferlist &xattr_value; | |
359 | int flags = 0; | |
360 | ||
361 | std::unique_ptr<XattrInfo> xinfo; | |
362 | ||
363 | XattrOp(int op, std::string_view xattr_name, const bufferlist &xattr_value, int flags) | |
364 | : op(op), | |
365 | xattr_name(xattr_name), | |
366 | xattr_value(xattr_value), | |
367 | flags (flags) { | |
368 | } | |
369 | }; | |
370 | ||
371 | struct XattrHandler { | |
372 | const std::string xattr_name; | |
373 | const std::string description; | |
374 | ||
375 | // basic checks are to be done in this handler. return -errno to | |
376 | // reject xattr request (set or remove), zero to proceed. handlers | |
377 | // may parse xattr value for verification if needed and have an | |
378 | // option to store custom data in XattrOp::xinfo. | |
379 | int (Server::*validate)(CInode *cur, const InodeStoreBase::xattr_map_const_ptr xattrs, | |
380 | XattrOp *xattr_op); | |
381 | ||
382 | // set xattr for an inode in xattr_map | |
383 | void (Server::*setxattr)(CInode *cur, InodeStoreBase::xattr_map_ptr xattrs, | |
384 | const XattrOp &xattr_op); | |
385 | ||
386 | // remove xattr for an inode from xattr_map | |
387 | void (Server::*removexattr)(CInode *cur, InodeStoreBase::xattr_map_ptr xattrs, | |
388 | const XattrOp &xattr_op); | |
389 | }; | |
390 | ||
391 | inline static const std::string DEFAULT_HANDLER = "<default>"; | |
392 | static const XattrHandler xattr_handlers[]; | |
393 | ||
394 | const XattrHandler* get_xattr_or_default_handler(std::string_view xattr_name); | |
395 | ||
396 | // generic variant to set/remove xattr in/from xattr_map | |
397 | int xattr_validate(CInode *cur, const InodeStoreBase::xattr_map_const_ptr xattrs, | |
398 | const std::string &xattr_name, int op, int flags); | |
399 | void xattr_set(InodeStoreBase::xattr_map_ptr xattrs, const std::string &xattr_name, | |
400 | const bufferlist &xattr_value); | |
401 | void xattr_rm(InodeStoreBase::xattr_map_ptr xattrs, const std::string &xattr_name); | |
402 | ||
403 | // default xattr handlers | |
404 | int default_xattr_validate(CInode *cur, const InodeStoreBase::xattr_map_const_ptr xattrs, | |
405 | XattrOp *xattr_op); | |
406 | void default_setxattr_handler(CInode *cur, InodeStoreBase::xattr_map_ptr xattrs, | |
407 | const XattrOp &xattr_op); | |
408 | void default_removexattr_handler(CInode *cur, InodeStoreBase::xattr_map_ptr xattrs, | |
409 | const XattrOp &xattr_op); | |
410 | ||
411 | // mirror info xattr handler | |
412 | int parse_mirror_info_xattr(const std::string &name, const std::string &value, | |
413 | std::string &cluster_id, std::string &fs_id); | |
414 | int mirror_info_xattr_validate(CInode *cur, const InodeStoreBase::xattr_map_const_ptr xattrs, | |
415 | XattrOp *xattr_op); | |
416 | void mirror_info_setxattr_handler(CInode *cur, InodeStoreBase::xattr_map_ptr xattrs, | |
417 | const XattrOp &xattr_op); | |
418 | void mirror_info_removexattr_handler(CInode *cur, InodeStoreBase::xattr_map_ptr xattrs, | |
419 | const XattrOp &xattr_op); | |
420 | ||
421 | static bool is_ceph_vxattr(std::string_view xattr_name) { | |
422 | return xattr_name.rfind("ceph.dir.layout", 0) == 0 || | |
423 | xattr_name.rfind("ceph.file.layout", 0) == 0 || | |
424 | xattr_name.rfind("ceph.quota", 0) == 0 || | |
20effc67 TL |
425 | xattr_name == "ceph.dir.subvolume" || |
426 | xattr_name == "ceph.dir.pin" || | |
427 | xattr_name == "ceph.dir.pin.random" || | |
428 | xattr_name == "ceph.dir.pin.distributed"; | |
f67539c2 TL |
429 | } |
430 | ||
1d09f67e TL |
431 | static bool is_ceph_dir_vxattr(std::string_view xattr_name) { |
432 | return (xattr_name == "ceph.dir.layout" || | |
433 | xattr_name == "ceph.dir.layout.json" || | |
434 | xattr_name == "ceph.dir.layout.object_size" || | |
435 | xattr_name == "ceph.dir.layout.stripe_unit" || | |
436 | xattr_name == "ceph.dir.layout.stripe_count" || | |
437 | xattr_name == "ceph.dir.layout.pool" || | |
438 | xattr_name == "ceph.dir.layout.pool_name" || | |
439 | xattr_name == "ceph.dir.layout.pool_id" || | |
440 | xattr_name == "ceph.dir.layout.pool_namespace" || | |
441 | xattr_name == "ceph.dir.pin" || | |
442 | xattr_name == "ceph.dir.pin.random" || | |
443 | xattr_name == "ceph.dir.pin.distributed"); | |
444 | } | |
445 | ||
446 | static bool is_ceph_file_vxattr(std::string_view xattr_name) { | |
447 | return (xattr_name == "ceph.file.layout" || | |
448 | xattr_name == "ceph.file.layout.json" || | |
449 | xattr_name == "ceph.file.layout.object_size" || | |
450 | xattr_name == "ceph.file.layout.stripe_unit" || | |
451 | xattr_name == "ceph.file.layout.stripe_count" || | |
452 | xattr_name == "ceph.file.layout.pool" || | |
453 | xattr_name == "ceph.file.layout.pool_name" || | |
454 | xattr_name == "ceph.file.layout.pool_id" || | |
455 | xattr_name == "ceph.file.layout.pool_namespace"); | |
456 | } | |
457 | ||
f67539c2 TL |
458 | static bool is_allowed_ceph_xattr(std::string_view xattr_name) { |
459 | // not a ceph xattr -- allow! | |
460 | if (xattr_name.rfind("ceph.", 0) != 0) { | |
461 | return true; | |
462 | } | |
463 | ||
b3b6e05e TL |
464 | return xattr_name == "ceph.mirror.info" || |
465 | xattr_name == "ceph.mirror.dirty_snap_id"; | |
f67539c2 TL |
466 | } |
467 | ||
9f95a23c | 468 | void reply_client_request(MDRequestRef& mdr, const ref_t<MClientReply> &reply); |
f91f0fd5 | 469 | void flush_session(Session *session, MDSGatherBuilder& gather); |
9f95a23c TL |
470 | |
471 | MDSRank *mds; | |
472 | MDCache *mdcache; | |
473 | MDLog *mdlog; | |
474 | PerfCounters *logger = nullptr; | |
475 | ||
f67539c2 | 476 | // OSDMap full status, used to generate CEPHFS_ENOSPC on some operations |
9f95a23c TL |
477 | bool is_full = false; |
478 | ||
479 | // State for while in reconnect | |
480 | MDSContext *reconnect_done = nullptr; | |
481 | int failed_reconnects = 0; | |
482 | bool reconnect_evicting = false; // true if I am waiting for evictions to complete | |
483 | // before proceeding to reconnect_gather_finish | |
484 | time reconnect_start = clock::zero(); | |
485 | time reconnect_last_seen = clock::zero(); | |
20effc67 TL |
486 | std::set<client_t> client_reconnect_gather; // clients i need a reconnect msg from. |
487 | std::set<client_t> client_reconnect_denied; // clients whose reconnect msg have been denied . | |
9f95a23c TL |
488 | |
489 | feature_bitset_t supported_features; | |
490 | feature_bitset_t required_client_features; | |
491 | ||
f91f0fd5 | 492 | bool forward_all_requests_to_auth = false; |
9f95a23c TL |
493 | bool replay_unsafe_with_closed_session = false; |
494 | double cap_revoke_eviction_timeout = 0; | |
495 | uint64_t max_snaps_per_dir = 100; | |
496 | unsigned delegate_inos_pct = 0; | |
20effc67 TL |
497 | uint64_t dir_max_entries = 0; |
498 | int64_t bal_fragment_size_max = 0; | |
a8e16298 TL |
499 | |
500 | DecayCounter recall_throttle; | |
501 | time last_recall_state; | |
adb31ebb | 502 | |
f67539c2 TL |
503 | MetricsHandler *metrics_handler; |
504 | ||
adb31ebb TL |
505 | // Cache cap acquisition throttle configs |
506 | uint64_t max_caps_per_client; | |
507 | uint64_t cap_acquisition_throttle; | |
508 | double max_caps_throttle_ratio; | |
509 | double caps_throttle_retry_request_timeout; | |
f67539c2 TL |
510 | |
511 | size_t alternate_name_max = g_conf().get_val<Option::size_t>("mds_alternate_name_max"); | |
7c673cae FG |
512 | }; |
513 | ||
92f5a8d4 TL |
514 | static inline constexpr auto operator|(Server::RecallFlags a, Server::RecallFlags b) { |
515 | using T = std::underlying_type<Server::RecallFlags>::type; | |
516 | return static_cast<Server::RecallFlags>(static_cast<T>(a) | static_cast<T>(b)); | |
517 | } | |
518 | static inline constexpr auto operator&(Server::RecallFlags a, Server::RecallFlags b) { | |
519 | using T = std::underlying_type<Server::RecallFlags>::type; | |
520 | return static_cast<Server::RecallFlags>(static_cast<T>(a) & static_cast<T>(b)); | |
521 | } | |
522 | static inline std::ostream& operator<<(std::ostream& os, const Server::RecallFlags& f) { | |
523 | using T = std::underlying_type<Server::RecallFlags>::type; | |
524 | return os << "0x" << std::hex << static_cast<T>(f) << std::dec; | |
525 | } | |
526 | static inline constexpr bool operator!(const Server::RecallFlags& f) { | |
527 | using T = std::underlying_type<Server::RecallFlags>::type; | |
528 | return static_cast<T>(f) == static_cast<T>(0); | |
529 | } | |
7c673cae | 530 | #endif |