1 // SPDX-License-Identifier: GPL-2.0-only 2 3 #include <linux/ceph/ceph_debug.h> 4 5 #include <linux/backing-dev.h> 6 #include <linux/ctype.h> 7 #include <linux/fs.h> 8 #include <linux/inet.h> 9 #include <linux/in6.h> 10 #include <linux/module.h> 11 #include <linux/mount.h> 12 #include <linux/fs_context.h> 13 #include <linux/fs_parser.h> 14 #include <linux/sched.h> 15 #include <linux/seq_file.h> 16 #include <linux/slab.h> 17 #include <linux/statfs.h> 18 #include <linux/string.h> 19 20 #include "super.h" 21 #include "mds_client.h" 22 #include "cache.h" 23 24 #include <linux/ceph/ceph_features.h> 25 #include <linux/ceph/decode.h> 26 #include <linux/ceph/mon_client.h> 27 #include <linux/ceph/auth.h> 28 #include <linux/ceph/debugfs.h> 29 30 #include <uapi/linux/magic.h> 31 32 static DEFINE_SPINLOCK(ceph_fsc_lock); 33 static LIST_HEAD(ceph_fsc_list); 34 35 /* 36 * Ceph superblock operations 37 * 38 * Handle the basics of mounting, unmounting. 39 */ 40 41 /* 42 * super ops 43 */ 44 static void ceph_put_super(struct super_block *s) 45 { 46 struct ceph_fs_client *fsc = ceph_sb_to_client(s); 47 48 dout("put_super\n"); 49 ceph_mdsc_close_sessions(fsc->mdsc); 50 } 51 52 static int ceph_statfs(struct dentry *dentry, struct kstatfs *buf) 53 { 54 struct ceph_fs_client *fsc = ceph_inode_to_client(d_inode(dentry)); 55 struct ceph_mon_client *monc = &fsc->client->monc; 56 struct ceph_statfs st; 57 int i, err; 58 u64 data_pool; 59 60 if (fsc->mdsc->mdsmap->m_num_data_pg_pools == 1) { 61 data_pool = fsc->mdsc->mdsmap->m_data_pg_pools[0]; 62 } else { 63 data_pool = CEPH_NOPOOL; 64 } 65 66 dout("statfs\n"); 67 err = ceph_monc_do_statfs(monc, data_pool, &st); 68 if (err < 0) 69 return err; 70 71 /* fill in kstatfs */ 72 buf->f_type = CEPH_SUPER_MAGIC; /* ?? */ 73 74 /* 75 * Express utilization in terms of large blocks to avoid 76 * overflow on 32-bit machines. 77 */ 78 buf->f_frsize = 1 << CEPH_BLOCK_SHIFT; 79 80 /* 81 * By default use root quota for stats; fallback to overall filesystem 82 * usage if using 'noquotadf' mount option or if the root dir doesn't 83 * have max_bytes quota set. 84 */ 85 if (ceph_test_mount_opt(fsc, NOQUOTADF) || 86 !ceph_quota_update_statfs(fsc, buf)) { 87 buf->f_blocks = le64_to_cpu(st.kb) >> (CEPH_BLOCK_SHIFT-10); 88 buf->f_bfree = le64_to_cpu(st.kb_avail) >> (CEPH_BLOCK_SHIFT-10); 89 buf->f_bavail = le64_to_cpu(st.kb_avail) >> (CEPH_BLOCK_SHIFT-10); 90 } 91 92 /* 93 * NOTE: for the time being, we make bsize == frsize to humor 94 * not-yet-ancient versions of glibc that are broken. 95 * Someday, we will probably want to report a real block 96 * size... whatever that may mean for a network file system! 97 */ 98 buf->f_bsize = buf->f_frsize; 99 100 buf->f_files = le64_to_cpu(st.num_objects); 101 buf->f_ffree = -1; 102 buf->f_namelen = NAME_MAX; 103 104 /* Must convert the fsid, for consistent values across arches */ 105 buf->f_fsid.val[0] = 0; 106 mutex_lock(&monc->mutex); 107 for (i = 0 ; i < sizeof(monc->monmap->fsid) / sizeof(__le32) ; ++i) 108 buf->f_fsid.val[0] ^= le32_to_cpu(((__le32 *)&monc->monmap->fsid)[i]); 109 mutex_unlock(&monc->mutex); 110 111 /* fold the fs_cluster_id into the upper bits */ 112 buf->f_fsid.val[1] = monc->fs_cluster_id; 113 114 return 0; 115 } 116 117 static int ceph_sync_fs(struct super_block *sb, int wait) 118 { 119 struct ceph_fs_client *fsc = ceph_sb_to_client(sb); 120 121 if (!wait) { 122 dout("sync_fs (non-blocking)\n"); 123 ceph_flush_dirty_caps(fsc->mdsc); 124 dout("sync_fs (non-blocking) done\n"); 125 return 0; 126 } 127 128 dout("sync_fs (blocking)\n"); 129 ceph_osdc_sync(&fsc->client->osdc); 130 ceph_mdsc_sync(fsc->mdsc); 131 dout("sync_fs (blocking) done\n"); 132 return 0; 133 } 134 135 /* 136 * mount options 137 */ 138 enum { 139 Opt_wsize, 140 Opt_rsize, 141 Opt_rasize, 142 Opt_caps_wanted_delay_min, 143 Opt_caps_wanted_delay_max, 144 Opt_caps_max, 145 Opt_readdir_max_entries, 146 Opt_readdir_max_bytes, 147 Opt_congestion_kb, 148 /* int args above */ 149 Opt_snapdirname, 150 Opt_mds_namespace, 151 Opt_recover_session, 152 Opt_source, 153 Opt_mon_addr, 154 /* string args above */ 155 Opt_dirstat, 156 Opt_rbytes, 157 Opt_asyncreaddir, 158 Opt_dcache, 159 Opt_ino32, 160 Opt_fscache, 161 Opt_poolperm, 162 Opt_require_active_mds, 163 Opt_acl, 164 Opt_quotadf, 165 Opt_copyfrom, 166 Opt_wsync, 167 Opt_pagecache, 168 }; 169 170 enum ceph_recover_session_mode { 171 ceph_recover_session_no, 172 ceph_recover_session_clean 173 }; 174 175 static const struct constant_table ceph_param_recover[] = { 176 { "no", ceph_recover_session_no }, 177 { "clean", ceph_recover_session_clean }, 178 {} 179 }; 180 181 static const struct fs_parameter_spec ceph_mount_parameters[] = { 182 fsparam_flag_no ("acl", Opt_acl), 183 fsparam_flag_no ("asyncreaddir", Opt_asyncreaddir), 184 fsparam_s32 ("caps_max", Opt_caps_max), 185 fsparam_u32 ("caps_wanted_delay_max", Opt_caps_wanted_delay_max), 186 fsparam_u32 ("caps_wanted_delay_min", Opt_caps_wanted_delay_min), 187 fsparam_u32 ("write_congestion_kb", Opt_congestion_kb), 188 fsparam_flag_no ("copyfrom", Opt_copyfrom), 189 fsparam_flag_no ("dcache", Opt_dcache), 190 fsparam_flag_no ("dirstat", Opt_dirstat), 191 fsparam_flag_no ("fsc", Opt_fscache), // fsc|nofsc 192 fsparam_string ("fsc", Opt_fscache), // fsc=... 193 fsparam_flag_no ("ino32", Opt_ino32), 194 fsparam_string ("mds_namespace", Opt_mds_namespace), 195 fsparam_flag_no ("poolperm", Opt_poolperm), 196 fsparam_flag_no ("quotadf", Opt_quotadf), 197 fsparam_u32 ("rasize", Opt_rasize), 198 fsparam_flag_no ("rbytes", Opt_rbytes), 199 fsparam_u32 ("readdir_max_bytes", Opt_readdir_max_bytes), 200 fsparam_u32 ("readdir_max_entries", Opt_readdir_max_entries), 201 fsparam_enum ("recover_session", Opt_recover_session, ceph_param_recover), 202 fsparam_flag_no ("require_active_mds", Opt_require_active_mds), 203 fsparam_u32 ("rsize", Opt_rsize), 204 fsparam_string ("snapdirname", Opt_snapdirname), 205 fsparam_string ("source", Opt_source), 206 fsparam_string ("mon_addr", Opt_mon_addr), 207 fsparam_u32 ("wsize", Opt_wsize), 208 fsparam_flag_no ("wsync", Opt_wsync), 209 fsparam_flag_no ("pagecache", Opt_pagecache), 210 {} 211 }; 212 213 struct ceph_parse_opts_ctx { 214 struct ceph_options *copts; 215 struct ceph_mount_options *opts; 216 }; 217 218 /* 219 * Remove adjacent slashes and then the trailing slash, unless it is 220 * the only remaining character. 221 * 222 * E.g. "//dir1////dir2///" --> "/dir1/dir2", "///" --> "/". 223 */ 224 static void canonicalize_path(char *path) 225 { 226 int i, j = 0; 227 228 for (i = 0; path[i] != '\0'; i++) { 229 if (path[i] != '/' || j < 1 || path[j - 1] != '/') 230 path[j++] = path[i]; 231 } 232 233 if (j > 1 && path[j - 1] == '/') 234 j--; 235 path[j] = '\0'; 236 } 237 238 /* 239 * Check if the mds namespace in ceph_mount_options matches 240 * the passed in namespace string. First time match (when 241 * ->mds_namespace is NULL) is treated specially, since 242 * ->mds_namespace needs to be initialized by the caller. 243 */ 244 static int namespace_equals(struct ceph_mount_options *fsopt, 245 const char *namespace, size_t len) 246 { 247 return !(fsopt->mds_namespace && 248 (strlen(fsopt->mds_namespace) != len || 249 strncmp(fsopt->mds_namespace, namespace, len))); 250 } 251 252 static int ceph_parse_old_source(const char *dev_name, const char *dev_name_end, 253 struct fs_context *fc) 254 { 255 int r; 256 struct ceph_parse_opts_ctx *pctx = fc->fs_private; 257 struct ceph_mount_options *fsopt = pctx->opts; 258 259 if (*dev_name_end != ':') 260 return invalfc(fc, "separator ':' missing in source"); 261 262 r = ceph_parse_mon_ips(dev_name, dev_name_end - dev_name, 263 pctx->copts, fc->log.log, ','); 264 if (r) 265 return r; 266 267 fsopt->new_dev_syntax = false; 268 return 0; 269 } 270 271 static int ceph_parse_new_source(const char *dev_name, const char *dev_name_end, 272 struct fs_context *fc) 273 { 274 size_t len; 275 struct ceph_fsid fsid; 276 struct ceph_parse_opts_ctx *pctx = fc->fs_private; 277 struct ceph_mount_options *fsopt = pctx->opts; 278 char *fsid_start, *fs_name_start; 279 280 if (*dev_name_end != '=') { 281 dout("separator '=' missing in source"); 282 return -EINVAL; 283 } 284 285 fsid_start = strchr(dev_name, '@'); 286 if (!fsid_start) 287 return invalfc(fc, "missing cluster fsid"); 288 ++fsid_start; /* start of cluster fsid */ 289 290 fs_name_start = strchr(fsid_start, '.'); 291 if (!fs_name_start) 292 return invalfc(fc, "missing file system name"); 293 294 if (ceph_parse_fsid(fsid_start, &fsid)) 295 return invalfc(fc, "Invalid FSID"); 296 297 ++fs_name_start; /* start of file system name */ 298 len = dev_name_end - fs_name_start; 299 300 if (!namespace_equals(fsopt, fs_name_start, len)) 301 return invalfc(fc, "Mismatching mds_namespace"); 302 kfree(fsopt->mds_namespace); 303 fsopt->mds_namespace = kstrndup(fs_name_start, len, GFP_KERNEL); 304 if (!fsopt->mds_namespace) 305 return -ENOMEM; 306 dout("file system (mds namespace) '%s'\n", fsopt->mds_namespace); 307 308 fsopt->new_dev_syntax = true; 309 return 0; 310 } 311 312 /* 313 * Parse the source parameter for new device format. Distinguish the device 314 * spec from the path. Try parsing new device format and fallback to old 315 * format if needed. 316 * 317 * New device syntax will looks like: 318 * <device_spec>=/<path> 319 * where 320 * <device_spec> is name@fsid.fsname 321 * <path> is optional, but if present must begin with '/' 322 * (monitor addresses are passed via mount option) 323 * 324 * Old device syntax is: 325 * <server_spec>[,<server_spec>...]:[<path>] 326 * where 327 * <server_spec> is <ip>[:<port>] 328 * <path> is optional, but if present must begin with '/' 329 */ 330 static int ceph_parse_source(struct fs_parameter *param, struct fs_context *fc) 331 { 332 struct ceph_parse_opts_ctx *pctx = fc->fs_private; 333 struct ceph_mount_options *fsopt = pctx->opts; 334 char *dev_name = param->string, *dev_name_end; 335 int ret; 336 337 dout("%s '%s'\n", __func__, dev_name); 338 if (!dev_name || !*dev_name) 339 return invalfc(fc, "Empty source"); 340 341 dev_name_end = strchr(dev_name, '/'); 342 if (dev_name_end) { 343 /* 344 * The server_path will include the whole chars from userland 345 * including the leading '/'. 346 */ 347 kfree(fsopt->server_path); 348 fsopt->server_path = kstrdup(dev_name_end, GFP_KERNEL); 349 if (!fsopt->server_path) 350 return -ENOMEM; 351 352 canonicalize_path(fsopt->server_path); 353 } else { 354 dev_name_end = dev_name + strlen(dev_name); 355 } 356 357 dev_name_end--; /* back up to separator */ 358 if (dev_name_end < dev_name) 359 return invalfc(fc, "Path missing in source"); 360 361 dout("device name '%.*s'\n", (int)(dev_name_end - dev_name), dev_name); 362 if (fsopt->server_path) 363 dout("server path '%s'\n", fsopt->server_path); 364 365 dout("trying new device syntax"); 366 ret = ceph_parse_new_source(dev_name, dev_name_end, fc); 367 if (ret) { 368 if (ret != -EINVAL) 369 return ret; 370 dout("trying old device syntax"); 371 ret = ceph_parse_old_source(dev_name, dev_name_end, fc); 372 if (ret) 373 return ret; 374 } 375 376 fc->source = param->string; 377 param->string = NULL; 378 return 0; 379 } 380 381 static int ceph_parse_mon_addr(struct fs_parameter *param, 382 struct fs_context *fc) 383 { 384 struct ceph_parse_opts_ctx *pctx = fc->fs_private; 385 struct ceph_mount_options *fsopt = pctx->opts; 386 387 kfree(fsopt->mon_addr); 388 fsopt->mon_addr = param->string; 389 param->string = NULL; 390 391 return ceph_parse_mon_ips(fsopt->mon_addr, strlen(fsopt->mon_addr), 392 pctx->copts, fc->log.log, '/'); 393 } 394 395 static int ceph_parse_mount_param(struct fs_context *fc, 396 struct fs_parameter *param) 397 { 398 struct ceph_parse_opts_ctx *pctx = fc->fs_private; 399 struct ceph_mount_options *fsopt = pctx->opts; 400 struct fs_parse_result result; 401 unsigned int mode; 402 int token, ret; 403 404 ret = ceph_parse_param(param, pctx->copts, fc->log.log); 405 if (ret != -ENOPARAM) 406 return ret; 407 408 token = fs_parse(fc, ceph_mount_parameters, param, &result); 409 dout("%s fs_parse '%s' token %d\n", __func__, param->key, token); 410 if (token < 0) 411 return token; 412 413 switch (token) { 414 case Opt_snapdirname: 415 kfree(fsopt->snapdir_name); 416 fsopt->snapdir_name = param->string; 417 param->string = NULL; 418 break; 419 case Opt_mds_namespace: 420 if (!namespace_equals(fsopt, param->string, strlen(param->string))) 421 return invalfc(fc, "Mismatching mds_namespace"); 422 kfree(fsopt->mds_namespace); 423 fsopt->mds_namespace = param->string; 424 param->string = NULL; 425 break; 426 case Opt_recover_session: 427 mode = result.uint_32; 428 if (mode == ceph_recover_session_no) 429 fsopt->flags &= ~CEPH_MOUNT_OPT_CLEANRECOVER; 430 else if (mode == ceph_recover_session_clean) 431 fsopt->flags |= CEPH_MOUNT_OPT_CLEANRECOVER; 432 else 433 BUG(); 434 break; 435 case Opt_source: 436 if (fc->source) 437 return invalfc(fc, "Multiple sources specified"); 438 return ceph_parse_source(param, fc); 439 case Opt_mon_addr: 440 return ceph_parse_mon_addr(param, fc); 441 case Opt_wsize: 442 if (result.uint_32 < PAGE_SIZE || 443 result.uint_32 > CEPH_MAX_WRITE_SIZE) 444 goto out_of_range; 445 fsopt->wsize = ALIGN(result.uint_32, PAGE_SIZE); 446 break; 447 case Opt_rsize: 448 if (result.uint_32 < PAGE_SIZE || 449 result.uint_32 > CEPH_MAX_READ_SIZE) 450 goto out_of_range; 451 fsopt->rsize = ALIGN(result.uint_32, PAGE_SIZE); 452 break; 453 case Opt_rasize: 454 fsopt->rasize = ALIGN(result.uint_32, PAGE_SIZE); 455 break; 456 case Opt_caps_wanted_delay_min: 457 if (result.uint_32 < 1) 458 goto out_of_range; 459 fsopt->caps_wanted_delay_min = result.uint_32; 460 break; 461 case Opt_caps_wanted_delay_max: 462 if (result.uint_32 < 1) 463 goto out_of_range; 464 fsopt->caps_wanted_delay_max = result.uint_32; 465 break; 466 case Opt_caps_max: 467 if (result.int_32 < 0) 468 goto out_of_range; 469 fsopt->caps_max = result.int_32; 470 break; 471 case Opt_readdir_max_entries: 472 if (result.uint_32 < 1) 473 goto out_of_range; 474 fsopt->max_readdir = result.uint_32; 475 break; 476 case Opt_readdir_max_bytes: 477 if (result.uint_32 < PAGE_SIZE && result.uint_32 != 0) 478 goto out_of_range; 479 fsopt->max_readdir_bytes = result.uint_32; 480 break; 481 case Opt_congestion_kb: 482 if (result.uint_32 < 1024) /* at least 1M */ 483 goto out_of_range; 484 fsopt->congestion_kb = result.uint_32; 485 break; 486 case Opt_dirstat: 487 if (!result.negated) 488 fsopt->flags |= CEPH_MOUNT_OPT_DIRSTAT; 489 else 490 fsopt->flags &= ~CEPH_MOUNT_OPT_DIRSTAT; 491 break; 492 case Opt_rbytes: 493 if (!result.negated) 494 fsopt->flags |= CEPH_MOUNT_OPT_RBYTES; 495 else 496 fsopt->flags &= ~CEPH_MOUNT_OPT_RBYTES; 497 break; 498 case Opt_asyncreaddir: 499 if (!result.negated) 500 fsopt->flags &= ~CEPH_MOUNT_OPT_NOASYNCREADDIR; 501 else 502 fsopt->flags |= CEPH_MOUNT_OPT_NOASYNCREADDIR; 503 break; 504 case Opt_dcache: 505 if (!result.negated) 506 fsopt->flags |= CEPH_MOUNT_OPT_DCACHE; 507 else 508 fsopt->flags &= ~CEPH_MOUNT_OPT_DCACHE; 509 break; 510 case Opt_ino32: 511 if (!result.negated) 512 fsopt->flags |= CEPH_MOUNT_OPT_INO32; 513 else 514 fsopt->flags &= ~CEPH_MOUNT_OPT_INO32; 515 break; 516 517 case Opt_fscache: 518 #ifdef CONFIG_CEPH_FSCACHE 519 kfree(fsopt->fscache_uniq); 520 fsopt->fscache_uniq = NULL; 521 if (result.negated) { 522 fsopt->flags &= ~CEPH_MOUNT_OPT_FSCACHE; 523 } else { 524 fsopt->flags |= CEPH_MOUNT_OPT_FSCACHE; 525 fsopt->fscache_uniq = param->string; 526 param->string = NULL; 527 } 528 break; 529 #else 530 return invalfc(fc, "fscache support is disabled"); 531 #endif 532 case Opt_poolperm: 533 if (!result.negated) 534 fsopt->flags &= ~CEPH_MOUNT_OPT_NOPOOLPERM; 535 else 536 fsopt->flags |= CEPH_MOUNT_OPT_NOPOOLPERM; 537 break; 538 case Opt_require_active_mds: 539 if (!result.negated) 540 fsopt->flags &= ~CEPH_MOUNT_OPT_MOUNTWAIT; 541 else 542 fsopt->flags |= CEPH_MOUNT_OPT_MOUNTWAIT; 543 break; 544 case Opt_quotadf: 545 if (!result.negated) 546 fsopt->flags &= ~CEPH_MOUNT_OPT_NOQUOTADF; 547 else 548 fsopt->flags |= CEPH_MOUNT_OPT_NOQUOTADF; 549 break; 550 case Opt_copyfrom: 551 if (!result.negated) 552 fsopt->flags &= ~CEPH_MOUNT_OPT_NOCOPYFROM; 553 else 554 fsopt->flags |= CEPH_MOUNT_OPT_NOCOPYFROM; 555 break; 556 case Opt_acl: 557 if (!result.negated) { 558 #ifdef CONFIG_CEPH_FS_POSIX_ACL 559 fc->sb_flags |= SB_POSIXACL; 560 #else 561 return invalfc(fc, "POSIX ACL support is disabled"); 562 #endif 563 } else { 564 fc->sb_flags &= ~SB_POSIXACL; 565 } 566 break; 567 case Opt_wsync: 568 if (!result.negated) 569 fsopt->flags &= ~CEPH_MOUNT_OPT_ASYNC_DIROPS; 570 else 571 fsopt->flags |= CEPH_MOUNT_OPT_ASYNC_DIROPS; 572 break; 573 case Opt_pagecache: 574 if (result.negated) 575 fsopt->flags |= CEPH_MOUNT_OPT_NOPAGECACHE; 576 else 577 fsopt->flags &= ~CEPH_MOUNT_OPT_NOPAGECACHE; 578 break; 579 default: 580 BUG(); 581 } 582 return 0; 583 584 out_of_range: 585 return invalfc(fc, "%s out of range", param->key); 586 } 587 588 static void destroy_mount_options(struct ceph_mount_options *args) 589 { 590 dout("destroy_mount_options %p\n", args); 591 if (!args) 592 return; 593 594 kfree(args->snapdir_name); 595 kfree(args->mds_namespace); 596 kfree(args->server_path); 597 kfree(args->fscache_uniq); 598 kfree(args->mon_addr); 599 kfree(args); 600 } 601 602 static int strcmp_null(const char *s1, const char *s2) 603 { 604 if (!s1 && !s2) 605 return 0; 606 if (s1 && !s2) 607 return -1; 608 if (!s1 && s2) 609 return 1; 610 return strcmp(s1, s2); 611 } 612 613 static int compare_mount_options(struct ceph_mount_options *new_fsopt, 614 struct ceph_options *new_opt, 615 struct ceph_fs_client *fsc) 616 { 617 struct ceph_mount_options *fsopt1 = new_fsopt; 618 struct ceph_mount_options *fsopt2 = fsc->mount_options; 619 int ofs = offsetof(struct ceph_mount_options, snapdir_name); 620 int ret; 621 622 ret = memcmp(fsopt1, fsopt2, ofs); 623 if (ret) 624 return ret; 625 626 ret = strcmp_null(fsopt1->snapdir_name, fsopt2->snapdir_name); 627 if (ret) 628 return ret; 629 630 ret = strcmp_null(fsopt1->mds_namespace, fsopt2->mds_namespace); 631 if (ret) 632 return ret; 633 634 ret = strcmp_null(fsopt1->server_path, fsopt2->server_path); 635 if (ret) 636 return ret; 637 638 ret = strcmp_null(fsopt1->fscache_uniq, fsopt2->fscache_uniq); 639 if (ret) 640 return ret; 641 642 ret = strcmp_null(fsopt1->mon_addr, fsopt2->mon_addr); 643 if (ret) 644 return ret; 645 646 return ceph_compare_options(new_opt, fsc->client); 647 } 648 649 /** 650 * ceph_show_options - Show mount options in /proc/mounts 651 * @m: seq_file to write to 652 * @root: root of that (sub)tree 653 */ 654 static int ceph_show_options(struct seq_file *m, struct dentry *root) 655 { 656 struct ceph_fs_client *fsc = ceph_sb_to_client(root->d_sb); 657 struct ceph_mount_options *fsopt = fsc->mount_options; 658 size_t pos; 659 int ret; 660 661 /* a comma between MNT/MS and client options */ 662 seq_putc(m, ','); 663 pos = m->count; 664 665 ret = ceph_print_client_options(m, fsc->client, false); 666 if (ret) 667 return ret; 668 669 /* retract our comma if no client options */ 670 if (m->count == pos) 671 m->count--; 672 673 if (fsopt->flags & CEPH_MOUNT_OPT_DIRSTAT) 674 seq_puts(m, ",dirstat"); 675 if ((fsopt->flags & CEPH_MOUNT_OPT_RBYTES)) 676 seq_puts(m, ",rbytes"); 677 if (fsopt->flags & CEPH_MOUNT_OPT_NOASYNCREADDIR) 678 seq_puts(m, ",noasyncreaddir"); 679 if ((fsopt->flags & CEPH_MOUNT_OPT_DCACHE) == 0) 680 seq_puts(m, ",nodcache"); 681 if (fsopt->flags & CEPH_MOUNT_OPT_INO32) 682 seq_puts(m, ",ino32"); 683 if (fsopt->flags & CEPH_MOUNT_OPT_FSCACHE) { 684 seq_show_option(m, "fsc", fsopt->fscache_uniq); 685 } 686 if (fsopt->flags & CEPH_MOUNT_OPT_NOPOOLPERM) 687 seq_puts(m, ",nopoolperm"); 688 if (fsopt->flags & CEPH_MOUNT_OPT_NOQUOTADF) 689 seq_puts(m, ",noquotadf"); 690 691 #ifdef CONFIG_CEPH_FS_POSIX_ACL 692 if (root->d_sb->s_flags & SB_POSIXACL) 693 seq_puts(m, ",acl"); 694 else 695 seq_puts(m, ",noacl"); 696 #endif 697 698 if ((fsopt->flags & CEPH_MOUNT_OPT_NOCOPYFROM) == 0) 699 seq_puts(m, ",copyfrom"); 700 701 /* dump mds_namespace when old device syntax is in use */ 702 if (fsopt->mds_namespace && !fsopt->new_dev_syntax) 703 seq_show_option(m, "mds_namespace", fsopt->mds_namespace); 704 705 if (fsopt->mon_addr) 706 seq_printf(m, ",mon_addr=%s", fsopt->mon_addr); 707 708 if (fsopt->flags & CEPH_MOUNT_OPT_CLEANRECOVER) 709 seq_show_option(m, "recover_session", "clean"); 710 711 if (!(fsopt->flags & CEPH_MOUNT_OPT_ASYNC_DIROPS)) 712 seq_puts(m, ",wsync"); 713 714 if (fsopt->flags & CEPH_MOUNT_OPT_NOPAGECACHE) 715 seq_puts(m, ",nopagecache"); 716 717 if (fsopt->wsize != CEPH_MAX_WRITE_SIZE) 718 seq_printf(m, ",wsize=%u", fsopt->wsize); 719 if (fsopt->rsize != CEPH_MAX_READ_SIZE) 720 seq_printf(m, ",rsize=%u", fsopt->rsize); 721 if (fsopt->rasize != CEPH_RASIZE_DEFAULT) 722 seq_printf(m, ",rasize=%u", fsopt->rasize); 723 if (fsopt->congestion_kb != default_congestion_kb()) 724 seq_printf(m, ",write_congestion_kb=%u", fsopt->congestion_kb); 725 if (fsopt->caps_max) 726 seq_printf(m, ",caps_max=%d", fsopt->caps_max); 727 if (fsopt->caps_wanted_delay_min != CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT) 728 seq_printf(m, ",caps_wanted_delay_min=%u", 729 fsopt->caps_wanted_delay_min); 730 if (fsopt->caps_wanted_delay_max != CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT) 731 seq_printf(m, ",caps_wanted_delay_max=%u", 732 fsopt->caps_wanted_delay_max); 733 if (fsopt->max_readdir != CEPH_MAX_READDIR_DEFAULT) 734 seq_printf(m, ",readdir_max_entries=%u", fsopt->max_readdir); 735 if (fsopt->max_readdir_bytes != CEPH_MAX_READDIR_BYTES_DEFAULT) 736 seq_printf(m, ",readdir_max_bytes=%u", fsopt->max_readdir_bytes); 737 if (strcmp(fsopt->snapdir_name, CEPH_SNAPDIRNAME_DEFAULT)) 738 seq_show_option(m, "snapdirname", fsopt->snapdir_name); 739 740 return 0; 741 } 742 743 /* 744 * handle any mon messages the standard library doesn't understand. 745 * return error if we don't either. 746 */ 747 static int extra_mon_dispatch(struct ceph_client *client, struct ceph_msg *msg) 748 { 749 struct ceph_fs_client *fsc = client->private; 750 int type = le16_to_cpu(msg->hdr.type); 751 752 switch (type) { 753 case CEPH_MSG_MDS_MAP: 754 ceph_mdsc_handle_mdsmap(fsc->mdsc, msg); 755 return 0; 756 case CEPH_MSG_FS_MAP_USER: 757 ceph_mdsc_handle_fsmap(fsc->mdsc, msg); 758 return 0; 759 default: 760 return -1; 761 } 762 } 763 764 /* 765 * create a new fs client 766 * 767 * Success or not, this function consumes @fsopt and @opt. 768 */ 769 static struct ceph_fs_client *create_fs_client(struct ceph_mount_options *fsopt, 770 struct ceph_options *opt) 771 { 772 struct ceph_fs_client *fsc; 773 int err; 774 775 fsc = kzalloc(sizeof(*fsc), GFP_KERNEL); 776 if (!fsc) { 777 err = -ENOMEM; 778 goto fail; 779 } 780 781 fsc->client = ceph_create_client(opt, fsc); 782 if (IS_ERR(fsc->client)) { 783 err = PTR_ERR(fsc->client); 784 goto fail; 785 } 786 opt = NULL; /* fsc->client now owns this */ 787 788 fsc->client->extra_mon_dispatch = extra_mon_dispatch; 789 ceph_set_opt(fsc->client, ABORT_ON_FULL); 790 791 if (!fsopt->mds_namespace) { 792 ceph_monc_want_map(&fsc->client->monc, CEPH_SUB_MDSMAP, 793 0, true); 794 } else { 795 ceph_monc_want_map(&fsc->client->monc, CEPH_SUB_FSMAP, 796 0, false); 797 } 798 799 fsc->mount_options = fsopt; 800 801 fsc->sb = NULL; 802 fsc->mount_state = CEPH_MOUNT_MOUNTING; 803 fsc->filp_gen = 1; 804 fsc->have_copy_from2 = true; 805 806 atomic_long_set(&fsc->writeback_count, 0); 807 fsc->write_congested = false; 808 809 err = -ENOMEM; 810 /* 811 * The number of concurrent works can be high but they don't need 812 * to be processed in parallel, limit concurrency. 813 */ 814 fsc->inode_wq = alloc_workqueue("ceph-inode", WQ_UNBOUND, 0); 815 if (!fsc->inode_wq) 816 goto fail_client; 817 fsc->cap_wq = alloc_workqueue("ceph-cap", 0, 1); 818 if (!fsc->cap_wq) 819 goto fail_inode_wq; 820 821 hash_init(fsc->async_unlink_conflict); 822 spin_lock_init(&fsc->async_unlink_conflict_lock); 823 824 spin_lock(&ceph_fsc_lock); 825 list_add_tail(&fsc->metric_wakeup, &ceph_fsc_list); 826 spin_unlock(&ceph_fsc_lock); 827 828 return fsc; 829 830 fail_inode_wq: 831 destroy_workqueue(fsc->inode_wq); 832 fail_client: 833 ceph_destroy_client(fsc->client); 834 fail: 835 kfree(fsc); 836 if (opt) 837 ceph_destroy_options(opt); 838 destroy_mount_options(fsopt); 839 return ERR_PTR(err); 840 } 841 842 static void flush_fs_workqueues(struct ceph_fs_client *fsc) 843 { 844 flush_workqueue(fsc->inode_wq); 845 flush_workqueue(fsc->cap_wq); 846 } 847 848 static void destroy_fs_client(struct ceph_fs_client *fsc) 849 { 850 dout("destroy_fs_client %p\n", fsc); 851 852 spin_lock(&ceph_fsc_lock); 853 list_del(&fsc->metric_wakeup); 854 spin_unlock(&ceph_fsc_lock); 855 856 ceph_mdsc_destroy(fsc); 857 destroy_workqueue(fsc->inode_wq); 858 destroy_workqueue(fsc->cap_wq); 859 860 destroy_mount_options(fsc->mount_options); 861 862 ceph_destroy_client(fsc->client); 863 864 kfree(fsc); 865 dout("destroy_fs_client %p done\n", fsc); 866 } 867 868 /* 869 * caches 870 */ 871 struct kmem_cache *ceph_inode_cachep; 872 struct kmem_cache *ceph_cap_cachep; 873 struct kmem_cache *ceph_cap_snap_cachep; 874 struct kmem_cache *ceph_cap_flush_cachep; 875 struct kmem_cache *ceph_dentry_cachep; 876 struct kmem_cache *ceph_file_cachep; 877 struct kmem_cache *ceph_dir_file_cachep; 878 struct kmem_cache *ceph_mds_request_cachep; 879 mempool_t *ceph_wb_pagevec_pool; 880 881 static void ceph_inode_init_once(void *foo) 882 { 883 struct ceph_inode_info *ci = foo; 884 inode_init_once(&ci->netfs.inode); 885 } 886 887 static int __init init_caches(void) 888 { 889 int error = -ENOMEM; 890 891 ceph_inode_cachep = kmem_cache_create("ceph_inode_info", 892 sizeof(struct ceph_inode_info), 893 __alignof__(struct ceph_inode_info), 894 SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD| 895 SLAB_ACCOUNT, ceph_inode_init_once); 896 if (!ceph_inode_cachep) 897 return -ENOMEM; 898 899 ceph_cap_cachep = KMEM_CACHE(ceph_cap, SLAB_MEM_SPREAD); 900 if (!ceph_cap_cachep) 901 goto bad_cap; 902 ceph_cap_snap_cachep = KMEM_CACHE(ceph_cap_snap, SLAB_MEM_SPREAD); 903 if (!ceph_cap_snap_cachep) 904 goto bad_cap_snap; 905 ceph_cap_flush_cachep = KMEM_CACHE(ceph_cap_flush, 906 SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD); 907 if (!ceph_cap_flush_cachep) 908 goto bad_cap_flush; 909 910 ceph_dentry_cachep = KMEM_CACHE(ceph_dentry_info, 911 SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD); 912 if (!ceph_dentry_cachep) 913 goto bad_dentry; 914 915 ceph_file_cachep = KMEM_CACHE(ceph_file_info, SLAB_MEM_SPREAD); 916 if (!ceph_file_cachep) 917 goto bad_file; 918 919 ceph_dir_file_cachep = KMEM_CACHE(ceph_dir_file_info, SLAB_MEM_SPREAD); 920 if (!ceph_dir_file_cachep) 921 goto bad_dir_file; 922 923 ceph_mds_request_cachep = KMEM_CACHE(ceph_mds_request, SLAB_MEM_SPREAD); 924 if (!ceph_mds_request_cachep) 925 goto bad_mds_req; 926 927 ceph_wb_pagevec_pool = mempool_create_kmalloc_pool(10, CEPH_MAX_WRITE_SIZE >> PAGE_SHIFT); 928 if (!ceph_wb_pagevec_pool) 929 goto bad_pagevec_pool; 930 931 return 0; 932 933 bad_pagevec_pool: 934 kmem_cache_destroy(ceph_mds_request_cachep); 935 bad_mds_req: 936 kmem_cache_destroy(ceph_dir_file_cachep); 937 bad_dir_file: 938 kmem_cache_destroy(ceph_file_cachep); 939 bad_file: 940 kmem_cache_destroy(ceph_dentry_cachep); 941 bad_dentry: 942 kmem_cache_destroy(ceph_cap_flush_cachep); 943 bad_cap_flush: 944 kmem_cache_destroy(ceph_cap_snap_cachep); 945 bad_cap_snap: 946 kmem_cache_destroy(ceph_cap_cachep); 947 bad_cap: 948 kmem_cache_destroy(ceph_inode_cachep); 949 return error; 950 } 951 952 static void destroy_caches(void) 953 { 954 /* 955 * Make sure all delayed rcu free inodes are flushed before we 956 * destroy cache. 957 */ 958 rcu_barrier(); 959 960 kmem_cache_destroy(ceph_inode_cachep); 961 kmem_cache_destroy(ceph_cap_cachep); 962 kmem_cache_destroy(ceph_cap_snap_cachep); 963 kmem_cache_destroy(ceph_cap_flush_cachep); 964 kmem_cache_destroy(ceph_dentry_cachep); 965 kmem_cache_destroy(ceph_file_cachep); 966 kmem_cache_destroy(ceph_dir_file_cachep); 967 kmem_cache_destroy(ceph_mds_request_cachep); 968 mempool_destroy(ceph_wb_pagevec_pool); 969 } 970 971 static void __ceph_umount_begin(struct ceph_fs_client *fsc) 972 { 973 ceph_osdc_abort_requests(&fsc->client->osdc, -EIO); 974 ceph_mdsc_force_umount(fsc->mdsc); 975 fsc->filp_gen++; // invalidate open files 976 } 977 978 /* 979 * ceph_umount_begin - initiate forced umount. Tear down the 980 * mount, skipping steps that may hang while waiting for server(s). 981 */ 982 void ceph_umount_begin(struct super_block *sb) 983 { 984 struct ceph_fs_client *fsc = ceph_sb_to_client(sb); 985 986 dout("ceph_umount_begin - starting forced umount\n"); 987 if (!fsc) 988 return; 989 fsc->mount_state = CEPH_MOUNT_SHUTDOWN; 990 __ceph_umount_begin(fsc); 991 } 992 993 static const struct super_operations ceph_super_ops = { 994 .alloc_inode = ceph_alloc_inode, 995 .free_inode = ceph_free_inode, 996 .write_inode = ceph_write_inode, 997 .drop_inode = generic_delete_inode, 998 .evict_inode = ceph_evict_inode, 999 .sync_fs = ceph_sync_fs, 1000 .put_super = ceph_put_super, 1001 .show_options = ceph_show_options, 1002 .statfs = ceph_statfs, 1003 .umount_begin = ceph_umount_begin, 1004 }; 1005 1006 /* 1007 * Bootstrap mount by opening the root directory. Note the mount 1008 * @started time from caller, and time out if this takes too long. 1009 */ 1010 static struct dentry *open_root_dentry(struct ceph_fs_client *fsc, 1011 const char *path, 1012 unsigned long started) 1013 { 1014 struct ceph_mds_client *mdsc = fsc->mdsc; 1015 struct ceph_mds_request *req = NULL; 1016 int err; 1017 struct dentry *root; 1018 1019 /* open dir */ 1020 dout("open_root_inode opening '%s'\n", path); 1021 req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_GETATTR, USE_ANY_MDS); 1022 if (IS_ERR(req)) 1023 return ERR_CAST(req); 1024 req->r_path1 = kstrdup(path, GFP_NOFS); 1025 if (!req->r_path1) { 1026 root = ERR_PTR(-ENOMEM); 1027 goto out; 1028 } 1029 1030 req->r_ino1.ino = CEPH_INO_ROOT; 1031 req->r_ino1.snap = CEPH_NOSNAP; 1032 req->r_started = started; 1033 req->r_timeout = fsc->client->options->mount_timeout; 1034 req->r_args.getattr.mask = cpu_to_le32(CEPH_STAT_CAP_INODE); 1035 req->r_num_caps = 2; 1036 err = ceph_mdsc_do_request(mdsc, NULL, req); 1037 if (err == 0) { 1038 struct inode *inode = req->r_target_inode; 1039 req->r_target_inode = NULL; 1040 dout("open_root_inode success\n"); 1041 root = d_make_root(inode); 1042 if (!root) { 1043 root = ERR_PTR(-ENOMEM); 1044 goto out; 1045 } 1046 dout("open_root_inode success, root dentry is %p\n", root); 1047 } else { 1048 root = ERR_PTR(err); 1049 } 1050 out: 1051 ceph_mdsc_put_request(req); 1052 return root; 1053 } 1054 1055 /* 1056 * mount: join the ceph cluster, and open root directory. 1057 */ 1058 static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc, 1059 struct fs_context *fc) 1060 { 1061 int err; 1062 unsigned long started = jiffies; /* note the start time */ 1063 struct dentry *root; 1064 1065 dout("mount start %p\n", fsc); 1066 mutex_lock(&fsc->client->mount_mutex); 1067 1068 if (!fsc->sb->s_root) { 1069 const char *path = fsc->mount_options->server_path ? 1070 fsc->mount_options->server_path + 1 : ""; 1071 1072 err = __ceph_open_session(fsc->client, started); 1073 if (err < 0) 1074 goto out; 1075 1076 /* setup fscache */ 1077 if (fsc->mount_options->flags & CEPH_MOUNT_OPT_FSCACHE) { 1078 err = ceph_fscache_register_fs(fsc, fc); 1079 if (err < 0) 1080 goto out; 1081 } 1082 1083 dout("mount opening path '%s'\n", path); 1084 1085 ceph_fs_debugfs_init(fsc); 1086 1087 root = open_root_dentry(fsc, path, started); 1088 if (IS_ERR(root)) { 1089 err = PTR_ERR(root); 1090 goto out; 1091 } 1092 fsc->sb->s_root = dget(root); 1093 } else { 1094 root = dget(fsc->sb->s_root); 1095 } 1096 1097 fsc->mount_state = CEPH_MOUNT_MOUNTED; 1098 dout("mount success\n"); 1099 mutex_unlock(&fsc->client->mount_mutex); 1100 return root; 1101 1102 out: 1103 mutex_unlock(&fsc->client->mount_mutex); 1104 return ERR_PTR(err); 1105 } 1106 1107 static int ceph_set_super(struct super_block *s, struct fs_context *fc) 1108 { 1109 struct ceph_fs_client *fsc = s->s_fs_info; 1110 int ret; 1111 1112 dout("set_super %p\n", s); 1113 1114 s->s_maxbytes = MAX_LFS_FILESIZE; 1115 1116 s->s_xattr = ceph_xattr_handlers; 1117 fsc->sb = s; 1118 fsc->max_file_size = 1ULL << 40; /* temp value until we get mdsmap */ 1119 1120 s->s_op = &ceph_super_ops; 1121 s->s_d_op = &ceph_dentry_ops; 1122 s->s_export_op = &ceph_export_ops; 1123 1124 s->s_time_gran = 1; 1125 s->s_time_min = 0; 1126 s->s_time_max = U32_MAX; 1127 s->s_flags |= SB_NODIRATIME | SB_NOATIME; 1128 1129 ret = set_anon_super_fc(s, fc); 1130 if (ret != 0) 1131 fsc->sb = NULL; 1132 return ret; 1133 } 1134 1135 /* 1136 * share superblock if same fs AND options 1137 */ 1138 static int ceph_compare_super(struct super_block *sb, struct fs_context *fc) 1139 { 1140 struct ceph_fs_client *new = fc->s_fs_info; 1141 struct ceph_mount_options *fsopt = new->mount_options; 1142 struct ceph_options *opt = new->client->options; 1143 struct ceph_fs_client *fsc = ceph_sb_to_client(sb); 1144 1145 dout("ceph_compare_super %p\n", sb); 1146 1147 if (compare_mount_options(fsopt, opt, fsc)) { 1148 dout("monitor(s)/mount options don't match\n"); 1149 return 0; 1150 } 1151 if ((opt->flags & CEPH_OPT_FSID) && 1152 ceph_fsid_compare(&opt->fsid, &fsc->client->fsid)) { 1153 dout("fsid doesn't match\n"); 1154 return 0; 1155 } 1156 if (fc->sb_flags != (sb->s_flags & ~SB_BORN)) { 1157 dout("flags differ\n"); 1158 return 0; 1159 } 1160 1161 if (fsc->blocklisted && !ceph_test_mount_opt(fsc, CLEANRECOVER)) { 1162 dout("client is blocklisted (and CLEANRECOVER is not set)\n"); 1163 return 0; 1164 } 1165 1166 if (fsc->mount_state == CEPH_MOUNT_SHUTDOWN) { 1167 dout("client has been forcibly unmounted\n"); 1168 return 0; 1169 } 1170 1171 return 1; 1172 } 1173 1174 /* 1175 * construct our own bdi so we can control readahead, etc. 1176 */ 1177 static atomic_long_t bdi_seq = ATOMIC_LONG_INIT(0); 1178 1179 static int ceph_setup_bdi(struct super_block *sb, struct ceph_fs_client *fsc) 1180 { 1181 int err; 1182 1183 err = super_setup_bdi_name(sb, "ceph-%ld", 1184 atomic_long_inc_return(&bdi_seq)); 1185 if (err) 1186 return err; 1187 1188 /* set ra_pages based on rasize mount option? */ 1189 sb->s_bdi->ra_pages = fsc->mount_options->rasize >> PAGE_SHIFT; 1190 1191 /* set io_pages based on max osd read size */ 1192 sb->s_bdi->io_pages = fsc->mount_options->rsize >> PAGE_SHIFT; 1193 1194 return 0; 1195 } 1196 1197 static int ceph_get_tree(struct fs_context *fc) 1198 { 1199 struct ceph_parse_opts_ctx *pctx = fc->fs_private; 1200 struct ceph_mount_options *fsopt = pctx->opts; 1201 struct super_block *sb; 1202 struct ceph_fs_client *fsc; 1203 struct dentry *res; 1204 int (*compare_super)(struct super_block *, struct fs_context *) = 1205 ceph_compare_super; 1206 int err; 1207 1208 dout("ceph_get_tree\n"); 1209 1210 if (!fc->source) 1211 return invalfc(fc, "No source"); 1212 if (fsopt->new_dev_syntax && !fsopt->mon_addr) 1213 return invalfc(fc, "No monitor address"); 1214 1215 /* create client (which we may/may not use) */ 1216 fsc = create_fs_client(pctx->opts, pctx->copts); 1217 pctx->opts = NULL; 1218 pctx->copts = NULL; 1219 if (IS_ERR(fsc)) { 1220 err = PTR_ERR(fsc); 1221 goto out_final; 1222 } 1223 1224 err = ceph_mdsc_init(fsc); 1225 if (err < 0) 1226 goto out; 1227 1228 if (ceph_test_opt(fsc->client, NOSHARE)) 1229 compare_super = NULL; 1230 1231 fc->s_fs_info = fsc; 1232 sb = sget_fc(fc, compare_super, ceph_set_super); 1233 fc->s_fs_info = NULL; 1234 if (IS_ERR(sb)) { 1235 err = PTR_ERR(sb); 1236 goto out; 1237 } 1238 1239 if (ceph_sb_to_client(sb) != fsc) { 1240 destroy_fs_client(fsc); 1241 fsc = ceph_sb_to_client(sb); 1242 dout("get_sb got existing client %p\n", fsc); 1243 } else { 1244 dout("get_sb using new client %p\n", fsc); 1245 err = ceph_setup_bdi(sb, fsc); 1246 if (err < 0) 1247 goto out_splat; 1248 } 1249 1250 res = ceph_real_mount(fsc, fc); 1251 if (IS_ERR(res)) { 1252 err = PTR_ERR(res); 1253 goto out_splat; 1254 } 1255 dout("root %p inode %p ino %llx.%llx\n", res, 1256 d_inode(res), ceph_vinop(d_inode(res))); 1257 fc->root = fsc->sb->s_root; 1258 return 0; 1259 1260 out_splat: 1261 if (!ceph_mdsmap_is_cluster_available(fsc->mdsc->mdsmap)) { 1262 pr_info("No mds server is up or the cluster is laggy\n"); 1263 err = -EHOSTUNREACH; 1264 } 1265 1266 ceph_mdsc_close_sessions(fsc->mdsc); 1267 deactivate_locked_super(sb); 1268 goto out_final; 1269 1270 out: 1271 destroy_fs_client(fsc); 1272 out_final: 1273 dout("ceph_get_tree fail %d\n", err); 1274 return err; 1275 } 1276 1277 static void ceph_free_fc(struct fs_context *fc) 1278 { 1279 struct ceph_parse_opts_ctx *pctx = fc->fs_private; 1280 1281 if (pctx) { 1282 destroy_mount_options(pctx->opts); 1283 ceph_destroy_options(pctx->copts); 1284 kfree(pctx); 1285 } 1286 } 1287 1288 static int ceph_reconfigure_fc(struct fs_context *fc) 1289 { 1290 struct ceph_parse_opts_ctx *pctx = fc->fs_private; 1291 struct ceph_mount_options *fsopt = pctx->opts; 1292 struct ceph_fs_client *fsc = ceph_sb_to_client(fc->root->d_sb); 1293 1294 if (fsopt->flags & CEPH_MOUNT_OPT_ASYNC_DIROPS) 1295 ceph_set_mount_opt(fsc, ASYNC_DIROPS); 1296 else 1297 ceph_clear_mount_opt(fsc, ASYNC_DIROPS); 1298 1299 if (strcmp_null(fsc->mount_options->mon_addr, fsopt->mon_addr)) { 1300 kfree(fsc->mount_options->mon_addr); 1301 fsc->mount_options->mon_addr = fsopt->mon_addr; 1302 fsopt->mon_addr = NULL; 1303 pr_notice("ceph: monitor addresses recorded, but not used for reconnection"); 1304 } 1305 1306 sync_filesystem(fc->root->d_sb); 1307 return 0; 1308 } 1309 1310 static const struct fs_context_operations ceph_context_ops = { 1311 .free = ceph_free_fc, 1312 .parse_param = ceph_parse_mount_param, 1313 .get_tree = ceph_get_tree, 1314 .reconfigure = ceph_reconfigure_fc, 1315 }; 1316 1317 /* 1318 * Set up the filesystem mount context. 1319 */ 1320 static int ceph_init_fs_context(struct fs_context *fc) 1321 { 1322 struct ceph_parse_opts_ctx *pctx; 1323 struct ceph_mount_options *fsopt; 1324 1325 pctx = kzalloc(sizeof(*pctx), GFP_KERNEL); 1326 if (!pctx) 1327 return -ENOMEM; 1328 1329 pctx->copts = ceph_alloc_options(); 1330 if (!pctx->copts) 1331 goto nomem; 1332 1333 pctx->opts = kzalloc(sizeof(*pctx->opts), GFP_KERNEL); 1334 if (!pctx->opts) 1335 goto nomem; 1336 1337 fsopt = pctx->opts; 1338 fsopt->flags = CEPH_MOUNT_OPT_DEFAULT; 1339 1340 fsopt->wsize = CEPH_MAX_WRITE_SIZE; 1341 fsopt->rsize = CEPH_MAX_READ_SIZE; 1342 fsopt->rasize = CEPH_RASIZE_DEFAULT; 1343 fsopt->snapdir_name = kstrdup(CEPH_SNAPDIRNAME_DEFAULT, GFP_KERNEL); 1344 if (!fsopt->snapdir_name) 1345 goto nomem; 1346 1347 fsopt->caps_wanted_delay_min = CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT; 1348 fsopt->caps_wanted_delay_max = CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT; 1349 fsopt->max_readdir = CEPH_MAX_READDIR_DEFAULT; 1350 fsopt->max_readdir_bytes = CEPH_MAX_READDIR_BYTES_DEFAULT; 1351 fsopt->congestion_kb = default_congestion_kb(); 1352 1353 #ifdef CONFIG_CEPH_FS_POSIX_ACL 1354 fc->sb_flags |= SB_POSIXACL; 1355 #endif 1356 1357 fc->fs_private = pctx; 1358 fc->ops = &ceph_context_ops; 1359 return 0; 1360 1361 nomem: 1362 destroy_mount_options(pctx->opts); 1363 ceph_destroy_options(pctx->copts); 1364 kfree(pctx); 1365 return -ENOMEM; 1366 } 1367 1368 static void ceph_kill_sb(struct super_block *s) 1369 { 1370 struct ceph_fs_client *fsc = ceph_sb_to_client(s); 1371 1372 dout("kill_sb %p\n", s); 1373 1374 ceph_mdsc_pre_umount(fsc->mdsc); 1375 flush_fs_workqueues(fsc); 1376 1377 kill_anon_super(s); 1378 1379 fsc->client->extra_mon_dispatch = NULL; 1380 ceph_fs_debugfs_cleanup(fsc); 1381 1382 ceph_fscache_unregister_fs(fsc); 1383 1384 destroy_fs_client(fsc); 1385 } 1386 1387 static struct file_system_type ceph_fs_type = { 1388 .owner = THIS_MODULE, 1389 .name = "ceph", 1390 .init_fs_context = ceph_init_fs_context, 1391 .kill_sb = ceph_kill_sb, 1392 .fs_flags = FS_RENAME_DOES_D_MOVE, 1393 }; 1394 MODULE_ALIAS_FS("ceph"); 1395 1396 int ceph_force_reconnect(struct super_block *sb) 1397 { 1398 struct ceph_fs_client *fsc = ceph_sb_to_client(sb); 1399 int err = 0; 1400 1401 fsc->mount_state = CEPH_MOUNT_RECOVER; 1402 __ceph_umount_begin(fsc); 1403 1404 /* Make sure all page caches get invalidated. 1405 * see remove_session_caps_cb() */ 1406 flush_workqueue(fsc->inode_wq); 1407 1408 /* In case that we were blocklisted. This also reset 1409 * all mon/osd connections */ 1410 ceph_reset_client_addr(fsc->client); 1411 1412 ceph_osdc_clear_abort_err(&fsc->client->osdc); 1413 1414 fsc->blocklisted = false; 1415 fsc->mount_state = CEPH_MOUNT_MOUNTED; 1416 1417 if (sb->s_root) { 1418 err = __ceph_do_getattr(d_inode(sb->s_root), NULL, 1419 CEPH_STAT_CAP_INODE, true); 1420 } 1421 return err; 1422 } 1423 1424 static int __init init_ceph(void) 1425 { 1426 int ret = init_caches(); 1427 if (ret) 1428 goto out; 1429 1430 ceph_flock_init(); 1431 ret = register_filesystem(&ceph_fs_type); 1432 if (ret) 1433 goto out_caches; 1434 1435 pr_info("loaded (mds proto %d)\n", CEPH_MDSC_PROTOCOL); 1436 1437 return 0; 1438 1439 out_caches: 1440 destroy_caches(); 1441 out: 1442 return ret; 1443 } 1444 1445 static void __exit exit_ceph(void) 1446 { 1447 dout("exit_ceph\n"); 1448 unregister_filesystem(&ceph_fs_type); 1449 destroy_caches(); 1450 } 1451 1452 static int param_set_metrics(const char *val, const struct kernel_param *kp) 1453 { 1454 struct ceph_fs_client *fsc; 1455 int ret; 1456 1457 ret = param_set_bool(val, kp); 1458 if (ret) { 1459 pr_err("Failed to parse sending metrics switch value '%s'\n", 1460 val); 1461 return ret; 1462 } else if (!disable_send_metrics) { 1463 // wake up all the mds clients 1464 spin_lock(&ceph_fsc_lock); 1465 list_for_each_entry(fsc, &ceph_fsc_list, metric_wakeup) { 1466 metric_schedule_delayed(&fsc->mdsc->metric); 1467 } 1468 spin_unlock(&ceph_fsc_lock); 1469 } 1470 1471 return 0; 1472 } 1473 1474 static const struct kernel_param_ops param_ops_metrics = { 1475 .set = param_set_metrics, 1476 .get = param_get_bool, 1477 }; 1478 1479 bool disable_send_metrics = false; 1480 module_param_cb(disable_send_metrics, ¶m_ops_metrics, &disable_send_metrics, 0644); 1481 MODULE_PARM_DESC(disable_send_metrics, "Enable sending perf metrics to ceph cluster (default: on)"); 1482 1483 /* for both v1 and v2 syntax */ 1484 static bool mount_support = true; 1485 static const struct kernel_param_ops param_ops_mount_syntax = { 1486 .get = param_get_bool, 1487 }; 1488 module_param_cb(mount_syntax_v1, ¶m_ops_mount_syntax, &mount_support, 0444); 1489 module_param_cb(mount_syntax_v2, ¶m_ops_mount_syntax, &mount_support, 0444); 1490 1491 module_init(init_ceph); 1492 module_exit(exit_ceph); 1493 1494 MODULE_AUTHOR("Sage Weil <sage@newdream.net>"); 1495 MODULE_AUTHOR("Yehuda Sadeh <yehuda@hq.newdream.net>"); 1496 MODULE_AUTHOR("Patience Warnick <patience@newdream.net>"); 1497 MODULE_DESCRIPTION("Ceph filesystem for Linux"); 1498 MODULE_LICENSE("GPL"); 1499