1#ifndef _FS_CEPH_MDS_CLIENT_H
2#define _FS_CEPH_MDS_CLIENT_H
3
4#include <linux/completion.h>
5#include <linux/kref.h>
6#include <linux/list.h>
7#include <linux/mutex.h>
8#include <linux/rbtree.h>
9#include <linux/spinlock.h>
10
11#include <linux/ceph/types.h>
12#include <linux/ceph/messenger.h>
13#include <linux/ceph/mdsmap.h>
14#include <linux/ceph/auth.h>
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30struct ceph_fs_client;
31struct ceph_cap;
32
33
34
35
36
37struct ceph_mds_reply_info_in {
38 struct ceph_mds_reply_inode *in;
39 struct ceph_dir_layout dir_layout;
40 u32 symlink_len;
41 char *symlink;
42 u32 xattr_len;
43 char *xattr_data;
44};
45
46
47
48
49
50
51
52struct ceph_mds_reply_info_parsed {
53 struct ceph_mds_reply_head *head;
54
55
56 struct ceph_mds_reply_info_in diri, targeti;
57 struct ceph_mds_reply_dirfrag *dirfrag;
58 char *dname;
59 u32 dname_len;
60 struct ceph_mds_reply_lease *dlease;
61
62
63 union {
64
65 struct ceph_filelock *filelock_reply;
66
67
68 struct {
69 struct ceph_mds_reply_dirfrag *dir_dir;
70 int dir_nr;
71 char **dir_dname;
72 u32 *dir_dname_len;
73 struct ceph_mds_reply_lease **dir_dlease;
74 struct ceph_mds_reply_info_in *dir_in;
75 u8 dir_complete, dir_end;
76 };
77 };
78
79
80
81 void *snapblob;
82 int snapblob_len;
83};
84
85
86
87
88
89#define CEPH_CAPS_PER_RELEASE ((PAGE_CACHE_SIZE - \
90 sizeof(struct ceph_mds_cap_release)) / \
91 sizeof(struct ceph_mds_cap_item))
92
93
94
95
96
97enum {
98 CEPH_MDS_SESSION_NEW = 1,
99 CEPH_MDS_SESSION_OPENING = 2,
100 CEPH_MDS_SESSION_OPEN = 3,
101 CEPH_MDS_SESSION_HUNG = 4,
102 CEPH_MDS_SESSION_CLOSING = 5,
103 CEPH_MDS_SESSION_RESTARTING = 6,
104 CEPH_MDS_SESSION_RECONNECTING = 7,
105};
106
107struct ceph_mds_session {
108 struct ceph_mds_client *s_mdsc;
109 int s_mds;
110 int s_state;
111 unsigned long s_ttl;
112 u64 s_seq;
113 struct mutex s_mutex;
114
115 struct ceph_connection s_con;
116
117 struct ceph_auth_handshake s_auth;
118
119
120 spinlock_t s_gen_ttl_lock;
121 u32 s_cap_gen;
122 unsigned long s_cap_ttl;
123
124
125 spinlock_t s_cap_lock;
126 struct list_head s_caps;
127 int s_nr_caps, s_trim_caps;
128 int s_num_cap_releases;
129 struct list_head s_cap_releases;
130 struct list_head s_cap_releases_done;
131 struct ceph_cap *s_cap_iterator;
132
133
134 struct list_head s_cap_flushing;
135 struct list_head s_cap_snaps_flushing;
136 unsigned long s_renew_requested;
137 u64 s_renew_seq;
138
139 atomic_t s_ref;
140 struct list_head s_waiting;
141 struct list_head s_unsafe;
142};
143
144
145
146
147enum {
148 USE_ANY_MDS,
149 USE_RANDOM_MDS,
150 USE_AUTH_MDS,
151};
152
153struct ceph_mds_request;
154struct ceph_mds_client;
155
156
157
158
159typedef void (*ceph_mds_request_callback_t) (struct ceph_mds_client *mdsc,
160 struct ceph_mds_request *req);
161
162
163
164
165struct ceph_mds_request {
166 u64 r_tid;
167 struct rb_node r_node;
168 struct ceph_mds_client *r_mdsc;
169
170 int r_op;
171
172
173 struct inode *r_inode;
174 struct dentry *r_dentry;
175 struct dentry *r_old_dentry;
176 struct inode *r_old_dentry_dir;
177 char *r_path1, *r_path2;
178 struct ceph_vino r_ino1, r_ino2;
179
180 struct inode *r_locked_dir;
181 struct inode *r_target_inode;
182
183 struct mutex r_fill_mutex;
184
185 union ceph_mds_request_args r_args;
186 int r_fmode;
187 uid_t r_uid;
188 gid_t r_gid;
189
190
191 int r_direct_mode;
192 u32 r_direct_hash;
193 bool r_direct_is_hash;
194
195
196 struct page **r_pages;
197 int r_num_pages;
198 int r_data_len;
199
200
201 int r_inode_drop, r_inode_unless;
202 int r_dentry_drop, r_dentry_unless;
203 int r_old_dentry_drop, r_old_dentry_unless;
204 struct inode *r_old_inode;
205 int r_old_inode_drop, r_old_inode_unless;
206
207 struct ceph_msg *r_request;
208 int r_request_release_offset;
209 struct ceph_msg *r_reply;
210 struct ceph_mds_reply_info_parsed r_reply_info;
211 int r_err;
212 bool r_aborted;
213
214 unsigned long r_timeout;
215 unsigned long r_started;
216 unsigned long r_request_started;
217
218
219
220 struct inode *r_unsafe_dir;
221 struct list_head r_unsafe_dir_item;
222
223 struct ceph_mds_session *r_session;
224
225 int r_attempts;
226 int r_num_fwd;
227 int r_resend_mds;
228 u32 r_sent_on_mseq;
229
230 struct kref r_kref;
231 struct list_head r_wait;
232 struct completion r_completion;
233 struct completion r_safe_completion;
234 ceph_mds_request_callback_t r_callback;
235 struct list_head r_unsafe_item;
236 bool r_got_unsafe, r_got_safe, r_got_result;
237
238 bool r_did_prepopulate;
239 u32 r_readdir_offset;
240
241 struct ceph_cap_reservation r_caps_reservation;
242 int r_num_caps;
243};
244
245
246
247
248struct ceph_mds_client {
249 struct ceph_fs_client *fsc;
250 struct mutex mutex;
251
252 struct ceph_mdsmap *mdsmap;
253 struct completion safe_umount_waiters;
254 wait_queue_head_t session_close_wq;
255 struct list_head waiting_for_map;
256
257 struct ceph_mds_session **sessions;
258 int max_sessions;
259 int stopping;
260
261
262
263
264
265
266
267
268 struct rw_semaphore snap_rwsem;
269 struct rb_root snap_realms;
270 struct list_head snap_empty;
271 spinlock_t snap_empty_lock;
272
273 u64 last_tid;
274 struct rb_root request_tree;
275 struct delayed_work delayed_work;
276 unsigned long last_renew_caps;
277 struct list_head cap_delay_list;
278 spinlock_t cap_delay_lock;
279 struct list_head snap_flush_list;
280 spinlock_t snap_flush_lock;
281
282 u64 cap_flush_seq;
283 struct list_head cap_dirty;
284 struct list_head cap_dirty_migrating;
285 int num_cap_flushing;
286 spinlock_t cap_dirty_lock;
287 wait_queue_head_t cap_flushing_wq;
288
289
290
291
292
293
294
295
296
297
298
299
300 spinlock_t caps_list_lock;
301 struct list_head caps_list;
302
303 int caps_total_count;
304 int caps_use_count;
305 int caps_reserve_count;
306 int caps_avail_count;
307 int caps_min_count;
308
309 spinlock_t dentry_lru_lock;
310 struct list_head dentry_lru;
311 int num_dentry;
312};
313
314extern const char *ceph_mds_op_name(int op);
315
316extern struct ceph_mds_session *
317__ceph_lookup_mds_session(struct ceph_mds_client *, int mds);
318
319static inline struct ceph_mds_session *
320ceph_get_mds_session(struct ceph_mds_session *s)
321{
322 atomic_inc(&s->s_ref);
323 return s;
324}
325
326extern void ceph_put_mds_session(struct ceph_mds_session *s);
327
328extern int ceph_send_msg_mds(struct ceph_mds_client *mdsc,
329 struct ceph_msg *msg, int mds);
330
331extern int ceph_mdsc_init(struct ceph_fs_client *fsc);
332extern void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc);
333extern void ceph_mdsc_destroy(struct ceph_fs_client *fsc);
334
335extern void ceph_mdsc_sync(struct ceph_mds_client *mdsc);
336
337extern void ceph_mdsc_lease_release(struct ceph_mds_client *mdsc,
338 struct inode *inode,
339 struct dentry *dn);
340
341extern void ceph_invalidate_dir_request(struct ceph_mds_request *req);
342
343extern struct ceph_mds_request *
344ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode);
345extern void ceph_mdsc_submit_request(struct ceph_mds_client *mdsc,
346 struct ceph_mds_request *req);
347extern int ceph_mdsc_do_request(struct ceph_mds_client *mdsc,
348 struct inode *dir,
349 struct ceph_mds_request *req);
350static inline void ceph_mdsc_get_request(struct ceph_mds_request *req)
351{
352 kref_get(&req->r_kref);
353}
354extern void ceph_mdsc_release_request(struct kref *kref);
355static inline void ceph_mdsc_put_request(struct ceph_mds_request *req)
356{
357 kref_put(&req->r_kref, ceph_mdsc_release_request);
358}
359
360extern int ceph_add_cap_releases(struct ceph_mds_client *mdsc,
361 struct ceph_mds_session *session);
362extern void ceph_send_cap_releases(struct ceph_mds_client *mdsc,
363 struct ceph_mds_session *session);
364
365extern void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc);
366
367extern char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base,
368 int stop_on_nosnap);
369
370extern void __ceph_mdsc_drop_dentry_lease(struct dentry *dentry);
371extern void ceph_mdsc_lease_send_msg(struct ceph_mds_session *session,
372 struct inode *inode,
373 struct dentry *dentry, char action,
374 u32 seq);
375
376extern void ceph_mdsc_handle_map(struct ceph_mds_client *mdsc,
377 struct ceph_msg *msg);
378
379extern void ceph_mdsc_open_export_target_sessions(struct ceph_mds_client *mdsc,
380 struct ceph_mds_session *session);
381
382#endif
383