xref: /openbmc/linux/fs/ceph/super.c (revision afc98d90)
1 
2 #include <linux/ceph/ceph_debug.h>
3 
4 #include <linux/backing-dev.h>
5 #include <linux/ctype.h>
6 #include <linux/fs.h>
7 #include <linux/inet.h>
8 #include <linux/in6.h>
9 #include <linux/module.h>
10 #include <linux/mount.h>
11 #include <linux/parser.h>
12 #include <linux/sched.h>
13 #include <linux/seq_file.h>
14 #include <linux/slab.h>
15 #include <linux/statfs.h>
16 #include <linux/string.h>
17 
18 #include "super.h"
19 #include "mds_client.h"
20 #include "cache.h"
21 
22 #include <linux/ceph/ceph_features.h>
23 #include <linux/ceph/decode.h>
24 #include <linux/ceph/mon_client.h>
25 #include <linux/ceph/auth.h>
26 #include <linux/ceph/debugfs.h>
27 
28 /*
29  * Ceph superblock operations
30  *
31  * Handle the basics of mounting, unmounting.
32  */
33 
34 /*
35  * super ops
36  */
37 static void ceph_put_super(struct super_block *s)
38 {
39 	struct ceph_fs_client *fsc = ceph_sb_to_client(s);
40 
41 	dout("put_super\n");
42 	ceph_mdsc_close_sessions(fsc->mdsc);
43 
44 	/*
45 	 * ensure we release the bdi before put_anon_super releases
46 	 * the device name.
47 	 */
48 	if (s->s_bdi == &fsc->backing_dev_info) {
49 		bdi_unregister(&fsc->backing_dev_info);
50 		s->s_bdi = NULL;
51 	}
52 
53 	return;
54 }
55 
56 static int ceph_statfs(struct dentry *dentry, struct kstatfs *buf)
57 {
58 	struct ceph_fs_client *fsc = ceph_inode_to_client(dentry->d_inode);
59 	struct ceph_monmap *monmap = fsc->client->monc.monmap;
60 	struct ceph_statfs st;
61 	u64 fsid;
62 	int err;
63 
64 	dout("statfs\n");
65 	err = ceph_monc_do_statfs(&fsc->client->monc, &st);
66 	if (err < 0)
67 		return err;
68 
69 	/* fill in kstatfs */
70 	buf->f_type = CEPH_SUPER_MAGIC;  /* ?? */
71 
72 	/*
73 	 * express utilization in terms of large blocks to avoid
74 	 * overflow on 32-bit machines.
75 	 *
76 	 * NOTE: for the time being, we make bsize == frsize to humor
77 	 * not-yet-ancient versions of glibc that are broken.
78 	 * Someday, we will probably want to report a real block
79 	 * size...  whatever that may mean for a network file system!
80 	 */
81 	buf->f_bsize = 1 << CEPH_BLOCK_SHIFT;
82 	buf->f_frsize = 1 << CEPH_BLOCK_SHIFT;
83 	buf->f_blocks = le64_to_cpu(st.kb) >> (CEPH_BLOCK_SHIFT-10);
84 	buf->f_bfree = le64_to_cpu(st.kb_avail) >> (CEPH_BLOCK_SHIFT-10);
85 	buf->f_bavail = le64_to_cpu(st.kb_avail) >> (CEPH_BLOCK_SHIFT-10);
86 
87 	buf->f_files = le64_to_cpu(st.num_objects);
88 	buf->f_ffree = -1;
89 	buf->f_namelen = NAME_MAX;
90 
91 	/* leave fsid little-endian, regardless of host endianness */
92 	fsid = *(u64 *)(&monmap->fsid) ^ *((u64 *)&monmap->fsid + 1);
93 	buf->f_fsid.val[0] = fsid & 0xffffffff;
94 	buf->f_fsid.val[1] = fsid >> 32;
95 
96 	return 0;
97 }
98 
99 
100 static int ceph_sync_fs(struct super_block *sb, int wait)
101 {
102 	struct ceph_fs_client *fsc = ceph_sb_to_client(sb);
103 
104 	if (!wait) {
105 		dout("sync_fs (non-blocking)\n");
106 		ceph_flush_dirty_caps(fsc->mdsc);
107 		dout("sync_fs (non-blocking) done\n");
108 		return 0;
109 	}
110 
111 	dout("sync_fs (blocking)\n");
112 	ceph_osdc_sync(&fsc->client->osdc);
113 	ceph_mdsc_sync(fsc->mdsc);
114 	dout("sync_fs (blocking) done\n");
115 	return 0;
116 }
117 
118 /*
119  * mount options
120  */
121 enum {
122 	Opt_wsize,
123 	Opt_rsize,
124 	Opt_rasize,
125 	Opt_caps_wanted_delay_min,
126 	Opt_caps_wanted_delay_max,
127 	Opt_cap_release_safety,
128 	Opt_readdir_max_entries,
129 	Opt_readdir_max_bytes,
130 	Opt_congestion_kb,
131 	Opt_last_int,
132 	/* int args above */
133 	Opt_snapdirname,
134 	Opt_last_string,
135 	/* string args above */
136 	Opt_dirstat,
137 	Opt_nodirstat,
138 	Opt_rbytes,
139 	Opt_norbytes,
140 	Opt_asyncreaddir,
141 	Opt_noasyncreaddir,
142 	Opt_dcache,
143 	Opt_nodcache,
144 	Opt_ino32,
145 	Opt_noino32,
146 	Opt_fscache,
147 	Opt_nofscache
148 };
149 
150 static match_table_t fsopt_tokens = {
151 	{Opt_wsize, "wsize=%d"},
152 	{Opt_rsize, "rsize=%d"},
153 	{Opt_rasize, "rasize=%d"},
154 	{Opt_caps_wanted_delay_min, "caps_wanted_delay_min=%d"},
155 	{Opt_caps_wanted_delay_max, "caps_wanted_delay_max=%d"},
156 	{Opt_cap_release_safety, "cap_release_safety=%d"},
157 	{Opt_readdir_max_entries, "readdir_max_entries=%d"},
158 	{Opt_readdir_max_bytes, "readdir_max_bytes=%d"},
159 	{Opt_congestion_kb, "write_congestion_kb=%d"},
160 	/* int args above */
161 	{Opt_snapdirname, "snapdirname=%s"},
162 	/* string args above */
163 	{Opt_dirstat, "dirstat"},
164 	{Opt_nodirstat, "nodirstat"},
165 	{Opt_rbytes, "rbytes"},
166 	{Opt_norbytes, "norbytes"},
167 	{Opt_asyncreaddir, "asyncreaddir"},
168 	{Opt_noasyncreaddir, "noasyncreaddir"},
169 	{Opt_dcache, "dcache"},
170 	{Opt_nodcache, "nodcache"},
171 	{Opt_ino32, "ino32"},
172 	{Opt_noino32, "noino32"},
173 	{Opt_fscache, "fsc"},
174 	{Opt_nofscache, "nofsc"},
175 	{-1, NULL}
176 };
177 
178 static int parse_fsopt_token(char *c, void *private)
179 {
180 	struct ceph_mount_options *fsopt = private;
181 	substring_t argstr[MAX_OPT_ARGS];
182 	int token, intval, ret;
183 
184 	token = match_token((char *)c, fsopt_tokens, argstr);
185 	if (token < 0)
186 		return -EINVAL;
187 
188 	if (token < Opt_last_int) {
189 		ret = match_int(&argstr[0], &intval);
190 		if (ret < 0) {
191 			pr_err("bad mount option arg (not int) "
192 			       "at '%s'\n", c);
193 			return ret;
194 		}
195 		dout("got int token %d val %d\n", token, intval);
196 	} else if (token > Opt_last_int && token < Opt_last_string) {
197 		dout("got string token %d val %s\n", token,
198 		     argstr[0].from);
199 	} else {
200 		dout("got token %d\n", token);
201 	}
202 
203 	switch (token) {
204 	case Opt_snapdirname:
205 		kfree(fsopt->snapdir_name);
206 		fsopt->snapdir_name = kstrndup(argstr[0].from,
207 					       argstr[0].to-argstr[0].from,
208 					       GFP_KERNEL);
209 		if (!fsopt->snapdir_name)
210 			return -ENOMEM;
211 		break;
212 
213 		/* misc */
214 	case Opt_wsize:
215 		fsopt->wsize = intval;
216 		break;
217 	case Opt_rsize:
218 		fsopt->rsize = intval;
219 		break;
220 	case Opt_rasize:
221 		fsopt->rasize = intval;
222 		break;
223 	case Opt_caps_wanted_delay_min:
224 		fsopt->caps_wanted_delay_min = intval;
225 		break;
226 	case Opt_caps_wanted_delay_max:
227 		fsopt->caps_wanted_delay_max = intval;
228 		break;
229 	case Opt_readdir_max_entries:
230 		fsopt->max_readdir = intval;
231 		break;
232 	case Opt_readdir_max_bytes:
233 		fsopt->max_readdir_bytes = intval;
234 		break;
235 	case Opt_congestion_kb:
236 		fsopt->congestion_kb = intval;
237 		break;
238 	case Opt_dirstat:
239 		fsopt->flags |= CEPH_MOUNT_OPT_DIRSTAT;
240 		break;
241 	case Opt_nodirstat:
242 		fsopt->flags &= ~CEPH_MOUNT_OPT_DIRSTAT;
243 		break;
244 	case Opt_rbytes:
245 		fsopt->flags |= CEPH_MOUNT_OPT_RBYTES;
246 		break;
247 	case Opt_norbytes:
248 		fsopt->flags &= ~CEPH_MOUNT_OPT_RBYTES;
249 		break;
250 	case Opt_asyncreaddir:
251 		fsopt->flags &= ~CEPH_MOUNT_OPT_NOASYNCREADDIR;
252 		break;
253 	case Opt_noasyncreaddir:
254 		fsopt->flags |= CEPH_MOUNT_OPT_NOASYNCREADDIR;
255 		break;
256 	case Opt_dcache:
257 		fsopt->flags |= CEPH_MOUNT_OPT_DCACHE;
258 		break;
259 	case Opt_nodcache:
260 		fsopt->flags &= ~CEPH_MOUNT_OPT_DCACHE;
261 		break;
262 	case Opt_ino32:
263 		fsopt->flags |= CEPH_MOUNT_OPT_INO32;
264 		break;
265 	case Opt_noino32:
266 		fsopt->flags &= ~CEPH_MOUNT_OPT_INO32;
267 		break;
268 	case Opt_fscache:
269 		fsopt->flags |= CEPH_MOUNT_OPT_FSCACHE;
270 		break;
271 	case Opt_nofscache:
272 		fsopt->flags &= ~CEPH_MOUNT_OPT_FSCACHE;
273 		break;
274 	default:
275 		BUG_ON(token);
276 	}
277 	return 0;
278 }
279 
280 static void destroy_mount_options(struct ceph_mount_options *args)
281 {
282 	dout("destroy_mount_options %p\n", args);
283 	kfree(args->snapdir_name);
284 	kfree(args);
285 }
286 
287 static int strcmp_null(const char *s1, const char *s2)
288 {
289 	if (!s1 && !s2)
290 		return 0;
291 	if (s1 && !s2)
292 		return -1;
293 	if (!s1 && s2)
294 		return 1;
295 	return strcmp(s1, s2);
296 }
297 
298 static int compare_mount_options(struct ceph_mount_options *new_fsopt,
299 				 struct ceph_options *new_opt,
300 				 struct ceph_fs_client *fsc)
301 {
302 	struct ceph_mount_options *fsopt1 = new_fsopt;
303 	struct ceph_mount_options *fsopt2 = fsc->mount_options;
304 	int ofs = offsetof(struct ceph_mount_options, snapdir_name);
305 	int ret;
306 
307 	ret = memcmp(fsopt1, fsopt2, ofs);
308 	if (ret)
309 		return ret;
310 
311 	ret = strcmp_null(fsopt1->snapdir_name, fsopt2->snapdir_name);
312 	if (ret)
313 		return ret;
314 
315 	return ceph_compare_options(new_opt, fsc->client);
316 }
317 
318 static int parse_mount_options(struct ceph_mount_options **pfsopt,
319 			       struct ceph_options **popt,
320 			       int flags, char *options,
321 			       const char *dev_name,
322 			       const char **path)
323 {
324 	struct ceph_mount_options *fsopt;
325 	const char *dev_name_end;
326 	int err;
327 
328 	if (!dev_name || !*dev_name)
329 		return -EINVAL;
330 
331 	fsopt = kzalloc(sizeof(*fsopt), GFP_KERNEL);
332 	if (!fsopt)
333 		return -ENOMEM;
334 
335 	dout("parse_mount_options %p, dev_name '%s'\n", fsopt, dev_name);
336 
337 	fsopt->sb_flags = flags;
338 	fsopt->flags = CEPH_MOUNT_OPT_DEFAULT;
339 
340 	fsopt->rsize = CEPH_RSIZE_DEFAULT;
341 	fsopt->rasize = CEPH_RASIZE_DEFAULT;
342 	fsopt->snapdir_name = kstrdup(CEPH_SNAPDIRNAME_DEFAULT, GFP_KERNEL);
343 	fsopt->caps_wanted_delay_min = CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT;
344 	fsopt->caps_wanted_delay_max = CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT;
345 	fsopt->cap_release_safety = CEPH_CAP_RELEASE_SAFETY_DEFAULT;
346 	fsopt->max_readdir = CEPH_MAX_READDIR_DEFAULT;
347 	fsopt->max_readdir_bytes = CEPH_MAX_READDIR_BYTES_DEFAULT;
348 	fsopt->congestion_kb = default_congestion_kb();
349 
350 	/*
351 	 * Distinguish the server list from the path in "dev_name".
352 	 * Internally we do not include the leading '/' in the path.
353 	 *
354 	 * "dev_name" will look like:
355 	 *     <server_spec>[,<server_spec>...]:[<path>]
356 	 * where
357 	 *     <server_spec> is <ip>[:<port>]
358 	 *     <path> is optional, but if present must begin with '/'
359 	 */
360 	dev_name_end = strchr(dev_name, '/');
361 	if (dev_name_end) {
362 		/* skip over leading '/' for path */
363 		*path = dev_name_end + 1;
364 	} else {
365 		/* path is empty */
366 		dev_name_end = dev_name + strlen(dev_name);
367 		*path = dev_name_end;
368 	}
369 	err = -EINVAL;
370 	dev_name_end--;		/* back up to ':' separator */
371 	if (dev_name_end < dev_name || *dev_name_end != ':') {
372 		pr_err("device name is missing path (no : separator in %s)\n",
373 				dev_name);
374 		goto out;
375 	}
376 	dout("device name '%.*s'\n", (int)(dev_name_end - dev_name), dev_name);
377 	dout("server path '%s'\n", *path);
378 
379 	*popt = ceph_parse_options(options, dev_name, dev_name_end,
380 				 parse_fsopt_token, (void *)fsopt);
381 	if (IS_ERR(*popt)) {
382 		err = PTR_ERR(*popt);
383 		goto out;
384 	}
385 
386 	/* success */
387 	*pfsopt = fsopt;
388 	return 0;
389 
390 out:
391 	destroy_mount_options(fsopt);
392 	return err;
393 }
394 
395 /**
396  * ceph_show_options - Show mount options in /proc/mounts
397  * @m: seq_file to write to
398  * @root: root of that (sub)tree
399  */
400 static int ceph_show_options(struct seq_file *m, struct dentry *root)
401 {
402 	struct ceph_fs_client *fsc = ceph_sb_to_client(root->d_sb);
403 	struct ceph_mount_options *fsopt = fsc->mount_options;
404 	struct ceph_options *opt = fsc->client->options;
405 
406 	if (opt->flags & CEPH_OPT_FSID)
407 		seq_printf(m, ",fsid=%pU", &opt->fsid);
408 	if (opt->flags & CEPH_OPT_NOSHARE)
409 		seq_puts(m, ",noshare");
410 	if (opt->flags & CEPH_OPT_NOCRC)
411 		seq_puts(m, ",nocrc");
412 
413 	if (opt->name)
414 		seq_printf(m, ",name=%s", opt->name);
415 	if (opt->key)
416 		seq_puts(m, ",secret=<hidden>");
417 
418 	if (opt->mount_timeout != CEPH_MOUNT_TIMEOUT_DEFAULT)
419 		seq_printf(m, ",mount_timeout=%d", opt->mount_timeout);
420 	if (opt->osd_idle_ttl != CEPH_OSD_IDLE_TTL_DEFAULT)
421 		seq_printf(m, ",osd_idle_ttl=%d", opt->osd_idle_ttl);
422 	if (opt->osd_keepalive_timeout != CEPH_OSD_KEEPALIVE_DEFAULT)
423 		seq_printf(m, ",osdkeepalivetimeout=%d",
424 			   opt->osd_keepalive_timeout);
425 
426 	if (fsopt->flags & CEPH_MOUNT_OPT_DIRSTAT)
427 		seq_puts(m, ",dirstat");
428 	if ((fsopt->flags & CEPH_MOUNT_OPT_RBYTES) == 0)
429 		seq_puts(m, ",norbytes");
430 	if (fsopt->flags & CEPH_MOUNT_OPT_NOASYNCREADDIR)
431 		seq_puts(m, ",noasyncreaddir");
432 	if (fsopt->flags & CEPH_MOUNT_OPT_DCACHE)
433 		seq_puts(m, ",dcache");
434 	else
435 		seq_puts(m, ",nodcache");
436 	if (fsopt->flags & CEPH_MOUNT_OPT_FSCACHE)
437 		seq_puts(m, ",fsc");
438 	else
439 		seq_puts(m, ",nofsc");
440 
441 	if (fsopt->wsize)
442 		seq_printf(m, ",wsize=%d", fsopt->wsize);
443 	if (fsopt->rsize != CEPH_RSIZE_DEFAULT)
444 		seq_printf(m, ",rsize=%d", fsopt->rsize);
445 	if (fsopt->rasize != CEPH_RASIZE_DEFAULT)
446 		seq_printf(m, ",rasize=%d", fsopt->rasize);
447 	if (fsopt->congestion_kb != default_congestion_kb())
448 		seq_printf(m, ",write_congestion_kb=%d", fsopt->congestion_kb);
449 	if (fsopt->caps_wanted_delay_min != CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT)
450 		seq_printf(m, ",caps_wanted_delay_min=%d",
451 			 fsopt->caps_wanted_delay_min);
452 	if (fsopt->caps_wanted_delay_max != CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT)
453 		seq_printf(m, ",caps_wanted_delay_max=%d",
454 			   fsopt->caps_wanted_delay_max);
455 	if (fsopt->cap_release_safety != CEPH_CAP_RELEASE_SAFETY_DEFAULT)
456 		seq_printf(m, ",cap_release_safety=%d",
457 			   fsopt->cap_release_safety);
458 	if (fsopt->max_readdir != CEPH_MAX_READDIR_DEFAULT)
459 		seq_printf(m, ",readdir_max_entries=%d", fsopt->max_readdir);
460 	if (fsopt->max_readdir_bytes != CEPH_MAX_READDIR_BYTES_DEFAULT)
461 		seq_printf(m, ",readdir_max_bytes=%d", fsopt->max_readdir_bytes);
462 	if (strcmp(fsopt->snapdir_name, CEPH_SNAPDIRNAME_DEFAULT))
463 		seq_printf(m, ",snapdirname=%s", fsopt->snapdir_name);
464 	return 0;
465 }
466 
467 /*
468  * handle any mon messages the standard library doesn't understand.
469  * return error if we don't either.
470  */
471 static int extra_mon_dispatch(struct ceph_client *client, struct ceph_msg *msg)
472 {
473 	struct ceph_fs_client *fsc = client->private;
474 	int type = le16_to_cpu(msg->hdr.type);
475 
476 	switch (type) {
477 	case CEPH_MSG_MDS_MAP:
478 		ceph_mdsc_handle_map(fsc->mdsc, msg);
479 		return 0;
480 
481 	default:
482 		return -1;
483 	}
484 }
485 
486 /*
487  * create a new fs client
488  */
489 static struct ceph_fs_client *create_fs_client(struct ceph_mount_options *fsopt,
490 					struct ceph_options *opt)
491 {
492 	struct ceph_fs_client *fsc;
493 	const u64 supported_features =
494 		CEPH_FEATURE_FLOCK |
495 		CEPH_FEATURE_DIRLAYOUTHASH;
496 	const u64 required_features = 0;
497 	int page_count;
498 	size_t size;
499 	int err = -ENOMEM;
500 
501 	fsc = kzalloc(sizeof(*fsc), GFP_KERNEL);
502 	if (!fsc)
503 		return ERR_PTR(-ENOMEM);
504 
505 	fsc->client = ceph_create_client(opt, fsc, supported_features,
506 					 required_features);
507 	if (IS_ERR(fsc->client)) {
508 		err = PTR_ERR(fsc->client);
509 		goto fail;
510 	}
511 	fsc->client->extra_mon_dispatch = extra_mon_dispatch;
512 	fsc->client->monc.want_mdsmap = 1;
513 
514 	fsc->mount_options = fsopt;
515 
516 	fsc->sb = NULL;
517 	fsc->mount_state = CEPH_MOUNT_MOUNTING;
518 
519 	atomic_long_set(&fsc->writeback_count, 0);
520 
521 	err = bdi_init(&fsc->backing_dev_info);
522 	if (err < 0)
523 		goto fail_client;
524 
525 	err = -ENOMEM;
526 	/*
527 	 * The number of concurrent works can be high but they don't need
528 	 * to be processed in parallel, limit concurrency.
529 	 */
530 	fsc->wb_wq = alloc_workqueue("ceph-writeback", 0, 1);
531 	if (fsc->wb_wq == NULL)
532 		goto fail_bdi;
533 	fsc->pg_inv_wq = alloc_workqueue("ceph-pg-invalid", 0, 1);
534 	if (fsc->pg_inv_wq == NULL)
535 		goto fail_wb_wq;
536 	fsc->trunc_wq = alloc_workqueue("ceph-trunc", 0, 1);
537 	if (fsc->trunc_wq == NULL)
538 		goto fail_pg_inv_wq;
539 
540 	/* set up mempools */
541 	err = -ENOMEM;
542 	page_count = fsc->mount_options->wsize >> PAGE_CACHE_SHIFT;
543 	size = sizeof (struct page *) * (page_count ? page_count : 1);
544 	fsc->wb_pagevec_pool = mempool_create_kmalloc_pool(10, size);
545 	if (!fsc->wb_pagevec_pool)
546 		goto fail_trunc_wq;
547 
548 	/* setup fscache */
549 	if ((fsopt->flags & CEPH_MOUNT_OPT_FSCACHE) &&
550 	    (ceph_fscache_register_fs(fsc) != 0))
551 		goto fail_fscache;
552 
553 	/* caps */
554 	fsc->min_caps = fsopt->max_readdir;
555 
556 	return fsc;
557 
558 fail_fscache:
559 	ceph_fscache_unregister_fs(fsc);
560 fail_trunc_wq:
561 	destroy_workqueue(fsc->trunc_wq);
562 fail_pg_inv_wq:
563 	destroy_workqueue(fsc->pg_inv_wq);
564 fail_wb_wq:
565 	destroy_workqueue(fsc->wb_wq);
566 fail_bdi:
567 	bdi_destroy(&fsc->backing_dev_info);
568 fail_client:
569 	ceph_destroy_client(fsc->client);
570 fail:
571 	kfree(fsc);
572 	return ERR_PTR(err);
573 }
574 
575 static void destroy_fs_client(struct ceph_fs_client *fsc)
576 {
577 	dout("destroy_fs_client %p\n", fsc);
578 
579 	ceph_fscache_unregister_fs(fsc);
580 
581 	destroy_workqueue(fsc->wb_wq);
582 	destroy_workqueue(fsc->pg_inv_wq);
583 	destroy_workqueue(fsc->trunc_wq);
584 
585 	bdi_destroy(&fsc->backing_dev_info);
586 
587 	mempool_destroy(fsc->wb_pagevec_pool);
588 
589 	destroy_mount_options(fsc->mount_options);
590 
591 	ceph_fs_debugfs_cleanup(fsc);
592 
593 	ceph_destroy_client(fsc->client);
594 
595 	kfree(fsc);
596 	dout("destroy_fs_client %p done\n", fsc);
597 }
598 
599 /*
600  * caches
601  */
602 struct kmem_cache *ceph_inode_cachep;
603 struct kmem_cache *ceph_cap_cachep;
604 struct kmem_cache *ceph_dentry_cachep;
605 struct kmem_cache *ceph_file_cachep;
606 
607 static void ceph_inode_init_once(void *foo)
608 {
609 	struct ceph_inode_info *ci = foo;
610 	inode_init_once(&ci->vfs_inode);
611 }
612 
613 static int __init init_caches(void)
614 {
615 	int error = -ENOMEM;
616 
617 	ceph_inode_cachep = kmem_cache_create("ceph_inode_info",
618 				      sizeof(struct ceph_inode_info),
619 				      __alignof__(struct ceph_inode_info),
620 				      (SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD),
621 				      ceph_inode_init_once);
622 	if (ceph_inode_cachep == NULL)
623 		return -ENOMEM;
624 
625 	ceph_cap_cachep = KMEM_CACHE(ceph_cap,
626 				     SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD);
627 	if (ceph_cap_cachep == NULL)
628 		goto bad_cap;
629 
630 	ceph_dentry_cachep = KMEM_CACHE(ceph_dentry_info,
631 					SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD);
632 	if (ceph_dentry_cachep == NULL)
633 		goto bad_dentry;
634 
635 	ceph_file_cachep = KMEM_CACHE(ceph_file_info,
636 				      SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD);
637 	if (ceph_file_cachep == NULL)
638 		goto bad_file;
639 
640 	if ((error = ceph_fscache_register()))
641 		goto bad_file;
642 
643 	return 0;
644 bad_file:
645 	kmem_cache_destroy(ceph_dentry_cachep);
646 bad_dentry:
647 	kmem_cache_destroy(ceph_cap_cachep);
648 bad_cap:
649 	kmem_cache_destroy(ceph_inode_cachep);
650 	return error;
651 }
652 
653 static void destroy_caches(void)
654 {
655 	/*
656 	 * Make sure all delayed rcu free inodes are flushed before we
657 	 * destroy cache.
658 	 */
659 	rcu_barrier();
660 
661 	kmem_cache_destroy(ceph_inode_cachep);
662 	kmem_cache_destroy(ceph_cap_cachep);
663 	kmem_cache_destroy(ceph_dentry_cachep);
664 	kmem_cache_destroy(ceph_file_cachep);
665 
666 	ceph_fscache_unregister();
667 }
668 
669 
670 /*
671  * ceph_umount_begin - initiate forced umount.  Tear down down the
672  * mount, skipping steps that may hang while waiting for server(s).
673  */
674 static void ceph_umount_begin(struct super_block *sb)
675 {
676 	struct ceph_fs_client *fsc = ceph_sb_to_client(sb);
677 
678 	dout("ceph_umount_begin - starting forced umount\n");
679 	if (!fsc)
680 		return;
681 	fsc->mount_state = CEPH_MOUNT_SHUTDOWN;
682 	return;
683 }
684 
685 static const struct super_operations ceph_super_ops = {
686 	.alloc_inode	= ceph_alloc_inode,
687 	.destroy_inode	= ceph_destroy_inode,
688 	.write_inode    = ceph_write_inode,
689 	.drop_inode	= ceph_drop_inode,
690 	.sync_fs        = ceph_sync_fs,
691 	.put_super	= ceph_put_super,
692 	.show_options   = ceph_show_options,
693 	.statfs		= ceph_statfs,
694 	.umount_begin   = ceph_umount_begin,
695 };
696 
697 /*
698  * Bootstrap mount by opening the root directory.  Note the mount
699  * @started time from caller, and time out if this takes too long.
700  */
701 static struct dentry *open_root_dentry(struct ceph_fs_client *fsc,
702 				       const char *path,
703 				       unsigned long started)
704 {
705 	struct ceph_mds_client *mdsc = fsc->mdsc;
706 	struct ceph_mds_request *req = NULL;
707 	int err;
708 	struct dentry *root;
709 
710 	/* open dir */
711 	dout("open_root_inode opening '%s'\n", path);
712 	req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_GETATTR, USE_ANY_MDS);
713 	if (IS_ERR(req))
714 		return ERR_CAST(req);
715 	req->r_path1 = kstrdup(path, GFP_NOFS);
716 	req->r_ino1.ino = CEPH_INO_ROOT;
717 	req->r_ino1.snap = CEPH_NOSNAP;
718 	req->r_started = started;
719 	req->r_timeout = fsc->client->options->mount_timeout * HZ;
720 	req->r_args.getattr.mask = cpu_to_le32(CEPH_STAT_CAP_INODE);
721 	req->r_num_caps = 2;
722 	err = ceph_mdsc_do_request(mdsc, NULL, req);
723 	if (err == 0) {
724 		struct inode *inode = req->r_target_inode;
725 		req->r_target_inode = NULL;
726 		dout("open_root_inode success\n");
727 		if (ceph_ino(inode) == CEPH_INO_ROOT &&
728 		    fsc->sb->s_root == NULL) {
729 			root = d_make_root(inode);
730 			if (!root) {
731 				root = ERR_PTR(-ENOMEM);
732 				goto out;
733 			}
734 		} else {
735 			root = d_obtain_alias(inode);
736 		}
737 		ceph_init_dentry(root);
738 		dout("open_root_inode success, root dentry is %p\n", root);
739 	} else {
740 		root = ERR_PTR(err);
741 	}
742 out:
743 	ceph_mdsc_put_request(req);
744 	return root;
745 }
746 
747 
748 
749 
750 /*
751  * mount: join the ceph cluster, and open root directory.
752  */
753 static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc,
754 		      const char *path)
755 {
756 	int err;
757 	unsigned long started = jiffies;  /* note the start time */
758 	struct dentry *root;
759 	int first = 0;   /* first vfsmount for this super_block */
760 
761 	dout("mount start\n");
762 	mutex_lock(&fsc->client->mount_mutex);
763 
764 	err = __ceph_open_session(fsc->client, started);
765 	if (err < 0)
766 		goto out;
767 
768 	dout("mount opening root\n");
769 	root = open_root_dentry(fsc, "", started);
770 	if (IS_ERR(root)) {
771 		err = PTR_ERR(root);
772 		goto out;
773 	}
774 	if (fsc->sb->s_root) {
775 		dput(root);
776 	} else {
777 		fsc->sb->s_root = root;
778 		first = 1;
779 
780 		err = ceph_fs_debugfs_init(fsc);
781 		if (err < 0)
782 			goto fail;
783 	}
784 
785 	if (path[0] == 0) {
786 		dget(root);
787 	} else {
788 		dout("mount opening base mountpoint\n");
789 		root = open_root_dentry(fsc, path, started);
790 		if (IS_ERR(root)) {
791 			err = PTR_ERR(root);
792 			goto fail;
793 		}
794 	}
795 
796 	fsc->mount_state = CEPH_MOUNT_MOUNTED;
797 	dout("mount success\n");
798 	mutex_unlock(&fsc->client->mount_mutex);
799 	return root;
800 
801 out:
802 	mutex_unlock(&fsc->client->mount_mutex);
803 	return ERR_PTR(err);
804 
805 fail:
806 	if (first) {
807 		dput(fsc->sb->s_root);
808 		fsc->sb->s_root = NULL;
809 	}
810 	goto out;
811 }
812 
813 static int ceph_set_super(struct super_block *s, void *data)
814 {
815 	struct ceph_fs_client *fsc = data;
816 	int ret;
817 
818 	dout("set_super %p data %p\n", s, data);
819 
820 	s->s_flags = fsc->mount_options->sb_flags;
821 	s->s_maxbytes = 1ULL << 40;  /* temp value until we get mdsmap */
822 #ifdef CONFIG_CEPH_FS_POSIX_ACL
823 	s->s_flags |= MS_POSIXACL;
824 #endif
825 
826 	s->s_xattr = ceph_xattr_handlers;
827 	s->s_fs_info = fsc;
828 	fsc->sb = s;
829 
830 	s->s_op = &ceph_super_ops;
831 	s->s_export_op = &ceph_export_ops;
832 
833 	s->s_time_gran = 1000;  /* 1000 ns == 1 us */
834 
835 	ret = set_anon_super(s, NULL);  /* what is that second arg for? */
836 	if (ret != 0)
837 		goto fail;
838 
839 	return ret;
840 
841 fail:
842 	s->s_fs_info = NULL;
843 	fsc->sb = NULL;
844 	return ret;
845 }
846 
847 /*
848  * share superblock if same fs AND options
849  */
850 static int ceph_compare_super(struct super_block *sb, void *data)
851 {
852 	struct ceph_fs_client *new = data;
853 	struct ceph_mount_options *fsopt = new->mount_options;
854 	struct ceph_options *opt = new->client->options;
855 	struct ceph_fs_client *other = ceph_sb_to_client(sb);
856 
857 	dout("ceph_compare_super %p\n", sb);
858 
859 	if (compare_mount_options(fsopt, opt, other)) {
860 		dout("monitor(s)/mount options don't match\n");
861 		return 0;
862 	}
863 	if ((opt->flags & CEPH_OPT_FSID) &&
864 	    ceph_fsid_compare(&opt->fsid, &other->client->fsid)) {
865 		dout("fsid doesn't match\n");
866 		return 0;
867 	}
868 	if (fsopt->sb_flags != other->mount_options->sb_flags) {
869 		dout("flags differ\n");
870 		return 0;
871 	}
872 	return 1;
873 }
874 
875 /*
876  * construct our own bdi so we can control readahead, etc.
877  */
878 static atomic_long_t bdi_seq = ATOMIC_LONG_INIT(0);
879 
880 static int ceph_register_bdi(struct super_block *sb,
881 			     struct ceph_fs_client *fsc)
882 {
883 	int err;
884 
885 	/* set ra_pages based on rasize mount option? */
886 	if (fsc->mount_options->rasize >= PAGE_CACHE_SIZE)
887 		fsc->backing_dev_info.ra_pages =
888 			(fsc->mount_options->rasize + PAGE_CACHE_SIZE - 1)
889 			>> PAGE_SHIFT;
890 	else
891 		fsc->backing_dev_info.ra_pages =
892 			default_backing_dev_info.ra_pages;
893 
894 	err = bdi_register(&fsc->backing_dev_info, NULL, "ceph-%ld",
895 			   atomic_long_inc_return(&bdi_seq));
896 	if (!err)
897 		sb->s_bdi = &fsc->backing_dev_info;
898 	return err;
899 }
900 
901 static struct dentry *ceph_mount(struct file_system_type *fs_type,
902 		       int flags, const char *dev_name, void *data)
903 {
904 	struct super_block *sb;
905 	struct ceph_fs_client *fsc;
906 	struct dentry *res;
907 	int err;
908 	int (*compare_super)(struct super_block *, void *) = ceph_compare_super;
909 	const char *path = NULL;
910 	struct ceph_mount_options *fsopt = NULL;
911 	struct ceph_options *opt = NULL;
912 
913 	dout("ceph_mount\n");
914 	err = parse_mount_options(&fsopt, &opt, flags, data, dev_name, &path);
915 	if (err < 0) {
916 		res = ERR_PTR(err);
917 		goto out_final;
918 	}
919 
920 	/* create client (which we may/may not use) */
921 	fsc = create_fs_client(fsopt, opt);
922 	if (IS_ERR(fsc)) {
923 		res = ERR_CAST(fsc);
924 		destroy_mount_options(fsopt);
925 		ceph_destroy_options(opt);
926 		goto out_final;
927 	}
928 
929 	err = ceph_mdsc_init(fsc);
930 	if (err < 0) {
931 		res = ERR_PTR(err);
932 		goto out;
933 	}
934 
935 	if (ceph_test_opt(fsc->client, NOSHARE))
936 		compare_super = NULL;
937 	sb = sget(fs_type, compare_super, ceph_set_super, flags, fsc);
938 	if (IS_ERR(sb)) {
939 		res = ERR_CAST(sb);
940 		goto out;
941 	}
942 
943 	if (ceph_sb_to_client(sb) != fsc) {
944 		ceph_mdsc_destroy(fsc);
945 		destroy_fs_client(fsc);
946 		fsc = ceph_sb_to_client(sb);
947 		dout("get_sb got existing client %p\n", fsc);
948 	} else {
949 		dout("get_sb using new client %p\n", fsc);
950 		err = ceph_register_bdi(sb, fsc);
951 		if (err < 0) {
952 			res = ERR_PTR(err);
953 			goto out_splat;
954 		}
955 	}
956 
957 	res = ceph_real_mount(fsc, path);
958 	if (IS_ERR(res))
959 		goto out_splat;
960 	dout("root %p inode %p ino %llx.%llx\n", res,
961 	     res->d_inode, ceph_vinop(res->d_inode));
962 	return res;
963 
964 out_splat:
965 	ceph_mdsc_close_sessions(fsc->mdsc);
966 	deactivate_locked_super(sb);
967 	goto out_final;
968 
969 out:
970 	ceph_mdsc_destroy(fsc);
971 	destroy_fs_client(fsc);
972 out_final:
973 	dout("ceph_mount fail %ld\n", PTR_ERR(res));
974 	return res;
975 }
976 
977 static void ceph_kill_sb(struct super_block *s)
978 {
979 	struct ceph_fs_client *fsc = ceph_sb_to_client(s);
980 	dout("kill_sb %p\n", s);
981 	ceph_mdsc_pre_umount(fsc->mdsc);
982 	kill_anon_super(s);    /* will call put_super after sb is r/o */
983 	ceph_mdsc_destroy(fsc);
984 	destroy_fs_client(fsc);
985 }
986 
987 static struct file_system_type ceph_fs_type = {
988 	.owner		= THIS_MODULE,
989 	.name		= "ceph",
990 	.mount		= ceph_mount,
991 	.kill_sb	= ceph_kill_sb,
992 	.fs_flags	= FS_RENAME_DOES_D_MOVE,
993 };
994 MODULE_ALIAS_FS("ceph");
995 
996 #define _STRINGIFY(x) #x
997 #define STRINGIFY(x) _STRINGIFY(x)
998 
999 static int __init init_ceph(void)
1000 {
1001 	int ret = init_caches();
1002 	if (ret)
1003 		goto out;
1004 
1005 	ceph_xattr_init();
1006 	ret = register_filesystem(&ceph_fs_type);
1007 	if (ret)
1008 		goto out_icache;
1009 
1010 	pr_info("loaded (mds proto %d)\n", CEPH_MDSC_PROTOCOL);
1011 
1012 	return 0;
1013 
1014 out_icache:
1015 	ceph_xattr_exit();
1016 	destroy_caches();
1017 out:
1018 	return ret;
1019 }
1020 
1021 static void __exit exit_ceph(void)
1022 {
1023 	dout("exit_ceph\n");
1024 	unregister_filesystem(&ceph_fs_type);
1025 	ceph_xattr_exit();
1026 	destroy_caches();
1027 }
1028 
1029 module_init(init_ceph);
1030 module_exit(exit_ceph);
1031 
1032 MODULE_AUTHOR("Sage Weil <sage@newdream.net>");
1033 MODULE_AUTHOR("Yehuda Sadeh <yehuda@hq.newdream.net>");
1034 MODULE_AUTHOR("Patience Warnick <patience@newdream.net>");
1035 MODULE_DESCRIPTION("Ceph filesystem for Linux");
1036 MODULE_LICENSE("GPL");
1037