Blame view

net/ceph/ceph_common.c 21.8 KB
09c434b8a   Thomas Gleixner   treewide: Add SPD...
1
  // SPDX-License-Identifier: GPL-2.0-only
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
2
3
4
5
6
7
8
  
  #include <linux/ceph/ceph_debug.h>
  #include <linux/backing-dev.h>
  #include <linux/ctype.h>
  #include <linux/fs.h>
  #include <linux/inet.h>
  #include <linux/in6.h>
e2c3d29b4   Tommi Virtanen   libceph: Get secr...
9
  #include <linux/key.h>
4b2a58abd   Tommi Virtanen   libceph: Create a...
10
  #include <keys/ceph-type.h>
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
11
12
  #include <linux/module.h>
  #include <linux/mount.h>
757856d2b   Ilya Dryomov   libceph: enable c...
13
  #include <linux/nsproxy.h>
82995cc6c   David Howells   libceph, rbd, cep...
14
  #include <linux/fs_parser.h>
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
15
  #include <linux/sched.h>
10c12851a   Ilya Dryomov   libceph: avoid a ...
16
  #include <linux/sched/mm.h>
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
17
18
19
20
  #include <linux/seq_file.h>
  #include <linux/slab.h>
  #include <linux/statfs.h>
  #include <linux/string.h>
eeb0bed55   Ilya Dryomov   libceph: add ceph...
21
  #include <linux/vmalloc.h>
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
22

1fe60e51a   Sage Weil   libceph: move fea...
23
  #include <linux/ceph/ceph_features.h>
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
24
25
26
27
28
  #include <linux/ceph/libceph.h>
  #include <linux/ceph/debugfs.h>
  #include <linux/ceph/decode.h>
  #include <linux/ceph/mon_client.h>
  #include <linux/ceph/auth.h>
8323c3aa7   Tommi Virtanen   ceph: Move secret...
29
  #include "crypto.h"
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
30

72fe25e34   Alex Elder   libceph: add a co...
31
32
33
34
35
36
37
38
39
40
41
42
43
  /*
   * Module compatibility interface.  For now it doesn't do anything,
   * but its existence signals a certain level of functionality.
   *
   * The data buffer is used to pass information both to and from
   * libceph.  The return value indicates whether libceph determines
   * it is compatible with the caller (from another kernel module),
   * given the provided data.
   *
   * The data pointer can be null.
   */
  bool libceph_compatible(void *data)
  {
1e32d34cf   Alex Elder   rbd: don't take e...
44
  	return true;
72fe25e34   Alex Elder   libceph: add a co...
45
46
  }
  EXPORT_SYMBOL(libceph_compatible);
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
47

d6a3408a7   Ilya Dryomov   libceph: supporte...
48
49
50
51
52
53
54
55
56
  static int param_get_supported_features(char *buffer,
  					const struct kernel_param *kp)
  {
  	return sprintf(buffer, "0x%llx", CEPH_FEATURES_SUPPORTED_DEFAULT);
  }
  static const struct kernel_param_ops param_ops_supported_features = {
  	.get = param_get_supported_features,
  };
  module_param_cb(supported_features, &param_ops_supported_features, NULL,
d6444062f   Joe Perches   net: Use octal no...
57
  		0444);
d6a3408a7   Ilya Dryomov   libceph: supporte...
58

