.. | .. |
---|
12 | 12 | #include <linux/types.h> |
---|
13 | 13 | #include <linux/errno.h> |
---|
14 | 14 | #include <linux/fs.h> |
---|
| 15 | +#include <linux/fs_context.h> |
---|
| 16 | +#include <linux/fs_parser.h> |
---|
15 | 17 | #include <linux/namei.h> |
---|
16 | 18 | #include <linux/vfs.h> |
---|
17 | 19 | #include <linux/slab.h> |
---|
18 | 20 | #include <linux/pagemap.h> |
---|
19 | 21 | #include <linux/time.h> |
---|
20 | | -#include <linux/parser.h> |
---|
21 | 22 | #include <linux/sysfs.h> |
---|
22 | 23 | #include <linux/init.h> |
---|
23 | 24 | #include <linux/kobject.h> |
---|
24 | 25 | #include <linux/seq_file.h> |
---|
25 | | -#include <linux/mount.h> |
---|
26 | 26 | #include <linux/uio.h> |
---|
27 | 27 | #include <asm/ebcdic.h> |
---|
28 | 28 | #include "hypfs.h" |
---|
.. | .. |
---|
76 | 76 | else |
---|
77 | 77 | simple_unlink(d_inode(parent), dentry); |
---|
78 | 78 | } |
---|
79 | | - d_delete(dentry); |
---|
| 79 | + d_drop(dentry); |
---|
80 | 80 | dput(dentry); |
---|
81 | 81 | inode_unlock(d_inode(parent)); |
---|
82 | 82 | } |
---|
.. | .. |
---|
207 | 207 | return 0; |
---|
208 | 208 | } |
---|
209 | 209 | |
---|
210 | | -enum { opt_uid, opt_gid, opt_err }; |
---|
| 210 | +enum { Opt_uid, Opt_gid, }; |
---|
211 | 211 | |
---|
212 | | -static const match_table_t hypfs_tokens = { |
---|
213 | | - {opt_uid, "uid=%u"}, |
---|
214 | | - {opt_gid, "gid=%u"}, |
---|
215 | | - {opt_err, NULL} |
---|
| 212 | +static const struct fs_parameter_spec hypfs_fs_parameters[] = { |
---|
| 213 | + fsparam_u32("gid", Opt_gid), |
---|
| 214 | + fsparam_u32("uid", Opt_uid), |
---|
| 215 | + {} |
---|
216 | 216 | }; |
---|
217 | 217 | |
---|
218 | | -static int hypfs_parse_options(char *options, struct super_block *sb) |
---|
| 218 | +static int hypfs_parse_param(struct fs_context *fc, struct fs_parameter *param) |
---|
219 | 219 | { |
---|
220 | | - char *str; |
---|
221 | | - substring_t args[MAX_OPT_ARGS]; |
---|
| 220 | + struct hypfs_sb_info *hypfs_info = fc->s_fs_info; |
---|
| 221 | + struct fs_parse_result result; |
---|
222 | 222 | kuid_t uid; |
---|
223 | 223 | kgid_t gid; |
---|
| 224 | + int opt; |
---|
224 | 225 | |
---|
225 | | - if (!options) |
---|
226 | | - return 0; |
---|
227 | | - while ((str = strsep(&options, ",")) != NULL) { |
---|
228 | | - int token, option; |
---|
229 | | - struct hypfs_sb_info *hypfs_info = sb->s_fs_info; |
---|
| 226 | + opt = fs_parse(fc, hypfs_fs_parameters, param, &result); |
---|
| 227 | + if (opt < 0) |
---|
| 228 | + return opt; |
---|
230 | 229 | |
---|
231 | | - if (!*str) |
---|
232 | | - continue; |
---|
233 | | - token = match_token(str, hypfs_tokens, args); |
---|
234 | | - switch (token) { |
---|
235 | | - case opt_uid: |
---|
236 | | - if (match_int(&args[0], &option)) |
---|
237 | | - return -EINVAL; |
---|
238 | | - uid = make_kuid(current_user_ns(), option); |
---|
239 | | - if (!uid_valid(uid)) |
---|
240 | | - return -EINVAL; |
---|
241 | | - hypfs_info->uid = uid; |
---|
242 | | - break; |
---|
243 | | - case opt_gid: |
---|
244 | | - if (match_int(&args[0], &option)) |
---|
245 | | - return -EINVAL; |
---|
246 | | - gid = make_kgid(current_user_ns(), option); |
---|
247 | | - if (!gid_valid(gid)) |
---|
248 | | - return -EINVAL; |
---|
249 | | - hypfs_info->gid = gid; |
---|
250 | | - break; |
---|
251 | | - case opt_err: |
---|
252 | | - default: |
---|
253 | | - pr_err("%s is not a valid mount option\n", str); |
---|
254 | | - return -EINVAL; |
---|
255 | | - } |
---|
| 230 | + switch (opt) { |
---|
| 231 | + case Opt_uid: |
---|
| 232 | + uid = make_kuid(current_user_ns(), result.uint_32); |
---|
| 233 | + if (!uid_valid(uid)) |
---|
| 234 | + return invalf(fc, "Unknown uid"); |
---|
| 235 | + hypfs_info->uid = uid; |
---|
| 236 | + break; |
---|
| 237 | + case Opt_gid: |
---|
| 238 | + gid = make_kgid(current_user_ns(), result.uint_32); |
---|
| 239 | + if (!gid_valid(gid)) |
---|
| 240 | + return invalf(fc, "Unknown gid"); |
---|
| 241 | + hypfs_info->gid = gid; |
---|
| 242 | + break; |
---|
256 | 243 | } |
---|
257 | 244 | return 0; |
---|
258 | 245 | } |
---|
.. | .. |
---|
266 | 253 | return 0; |
---|
267 | 254 | } |
---|
268 | 255 | |
---|
269 | | -static int hypfs_fill_super(struct super_block *sb, void *data, int silent) |
---|
| 256 | +static int hypfs_fill_super(struct super_block *sb, struct fs_context *fc) |
---|
270 | 257 | { |
---|
| 258 | + struct hypfs_sb_info *sbi = sb->s_fs_info; |
---|
271 | 259 | struct inode *root_inode; |
---|
272 | 260 | struct dentry *root_dentry, *update_file; |
---|
273 | | - int rc = 0; |
---|
274 | | - struct hypfs_sb_info *sbi; |
---|
| 261 | + int rc; |
---|
275 | 262 | |
---|
276 | | - sbi = kzalloc(sizeof(struct hypfs_sb_info), GFP_KERNEL); |
---|
277 | | - if (!sbi) |
---|
278 | | - return -ENOMEM; |
---|
279 | | - mutex_init(&sbi->lock); |
---|
280 | | - sbi->uid = current_uid(); |
---|
281 | | - sbi->gid = current_gid(); |
---|
282 | | - sb->s_fs_info = sbi; |
---|
283 | 263 | sb->s_blocksize = PAGE_SIZE; |
---|
284 | 264 | sb->s_blocksize_bits = PAGE_SHIFT; |
---|
285 | 265 | sb->s_magic = HYPFS_MAGIC; |
---|
286 | 266 | sb->s_op = &hypfs_s_ops; |
---|
287 | | - if (hypfs_parse_options(data, sb)) |
---|
288 | | - return -EINVAL; |
---|
| 267 | + |
---|
289 | 268 | root_inode = hypfs_make_inode(sb, S_IFDIR | 0755); |
---|
290 | 269 | if (!root_inode) |
---|
291 | 270 | return -ENOMEM; |
---|
.. | .. |
---|
309 | 288 | return 0; |
---|
310 | 289 | } |
---|
311 | 290 | |
---|
312 | | -static struct dentry *hypfs_mount(struct file_system_type *fst, int flags, |
---|
313 | | - const char *devname, void *data) |
---|
| 291 | +static int hypfs_get_tree(struct fs_context *fc) |
---|
314 | 292 | { |
---|
315 | | - return mount_single(fst, flags, data, hypfs_fill_super); |
---|
| 293 | + return get_tree_single(fc, hypfs_fill_super); |
---|
| 294 | +} |
---|
| 295 | + |
---|
| 296 | +static void hypfs_free_fc(struct fs_context *fc) |
---|
| 297 | +{ |
---|
| 298 | + kfree(fc->s_fs_info); |
---|
| 299 | +} |
---|
| 300 | + |
---|
| 301 | +static const struct fs_context_operations hypfs_context_ops = { |
---|
| 302 | + .free = hypfs_free_fc, |
---|
| 303 | + .parse_param = hypfs_parse_param, |
---|
| 304 | + .get_tree = hypfs_get_tree, |
---|
| 305 | +}; |
---|
| 306 | + |
---|
| 307 | +static int hypfs_init_fs_context(struct fs_context *fc) |
---|
| 308 | +{ |
---|
| 309 | + struct hypfs_sb_info *sbi; |
---|
| 310 | + |
---|
| 311 | + sbi = kzalloc(sizeof(struct hypfs_sb_info), GFP_KERNEL); |
---|
| 312 | + if (!sbi) |
---|
| 313 | + return -ENOMEM; |
---|
| 314 | + |
---|
| 315 | + mutex_init(&sbi->lock); |
---|
| 316 | + sbi->uid = current_uid(); |
---|
| 317 | + sbi->gid = current_gid(); |
---|
| 318 | + |
---|
| 319 | + fc->s_fs_info = sbi; |
---|
| 320 | + fc->ops = &hypfs_context_ops; |
---|
| 321 | + return 0; |
---|
316 | 322 | } |
---|
317 | 323 | |
---|
318 | 324 | static void hypfs_kill_super(struct super_block *sb) |
---|
.. | .. |
---|
443 | 449 | static struct file_system_type hypfs_type = { |
---|
444 | 450 | .owner = THIS_MODULE, |
---|
445 | 451 | .name = "s390_hypfs", |
---|
446 | | - .mount = hypfs_mount, |
---|
| 452 | + .init_fs_context = hypfs_init_fs_context, |
---|
| 453 | + .parameters = hypfs_fs_parameters, |
---|
447 | 454 | .kill_sb = hypfs_kill_super |
---|
448 | 455 | }; |
---|
449 | 456 | |
---|
.. | .. |
---|
457 | 464 | { |
---|
458 | 465 | int rc; |
---|
459 | 466 | |
---|
460 | | - rc = hypfs_dbfs_init(); |
---|
461 | | - if (rc) |
---|
462 | | - return rc; |
---|
| 467 | + hypfs_dbfs_init(); |
---|
| 468 | + |
---|
463 | 469 | if (hypfs_diag_init()) { |
---|
464 | 470 | rc = -ENODATA; |
---|
465 | 471 | goto fail_dbfs_exit; |
---|
.. | .. |
---|
468 | 474 | rc = -ENODATA; |
---|
469 | 475 | goto fail_hypfs_diag_exit; |
---|
470 | 476 | } |
---|
471 | | - if (hypfs_sprp_init()) { |
---|
472 | | - rc = -ENODATA; |
---|
473 | | - goto fail_hypfs_vm_exit; |
---|
474 | | - } |
---|
| 477 | + hypfs_sprp_init(); |
---|
475 | 478 | if (hypfs_diag0c_init()) { |
---|
476 | 479 | rc = -ENODATA; |
---|
477 | 480 | goto fail_hypfs_sprp_exit; |
---|
.. | .. |
---|
490 | 493 | hypfs_diag0c_exit(); |
---|
491 | 494 | fail_hypfs_sprp_exit: |
---|
492 | 495 | hypfs_sprp_exit(); |
---|
493 | | -fail_hypfs_vm_exit: |
---|
494 | 496 | hypfs_vm_exit(); |
---|
495 | 497 | fail_hypfs_diag_exit: |
---|
496 | 498 | hypfs_diag_exit(); |
---|
| 499 | + pr_err("Initialization of hypfs failed with rc=%i\n", rc); |
---|
497 | 500 | fail_dbfs_exit: |
---|
498 | 501 | hypfs_dbfs_exit(); |
---|
499 | | - pr_err("Initialization of hypfs failed with rc=%i\n", rc); |
---|
500 | 502 | return rc; |
---|
501 | 503 | } |
---|
502 | 504 | device_initcall(hypfs_init) |
---|