diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-12 17:08:19 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-12 17:08:19 -0400 |
commit | 7b47a9e7c8f672b6fb0b77fca11a63a8a77f5a91 (patch) | |
tree | cf05645120ba2323c36acefdea6e62addf320f8c /ipc | |
parent | dbc2fba3fc46084f502aec53183995a632998dcd (diff) | |
parent | c99c2171fc61476afac0dfb59fb2c447a01fb1e0 (diff) |
Merge branch 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs mount infrastructure updates from Al Viro:
"The rest of core infrastructure; no new syscalls in that pile, but the
old parts are switched to new infrastructure. At that point
conversions of individual filesystems can happen independently; some
are done here (afs, cgroup, procfs, etc.), there's also a large series
outside of that pile dealing with NFS (quite a bit of option-parsing
stuff is getting used there - it's one of the most convoluted
filesystems in terms of mount-related logics), but NFS bits are the
next cycle fodder.
It got seriously simplified since the last cycle; documentation is
probably the weakest bit at the moment - I considered dropping the
commit introducing Documentation/filesystems/mount_api.txt (cutting
the size increase by quarter ;-), but decided that it would be better
to fix it up after -rc1 instead.
That pile allows to do followup work in independent branches, which
should make life much easier for the next cycle. fs/super.c size
increase is unpleasant; there's a followup series that allows to
shrink it considerably, but I decided to leave that until the next
cycle"
* 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (41 commits)
afs: Use fs_context to pass parameters over automount
afs: Add fs_context support
vfs: Add some logging to the core users of the fs_context log
vfs: Implement logging through fs_context
vfs: Provide documentation for new mount API
vfs: Remove kern_mount_data()
hugetlbfs: Convert to fs_context
cpuset: Use fs_context
kernfs, sysfs, cgroup, intel_rdt: Support fs_context
cgroup: store a reference to cgroup_ns into cgroup_fs_context
cgroup1_get_tree(): separate "get cgroup_root to use" into a separate helper
cgroup_do_mount(): massage calling conventions
cgroup: stash cgroup_root reference into cgroup_fs_context
cgroup2: switch to option-by-option parsing
cgroup1: switch to option-by-option parsing
cgroup: take options parsing into ->parse_monolithic()
cgroup: fold cgroup1_mount() into cgroup1_get_tree()
cgroup: start switching to fs_context
ipc: Convert mqueue fs to fs_context
proc: Add fs_context support to procfs
...
Diffstat (limited to 'ipc')
-rw-r--r-- | ipc/mqueue.c | 94 | ||||
-rw-r--r-- | ipc/namespace.c | 2 |
2 files changed, 73 insertions, 23 deletions
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index c839bf83231d..aea30530c472 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/pagemap.h> | 18 | #include <linux/pagemap.h> |
19 | #include <linux/file.h> | 19 | #include <linux/file.h> |
20 | #include <linux/mount.h> | 20 | #include <linux/mount.h> |
21 | #include <linux/fs_context.h> | ||
21 | #include <linux/namei.h> | 22 | #include <linux/namei.h> |
22 | #include <linux/sysctl.h> | 23 | #include <linux/sysctl.h> |
23 | #include <linux/poll.h> | 24 | #include <linux/poll.h> |
@@ -42,6 +43,10 @@ | |||
42 | #include <net/sock.h> | 43 | #include <net/sock.h> |
43 | #include "util.h" | 44 | #include "util.h" |
44 | 45 | ||
46 | struct mqueue_fs_context { | ||
47 | struct ipc_namespace *ipc_ns; | ||
48 | }; | ||
49 | |||
45 | #define MQUEUE_MAGIC 0x19800202 | 50 | #define MQUEUE_MAGIC 0x19800202 |
46 | #define DIRENT_SIZE 20 | 51 | #define DIRENT_SIZE 20 |
47 | #define FILENT_SIZE 80 | 52 | #define FILENT_SIZE 80 |
@@ -87,9 +92,11 @@ struct mqueue_inode_info { | |||
87 | unsigned long qsize; /* size of queue in memory (sum of all msgs) */ | 92 | unsigned long qsize; /* size of queue in memory (sum of all msgs) */ |
88 | }; | 93 | }; |
89 | 94 | ||
95 | static struct file_system_type mqueue_fs_type; | ||
90 | static const struct inode_operations mqueue_dir_inode_operations; | 96 | static const struct inode_operations mqueue_dir_inode_operations; |
91 | static const struct file_operations mqueue_file_operations; | 97 | static const struct file_operations mqueue_file_operations; |
92 | static const struct super_operations mqueue_super_ops; | 98 | static const struct super_operations mqueue_super_ops; |
99 | static const struct fs_context_operations mqueue_fs_context_ops; | ||
93 | static void remove_notification(struct mqueue_inode_info *info); | 100 | static void remove_notification(struct mqueue_inode_info *info); |
94 | 101 | ||
95 | static struct kmem_cache *mqueue_inode_cachep; | 102 | static struct kmem_cache *mqueue_inode_cachep; |
@@ -322,7 +329,7 @@ err: | |||
322 | return ERR_PTR(ret); | 329 | return ERR_PTR(ret); |
323 | } | 330 | } |
324 | 331 | ||
325 | static int mqueue_fill_super(struct super_block *sb, void *data, int silent) | 332 | static int mqueue_fill_super(struct super_block *sb, struct fs_context *fc) |
326 | { | 333 | { |
327 | struct inode *inode; | 334 | struct inode *inode; |
328 | struct ipc_namespace *ns = sb->s_fs_info; | 335 | struct ipc_namespace *ns = sb->s_fs_info; |
@@ -343,18 +350,56 @@ static int mqueue_fill_super(struct super_block *sb, void *data, int silent) | |||
343 | return 0; | 350 | return 0; |
344 | } | 351 | } |
345 | 352 | ||
346 | static struct dentry *mqueue_mount(struct file_system_type *fs_type, | 353 | static int mqueue_get_tree(struct fs_context *fc) |
347 | int flags, const char *dev_name, | ||
348 | void *data) | ||
349 | { | 354 | { |
350 | struct ipc_namespace *ns; | 355 | struct mqueue_fs_context *ctx = fc->fs_private; |
351 | if (flags & SB_KERNMOUNT) { | 356 | |
352 | ns = data; | 357 | put_user_ns(fc->user_ns); |
353 | data = NULL; | 358 | fc->user_ns = get_user_ns(ctx->ipc_ns->user_ns); |
354 | } else { | 359 | fc->s_fs_info = ctx->ipc_ns; |
355 | ns = current->nsproxy->ipc_ns; | 360 | return vfs_get_super(fc, vfs_get_keyed_super, mqueue_fill_super); |
356 | } | 361 | } |
357 | return mount_ns(fs_type, flags, data, ns, ns->user_ns, mqueue_fill_super); | 362 | |
363 | static void mqueue_fs_context_free(struct fs_context *fc) | ||
364 | { | ||
365 | struct mqueue_fs_context *ctx = fc->fs_private; | ||
366 | |||
367 | if (ctx->ipc_ns) | ||
368 | put_ipc_ns(ctx->ipc_ns); | ||
369 | kfree(ctx); | ||
370 | } | ||
371 | |||
372 | static int mqueue_init_fs_context(struct fs_context *fc) | ||
373 | { | ||
374 | struct mqueue_fs_context *ctx; | ||
375 | |||
376 | ctx = kzalloc(sizeof(struct mqueue_fs_context), GFP_KERNEL); | ||
377 | if (!ctx) | ||
378 | return -ENOMEM; | ||
379 | |||
380 | ctx->ipc_ns = get_ipc_ns(current->nsproxy->ipc_ns); | ||
381 | fc->fs_private = ctx; | ||
382 | fc->ops = &mqueue_fs_context_ops; | ||
383 | return 0; | ||
384 | } | ||
385 | |||
386 | static struct vfsmount *mq_create_mount(struct ipc_namespace *ns) | ||
387 | { | ||
388 | struct mqueue_fs_context *ctx; | ||
389 | struct fs_context *fc; | ||
390 | struct vfsmount *mnt; | ||
391 | |||
392 | fc = fs_context_for_mount(&mqueue_fs_type, SB_KERNMOUNT); | ||
393 | if (IS_ERR(fc)) | ||
394 | return ERR_CAST(fc); | ||
395 | |||
396 | ctx = fc->fs_private; | ||
397 | put_ipc_ns(ctx->ipc_ns); | ||
398 | ctx->ipc_ns = get_ipc_ns(ns); | ||
399 | |||
400 | mnt = fc_mount(fc); | ||
401 | put_fs_context(fc); | ||
402 | return mnt; | ||
358 | } | 403 | } |
359 | 404 | ||
360 | static void init_once(void *foo) | 405 | static void init_once(void *foo) |
@@ -1522,15 +1567,22 @@ static const struct super_operations mqueue_super_ops = { | |||
1522 | .statfs = simple_statfs, | 1567 | .statfs = simple_statfs, |
1523 | }; | 1568 | }; |
1524 | 1569 | ||
1570 | static const struct fs_context_operations mqueue_fs_context_ops = { | ||
1571 | .free = mqueue_fs_context_free, | ||
1572 | .get_tree = mqueue_get_tree, | ||
1573 | }; | ||
1574 | |||
1525 | static struct file_system_type mqueue_fs_type = { | 1575 | static struct file_system_type mqueue_fs_type = { |
1526 | .name = "mqueue", | 1576 | .name = "mqueue", |
1527 | .mount = mqueue_mount, | 1577 | .init_fs_context = mqueue_init_fs_context, |
1528 | .kill_sb = kill_litter_super, | 1578 | .kill_sb = kill_litter_super, |
1529 | .fs_flags = FS_USERNS_MOUNT, | 1579 | .fs_flags = FS_USERNS_MOUNT, |
1530 | }; | 1580 | }; |
1531 | 1581 | ||
1532 | int mq_init_ns(struct ipc_namespace *ns) | 1582 | int mq_init_ns(struct ipc_namespace *ns) |
1533 | { | 1583 | { |
1584 | struct vfsmount *m; | ||
1585 | |||
1534 | ns->mq_queues_count = 0; | 1586 | ns->mq_queues_count = 0; |
1535 | ns->mq_queues_max = DFLT_QUEUESMAX; | 1587 | ns->mq_queues_max = DFLT_QUEUESMAX; |
1536 | ns->mq_msg_max = DFLT_MSGMAX; | 1588 | ns->mq_msg_max = DFLT_MSGMAX; |
@@ -1538,12 +1590,10 @@ int mq_init_ns(struct ipc_namespace *ns) | |||
1538 | ns->mq_msg_default = DFLT_MSG; | 1590 | ns->mq_msg_default = DFLT_MSG; |
1539 | ns->mq_msgsize_default = DFLT_MSGSIZE; | 1591 | ns->mq_msgsize_default = DFLT_MSGSIZE; |
1540 | 1592 | ||
1541 | ns->mq_mnt = kern_mount_data(&mqueue_fs_type, ns); | 1593 | m = mq_create_mount(ns); |
1542 | if (IS_ERR(ns->mq_mnt)) { | 1594 | if (IS_ERR(m)) |
1543 | int err = PTR_ERR(ns->mq_mnt); | 1595 | return PTR_ERR(m); |
1544 | ns->mq_mnt = NULL; | 1596 | ns->mq_mnt = m; |
1545 | return err; | ||
1546 | } | ||
1547 | return 0; | 1597 | return 0; |
1548 | } | 1598 | } |
1549 | 1599 | ||
diff --git a/ipc/namespace.c b/ipc/namespace.c index 21607791d62c..b3ca1476ca51 100644 --- a/ipc/namespace.c +++ b/ipc/namespace.c | |||
@@ -42,7 +42,7 @@ static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns, | |||
42 | goto fail; | 42 | goto fail; |
43 | 43 | ||
44 | err = -ENOMEM; | 44 | err = -ENOMEM; |
45 | ns = kmalloc(sizeof(struct ipc_namespace), GFP_KERNEL); | 45 | ns = kzalloc(sizeof(struct ipc_namespace), GFP_KERNEL); |
46 | if (ns == NULL) | 46 | if (ns == NULL) |
47 | goto fail_dec; | 47 | goto fail_dec; |
48 | 48 | ||