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