3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
59
60
61
62
63
64
65
66
67
68
69
70
71
  const char *ceph_msg_type_name(int type)
  {
  	switch (type) {
  	case CEPH_MSG_SHUTDOWN: return "shutdown";
  	case CEPH_MSG_PING: return "ping";
  	case CEPH_MSG_AUTH: return "auth";
  	case CEPH_MSG_AUTH_REPLY: return "auth_reply";
  	case CEPH_MSG_MON_MAP: return "mon_map";
  	case CEPH_MSG_MON_GET_MAP: return "mon_get_map";
  	case CEPH_MSG_MON_SUBSCRIBE: return "mon_subscribe";
  	case CEPH_MSG_MON_SUBSCRIBE_ACK: return "mon_subscribe_ack";
  	case CEPH_MSG_STATFS: return "statfs";
  	case CEPH_MSG_STATFS_REPLY: return "statfs_reply";
513a8243d   Ilya Dryomov   libceph: mon_get_...
72
73
  	case CEPH_MSG_MON_GET_VERSION: return "mon_get_version";
  	case CEPH_MSG_MON_GET_VERSION_REPLY: return "mon_get_version_reply";
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
74
  	case CEPH_MSG_MDS_MAP: return "mds_map";
f2f87877b   Chengguang Xu   libceph: adding m...
75
  	case CEPH_MSG_FS_MAP_USER: return "fs_map_user";
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
76
77
78
79
80
81
82
  	case CEPH_MSG_CLIENT_SESSION: return "client_session";
  	case CEPH_MSG_CLIENT_RECONNECT: return "client_reconnect";
  	case CEPH_MSG_CLIENT_REQUEST: return "client_request";
  	case CEPH_MSG_CLIENT_REQUEST_FORWARD: return "client_request_forward";
  	case CEPH_MSG_CLIENT_REPLY: return "client_reply";
  	case CEPH_MSG_CLIENT_CAPS: return "client_caps";
  	case CEPH_MSG_CLIENT_CAPRELEASE: return "client_cap_release";
fb18a5756   Luis Henriques   ceph: quota: add ...
83
  	case CEPH_MSG_CLIENT_QUOTA: return "client_quota";
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
84
85
  	case CEPH_MSG_CLIENT_SNAP: return "client_snap";
  	case CEPH_MSG_CLIENT_LEASE: return "client_lease";
f2f87877b   Chengguang Xu   libceph: adding m...
86
87
88
89
  	case CEPH_MSG_POOLOP_REPLY: return "poolop_reply";
  	case CEPH_MSG_POOLOP: return "poolop";
  	case CEPH_MSG_MON_COMMAND: return "mon_command";
  	case CEPH_MSG_MON_COMMAND_ACK: return "mon_command_ack";
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
90
91
92
  	case CEPH_MSG_OSD_MAP: return "osd_map";
  	case CEPH_MSG_OSD_OP: return "osd_op";
  	case CEPH_MSG_OSD_OPREPLY: return "osd_opreply";
a40c4f10e   Yehuda Sadeh   libceph: add ling...
93
  	case CEPH_MSG_WATCH_NOTIFY: return "watch_notify";
a02a946df   Ilya Dryomov   libceph: respect ...
94
  	case CEPH_MSG_OSD_BACKOFF: return "osd_backoff";
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
  	default: return "unknown";
  	}
  }
  EXPORT_SYMBOL(ceph_msg_type_name);
  
  /*
   * Initially learn our fsid, or verify an fsid matches.
   */
  int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid)
  {
  	if (client->have_fsid) {
  		if (ceph_fsid_compare(&client->fsid, fsid)) {
  			pr_err("bad fsid, had %pU got %pU",
  			       &client->fsid, fsid);
  			return -1;
  		}
  	} else {
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
112
  		memcpy(&client->fsid, fsid, sizeof(*fsid));
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
  	}
  	return 0;
  }
  EXPORT_SYMBOL(ceph_check_fsid);
  
  static int strcmp_null(const char *s1, const char *s2)
  {
  	if (!s1 && !s2)
  		return 0;
  	if (s1 && !s2)
  		return -1;
  	if (!s1 && s2)
  		return 1;
  	return strcmp(s1, s2);
  }
  
  int ceph_compare_options(struct ceph_options *new_opt,
  			 struct ceph_client *client)
  {
  	struct ceph_options *opt1 = new_opt;
  	struct ceph_options *opt2 = client->options;
  	int ofs = offsetof(struct ceph_options, mon_addr);
  	int i;
  	int ret;
757856d2b   Ilya Dryomov   libceph: enable c...
137
138
139
140
141
142
  	/*
  	 * Don't bother comparing options if network namespaces don't
  	 * match.
  	 */
  	if (!net_eq(current->nsproxy->net_ns, read_pnet(&client->msgr.net)))
  		return -1;
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
143
144
145
146
147
148
149
  	ret = memcmp(opt1, opt2, ofs);
  	if (ret)
  		return ret;
  
  	ret = strcmp_null(opt1->name, opt2->name);
  	if (ret)
  		return ret;
8323c3aa7   Tommi Virtanen   ceph: Move secret...
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
  	if (opt1->key && !opt2->key)
  		return -1;
  	if (!opt1->key && opt2->key)
  		return 1;
  	if (opt1->key && opt2->key) {
  		if (opt1->key->type != opt2->key->type)
  			return -1;
  		if (opt1->key->created.tv_sec != opt2->key->created.tv_sec)
  			return -1;
  		if (opt1->key->created.tv_nsec != opt2->key->created.tv_nsec)
  			return -1;
  		if (opt1->key->len != opt2->key->len)
  			return -1;
  		if (opt1->key->key && !opt2->key->key)
  			return -1;
  		if (!opt1->key->key && opt2->key->key)
  			return 1;
  		if (opt1->key->key && opt2->key->key) {
  			ret = memcmp(opt1->key->key, opt2->key->key, opt1->key->len);
  			if (ret)
  				return ret;
  		}
  	}
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
173

45e6aa9f5   Ilya Dryomov   libceph: crush_lo...
174
175
176
  	ret = ceph_compare_crush_locs(&opt1->crush_locs, &opt2->crush_locs);
  	if (ret)
  		return ret;
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
177
178
179
180
181
182
183
184
185
  	/* any matching mon ip implies a match */
  	for (i = 0; i < opt1->num_mon; i++) {
  		if (ceph_monmap_contains(client->monc.monmap,
  				 &opt1->mon_addr[i]))
  			return 0;
  	}
  	return -1;
  }
  EXPORT_SYMBOL(ceph_compare_options);
10c12851a   Ilya Dryomov   libceph: avoid a ...
186
187
188
189
  /*
   * kvmalloc() doesn't fall back to the vmalloc allocator unless flags are
   * compatible with (a superset of) GFP_KERNEL.  This is because while the
   * actual pages are allocated with the specified flags, the page table pages
ed1f324c5   Christoph Hellwig   mm: remove map_vm...
190
   * are always allocated with GFP_KERNEL.
10c12851a   Ilya Dryomov   libceph: avoid a ...
191
192
193
   *
   * ceph_kvmalloc() may be called with GFP_KERNEL, GFP_NOFS or GFP_NOIO.
   */
