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