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/mqueue.c | |
| 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/mqueue.c')
| -rw-r--r-- | ipc/mqueue.c | 94 |
1 files changed, 72 insertions, 22 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 | ||