eeb0bed55   Ilya Dryomov   libceph: add ceph...
194
195
  void *ceph_kvmalloc(size_t size, gfp_t flags)
  {
10c12851a   Ilya Dryomov   libceph: avoid a ...
196
197
198
199
200
201
202
203
204
205
206
207
  	void *p;
  
  	if ((flags & (__GFP_IO | __GFP_FS)) == (__GFP_IO | __GFP_FS)) {
  		p = kvmalloc(size, flags);
  	} else if ((flags & (__GFP_IO | __GFP_FS)) == __GFP_IO) {
  		unsigned int nofs_flag = memalloc_nofs_save();
  		p = kvmalloc(size, GFP_KERNEL);
  		memalloc_nofs_restore(nofs_flag);
  	} else {
  		unsigned int noio_flag = memalloc_noio_save();
  		p = kvmalloc(size, GFP_KERNEL);
  		memalloc_noio_restore(noio_flag);
eeb0bed55   Ilya Dryomov   libceph: add ceph...
208
  	}
10c12851a   Ilya Dryomov   libceph: avoid a ...
209
  	return p;
eeb0bed55   Ilya Dryomov   libceph: add ceph...
210
  }
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
  static int parse_fsid(const char *str, struct ceph_fsid *fsid)
  {
  	int i = 0;
  	char tmp[3];
  	int err = -EINVAL;
  	int d;
  
  	dout("parse_fsid '%s'
  ", str);
  	tmp[2] = 0;
  	while (*str && i < 16) {
  		if (ispunct(*str)) {
  			str++;
  			continue;
  		}
  		if (!isxdigit(str[0]) || !isxdigit(str[1]))
  			break;
  		tmp[0] = str[0];
  		tmp[1] = str[1];
  		if (sscanf(tmp, "%x", &d) < 1)
  			break;
  		fsid->fsid[i] = d & 0xff;
  		i++;
  		str += 2;
  	}
  
  	if (i == 16)
  		err = 0;
4c069a582   Chengguang Xu   ceph: add newline...
239
240
  	dout("parse_fsid ret %d got fsid %pU
  ", err, fsid);
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
241
242
243
244
245
246
247
248
249
250
251
  	return err;
  }
  
  /*
   * ceph options
   */
  enum {
  	Opt_osdtimeout,
  	Opt_osdkeepalivetimeout,
  	Opt_mount_timeout,
  	Opt_osd_idle_ttl,
7cc5e38f2   Ilya Dryomov   libceph: osd_requ...
252
  	Opt_osd_request_timeout,
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
253
254
255
256
  	/* int args above */
  	Opt_fsid,
  	Opt_name,
  	Opt_secret,
e2c3d29b4   Tommi Virtanen   libceph: Get secr...
257
  	Opt_key,
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
258
  	Opt_ip,
45e6aa9f5   Ilya Dryomov   libceph: crush_lo...
259
  	Opt_crush_location,
8ad44d5e0   Ilya Dryomov   libceph: read_fro...
260
  	Opt_read_from_replica,
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
261
  	/* string args above */
cffaba15c   Alex Elder   ceph: ensure Bool...
262
  	Opt_share,
cffaba15c   Alex Elder   ceph: ensure Bool...
263
  	Opt_crc,
a3fc98005   Yan, Zheng   libceph: require ...
264
  	Opt_cephx_require_signatures,
a51983e4d   Ilya Dryomov   libceph: add noce...
265
  	Opt_cephx_sign_messages,
ba988f87f   Chaitanya Huilgol   libceph: tcp_node...
266
  	Opt_tcp_nodelay,
02b2f549d   Dongsheng Yang   libceph: allow se...
267
  	Opt_abort_on_full,
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
268
  };
8ad44d5e0   Ilya Dryomov   libceph: read_fro...
269
270
271
272
273
274
275
276
277
278
279
280
  enum {
  	Opt_read_from_replica_no,
  	Opt_read_from_replica_balance,
  	Opt_read_from_replica_localize,
  };
  
  static const struct constant_table ceph_param_read_from_replica[] = {
  	{"no",		Opt_read_from_replica_no},
  	{"balance",	Opt_read_from_replica_balance},
  	{"localize",	Opt_read_from_replica_localize},
  	{}
  };
d7167b149   Al Viro   fs_parse: fold fs...
281
  static const struct fs_parameter_spec ceph_parameters[] = {
82995cc6c   David Howells   libceph, rbd, cep...
282
283
284
285
  	fsparam_flag	("abort_on_full",		Opt_abort_on_full),
  	fsparam_flag_no ("cephx_require_signatures",	Opt_cephx_require_signatures),
  	fsparam_flag_no ("cephx_sign_messages",		Opt_cephx_sign_messages),
  	fsparam_flag_no ("crc",				Opt_crc),
45e6aa9f5   Ilya Dryomov   libceph: crush_lo...
286
  	fsparam_string	("crush_location",		Opt_crush_location),
82995cc6c   David Howells   libceph, rbd, cep...
287
288
289
290
291
292
293
294
295
  	fsparam_string	("fsid",			Opt_fsid),
  	fsparam_string	("ip",				Opt_ip),
  	fsparam_string	("key",				Opt_key),
  	fsparam_u32	("mount_timeout",		Opt_mount_timeout),
  	fsparam_string	("name",			Opt_name),
  	fsparam_u32	("osd_idle_ttl",		Opt_osd_idle_ttl),
  	fsparam_u32	("osd_request_timeout",		Opt_osd_request_timeout),
  	fsparam_u32	("osdkeepalive",		Opt_osdkeepalivetimeout),
  	__fsparam	(fs_param_is_s32, "osdtimeout", Opt_osdtimeout,
2710c957a   Al Viro   fs_parse: get rid...
296
  			 fs_param_deprecated, NULL),
8ad44d5e0   Ilya Dryomov   libceph: read_fro...
297
298
  	fsparam_enum	("read_from_replica",		Opt_read_from_replica,
  			 ceph_param_read_from_replica),
82995cc6c   David Howells   libceph, rbd, cep...
299
300
301
302
303
  	fsparam_string	("secret",			Opt_secret),
  	fsparam_flag_no ("share",			Opt_share),
  	fsparam_flag_no ("tcp_nodelay",			Opt_tcp_nodelay),
  	{}
  };
82995cc6c   David Howells   libceph, rbd, cep...
304
305
306
307
308
309
310
  struct ceph_options *ceph_alloc_options(void)
  {
  	struct ceph_options *opt;
  
  	opt = kzalloc(sizeof(*opt), GFP_KERNEL);
  	if (!opt)
  		return NULL;
45e6aa9f5   Ilya Dryomov   libceph: crush_lo...
311
  	opt->crush_locs = RB_ROOT;
82995cc6c   David Howells   libceph, rbd, cep...
312
313
314
315
316
317
318
319
320
321
322
323
  	opt->mon_addr = kcalloc(CEPH_MAX_MON, sizeof(*opt->mon_addr),
  				GFP_KERNEL);
  	if (!opt->mon_addr) {
  		kfree(opt);
  		return NULL;
  	}
  
  	opt->flags = CEPH_OPT_DEFAULT;
  	opt->osd_keepalive_timeout = CEPH_OSD_KEEPALIVE_DEFAULT;
  	opt->mount_timeout = CEPH_MOUNT_TIMEOUT_DEFAULT;
  	opt->osd_idle_ttl = CEPH_OSD_IDLE_TTL_DEFAULT;
  	opt->osd_request_timeout = CEPH_OSD_REQUEST_TIMEOUT_DEFAULT;
22d2cfdff   Ilya Dryomov   libceph: move awa...
324
  	opt->read_from_replica = CEPH_READ_FROM_REPLICA_DEFAULT;
82995cc6c   David Howells   libceph, rbd, cep...
325
326
327
  	return opt;
  }
  EXPORT_SYMBOL(ceph_alloc_options);
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
328
329
330
331
  void ceph_destroy_options(struct ceph_options *opt)
  {
  	dout("destroy_options %p
  ", opt);
82995cc6c   David Howells   libceph, rbd, cep...
332
333
  	if (!opt)
  		return;
45e6aa9f5   Ilya Dryomov   libceph: crush_lo...
334
  	ceph_clear_crush_locs(&opt->crush_locs);
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
335
  	kfree(opt->name);
8323c3aa7   Tommi Virtanen   ceph: Move secret...
336
337
338
339
  	if (opt->key) {
  		ceph_crypto_key_destroy(opt->key);
  		kfree(opt->key);
  	}
1cad78932   Noah Watkins   libceph: fix pars...
340
  	kfree(opt->mon_addr);
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
341
342
343
  	kfree(opt);
  }
  EXPORT_SYMBOL(ceph_destroy_options);
e2c3d29b4   Tommi Virtanen   libceph: Get secr...
344
  /* get secret from key store */
82995cc6c   David Howells   libceph, rbd, cep...
345
  static int get_secret(struct ceph_crypto_key *dst, const char *name,
2c3f3dc31   Al Viro   switch rbd and li...
346
  		      struct p_log *log)
82995cc6c   David Howells   libceph, rbd, cep...
347
  {
e2c3d29b4   Tommi Virtanen   libceph: Get secr...
348
349
350
  	struct key *ukey;
  	int key_err;
  	int err = 0;
4b2a58abd   Tommi Virtanen   libceph: Create a...
351
  	struct ceph_crypto_key *ckey;
e2c3d29b4   Tommi Virtanen   libceph: Get secr...
352

4b2a58abd   Tommi Virtanen   libceph: Create a...
353
  	ukey = request_key(&key_type_ceph, name, NULL);
bad87216f   YueHaibing   libceph: remove u...
354
  	if (IS_ERR(ukey)) {
e2c3d29b4   Tommi Virtanen   libceph: Get secr...
355
356
357
358
359
  		/* request_key errors don't map nicely to mount(2)
  		   errors; don't even try, but still printk */
  		key_err = PTR_ERR(ukey);
  		switch (key_err) {
  		case -ENOKEY:
2c3f3dc31   Al Viro   switch rbd and li...
360
  			error_plog(log, "Failed due to key not found: %s",
82995cc6c   David Howells   libceph, rbd, cep...
361
  			       name);
e2c3d29b4   Tommi Virtanen   libceph: Get secr...
362
363
  			break;
  		case -EKEYEXPIRED:
2c3f3dc31   Al Viro   switch rbd and li...
364
  			error_plog(log, "Failed due to expired key: %s",
82995cc6c   David Howells   libceph, rbd, cep...
365
  			       name);
e2c3d29b4   Tommi Virtanen   libceph: Get secr...
366
367
  			break;
  		case -EKEYREVOKED:
2c3f3dc31   Al Viro   switch rbd and li...
368
  			error_plog(log, "Failed due to revoked key: %s",
82995cc6c   David Howells   libceph, rbd, cep...
369
  			       name);
e2c3d29b4   Tommi Virtanen   libceph: Get secr...
370
371
  			break;
  		default:
2c3f3dc31   Al Viro   switch rbd and li...
372
  			error_plog(log, "Failed due to key error %d: %s",
82995cc6c   David Howells   libceph, rbd, cep...
373
  			       key_err, name);
e2c3d29b4   Tommi Virtanen   libceph: Get secr...
374
375
376
377
  		}
  		err = -EPERM;
  		goto out;
  	}
146aa8b14   David Howells   KEYS: Merge the t...
378
  	ckey = ukey->payload.data[0];
4b2a58abd   Tommi Virtanen   libceph: Create a...
379
  	err = ceph_crypto_key_clone(dst, ckey);
e2c3d29b4   Tommi Virtanen   libceph: Get secr...
380
381
382
383
384
385
386
387
388
  	if (err)
  		goto out_key;
  	/* pass through, err is 0 */
  
  out_key:
  	key_put(ukey);
  out:
  	return err;
  }
82995cc6c   David Howells   libceph, rbd, cep...
389
  int ceph_parse_mon_ips(const char *buf, size_t len, struct ceph_options *opt,
c80c98f0d   Al Viro   ceph_parse_param(...
390
  		       struct fc_log *l)
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
391
  {
c80c98f0d   Al Viro   ceph_parse_param(...
392
  	struct p_log log = {.prefix = "libceph", .log = l};
82995cc6c   David Howells   libceph, rbd, cep...
393
  	int ret;
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
394

3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
395
  	/* ip1[:port1][,ip2[:port2]...] */
82995cc6c   David Howells   libceph, rbd, cep...
396
397
398
  	ret = ceph_parse_ips(buf, buf + len, opt->mon_addr, CEPH_MAX_MON,
  			     &opt->num_mon);
  	if (ret) {
2c3f3dc31   Al Viro   switch rbd and li...
399
  		error_plog(&log, "Failed to parse monitor IPs: %d", ret);
82995cc6c   David Howells   libceph, rbd, cep...
400
401
  		return ret;
  	}
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
402

82995cc6c   David Howells   libceph, rbd, cep...
403
404
405
406
407
  	return 0;
  }
  EXPORT_SYMBOL(ceph_parse_mon_ips);
  
  int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt,
c80c98f0d   Al Viro   ceph_parse_param(...
408
  		     struct fc_log *l)
82995cc6c   David Howells   libceph, rbd, cep...
409
410
411
  {
  	struct fs_parse_result result;
  	int token, err;
c80c98f0d   Al Viro   ceph_parse_param(...
412
  	struct p_log log = {.prefix = "libceph", .log = l};
82995cc6c   David Howells   libceph, rbd, cep...
413

d7167b149   Al Viro   fs_parse: fold fs...
414
  	token = __fs_parse(&log, ceph_parameters, param, &result);
82995cc6c   David Howells   libceph, rbd, cep...
415
416
417
418
419
420
421
422
423
424
425
426
  	dout("%s fs_parse '%s' token %d
  ", __func__, param->key, token);
  	if (token < 0)
  		return token;
  
  	switch (token) {
  	case Opt_ip:
  		err = ceph_parse_ips(param->string,
  				     param->string + param->size,
  				     &opt->my_addr,
  				     1, NULL);
  		if (err) {
2c3f3dc31   Al Viro   switch rbd and li...
427
  			error_plog(&log, "Failed to parse ip: %d", err);
82995cc6c   David Howells   libceph, rbd, cep...
428
  			return err;
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
429
  		}
82995cc6c   David Howells   libceph, rbd, cep...
430
431
432
433
434
435
  		opt->flags |= CEPH_OPT_MYIP;
  		break;
  
  	case Opt_fsid:
  		err = parse_fsid(param->string, &opt->fsid);
  		if (err) {
2c3f3dc31   Al Viro   switch rbd and li...
436
  			error_plog(&log, "Failed to parse fsid: %d", err);
82995cc6c   David Howells   libceph, rbd, cep...
437
  			return err;
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
438
  		}
82995cc6c   David Howells   libceph, rbd, cep...
439
440
441
442
443
444
445
446
447
448
  		opt->flags |= CEPH_OPT_FSID;
  		break;
  	case Opt_name:
  		kfree(opt->name);
  		opt->name = param->string;
  		param->string = NULL;
  		break;
  	case Opt_secret:
  		ceph_crypto_key_destroy(opt->key);
  		kfree(opt->key);
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
449

82995cc6c   David Howells   libceph, rbd, cep...
450
451
452
453
454
  		opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
  		if (!opt->key)
  			return -ENOMEM;
  		err = ceph_crypto_key_unarmor(opt->key, param->string);
  		if (err) {
2c3f3dc31   Al Viro   switch rbd and li...
455
  			error_plog(&log, "Failed to parse secret: %d", err);
82995cc6c   David Howells   libceph, rbd, cep...
456
457
458
459
460
461
  			return err;
  		}
  		break;
  	case Opt_key:
  		ceph_crypto_key_destroy(opt->key);
  		kfree(opt->key);
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
462

82995cc6c   David Howells   libceph, rbd, cep...
463
464
465
  		opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
  		if (!opt->key)
  			return -ENOMEM;
2c3f3dc31   Al Viro   switch rbd and li...
466
  		return get_secret(opt->key, param->string, &log);
45e6aa9f5   Ilya Dryomov   libceph: crush_lo...
467
468
469
470
471
472
473
474
475
476
  	case Opt_crush_location:
  		ceph_clear_crush_locs(&opt->crush_locs);
  		err = ceph_parse_crush_location(param->string,
  						&opt->crush_locs);
  		if (err) {
  			error_plog(&log, "Failed to parse CRUSH location: %d",
  				   err);
  			return err;
  		}
  		break;
8ad44d5e0   Ilya Dryomov   libceph: read_fro...
477
478
479
  	case Opt_read_from_replica:
  		switch (result.uint_32) {
  		case Opt_read_from_replica_no:
22d2cfdff   Ilya Dryomov   libceph: move awa...
480
  			opt->read_from_replica = 0;
8ad44d5e0   Ilya Dryomov   libceph: read_fro...
481
482
  			break;
  		case Opt_read_from_replica_balance:
22d2cfdff   Ilya Dryomov   libceph: move awa...
483
  			opt->read_from_replica = CEPH_OSD_FLAG_BALANCE_READS;
8ad44d5e0   Ilya Dryomov   libceph: read_fro...
484
485
  			break;
  		case Opt_read_from_replica_localize:
22d2cfdff   Ilya Dryomov   libceph: move awa...
486
  			opt->read_from_replica = CEPH_OSD_FLAG_LOCALIZE_READS;
8ad44d5e0   Ilya Dryomov   libceph: read_fro...
487
488
489
490
491
  			break;
  		default:
  			BUG();
  		}
  		break;
82995cc6c   David Howells   libceph, rbd, cep...
492
493
  
  	case Opt_osdtimeout:
2c3f3dc31   Al Viro   switch rbd and li...
494
  		warn_plog(&log, "Ignoring osdtimeout");
82995cc6c   David Howells   libceph, rbd, cep...
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
  		break;
  	case Opt_osdkeepalivetimeout:
  		/* 0 isn't well defined right now, reject it */
  		if (result.uint_32 < 1 || result.uint_32 > INT_MAX / 1000)
  			goto out_of_range;
  		opt->osd_keepalive_timeout =
  		    msecs_to_jiffies(result.uint_32 * 1000);
  		break;
  	case Opt_osd_idle_ttl:
  		/* 0 isn't well defined right now, reject it */
  		if (result.uint_32 < 1 || result.uint_32 > INT_MAX / 1000)
  			goto out_of_range;
  		opt->osd_idle_ttl = msecs_to_jiffies(result.uint_32 * 1000);
  		break;
  	case Opt_mount_timeout:
  		/* 0 is "wait forever" (i.e. infinite timeout) */
  		if (result.uint_32 > INT_MAX / 1000)
  			goto out_of_range;
  		opt->mount_timeout = msecs_to_jiffies(result.uint_32 * 1000);
  		break;
  	case Opt_osd_request_timeout:
  		/* 0 is "wait forever" (i.e. infinite timeout) */
  		if (result.uint_32 > INT_MAX / 1000)
  			goto out_of_range;
  		opt->osd_request_timeout =
  		    msecs_to_jiffies(result.uint_32 * 1000);
  		break;
  
  	case Opt_share:
  		if (!result.negated)
cffaba15c   Alex Elder   ceph: ensure Bool...
525
  			opt->flags &= ~CEPH_OPT_NOSHARE;
82995cc6c   David Howells   libceph, rbd, cep...
526
  		else
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
527
  			opt->flags |= CEPH_OPT_NOSHARE;
82995cc6c   David Howells   libceph, rbd, cep...
528
529
530
  		break;
  	case Opt_crc:
  		if (!result.negated)
cffaba15c   Alex Elder   ceph: ensure Bool...
531
  			opt->flags &= ~CEPH_OPT_NOCRC;
82995cc6c   David Howells   libceph, rbd, cep...
532
  		else
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
533
  			opt->flags |= CEPH_OPT_NOCRC;
82995cc6c   David Howells   libceph, rbd, cep...
534
535
536
  		break;
  	case Opt_cephx_require_signatures:
  		if (!result.negated)
a3fc98005   Yan, Zheng   libceph: require ...
537
  			opt->flags &= ~CEPH_OPT_NOMSGAUTH;
82995cc6c   David Howells   libceph, rbd, cep...
538
  		else
a3fc98005   Yan, Zheng   libceph: require ...
539
  			opt->flags |= CEPH_OPT_NOMSGAUTH;
82995cc6c   David Howells   libceph, rbd, cep...
540
541
542
  		break;
  	case Opt_cephx_sign_messages:
  		if (!result.negated)
a51983e4d   Ilya Dryomov   libceph: add noce...
543
  			opt->flags &= ~CEPH_OPT_NOMSGSIGN;
82995cc6c   David Howells   libceph, rbd, cep...
544
  		else
a51983e4d   Ilya Dryomov   libceph: add noce...
545
  			opt->flags |= CEPH_OPT_NOMSGSIGN;
82995cc6c   David Howells   libceph, rbd, cep...
546
547
548
  		break;
  	case Opt_tcp_nodelay:
  		if (!result.negated)
ba988f87f   Chaitanya Huilgol   libceph: tcp_node...
549
  			opt->flags |= CEPH_OPT_TCP_NODELAY;
82995cc6c   David Howells   libceph, rbd, cep...
550
  		else
ba988f87f   Chaitanya Huilgol   libceph: tcp_node...
551
  			opt->flags &= ~CEPH_OPT_TCP_NODELAY;
82995cc6c   David Howells   libceph, rbd, cep...
552
  		break;
ba988f87f   Chaitanya Huilgol   libceph: tcp_node...
553

82995cc6c   David Howells   libceph, rbd, cep...
554
555
556
  	case Opt_abort_on_full:
  		opt->flags |= CEPH_OPT_ABORT_ON_FULL;
  		break;
02b2f549d   Dongsheng Yang   libceph: allow se...
557

82995cc6c   David Howells   libceph, rbd, cep...
558
559
  	default:
  		BUG();
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
560
  	}
82995cc6c   David Howells   libceph, rbd, cep...
561
  	return 0;
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
562

82995cc6c   David Howells   libceph, rbd, cep...
563
  out_of_range:
2c3f3dc31   Al Viro   switch rbd and li...
564
  	return inval_plog(&log, "%s out of range", param->key);
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
565
  }
82995cc6c   David Howells   libceph, rbd, cep...
566
  EXPORT_SYMBOL(ceph_parse_param);
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
567

02b2f549d   Dongsheng Yang   libceph: allow se...
568
569
  int ceph_print_client_options(struct seq_file *m, struct ceph_client *client,
  			      bool show_all)
ff40f9ae9   Ilya Dryomov   libceph, ceph: sp...
570
571
572
  {
  	struct ceph_options *opt = client->options;
  	size_t pos = m->count;
45e6aa9f5   Ilya Dryomov   libceph: crush_lo...
573
  	struct rb_node *n;
ff40f9ae9   Ilya Dryomov   libceph, ceph: sp...
574

a068acf2e   Kees Cook   fs: create and us...
575
576
577
578
579
580
  	if (opt->name) {
  		seq_puts(m, "name=");
  		seq_escape(m, opt->name, ", \t
  \\");
  		seq_putc(m, ',');
  	}
ff40f9ae9   Ilya Dryomov   libceph, ceph: sp...
581
582
  	if (opt->key)
  		seq_puts(m, "secret=<hidden>,");
45e6aa9f5   Ilya Dryomov   libceph: crush_lo...
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
  	if (!RB_EMPTY_ROOT(&opt->crush_locs)) {
  		seq_puts(m, "crush_location=");
  		for (n = rb_first(&opt->crush_locs); ; ) {
  			struct crush_loc_node *loc =
  			    rb_entry(n, struct crush_loc_node, cl_node);
  
  			seq_printf(m, "%s:%s", loc->cl_loc.cl_type_name,
  				   loc->cl_loc.cl_name);
  			n = rb_next(n);
  			if (!n)
  				break;
  
  			seq_putc(m, '|');
  		}
  		seq_putc(m, ',');
  	}
22d2cfdff   Ilya Dryomov   libceph: move awa...
599
  	if (opt->read_from_replica == CEPH_OSD_FLAG_BALANCE_READS) {
8ad44d5e0   Ilya Dryomov   libceph: read_fro...
600
  		seq_puts(m, "read_from_replica=balance,");
22d2cfdff   Ilya Dryomov   libceph: move awa...
601
  	} else if (opt->read_from_replica == CEPH_OSD_FLAG_LOCALIZE_READS) {
8ad44d5e0   Ilya Dryomov   libceph: read_fro...
602
603
  		seq_puts(m, "read_from_replica=localize,");
  	}
45e6aa9f5   Ilya Dryomov   libceph: crush_lo...
604

ff40f9ae9   Ilya Dryomov   libceph, ceph: sp...
605
606
607
608
609
610
611
612
  	if (opt->flags & CEPH_OPT_FSID)
  		seq_printf(m, "fsid=%pU,", &opt->fsid);
  	if (opt->flags & CEPH_OPT_NOSHARE)
  		seq_puts(m, "noshare,");
  	if (opt->flags & CEPH_OPT_NOCRC)
  		seq_puts(m, "nocrc,");
  	if (opt->flags & CEPH_OPT_NOMSGAUTH)
  		seq_puts(m, "nocephx_require_signatures,");
a51983e4d   Ilya Dryomov   libceph: add noce...
613
614
  	if (opt->flags & CEPH_OPT_NOMSGSIGN)
  		seq_puts(m, "nocephx_sign_messages,");
ff40f9ae9   Ilya Dryomov   libceph, ceph: sp...
615
616
  	if ((opt->flags & CEPH_OPT_TCP_NODELAY) == 0)
  		seq_puts(m, "notcp_nodelay,");
02b2f549d   Dongsheng Yang   libceph: allow se...
617
618
  	if (show_all && (opt->flags & CEPH_OPT_ABORT_ON_FULL))
  		seq_puts(m, "abort_on_full,");
ff40f9ae9   Ilya Dryomov   libceph, ceph: sp...
619
620
  
  	if (opt->mount_timeout != CEPH_MOUNT_TIMEOUT_DEFAULT)
a319bf56a   Ilya Dryomov   libceph: store ti...
621
622
  		seq_printf(m, "mount_timeout=%d,",
  			   jiffies_to_msecs(opt->mount_timeout) / 1000);
ff40f9ae9   Ilya Dryomov   libceph, ceph: sp...
623
  	if (opt->osd_idle_ttl != CEPH_OSD_IDLE_TTL_DEFAULT)
a319bf56a   Ilya Dryomov   libceph: store ti...
624
625
  		seq_printf(m, "osd_idle_ttl=%d,",
  			   jiffies_to_msecs(opt->osd_idle_ttl) / 1000);
ff40f9ae9   Ilya Dryomov   libceph, ceph: sp...
626
627
  	if (opt->osd_keepalive_timeout != CEPH_OSD_KEEPALIVE_DEFAULT)
  		seq_printf(m, "osdkeepalivetimeout=%d,",
a319bf56a   Ilya Dryomov   libceph: store ti...
628
  		    jiffies_to_msecs(opt->osd_keepalive_timeout) / 1000);
7cc5e38f2   Ilya Dryomov   libceph: osd_requ...
629
630
631
  	if (opt->osd_request_timeout != CEPH_OSD_REQUEST_TIMEOUT_DEFAULT)
  		seq_printf(m, "osd_request_timeout=%d,",
  			   jiffies_to_msecs(opt->osd_request_timeout) / 1000);
ff40f9ae9   Ilya Dryomov   libceph, ceph: sp...
632
633
634
635
636
637
638
639
  
  	/* drop redundant comma */
  	if (m->count != pos)
  		m->count--;
  
  	return 0;
  }
  EXPORT_SYMBOL(ceph_print_client_options);
005a07bf0   Ilya Dryomov   rbd: add 'client_...
640
641
642
643
644
  struct ceph_entity_addr *ceph_client_addr(struct ceph_client *client)
  {
  	return &client->msgr.inst.addr;
  }
  EXPORT_SYMBOL(ceph_client_addr);
033268a5f   Ilya Dryomov   libceph: rename c...
645
  u64 ceph_client_gid(struct ceph_client *client)
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
646
647
648
  {
  	return client->monc.auth->global_id;
  }
033268a5f   Ilya Dryomov   libceph: rename c...
649
  EXPORT_SYMBOL(ceph_client_gid);
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
650
651
652
653
  
  /*
   * create a fresh client instance
   */
74da4a0f5   Ilya Dryomov   libceph, ceph: al...
654
  struct ceph_client *ceph_create_client(struct ceph_options *opt, void *private)
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
655
656
  {
  	struct ceph_client *client;
6ab00d465   Sage Weil   libceph: create m...
657
  	struct ceph_entity_addr *myaddr = NULL;
ae5b806a3   Jason A. Donenfeld   ceph: ensure RNG ...
658
659
660
661
662
  	int err;
  
  	err = wait_for_random_bytes();
  	if (err < 0)
  		return ERR_PTR(err);
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
663
664
665
666
667
668
669
670
671
672
673
674
675
  
  	client = kzalloc(sizeof(*client), GFP_KERNEL);
  	if (client == NULL)
  		return ERR_PTR(-ENOMEM);
  
  	client->private = private;
  	client->options = opt;
  
  	mutex_init(&client->mount_mutex);
  	init_waitqueue_head(&client->auth_wq);
  	client->auth_err = 0;
  
  	client->extra_mon_dispatch = NULL;
74da4a0f5   Ilya Dryomov   libceph, ceph: al...
676
677
678
679
680
  	client->supported_features = CEPH_FEATURES_SUPPORTED_DEFAULT;
  	client->required_features = CEPH_FEATURES_REQUIRED_DEFAULT;
  
  	if (!ceph_test_opt(client, NOMSGAUTH))
  		client->required_features |= CEPH_FEATURE_MSG_AUTH;
6ab00d465   Sage Weil   libceph: create m...
681
682
683
684
  
  	/* msgr */
  	if (ceph_test_opt(client, MYIP))
  		myaddr = &client->options->my_addr;
ba988f87f   Chaitanya Huilgol   libceph: tcp_node...
685

859bff51d   Ilya Dryomov   libceph: stop dup...
686
  	ceph_messenger_init(&client->msgr, myaddr);
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
687
688
689
690
  
  	/* subsystems */
  	err = ceph_monc_init(&client->monc, client);
  	if (err < 0)
15d9882c3   Alex Elder   libceph: embed ce...
691
  		goto fail;
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
692
693
694
695
696
697
698
699
700
  	err = ceph_osdc_init(&client->osdc, client);
  	if (err < 0)
  		goto fail_monc;
  
  	return client;
  
  fail_monc:
  	ceph_monc_stop(&client->monc);
  fail:
757856d2b   Ilya Dryomov   libceph: enable c...
701
  	ceph_messenger_fini(&client->msgr);
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
702
703
704
705
706
707
708
709
710
  	kfree(client);
  	return ERR_PTR(err);
  }
  EXPORT_SYMBOL(ceph_create_client);
  
  void ceph_destroy_client(struct ceph_client *client)
  {
  	dout("destroy_client %p
  ", client);
a2a325841   Guanjun He   libceph: prevent ...
711
  	atomic_set(&client->msgr.stopping, 1);
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
712
713
  	/* unmount */
  	ceph_osdc_stop(&client->osdc);
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
714
  	ceph_monc_stop(&client->monc);
757856d2b   Ilya Dryomov   libceph: enable c...
715
  	ceph_messenger_fini(&client->msgr);
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
716
717
  
  	ceph_debugfs_client_cleanup(client);
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
718
719
720
721
722
723
724
  	ceph_destroy_options(client->options);
  
  	kfree(client);
  	dout("destroy_client %p done
  ", client);
  }
  EXPORT_SYMBOL(ceph_destroy_client);
120a75ea9   Yan, Zheng   libceph: add func...
725
726
727
728
729
730
731
  void ceph_reset_client_addr(struct ceph_client *client)
  {
  	ceph_messenger_reset_nonce(&client->msgr);
  	ceph_monc_reopen_session(&client->monc);
  	ceph_osdc_reopen_osds(&client->osdc);
  }
  EXPORT_SYMBOL(ceph_reset_client_addr);
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
732
733
734
  /*
   * true if we have the mon map (and have thus joined the cluster)
   */
3b33f692c   Zhang Zhuoyu   ceph: make logica...
735
  static bool have_mon_and_osd_map(struct ceph_client *client)
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
736
737
738
739
740
741
742
743
744
745
  {
  	return client->monc.monmap && client->monc.monmap->epoch &&
  	       client->osdc.osdmap && client->osdc.osdmap->epoch;
  }
  
  /*
   * mount: join the ceph cluster, and open root directory.
   */
  int __ceph_open_session(struct ceph_client *client, unsigned long started)
  {
a319bf56a   Ilya Dryomov   libceph: store ti...
746
  	unsigned long timeout = client->options->mount_timeout;
216639dd5   Ilya Dryomov   libceph: a couple...
747
  	long err;
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
748

3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
749
750
751
752
753
754
  	/* open session, and wait for mon and osd maps */
  	err = ceph_monc_open_session(&client->monc);
  	if (err < 0)
  		return err;
  
  	while (!have_mon_and_osd_map(client)) {
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
755
  		if (timeout && time_after_eq(jiffies, started + timeout))
216639dd5   Ilya Dryomov   libceph: a couple...
756
  			return -ETIMEDOUT;
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
757
758
759
760
761
762
  
  		/* wait */
  		dout("mount waiting for mon_map
  ");
  		err = wait_event_interruptible_timeout(client->auth_wq,
  			have_mon_and_osd_map(client) || (client->auth_err < 0),
a319bf56a   Ilya Dryomov   libceph: store ti...
763
  			ceph_timeout_jiffies(timeout));
216639dd5   Ilya Dryomov   libceph: a couple...
764
  		if (err < 0)
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
765
766
767
768
  			return err;
  		if (client->auth_err < 0)
  			return client->auth_err;
  	}
033268a5f   Ilya Dryomov   libceph: rename c...
769
770
771
  	pr_info("client%llu fsid %pU
  ", ceph_client_gid(client),
  		&client->fsid);
02ac956c4   Ilya Dryomov   libceph: move deb...
772
  	ceph_debugfs_client_init(client);
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
773
774
775
  	return 0;
  }
  EXPORT_SYMBOL(__ceph_open_session);
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
  int ceph_open_session(struct ceph_client *client)
  {
  	int ret;
  	unsigned long started = jiffies;  /* note the start time */
  
  	dout("open_session start
  ");
  	mutex_lock(&client->mount_mutex);
  
  	ret = __ceph_open_session(client, started);
  
  	mutex_unlock(&client->mount_mutex);
  	return ret;
  }
  EXPORT_SYMBOL(ceph_open_session);
bb229bbb3   Ilya Dryomov   libceph: wait for...
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
  int ceph_wait_for_latest_osdmap(struct ceph_client *client,
  				unsigned long timeout)
  {
  	u64 newest_epoch;
  	int ret;
  
  	ret = ceph_monc_get_version(&client->monc, "osdmap", &newest_epoch);
  	if (ret)
  		return ret;
  
  	if (client->osdc.osdmap->epoch >= newest_epoch)
  		return 0;
  
  	ceph_osdc_maybe_request_map(&client->osdc);
  	return ceph_monc_wait_osdmap(&client->monc, newest_epoch, timeout);
  }
  EXPORT_SYMBOL(ceph_wait_for_latest_osdmap);
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
808
809
810
811
  
  static int __init init_ceph_lib(void)
  {
  	int ret = 0;
1a829ff2a   Greg Kroah-Hartman   ceph: no need to ...
812
  	ceph_debugfs_init();
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
813

4b2a58abd   Tommi Virtanen   libceph: Create a...
814
  	ret = ceph_crypto_init();
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
815
816
  	if (ret < 0)
  		goto out_debugfs;
4b2a58abd   Tommi Virtanen   libceph: Create a...
817
818
819
  	ret = ceph_msgr_init();
  	if (ret < 0)
  		goto out_crypto;
5522ae0b6   Alex Elder   libceph: use slab...
820
821
822
  	ret = ceph_osdc_setup();
  	if (ret < 0)
  		goto out_msgr;
4f6a7e5ee   Sage Weil   ceph: update supp...
823
824
825
  	pr_info("loaded (mon/osd proto %d/%d)
  ",
  		CEPH_MONC_PROTOCOL, CEPH_OSDC_PROTOCOL);
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
826
827
  
  	return 0;
5522ae0b6   Alex Elder   libceph: use slab...
828
829
  out_msgr:
  	ceph_msgr_exit();
4b2a58abd   Tommi Virtanen   libceph: Create a...
830
831
  out_crypto:
  	ceph_crypto_shutdown();
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
832
833
  out_debugfs:
  	ceph_debugfs_cleanup();
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
834
835
836
837
838
839
840
  	return ret;
  }
  
  static void __exit exit_ceph_lib(void)
  {
  	dout("exit_ceph_lib
  ");
51e927379   Yan, Zheng   libceph: introduc...
841
  	WARN_ON(!ceph_strings_empty());
5522ae0b6   Alex Elder   libceph: use slab...
842
  	ceph_osdc_cleanup();
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
843
  	ceph_msgr_exit();
4b2a58abd   Tommi Virtanen   libceph: Create a...
844
  	ceph_crypto_shutdown();
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
845
846
847
848
849
850
851
852
853
  	ceph_debugfs_cleanup();
  }
  
  module_init(init_ceph_lib);
  module_exit(exit_ceph_lib);
  
  MODULE_AUTHOR("Sage Weil <sage@newdream.net>");
  MODULE_AUTHOR("Yehuda Sadeh <yehuda@hq.newdream.net>");
  MODULE_AUTHOR("Patience Warnick <patience@newdream.net>");
6c13a6bb5   Hong Zhiguo   libceph: fix wron...
854
  MODULE_DESCRIPTION("Ceph core library");
3d14c5d2b   Yehuda Sadeh   ceph: factor out ...
855
  MODULE_LICENSE("GPL");