diff options
41 files changed, 531 insertions, 163 deletions
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index 48c9faa73a76..73e7d91f03dc 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt | |||
| @@ -1225,12 +1225,6 @@ The underlying reason for the above rules is to make sure, that a | |||
| 1225 | mount can be accurately replicated (e.g. umounting and mounting again) | 1225 | mount can be accurately replicated (e.g. umounting and mounting again) |
| 1226 | based on the information found in /proc/mounts. | 1226 | based on the information found in /proc/mounts. |
| 1227 | 1227 | ||
| 1228 | A simple method of saving options at mount/remount time and showing | ||
| 1229 | them is provided with the save_mount_options() and | ||
| 1230 | generic_show_options() helper functions. Please note, that using | ||
| 1231 | these may have drawbacks. For more info see header comments for these | ||
| 1232 | functions in fs/namespace.c. | ||
| 1233 | |||
| 1234 | Resources | 1228 | Resources |
| 1235 | ========= | 1229 | ========= |
| 1236 | 1230 | ||
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index d8af9bc0489f..9558d725a99b 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c | |||
| @@ -605,6 +605,24 @@ static const match_table_t spufs_tokens = { | |||
| 605 | { Opt_err, NULL }, | 605 | { Opt_err, NULL }, |
| 606 | }; | 606 | }; |
| 607 | 607 | ||
| 608 | static int spufs_show_options(struct seq_file *m, struct dentry *root) | ||
| 609 | { | ||
| 610 | struct spufs_sb_info *sbi = spufs_get_sb_info(root->d_sb); | ||
| 611 | struct inode *inode = root->d_inode; | ||
| 612 | |||
| 613 | if (!uid_eq(inode->i_uid, GLOBAL_ROOT_UID)) | ||
| 614 | seq_printf(m, ",uid=%u", | ||
| 615 | from_kuid_munged(&init_user_ns, inode->i_uid)); | ||
| 616 | if (!gid_eq(inode->i_gid, GLOBAL_ROOT_GID)) | ||
| 617 | seq_printf(m, ",gid=%u", | ||
| 618 | from_kgid_munged(&init_user_ns, inode->i_gid)); | ||
| 619 | if ((inode->i_mode & S_IALLUGO) != 0775) | ||
| 620 | seq_printf(m, ",mode=%o", inode->i_mode); | ||
| 621 | if (sbi->debug) | ||
| 622 | seq_puts(m, ",debug"); | ||
| 623 | return 0; | ||
| 624 | } | ||
| 625 | |||
| 608 | static int | 626 | static int |
| 609 | spufs_parse_options(struct super_block *sb, char *options, struct inode *root) | 627 | spufs_parse_options(struct super_block *sb, char *options, struct inode *root) |
| 610 | { | 628 | { |
| @@ -724,11 +742,9 @@ spufs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 724 | .destroy_inode = spufs_destroy_inode, | 742 | .destroy_inode = spufs_destroy_inode, |
| 725 | .statfs = simple_statfs, | 743 | .statfs = simple_statfs, |
| 726 | .evict_inode = spufs_evict_inode, | 744 | .evict_inode = spufs_evict_inode, |
| 727 | .show_options = generic_show_options, | 745 | .show_options = spufs_show_options, |
| 728 | }; | 746 | }; |
| 729 | 747 | ||
| 730 | save_mount_options(sb, data); | ||
| 731 | |||
| 732 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 748 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
| 733 | if (!info) | 749 | if (!info) |
| 734 | return -ENOMEM; | 750 | return -ENOMEM; |
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index c202930086ed..8fb89ddc6cc7 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <linux/parser.h> | 33 | #include <linux/parser.h> |
| 34 | #include <linux/idr.h> | 34 | #include <linux/idr.h> |
| 35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
| 36 | #include <linux/seq_file.h> | ||
| 36 | #include <net/9p/9p.h> | 37 | #include <net/9p/9p.h> |
| 37 | #include <net/9p/client.h> | 38 | #include <net/9p/client.h> |
| 38 | #include <net/9p/transport.h> | 39 | #include <net/9p/transport.h> |
| @@ -82,6 +83,13 @@ static const match_table_t tokens = { | |||
| 82 | {Opt_err, NULL} | 83 | {Opt_err, NULL} |
| 83 | }; | 84 | }; |
| 84 | 85 | ||
| 86 | static const char *const v9fs_cache_modes[nr__p9_cache_modes] = { | ||
| 87 | [CACHE_NONE] = "none", | ||
| 88 | [CACHE_MMAP] = "mmap", | ||
| 89 | [CACHE_LOOSE] = "loose", | ||
| 90 | [CACHE_FSCACHE] = "fscache", | ||
| 91 | }; | ||
| 92 | |||
| 85 | /* Interpret mount options for cache mode */ | 93 | /* Interpret mount options for cache mode */ |
| 86 | static int get_cache_mode(char *s) | 94 | static int get_cache_mode(char *s) |
| 87 | { | 95 | { |
| @@ -104,6 +112,58 @@ static int get_cache_mode(char *s) | |||
| 104 | return version; | 112 | return version; |
| 105 | } | 113 | } |
| 106 | 114 | ||
| 115 | /* | ||
| 116 | * Display the mount options in /proc/mounts. | ||
| 117 | */ | ||
| 118 | int v9fs_show_options(struct seq_file *m, struct dentry *root) | ||
| 119 | { | ||
| 120 | struct v9fs_session_info *v9ses = root->d_sb->s_fs_info; | ||
| 121 | |||
| 122 | if (v9ses->debug) | ||
| 123 | seq_printf(m, ",debug=%x", v9ses->debug); | ||
| 124 | if (!uid_eq(v9ses->dfltuid, V9FS_DEFUID)) | ||
| 125 | seq_printf(m, ",dfltuid=%u", | ||
| 126 | from_kuid_munged(&init_user_ns, v9ses->dfltuid)); | ||
| 127 | if (!gid_eq(v9ses->dfltgid, V9FS_DEFGID)) | ||
| 128 | seq_printf(m, ",dfltgid=%u", | ||
| 129 | from_kgid_munged(&init_user_ns, v9ses->dfltgid)); | ||
| 130 | if (v9ses->afid != ~0) | ||
| 131 | seq_printf(m, ",afid=%u", v9ses->afid); | ||
| 132 | if (strcmp(v9ses->uname, V9FS_DEFUSER) != 0) | ||
| 133 | seq_printf(m, ",uname=%s", v9ses->uname); | ||
| 134 | if (strcmp(v9ses->aname, V9FS_DEFANAME) != 0) | ||
| 135 | seq_printf(m, ",aname=%s", v9ses->aname); | ||
| 136 | if (v9ses->nodev) | ||
| 137 | seq_puts(m, ",nodevmap"); | ||
| 138 | if (v9ses->cache) | ||
| 139 | seq_printf(m, ",%s", v9fs_cache_modes[v9ses->cache]); | ||
| 140 | #ifdef CONFIG_9P_FSCACHE | ||
| 141 | if (v9ses->cachetag && v9ses->cache == CACHE_FSCACHE) | ||
| 142 | seq_printf(m, ",cachetag=%s", v9ses->cachetag); | ||
| 143 | #endif | ||
| 144 | |||
| 145 | switch (v9ses->flags & V9FS_ACCESS_MASK) { | ||
| 146 | case V9FS_ACCESS_USER: | ||
| 147 | seq_puts(m, ",access=user"); | ||
| 148 | break; | ||
| 149 | case V9FS_ACCESS_ANY: | ||
| 150 | seq_puts(m, ",access=any"); | ||
| 151 | break; | ||
| 152 | case V9FS_ACCESS_CLIENT: | ||
| 153 | seq_puts(m, ",access=client"); | ||
| 154 | break; | ||
| 155 | case V9FS_ACCESS_SINGLE: | ||
| 156 | seq_printf(m, ",access=%u", | ||
| 157 | from_kuid_munged(&init_user_ns, v9ses->uid)); | ||
| 158 | break; | ||
| 159 | } | ||
| 160 | |||
| 161 | if (v9ses->flags & V9FS_POSIX_ACL) | ||
| 162 | seq_puts(m, ",posixacl"); | ||
| 163 | |||
| 164 | return p9_show_client_options(m, v9ses->clnt); | ||
| 165 | } | ||
| 166 | |||
| 107 | /** | 167 | /** |
| 108 | * v9fs_parse_options - parse mount options into session structure | 168 | * v9fs_parse_options - parse mount options into session structure |
| 109 | * @v9ses: existing v9fs session information | 169 | * @v9ses: existing v9fs session information |
| @@ -230,6 +290,7 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts) | |||
| 230 | break; | 290 | break; |
| 231 | case Opt_cachetag: | 291 | case Opt_cachetag: |
| 232 | #ifdef CONFIG_9P_FSCACHE | 292 | #ifdef CONFIG_9P_FSCACHE |
| 293 | kfree(v9ses->cachetag); | ||
| 233 | v9ses->cachetag = match_strdup(&args[0]); | 294 | v9ses->cachetag = match_strdup(&args[0]); |
| 234 | #endif | 295 | #endif |
| 235 | break; | 296 | break; |
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index 76eaf49abd3a..982e017acadb 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h | |||
| @@ -67,6 +67,7 @@ enum p9_cache_modes { | |||
| 67 | CACHE_MMAP, | 67 | CACHE_MMAP, |
| 68 | CACHE_LOOSE, | 68 | CACHE_LOOSE, |
| 69 | CACHE_FSCACHE, | 69 | CACHE_FSCACHE, |
| 70 | nr__p9_cache_modes | ||
| 70 | }; | 71 | }; |
| 71 | 72 | ||
| 72 | /** | 73 | /** |
| @@ -137,6 +138,8 @@ static inline struct v9fs_inode *V9FS_I(const struct inode *inode) | |||
| 137 | return container_of(inode, struct v9fs_inode, vfs_inode); | 138 | return container_of(inode, struct v9fs_inode, vfs_inode); |
| 138 | } | 139 | } |
| 139 | 140 | ||
| 141 | extern int v9fs_show_options(struct seq_file *m, struct dentry *root); | ||
| 142 | |||
| 140 | struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *, | 143 | struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *, |
| 141 | char *); | 144 | char *); |
| 142 | extern void v9fs_session_close(struct v9fs_session_info *v9ses); | 145 | extern void v9fs_session_close(struct v9fs_session_info *v9ses); |
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index a0965fb587a5..8b75463cb211 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c | |||
| @@ -33,7 +33,6 @@ | |||
| 33 | #include <linux/string.h> | 33 | #include <linux/string.h> |
| 34 | #include <linux/inet.h> | 34 | #include <linux/inet.h> |
| 35 | #include <linux/pagemap.h> | 35 | #include <linux/pagemap.h> |
| 36 | #include <linux/seq_file.h> | ||
| 37 | #include <linux/mount.h> | 36 | #include <linux/mount.h> |
| 38 | #include <linux/idr.h> | 37 | #include <linux/idr.h> |
| 39 | #include <linux/sched.h> | 38 | #include <linux/sched.h> |
| @@ -104,7 +103,6 @@ v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses, | |||
| 104 | sb->s_flags |= MS_POSIXACL; | 103 | sb->s_flags |= MS_POSIXACL; |
| 105 | #endif | 104 | #endif |
| 106 | 105 | ||
| 107 | save_mount_options(sb, data); | ||
| 108 | return 0; | 106 | return 0; |
| 109 | } | 107 | } |
| 110 | 108 | ||
| @@ -349,7 +347,7 @@ static const struct super_operations v9fs_super_ops = { | |||
| 349 | .destroy_inode = v9fs_destroy_inode, | 347 | .destroy_inode = v9fs_destroy_inode, |
| 350 | .statfs = simple_statfs, | 348 | .statfs = simple_statfs, |
| 351 | .evict_inode = v9fs_evict_inode, | 349 | .evict_inode = v9fs_evict_inode, |
| 352 | .show_options = generic_show_options, | 350 | .show_options = v9fs_show_options, |
| 353 | .umount_begin = v9fs_umount_begin, | 351 | .umount_begin = v9fs_umount_begin, |
| 354 | .write_inode = v9fs_write_inode, | 352 | .write_inode = v9fs_write_inode, |
| 355 | }; | 353 | }; |
| @@ -360,7 +358,7 @@ static const struct super_operations v9fs_super_ops_dotl = { | |||
| 360 | .statfs = v9fs_statfs, | 358 | .statfs = v9fs_statfs, |
| 361 | .drop_inode = v9fs_drop_inode, | 359 | .drop_inode = v9fs_drop_inode, |
| 362 | .evict_inode = v9fs_evict_inode, | 360 | .evict_inode = v9fs_evict_inode, |
| 363 | .show_options = generic_show_options, | 361 | .show_options = v9fs_show_options, |
| 364 | .umount_begin = v9fs_umount_begin, | 362 | .umount_begin = v9fs_umount_begin, |
| 365 | .write_inode = v9fs_write_inode_dotl, | 363 | .write_inode = v9fs_write_inode_dotl, |
| 366 | }; | 364 | }; |
diff --git a/fs/affs/super.c b/fs/affs/super.c index c2c27a8f128e..7bf47a41cb4f 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c | |||
| @@ -20,9 +20,11 @@ | |||
| 20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
| 21 | #include <linux/writeback.h> | 21 | #include <linux/writeback.h> |
| 22 | #include <linux/blkdev.h> | 22 | #include <linux/blkdev.h> |
| 23 | #include <linux/seq_file.h> | ||
| 23 | #include "affs.h" | 24 | #include "affs.h" |
| 24 | 25 | ||
| 25 | static int affs_statfs(struct dentry *dentry, struct kstatfs *buf); | 26 | static int affs_statfs(struct dentry *dentry, struct kstatfs *buf); |
| 27 | static int affs_show_options(struct seq_file *m, struct dentry *root); | ||
| 26 | static int affs_remount (struct super_block *sb, int *flags, char *data); | 28 | static int affs_remount (struct super_block *sb, int *flags, char *data); |
| 27 | 29 | ||
| 28 | static void | 30 | static void |
| @@ -159,7 +161,7 @@ static const struct super_operations affs_sops = { | |||
| 159 | .sync_fs = affs_sync_fs, | 161 | .sync_fs = affs_sync_fs, |
| 160 | .statfs = affs_statfs, | 162 | .statfs = affs_statfs, |
| 161 | .remount_fs = affs_remount, | 163 | .remount_fs = affs_remount, |
| 162 | .show_options = generic_show_options, | 164 | .show_options = affs_show_options, |
| 163 | }; | 165 | }; |
| 164 | 166 | ||
| 165 | enum { | 167 | enum { |
| @@ -293,6 +295,40 @@ parse_options(char *options, kuid_t *uid, kgid_t *gid, int *mode, int *reserved, | |||
| 293 | return 1; | 295 | return 1; |
| 294 | } | 296 | } |
| 295 | 297 | ||
| 298 | static int affs_show_options(struct seq_file *m, struct dentry *root) | ||
| 299 | { | ||
| 300 | struct super_block *sb = root->d_sb; | ||
| 301 | struct affs_sb_info *sbi = AFFS_SB(sb); | ||
| 302 | |||
| 303 | if (sb->s_blocksize) | ||
| 304 | seq_printf(m, ",bs=%lu", sb->s_blocksize); | ||
| 305 | if (affs_test_opt(sbi->s_flags, SF_SETMODE)) | ||
| 306 | seq_printf(m, ",mode=%o", sbi->s_mode); | ||
| 307 | if (affs_test_opt(sbi->s_flags, SF_MUFS)) | ||
| 308 | seq_puts(m, ",mufs"); | ||
| 309 | if (affs_test_opt(sbi->s_flags, SF_NO_TRUNCATE)) | ||
| 310 | seq_puts(m, ",nofilenametruncate"); | ||
| 311 | if (affs_test_opt(sbi->s_flags, SF_PREFIX)) | ||
| 312 | seq_printf(m, ",prefix=%s", sbi->s_prefix); | ||
| 313 | if (affs_test_opt(sbi->s_flags, SF_IMMUTABLE)) | ||
| 314 | seq_puts(m, ",protect"); | ||
| 315 | if (sbi->s_reserved != 2) | ||
| 316 | seq_printf(m, ",reserved=%u", sbi->s_reserved); | ||
| 317 | if (sbi->s_root_block != (sbi->s_reserved + sbi->s_partition_size - 1) / 2) | ||
| 318 | seq_printf(m, ",root=%u", sbi->s_root_block); | ||
| 319 | if (affs_test_opt(sbi->s_flags, SF_SETGID)) | ||
| 320 | seq_printf(m, ",setgid=%u", | ||
| 321 | from_kgid_munged(&init_user_ns, sbi->s_gid)); | ||
| 322 | if (affs_test_opt(sbi->s_flags, SF_SETUID)) | ||
| 323 | seq_printf(m, ",setuid=%u", | ||
| 324 | from_kuid_munged(&init_user_ns, sbi->s_uid)); | ||
| 325 | if (affs_test_opt(sbi->s_flags, SF_VERBOSE)) | ||
| 326 | seq_puts(m, ",verbose"); | ||
| 327 | if (sbi->s_volume[0]) | ||
| 328 | seq_printf(m, ",volume=%s", sbi->s_volume); | ||
| 329 | return 0; | ||
| 330 | } | ||
| 331 | |||
| 296 | /* This function definitely needs to be split up. Some fine day I'll | 332 | /* This function definitely needs to be split up. Some fine day I'll |
| 297 | * hopefully have the guts to do so. Until then: sorry for the mess. | 333 | * hopefully have the guts to do so. Until then: sorry for the mess. |
| 298 | */ | 334 | */ |
| @@ -316,8 +352,6 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 316 | u8 sig[4]; | 352 | u8 sig[4]; |
| 317 | int ret; | 353 | int ret; |
| 318 | 354 | ||
| 319 | save_mount_options(sb, data); | ||
| 320 | |||
| 321 | pr_debug("read_super(%s)\n", data ? (const char *)data : "no options"); | 355 | pr_debug("read_super(%s)\n", data ? (const char *)data : "no options"); |
| 322 | 356 | ||
| 323 | sb->s_magic = AFFS_SUPER_MAGIC; | 357 | sb->s_magic = AFFS_SUPER_MAGIC; |
| @@ -548,8 +582,6 @@ affs_remount(struct super_block *sb, int *flags, char *data) | |||
| 548 | } | 582 | } |
| 549 | 583 | ||
| 550 | flush_delayed_work(&sbi->sb_work); | 584 | flush_delayed_work(&sbi->sb_work); |
| 551 | if (new_opts) | ||
| 552 | replace_mount_options(sb, new_opts); | ||
| 553 | 585 | ||
| 554 | sbi->s_flags = mount_flags; | 586 | sbi->s_flags = mount_flags; |
| 555 | sbi->s_mode = mode; | 587 | sbi->s_mode = mode; |
diff --git a/fs/afs/super.c b/fs/afs/super.c index 67680c2d96cf..689173c0a682 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c | |||
| @@ -37,6 +37,8 @@ static void afs_kill_super(struct super_block *sb); | |||
| 37 | static struct inode *afs_alloc_inode(struct super_block *sb); | 37 | static struct inode *afs_alloc_inode(struct super_block *sb); |
| 38 | static void afs_destroy_inode(struct inode *inode); | 38 | static void afs_destroy_inode(struct inode *inode); |
| 39 | static int afs_statfs(struct dentry *dentry, struct kstatfs *buf); | 39 | static int afs_statfs(struct dentry *dentry, struct kstatfs *buf); |
| 40 | static int afs_show_devname(struct seq_file *m, struct dentry *root); | ||
| 41 | static int afs_show_options(struct seq_file *m, struct dentry *root); | ||
| 40 | 42 | ||
| 41 | struct file_system_type afs_fs_type = { | 43 | struct file_system_type afs_fs_type = { |
| 42 | .owner = THIS_MODULE, | 44 | .owner = THIS_MODULE, |
| @@ -53,7 +55,8 @@ static const struct super_operations afs_super_ops = { | |||
| 53 | .drop_inode = afs_drop_inode, | 55 | .drop_inode = afs_drop_inode, |
| 54 | .destroy_inode = afs_destroy_inode, | 56 | .destroy_inode = afs_destroy_inode, |
| 55 | .evict_inode = afs_evict_inode, | 57 | .evict_inode = afs_evict_inode, |
| 56 | .show_options = generic_show_options, | 58 | .show_devname = afs_show_devname, |
| 59 | .show_options = afs_show_options, | ||
| 57 | }; | 60 | }; |
| 58 | 61 | ||
| 59 | static struct kmem_cache *afs_inode_cachep; | 62 | static struct kmem_cache *afs_inode_cachep; |
| @@ -136,6 +139,45 @@ void __exit afs_fs_exit(void) | |||
| 136 | } | 139 | } |
| 137 | 140 | ||
| 138 | /* | 141 | /* |
| 142 | * Display the mount device name in /proc/mounts. | ||
| 143 | */ | ||
| 144 | static int afs_show_devname(struct seq_file *m, struct dentry *root) | ||
| 145 | { | ||
| 146 | struct afs_super_info *as = root->d_sb->s_fs_info; | ||
| 147 | struct afs_volume *volume = as->volume; | ||
| 148 | struct afs_cell *cell = volume->cell; | ||
| 149 | const char *suf = ""; | ||
| 150 | char pref = '%'; | ||
| 151 | |||
| 152 | switch (volume->type) { | ||
| 153 | case AFSVL_RWVOL: | ||
| 154 | break; | ||
| 155 | case AFSVL_ROVOL: | ||
| 156 | pref = '#'; | ||
| 157 | if (volume->type_force) | ||
| 158 | suf = ".readonly"; | ||
| 159 | break; | ||
| 160 | case AFSVL_BACKVOL: | ||
| 161 | pref = '#'; | ||
| 162 | suf = ".backup"; | ||
| 163 | break; | ||
| 164 | } | ||
| 165 | |||
| 166 | seq_printf(m, "%c%s:%s%s", pref, cell->name, volume->vlocation->vldb.name, suf); | ||
| 167 | return 0; | ||
| 168 | } | ||
| 169 | |||
| 170 | /* | ||
| 171 | * Display the mount options in /proc/mounts. | ||
| 172 | */ | ||
| 173 | static int afs_show_options(struct seq_file *m, struct dentry *root) | ||
| 174 | { | ||
| 175 | if (test_bit(AFS_VNODE_AUTOCELL, &AFS_FS_I(d_inode(root))->flags)) | ||
| 176 | seq_puts(m, "autocell"); | ||
| 177 | return 0; | ||
| 178 | } | ||
| 179 | |||
| 180 | /* | ||
| 139 | * parse the mount options | 181 | * parse the mount options |
| 140 | * - this function has been shamelessly adapted from the ext3 fs which | 182 | * - this function has been shamelessly adapted from the ext3 fs which |
| 141 | * shamelessly adapted it from the msdos fs | 183 | * shamelessly adapted it from the msdos fs |
| @@ -427,7 +469,6 @@ static struct dentry *afs_mount(struct file_system_type *fs_type, | |||
| 427 | deactivate_locked_super(sb); | 469 | deactivate_locked_super(sb); |
| 428 | goto error; | 470 | goto error; |
| 429 | } | 471 | } |
| 430 | save_mount_options(sb, new_opts); | ||
| 431 | sb->s_flags |= MS_ACTIVE; | 472 | sb->s_flags |= MS_ACTIVE; |
| 432 | } else { | 473 | } else { |
| 433 | _debug("reuse"); | 474 | _debug("reuse"); |
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index 63e7c4760bfb..4a4a5a366158 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
| 21 | #include <linux/cred.h> | 21 | #include <linux/cred.h> |
| 22 | #include <linux/exportfs.h> | 22 | #include <linux/exportfs.h> |
| 23 | #include <linux/seq_file.h> | ||
| 23 | 24 | ||
| 24 | #include "befs.h" | 25 | #include "befs.h" |
| 25 | #include "btree.h" | 26 | #include "btree.h" |
| @@ -53,6 +54,7 @@ static int befs_nls2utf(struct super_block *sb, const char *in, int in_len, | |||
| 53 | static void befs_put_super(struct super_block *); | 54 | static void befs_put_super(struct super_block *); |
| 54 | static int befs_remount(struct super_block *, int *, char *); | 55 | static int befs_remount(struct super_block *, int *, char *); |
| 55 | static int befs_statfs(struct dentry *, struct kstatfs *); | 56 | static int befs_statfs(struct dentry *, struct kstatfs *); |
| 57 | static int befs_show_options(struct seq_file *, struct dentry *); | ||
| 56 | static int parse_options(char *, struct befs_mount_options *); | 58 | static int parse_options(char *, struct befs_mount_options *); |
| 57 | static struct dentry *befs_fh_to_dentry(struct super_block *sb, | 59 | static struct dentry *befs_fh_to_dentry(struct super_block *sb, |
| 58 | struct fid *fid, int fh_len, int fh_type); | 60 | struct fid *fid, int fh_len, int fh_type); |
| @@ -66,7 +68,7 @@ static const struct super_operations befs_sops = { | |||
| 66 | .put_super = befs_put_super, /* uninit super */ | 68 | .put_super = befs_put_super, /* uninit super */ |
| 67 | .statfs = befs_statfs, /* statfs */ | 69 | .statfs = befs_statfs, /* statfs */ |
| 68 | .remount_fs = befs_remount, | 70 | .remount_fs = befs_remount, |
| 69 | .show_options = generic_show_options, | 71 | .show_options = befs_show_options, |
| 70 | }; | 72 | }; |
| 71 | 73 | ||
| 72 | /* slab cache for befs_inode_info objects */ | 74 | /* slab cache for befs_inode_info objects */ |
| @@ -771,6 +773,24 @@ parse_options(char *options, struct befs_mount_options *opts) | |||
| 771 | return 1; | 773 | return 1; |
| 772 | } | 774 | } |
| 773 | 775 | ||
| 776 | static int befs_show_options(struct seq_file *m, struct dentry *root) | ||
| 777 | { | ||
| 778 | struct befs_sb_info *befs_sb = BEFS_SB(root->d_sb); | ||
| 779 | struct befs_mount_options *opts = &befs_sb->mount_opts; | ||
| 780 | |||
| 781 | if (!uid_eq(opts->uid, GLOBAL_ROOT_UID)) | ||
| 782 | seq_printf(m, ",uid=%u", | ||
| 783 | from_kuid_munged(&init_user_ns, opts->uid)); | ||
| 784 | if (!gid_eq(opts->gid, GLOBAL_ROOT_GID)) | ||
| 785 | seq_printf(m, ",gid=%u", | ||
| 786 | from_kgid_munged(&init_user_ns, opts->gid)); | ||
| 787 | if (opts->iocharset) | ||
| 788 | seq_printf(m, ",charset=%s", opts->iocharset); | ||
| 789 | if (opts->debug) | ||
| 790 | seq_puts(m, ",debug"); | ||
| 791 | return 0; | ||
| 792 | } | ||
| 793 | |||
| 774 | /* This function has the responsibiltiy of getting the | 794 | /* This function has the responsibiltiy of getting the |
| 775 | * filesystem ready for unmounting. | 795 | * filesystem ready for unmounting. |
| 776 | * Basically, we free everything that we allocated in | 796 | * Basically, we free everything that we allocated in |
| @@ -804,8 +824,6 @@ befs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 804 | const off_t x86_sb_off = 512; | 824 | const off_t x86_sb_off = 512; |
| 805 | int blocksize; | 825 | int blocksize; |
| 806 | 826 | ||
| 807 | save_mount_options(sb, data); | ||
| 808 | |||
| 809 | sb->s_fs_info = kzalloc(sizeof(*befs_sb), GFP_KERNEL); | 827 | sb->s_fs_info = kzalloc(sizeof(*befs_sb), GFP_KERNEL); |
| 810 | if (sb->s_fs_info == NULL) | 828 | if (sb->s_fs_info == NULL) |
| 811 | goto unacquire_none; | 829 | goto unacquire_none; |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 74e47794e63f..12540b6104b5 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
| @@ -1154,7 +1154,6 @@ static int btrfs_fill_super(struct super_block *sb, | |||
| 1154 | goto fail_close; | 1154 | goto fail_close; |
| 1155 | } | 1155 | } |
| 1156 | 1156 | ||
| 1157 | save_mount_options(sb, data); | ||
| 1158 | cleancache_init_fs(sb); | 1157 | cleancache_init_fs(sb); |
| 1159 | sb->s_flags |= MS_ACTIVE; | 1158 | sb->s_flags |= MS_ACTIVE; |
| 1160 | return 0; | 1159 | return 0; |
diff --git a/fs/dcache.c b/fs/dcache.c index 6c30be668487..f90141387f01 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
| @@ -90,6 +90,11 @@ EXPORT_SYMBOL(rename_lock); | |||
| 90 | 90 | ||
| 91 | static struct kmem_cache *dentry_cache __read_mostly; | 91 | static struct kmem_cache *dentry_cache __read_mostly; |
| 92 | 92 | ||
| 93 | const struct qstr empty_name = QSTR_INIT("", 0); | ||
| 94 | EXPORT_SYMBOL(empty_name); | ||
| 95 | const struct qstr slash_name = QSTR_INIT("/", 1); | ||
| 96 | EXPORT_SYMBOL(slash_name); | ||
| 97 | |||
| 93 | /* | 98 | /* |
| 94 | * This is the single most critical data structure when it comes | 99 | * This is the single most critical data structure when it comes |
| 95 | * to the dcache: the hashtable for lookups. Somebody should try | 100 | * to the dcache: the hashtable for lookups. Somebody should try |
| @@ -1606,8 +1611,7 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name) | |||
| 1606 | */ | 1611 | */ |
| 1607 | dentry->d_iname[DNAME_INLINE_LEN-1] = 0; | 1612 | dentry->d_iname[DNAME_INLINE_LEN-1] = 0; |
| 1608 | if (unlikely(!name)) { | 1613 | if (unlikely(!name)) { |
| 1609 | static const struct qstr anon = QSTR_INIT("/", 1); | 1614 | name = &slash_name; |
| 1610 | name = &anon; | ||
| 1611 | dname = dentry->d_iname; | 1615 | dname = dentry->d_iname; |
| 1612 | } else if (name->len > DNAME_INLINE_LEN-1) { | 1616 | } else if (name->len > DNAME_INLINE_LEN-1) { |
| 1613 | size_t size = offsetof(struct external_name, name[1]); | 1617 | size_t size = offsetof(struct external_name, name[1]); |
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index a0e4e2f7e0be..c59f015f386e 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c | |||
| @@ -203,8 +203,6 @@ static int debug_fill_super(struct super_block *sb, void *data, int silent) | |||
| 203 | struct debugfs_fs_info *fsi; | 203 | struct debugfs_fs_info *fsi; |
| 204 | int err; | 204 | int err; |
| 205 | 205 | ||
| 206 | save_mount_options(sb, data); | ||
| 207 | |||
| 208 | fsi = kzalloc(sizeof(struct debugfs_fs_info), GFP_KERNEL); | 206 | fsi = kzalloc(sizeof(struct debugfs_fs_info), GFP_KERNEL); |
| 209 | sb->s_fs_info = fsi; | 207 | sb->s_fs_info = fsi; |
| 210 | if (!fsi) { | 208 | if (!fsi) { |
diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c index d7a7c53803c1..5b68e4294faa 100644 --- a/fs/efivarfs/super.c +++ b/fs/efivarfs/super.c | |||
| @@ -29,7 +29,6 @@ static const struct super_operations efivarfs_ops = { | |||
| 29 | .statfs = simple_statfs, | 29 | .statfs = simple_statfs, |
| 30 | .drop_inode = generic_delete_inode, | 30 | .drop_inode = generic_delete_inode, |
| 31 | .evict_inode = efivarfs_evict_inode, | 31 | .evict_inode = efivarfs_evict_inode, |
| 32 | .show_options = generic_show_options, | ||
| 33 | }; | 32 | }; |
| 34 | 33 | ||
| 35 | static struct super_block *efivarfs_sb; | 34 | static struct super_block *efivarfs_sb; |
diff --git a/fs/filesystems.c b/fs/filesystems.c index 8b99955e3504..a920ad2629ac 100644 --- a/fs/filesystems.c +++ b/fs/filesystems.c | |||
| @@ -33,9 +33,10 @@ static struct file_system_type *file_systems; | |||
| 33 | static DEFINE_RWLOCK(file_systems_lock); | 33 | static DEFINE_RWLOCK(file_systems_lock); |
| 34 | 34 | ||
| 35 | /* WARNING: This can be used only if we _already_ own a reference */ | 35 | /* WARNING: This can be used only if we _already_ own a reference */ |
| 36 | void get_filesystem(struct file_system_type *fs) | 36 | struct file_system_type *get_filesystem(struct file_system_type *fs) |
| 37 | { | 37 | { |
| 38 | __module_get(fs->owner); | 38 | __module_get(fs->owner); |
| 39 | return fs; | ||
| 39 | } | 40 | } |
| 40 | 41 | ||
| 41 | void put_filesystem(struct file_system_type *fs) | 42 | void put_filesystem(struct file_system_type *fs) |
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index db427658ccd9..5ee2e2f8576c 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c | |||
| @@ -872,7 +872,6 @@ static struct gfs2_leaf *new_leaf(struct inode *inode, struct buffer_head **pbh, | |||
| 872 | struct buffer_head *bh; | 872 | struct buffer_head *bh; |
| 873 | struct gfs2_leaf *leaf; | 873 | struct gfs2_leaf *leaf; |
| 874 | struct gfs2_dirent *dent; | 874 | struct gfs2_dirent *dent; |
| 875 | struct qstr name = { .name = "" }; | ||
| 876 | struct timespec tv = current_time(inode); | 875 | struct timespec tv = current_time(inode); |
| 877 | 876 | ||
| 878 | error = gfs2_alloc_blocks(ip, &bn, &n, 0, NULL); | 877 | error = gfs2_alloc_blocks(ip, &bn, &n, 0, NULL); |
| @@ -896,7 +895,7 @@ static struct gfs2_leaf *new_leaf(struct inode *inode, struct buffer_head **pbh, | |||
| 896 | leaf->lf_sec = cpu_to_be64(tv.tv_sec); | 895 | leaf->lf_sec = cpu_to_be64(tv.tv_sec); |
| 897 | memset(leaf->lf_reserved2, 0, sizeof(leaf->lf_reserved2)); | 896 | memset(leaf->lf_reserved2, 0, sizeof(leaf->lf_reserved2)); |
| 898 | dent = (struct gfs2_dirent *)(leaf+1); | 897 | dent = (struct gfs2_dirent *)(leaf+1); |
| 899 | gfs2_qstr2dirent(&name, bh->b_size - sizeof(struct gfs2_leaf), dent); | 898 | gfs2_qstr2dirent(&empty_name, bh->b_size - sizeof(struct gfs2_leaf), dent); |
| 900 | *pbh = bh; | 899 | *pbh = bh; |
| 901 | return leaf; | 900 | return leaf; |
| 902 | } | 901 | } |
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 52388611635e..28d2753be094 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
| @@ -46,13 +46,13 @@ static const struct inode_operations hugetlbfs_dir_inode_operations; | |||
| 46 | static const struct inode_operations hugetlbfs_inode_operations; | 46 | static const struct inode_operations hugetlbfs_inode_operations; |
| 47 | 47 | ||
| 48 | struct hugetlbfs_config { | 48 | struct hugetlbfs_config { |
| 49 | kuid_t uid; | 49 | struct hstate *hstate; |
| 50 | kgid_t gid; | 50 | long max_hpages; |
| 51 | umode_t mode; | 51 | long nr_inodes; |
| 52 | long max_hpages; | 52 | long min_hpages; |
| 53 | long nr_inodes; | 53 | kuid_t uid; |
| 54 | struct hstate *hstate; | 54 | kgid_t gid; |
| 55 | long min_hpages; | 55 | umode_t mode; |
| 56 | }; | 56 | }; |
| 57 | 57 | ||
| 58 | struct hugetlbfs_inode_info { | 58 | struct hugetlbfs_inode_info { |
| @@ -861,6 +861,46 @@ static int hugetlbfs_error_remove_page(struct address_space *mapping, | |||
| 861 | return 0; | 861 | return 0; |
| 862 | } | 862 | } |
| 863 | 863 | ||
| 864 | /* | ||
| 865 | * Display the mount options in /proc/mounts. | ||
| 866 | */ | ||
| 867 | static int hugetlbfs_show_options(struct seq_file *m, struct dentry *root) | ||
| 868 | { | ||
| 869 | struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(root->d_sb); | ||
| 870 | struct hugepage_subpool *spool = sbinfo->spool; | ||
| 871 | unsigned long hpage_size = huge_page_size(sbinfo->hstate); | ||
| 872 | unsigned hpage_shift = huge_page_shift(sbinfo->hstate); | ||
| 873 | char mod; | ||
| 874 | |||
| 875 | if (!uid_eq(sbinfo->uid, GLOBAL_ROOT_UID)) | ||
| 876 | seq_printf(m, ",uid=%u", | ||
| 877 | from_kuid_munged(&init_user_ns, sbinfo->uid)); | ||
| 878 | if (!gid_eq(sbinfo->gid, GLOBAL_ROOT_GID)) | ||
| 879 | seq_printf(m, ",gid=%u", | ||
| 880 | from_kgid_munged(&init_user_ns, sbinfo->gid)); | ||
| 881 | if (sbinfo->mode != 0755) | ||
| 882 | seq_printf(m, ",mode=%o", sbinfo->mode); | ||
| 883 | if (sbinfo->max_inodes != -1) | ||
| 884 | seq_printf(m, ",nr_inodes=%lu", sbinfo->max_inodes); | ||
| 885 | |||
| 886 | hpage_size /= 1024; | ||
| 887 | mod = 'K'; | ||
| 888 | if (hpage_size >= 1024) { | ||
| 889 | hpage_size /= 1024; | ||
| 890 | mod = 'M'; | ||
| 891 | } | ||
| 892 | seq_printf(m, ",pagesize=%lu%c", hpage_size, mod); | ||
| 893 | if (spool) { | ||
| 894 | if (spool->max_hpages != -1) | ||
| 895 | seq_printf(m, ",size=%llu", | ||
| 896 | (unsigned long long)spool->max_hpages << hpage_shift); | ||
| 897 | if (spool->min_hpages != -1) | ||
| 898 | seq_printf(m, ",min_size=%llu", | ||
| 899 | (unsigned long long)spool->min_hpages << hpage_shift); | ||
| 900 | } | ||
| 901 | return 0; | ||
| 902 | } | ||
| 903 | |||
| 864 | static int hugetlbfs_statfs(struct dentry *dentry, struct kstatfs *buf) | 904 | static int hugetlbfs_statfs(struct dentry *dentry, struct kstatfs *buf) |
| 865 | { | 905 | { |
| 866 | struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(dentry->d_sb); | 906 | struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(dentry->d_sb); |
| @@ -1019,19 +1059,19 @@ static const struct super_operations hugetlbfs_ops = { | |||
| 1019 | .evict_inode = hugetlbfs_evict_inode, | 1059 | .evict_inode = hugetlbfs_evict_inode, |
| 1020 | .statfs = hugetlbfs_statfs, | 1060 | .statfs = hugetlbfs_statfs, |
| 1021 | .put_super = hugetlbfs_put_super, | 1061 | .put_super = hugetlbfs_put_super, |
| 1022 | .show_options = generic_show_options, | 1062 | .show_options = hugetlbfs_show_options, |
| 1023 | }; | 1063 | }; |
| 1024 | 1064 | ||
| 1025 | enum { NO_SIZE, SIZE_STD, SIZE_PERCENT }; | 1065 | enum hugetlbfs_size_type { NO_SIZE, SIZE_STD, SIZE_PERCENT }; |
| 1026 | 1066 | ||
| 1027 | /* | 1067 | /* |
| 1028 | * Convert size option passed from command line to number of huge pages | 1068 | * Convert size option passed from command line to number of huge pages |
| 1029 | * in the pool specified by hstate. Size option could be in bytes | 1069 | * in the pool specified by hstate. Size option could be in bytes |
| 1030 | * (val_type == SIZE_STD) or percentage of the pool (val_type == SIZE_PERCENT). | 1070 | * (val_type == SIZE_STD) or percentage of the pool (val_type == SIZE_PERCENT). |
| 1031 | */ | 1071 | */ |
| 1032 | static long long | 1072 | static long |
| 1033 | hugetlbfs_size_to_hpages(struct hstate *h, unsigned long long size_opt, | 1073 | hugetlbfs_size_to_hpages(struct hstate *h, unsigned long long size_opt, |
| 1034 | int val_type) | 1074 | enum hugetlbfs_size_type val_type) |
| 1035 | { | 1075 | { |
| 1036 | if (val_type == NO_SIZE) | 1076 | if (val_type == NO_SIZE) |
| 1037 | return -1; | 1077 | return -1; |
| @@ -1053,7 +1093,7 @@ hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig) | |||
| 1053 | substring_t args[MAX_OPT_ARGS]; | 1093 | substring_t args[MAX_OPT_ARGS]; |
| 1054 | int option; | 1094 | int option; |
| 1055 | unsigned long long max_size_opt = 0, min_size_opt = 0; | 1095 | unsigned long long max_size_opt = 0, min_size_opt = 0; |
| 1056 | int max_val_type = NO_SIZE, min_val_type = NO_SIZE; | 1096 | enum hugetlbfs_size_type max_val_type = NO_SIZE, min_val_type = NO_SIZE; |
| 1057 | 1097 | ||
| 1058 | if (!options) | 1098 | if (!options) |
| 1059 | return 0; | 1099 | return 0; |
| @@ -1167,8 +1207,6 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 1167 | struct hugetlbfs_config config; | 1207 | struct hugetlbfs_config config; |
| 1168 | struct hugetlbfs_sb_info *sbinfo; | 1208 | struct hugetlbfs_sb_info *sbinfo; |
| 1169 | 1209 | ||
| 1170 | save_mount_options(sb, data); | ||
| 1171 | |||
| 1172 | config.max_hpages = -1; /* No limit on size by default */ | 1210 | config.max_hpages = -1; /* No limit on size by default */ |
| 1173 | config.nr_inodes = -1; /* No limit on number of inodes by default */ | 1211 | config.nr_inodes = -1; /* No limit on number of inodes by default */ |
| 1174 | config.uid = current_fsuid(); | 1212 | config.uid = current_fsuid(); |
| @@ -1189,6 +1227,10 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 1189 | sbinfo->max_inodes = config.nr_inodes; | 1227 | sbinfo->max_inodes = config.nr_inodes; |
| 1190 | sbinfo->free_inodes = config.nr_inodes; | 1228 | sbinfo->free_inodes = config.nr_inodes; |
| 1191 | sbinfo->spool = NULL; | 1229 | sbinfo->spool = NULL; |
| 1230 | sbinfo->uid = config.uid; | ||
| 1231 | sbinfo->gid = config.gid; | ||
| 1232 | sbinfo->mode = config.mode; | ||
| 1233 | |||
| 1192 | /* | 1234 | /* |
| 1193 | * Allocate and initialize subpool if maximum or minimum size is | 1235 | * Allocate and initialize subpool if maximum or minimum size is |
| 1194 | * specified. Any needed reservations (for minimim size) are taken | 1236 | * specified. Any needed reservations (for minimim size) are taken |
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 020ba0936146..8cf898a59730 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/parser.h> | 23 | #include <linux/parser.h> |
| 24 | #include <linux/mpage.h> | 24 | #include <linux/mpage.h> |
| 25 | #include <linux/user_namespace.h> | 25 | #include <linux/user_namespace.h> |
| 26 | #include <linux/seq_file.h> | ||
| 26 | 27 | ||
| 27 | #include "isofs.h" | 28 | #include "isofs.h" |
| 28 | #include "zisofs.h" | 29 | #include "zisofs.h" |
| @@ -57,6 +58,7 @@ static void isofs_put_super(struct super_block *sb) | |||
| 57 | 58 | ||
| 58 | static int isofs_read_inode(struct inode *, int relocated); | 59 | static int isofs_read_inode(struct inode *, int relocated); |
| 59 | static int isofs_statfs (struct dentry *, struct kstatfs *); | 60 | static int isofs_statfs (struct dentry *, struct kstatfs *); |
| 61 | static int isofs_show_options(struct seq_file *, struct dentry *); | ||
| 60 | 62 | ||
| 61 | static struct kmem_cache *isofs_inode_cachep; | 63 | static struct kmem_cache *isofs_inode_cachep; |
| 62 | 64 | ||
| @@ -123,7 +125,7 @@ static const struct super_operations isofs_sops = { | |||
| 123 | .put_super = isofs_put_super, | 125 | .put_super = isofs_put_super, |
| 124 | .statfs = isofs_statfs, | 126 | .statfs = isofs_statfs, |
| 125 | .remount_fs = isofs_remount, | 127 | .remount_fs = isofs_remount, |
| 126 | .show_options = generic_show_options, | 128 | .show_options = isofs_show_options, |
| 127 | }; | 129 | }; |
| 128 | 130 | ||
| 129 | 131 | ||
| @@ -473,6 +475,48 @@ static int parse_options(char *options, struct iso9660_options *popt) | |||
| 473 | } | 475 | } |
| 474 | 476 | ||
| 475 | /* | 477 | /* |
| 478 | * Display the mount options in /proc/mounts. | ||
| 479 | */ | ||
| 480 | static int isofs_show_options(struct seq_file *m, struct dentry *root) | ||
| 481 | { | ||
| 482 | struct isofs_sb_info *sbi = ISOFS_SB(root->d_sb); | ||
| 483 | |||
| 484 | if (!sbi->s_rock) seq_puts(m, ",norock"); | ||
| 485 | else if (!sbi->s_joliet_level) seq_puts(m, ",nojoliet"); | ||
| 486 | if (sbi->s_cruft) seq_puts(m, ",cruft"); | ||
| 487 | if (sbi->s_hide) seq_puts(m, ",hide"); | ||
| 488 | if (sbi->s_nocompress) seq_puts(m, ",nocompress"); | ||
| 489 | if (sbi->s_overriderockperm) seq_puts(m, ",overriderockperm"); | ||
| 490 | if (sbi->s_showassoc) seq_puts(m, ",showassoc"); | ||
| 491 | if (sbi->s_utf8) seq_puts(m, ",utf8"); | ||
| 492 | |||
| 493 | if (sbi->s_check) seq_printf(m, ",check=%c", sbi->s_check); | ||
| 494 | if (sbi->s_mapping) seq_printf(m, ",map=%c", sbi->s_mapping); | ||
| 495 | if (sbi->s_session != 255) seq_printf(m, ",session=%u", sbi->s_session - 1); | ||
| 496 | if (sbi->s_sbsector != -1) seq_printf(m, ",sbsector=%u", sbi->s_sbsector); | ||
| 497 | |||
| 498 | if (root->d_sb->s_blocksize != 1024) | ||
| 499 | seq_printf(m, ",blocksize=%lu", root->d_sb->s_blocksize); | ||
| 500 | |||
| 501 | if (sbi->s_uid_set) | ||
| 502 | seq_printf(m, ",uid=%u", | ||
| 503 | from_kuid_munged(&init_user_ns, sbi->s_uid)); | ||
| 504 | if (sbi->s_gid_set) | ||
| 505 | seq_printf(m, ",gid=%u", | ||
| 506 | from_kgid_munged(&init_user_ns, sbi->s_gid)); | ||
| 507 | |||
| 508 | if (sbi->s_dmode != ISOFS_INVALID_MODE) | ||
| 509 | seq_printf(m, ",dmode=%o", sbi->s_dmode); | ||
| 510 | if (sbi->s_fmode != ISOFS_INVALID_MODE) | ||
| 511 | seq_printf(m, ",fmode=%o", sbi->s_fmode); | ||
| 512 | |||
| 513 | if (sbi->s_nls_iocharset && | ||
| 514 | strcmp(sbi->s_nls_iocharset->charset, CONFIG_NLS_DEFAULT) != 0) | ||
| 515 | seq_printf(m, ",iocharset=%s", sbi->s_nls_iocharset->charset); | ||
| 516 | return 0; | ||
| 517 | } | ||
| 518 | |||
| 519 | /* | ||
| 476 | * look if the driver can tell the multi session redirection value | 520 | * look if the driver can tell the multi session redirection value |
| 477 | * | 521 | * |
| 478 | * don't change this if you don't know what you do, please! | 522 | * don't change this if you don't know what you do, please! |
| @@ -583,8 +627,6 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) | |||
| 583 | int table, error = -EINVAL; | 627 | int table, error = -EINVAL; |
| 584 | unsigned int vol_desc_start; | 628 | unsigned int vol_desc_start; |
| 585 | 629 | ||
| 586 | save_mount_options(s, data); | ||
| 587 | |||
| 588 | sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); | 630 | sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); |
| 589 | if (!sbi) | 631 | if (!sbi) |
| 590 | return -ENOMEM; | 632 | return -ENOMEM; |
| @@ -605,6 +647,8 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) | |||
| 605 | opt.blocksize = sb_min_blocksize(s, opt.blocksize); | 647 | opt.blocksize = sb_min_blocksize(s, opt.blocksize); |
| 606 | 648 | ||
| 607 | sbi->s_high_sierra = 0; /* default is iso9660 */ | 649 | sbi->s_high_sierra = 0; /* default is iso9660 */ |
| 650 | sbi->s_session = opt.session; | ||
| 651 | sbi->s_sbsector = opt.sbsector; | ||
| 608 | 652 | ||
| 609 | vol_desc_start = (opt.sbsector != -1) ? | 653 | vol_desc_start = (opt.sbsector != -1) ? |
| 610 | opt.sbsector : isofs_get_last_session(s,opt.session); | 654 | opt.sbsector : isofs_get_last_session(s,opt.session); |
| @@ -911,6 +955,7 @@ root_found: | |||
| 911 | table += 2; | 955 | table += 2; |
| 912 | if (opt.check == 'r') | 956 | if (opt.check == 'r') |
| 913 | table++; | 957 | table++; |
| 958 | sbi->s_check = opt.check; | ||
| 914 | 959 | ||
| 915 | if (table) | 960 | if (table) |
| 916 | s->s_d_op = &isofs_dentry_ops[table - 1]; | 961 | s->s_d_op = &isofs_dentry_ops[table - 1]; |
diff --git a/fs/isofs/isofs.h b/fs/isofs/isofs.h index 0ac4c1f73fbd..133a456b0425 100644 --- a/fs/isofs/isofs.h +++ b/fs/isofs/isofs.h | |||
| @@ -36,8 +36,11 @@ struct isofs_sb_info { | |||
| 36 | unsigned long s_max_size; | 36 | unsigned long s_max_size; |
| 37 | 37 | ||
| 38 | int s_rock_offset; /* offset of SUSP fields within SU area */ | 38 | int s_rock_offset; /* offset of SUSP fields within SU area */ |
| 39 | s32 s_sbsector; | ||
| 39 | unsigned char s_joliet_level; | 40 | unsigned char s_joliet_level; |
| 40 | unsigned char s_mapping; | 41 | unsigned char s_mapping; |
| 42 | unsigned char s_check; | ||
| 43 | unsigned char s_session; | ||
| 41 | unsigned int s_high_sierra:1; | 44 | unsigned int s_high_sierra:1; |
| 42 | unsigned int s_rock:2; | 45 | unsigned int s_rock:2; |
| 43 | unsigned int s_utf8:1; | 46 | unsigned int s_utf8:1; |
diff --git a/fs/namei.c b/fs/namei.c index e0b46eb0e212..88fd38d1e3e7 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -3400,7 +3400,6 @@ out: | |||
| 3400 | 3400 | ||
| 3401 | struct dentry *vfs_tmpfile(struct dentry *dentry, umode_t mode, int open_flag) | 3401 | struct dentry *vfs_tmpfile(struct dentry *dentry, umode_t mode, int open_flag) |
| 3402 | { | 3402 | { |
| 3403 | static const struct qstr name = QSTR_INIT("/", 1); | ||
| 3404 | struct dentry *child = NULL; | 3403 | struct dentry *child = NULL; |
| 3405 | struct inode *dir = dentry->d_inode; | 3404 | struct inode *dir = dentry->d_inode; |
| 3406 | struct inode *inode; | 3405 | struct inode *inode; |
| @@ -3414,7 +3413,7 @@ struct dentry *vfs_tmpfile(struct dentry *dentry, umode_t mode, int open_flag) | |||
| 3414 | if (!dir->i_op->tmpfile) | 3413 | if (!dir->i_op->tmpfile) |
| 3415 | goto out_err; | 3414 | goto out_err; |
| 3416 | error = -ENOMEM; | 3415 | error = -ENOMEM; |
| 3417 | child = d_alloc(dentry, &name); | 3416 | child = d_alloc(dentry, &slash_name); |
| 3418 | if (unlikely(!child)) | 3417 | if (unlikely(!child)) |
| 3419 | goto out_err; | 3418 | goto out_err; |
| 3420 | error = dir->i_op->tmpfile(dir, child, mode); | 3419 | error = dir->i_op->tmpfile(dir, child, mode); |
diff --git a/fs/namespace.c b/fs/namespace.c index 81f934b5d571..f8893dc6a989 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
| @@ -1238,65 +1238,6 @@ struct vfsmount *mnt_clone_internal(const struct path *path) | |||
| 1238 | return &p->mnt; | 1238 | return &p->mnt; |
| 1239 | } | 1239 | } |
| 1240 | 1240 | ||
| 1241 | static inline void mangle(struct seq_file *m, const char *s) | ||
| 1242 | { | ||
| 1243 | seq_escape(m, s, " \t\n\\"); | ||
| 1244 | } | ||
| 1245 | |||
| 1246 | /* | ||
| 1247 | * Simple .show_options callback for filesystems which don't want to | ||
| 1248 | * implement more complex mount option showing. | ||
| 1249 | * | ||
| 1250 | * See also save_mount_options(). | ||
| 1251 | */ | ||
| 1252 | int generic_show_options(struct seq_file *m, struct dentry *root) | ||
| 1253 | { | ||
| 1254 | const char *options; | ||
| 1255 | |||
| 1256 | rcu_read_lock(); | ||
| 1257 | options = rcu_dereference(root->d_sb->s_options); | ||
| 1258 | |||
| 1259 | if (options != NULL && options[0]) { | ||
| 1260 | seq_putc(m, ','); | ||
| 1261 | mangle(m, options); | ||
| 1262 | } | ||
| 1263 | rcu_read_unlock(); | ||
| 1264 | |||
| 1265 | return 0; | ||
| 1266 | } | ||
| 1267 | EXPORT_SYMBOL(generic_show_options); | ||
| 1268 | |||
| 1269 | /* | ||
| 1270 | * If filesystem uses generic_show_options(), this function should be | ||
| 1271 | * called from the fill_super() callback. | ||
| 1272 | * | ||
| 1273 | * The .remount_fs callback usually needs to be handled in a special | ||
| 1274 | * way, to make sure, that previous options are not overwritten if the | ||
| 1275 | * remount fails. | ||
| 1276 | * | ||
| 1277 | * Also note, that if the filesystem's .remount_fs function doesn't | ||
| 1278 | * reset all options to their default value, but changes only newly | ||
| 1279 | * given options, then the displayed options will not reflect reality | ||
| 1280 | * any more. | ||
| 1281 | */ | ||
| 1282 | void save_mount_options(struct super_block *sb, char *options) | ||
| 1283 | { | ||
| 1284 | BUG_ON(sb->s_options); | ||
| 1285 | rcu_assign_pointer(sb->s_options, kstrdup(options, GFP_KERNEL)); | ||
| 1286 | } | ||
| 1287 | EXPORT_SYMBOL(save_mount_options); | ||
| 1288 | |||
| 1289 | void replace_mount_options(struct super_block *sb, char *options) | ||
| 1290 | { | ||
| 1291 | char *old = sb->s_options; | ||
| 1292 | rcu_assign_pointer(sb->s_options, options); | ||
| 1293 | if (old) { | ||
| 1294 | synchronize_rcu(); | ||
| 1295 | kfree(old); | ||
| 1296 | } | ||
| 1297 | } | ||
| 1298 | EXPORT_SYMBOL(replace_mount_options); | ||
| 1299 | |||
| 1300 | #ifdef CONFIG_PROC_FS | 1241 | #ifdef CONFIG_PROC_FS |
| 1301 | /* iterator; we want it to have access to namespace_sem, thus here... */ | 1242 | /* iterator; we want it to have access to namespace_sem, thus here... */ |
| 1302 | static void *m_start(struct seq_file *m, loff_t *pos) | 1243 | static void *m_start(struct seq_file *m, loff_t *pos) |
| @@ -1657,7 +1598,7 @@ out_unlock: | |||
| 1657 | namespace_unlock(); | 1598 | namespace_unlock(); |
| 1658 | } | 1599 | } |
| 1659 | 1600 | ||
| 1660 | /* | 1601 | /* |
| 1661 | * Is the caller allowed to modify his namespace? | 1602 | * Is the caller allowed to modify his namespace? |
| 1662 | */ | 1603 | */ |
| 1663 | static inline bool may_mount(void) | 1604 | static inline bool may_mount(void) |
| @@ -2211,7 +2152,7 @@ static int do_loopback(struct path *path, const char *old_name, | |||
| 2211 | 2152 | ||
| 2212 | err = -EINVAL; | 2153 | err = -EINVAL; |
| 2213 | if (mnt_ns_loop(old_path.dentry)) | 2154 | if (mnt_ns_loop(old_path.dentry)) |
| 2214 | goto out; | 2155 | goto out; |
| 2215 | 2156 | ||
| 2216 | mp = lock_mount(path); | 2157 | mp = lock_mount(path); |
| 2217 | err = PTR_ERR(mp); | 2158 | err = PTR_ERR(mp); |
| @@ -53,7 +53,6 @@ static void nsfs_evict(struct inode *inode) | |||
| 53 | static void *__ns_get_path(struct path *path, struct ns_common *ns) | 53 | static void *__ns_get_path(struct path *path, struct ns_common *ns) |
| 54 | { | 54 | { |
| 55 | struct vfsmount *mnt = nsfs_mnt; | 55 | struct vfsmount *mnt = nsfs_mnt; |
| 56 | struct qstr qname = { .name = "", }; | ||
| 57 | struct dentry *dentry; | 56 | struct dentry *dentry; |
| 58 | struct inode *inode; | 57 | struct inode *inode; |
| 59 | unsigned long d; | 58 | unsigned long d; |
| @@ -85,7 +84,7 @@ slow: | |||
| 85 | inode->i_fop = &ns_file_operations; | 84 | inode->i_fop = &ns_file_operations; |
| 86 | inode->i_private = ns; | 85 | inode->i_private = ns; |
| 87 | 86 | ||
| 88 | dentry = d_alloc_pseudo(mnt->mnt_sb, &qname); | 87 | dentry = d_alloc_pseudo(mnt->mnt_sb, &empty_name); |
| 89 | if (!dentry) { | 88 | if (!dentry) { |
| 90 | iput(inode); | 89 | iput(inode); |
| 91 | return ERR_PTR(-ENOMEM); | 90 | return ERR_PTR(-ENOMEM); |
diff --git a/fs/omfs/inode.c b/fs/omfs/inode.c index 8c9034ee7383..ee14af9e26f2 100644 --- a/fs/omfs/inode.c +++ b/fs/omfs/inode.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/buffer_head.h> | 13 | #include <linux/buffer_head.h> |
| 14 | #include <linux/vmalloc.h> | 14 | #include <linux/vmalloc.h> |
| 15 | #include <linux/writeback.h> | 15 | #include <linux/writeback.h> |
| 16 | #include <linux/seq_file.h> | ||
| 16 | #include <linux/crc-itu-t.h> | 17 | #include <linux/crc-itu-t.h> |
| 17 | #include "omfs.h" | 18 | #include "omfs.h" |
| 18 | 19 | ||
| @@ -290,12 +291,40 @@ static int omfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
| 290 | return 0; | 291 | return 0; |
| 291 | } | 292 | } |
| 292 | 293 | ||
| 294 | /* | ||
| 295 | * Display the mount options in /proc/mounts. | ||
| 296 | */ | ||
| 297 | static int omfs_show_options(struct seq_file *m, struct dentry *root) | ||
| 298 | { | ||
| 299 | struct omfs_sb_info *sbi = OMFS_SB(root->d_sb); | ||
| 300 | umode_t cur_umask = current_umask(); | ||
| 301 | |||
| 302 | if (!uid_eq(sbi->s_uid, current_uid())) | ||
| 303 | seq_printf(m, ",uid=%u", | ||
| 304 | from_kuid_munged(&init_user_ns, sbi->s_uid)); | ||
| 305 | if (!gid_eq(sbi->s_gid, current_gid())) | ||
| 306 | seq_printf(m, ",gid=%u", | ||
| 307 | from_kgid_munged(&init_user_ns, sbi->s_gid)); | ||
| 308 | |||
| 309 | if (sbi->s_dmask == sbi->s_fmask) { | ||
| 310 | if (sbi->s_fmask != cur_umask) | ||
| 311 | seq_printf(m, ",umask=%o", sbi->s_fmask); | ||
| 312 | } else { | ||
| 313 | if (sbi->s_dmask != cur_umask) | ||
| 314 | seq_printf(m, ",dmask=%o", sbi->s_dmask); | ||
| 315 | if (sbi->s_fmask != cur_umask) | ||
| 316 | seq_printf(m, ",fmask=%o", sbi->s_fmask); | ||
| 317 | } | ||
| 318 | |||
| 319 | return 0; | ||
| 320 | } | ||
| 321 | |||
| 293 | static const struct super_operations omfs_sops = { | 322 | static const struct super_operations omfs_sops = { |
| 294 | .write_inode = omfs_write_inode, | 323 | .write_inode = omfs_write_inode, |
| 295 | .evict_inode = omfs_evict_inode, | 324 | .evict_inode = omfs_evict_inode, |
| 296 | .put_super = omfs_put_super, | 325 | .put_super = omfs_put_super, |
| 297 | .statfs = omfs_statfs, | 326 | .statfs = omfs_statfs, |
| 298 | .show_options = generic_show_options, | 327 | .show_options = omfs_show_options, |
| 299 | }; | 328 | }; |
| 300 | 329 | ||
| 301 | /* | 330 | /* |
| @@ -434,8 +463,6 @@ static int omfs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 434 | struct inode *root; | 463 | struct inode *root; |
| 435 | int ret = -EINVAL; | 464 | int ret = -EINVAL; |
| 436 | 465 | ||
| 437 | save_mount_options(sb, (char *) data); | ||
| 438 | |||
| 439 | sbi = kzalloc(sizeof(struct omfs_sb_info), GFP_KERNEL); | 466 | sbi = kzalloc(sizeof(struct omfs_sb_info), GFP_KERNEL); |
| 440 | if (!sbi) | 467 | if (!sbi) |
| 441 | return -ENOMEM; | 468 | return -ENOMEM; |
diff --git a/fs/orangefs/super.c b/fs/orangefs/super.c index 5c7c273e17ec..5a1bed6c8c6a 100644 --- a/fs/orangefs/super.c +++ b/fs/orangefs/super.c | |||
| @@ -35,6 +35,19 @@ static const match_table_t tokens = { | |||
| 35 | 35 | ||
| 36 | uint64_t orangefs_features; | 36 | uint64_t orangefs_features; |
| 37 | 37 | ||
| 38 | static int orangefs_show_options(struct seq_file *m, struct dentry *root) | ||
| 39 | { | ||
| 40 | struct orangefs_sb_info_s *orangefs_sb = ORANGEFS_SB(root->d_sb); | ||
| 41 | |||
| 42 | if (root->d_sb->s_flags & MS_POSIXACL) | ||
| 43 | seq_puts(m, ",acl"); | ||
| 44 | if (orangefs_sb->flags & ORANGEFS_OPT_INTR) | ||
| 45 | seq_puts(m, ",intr"); | ||
| 46 | if (orangefs_sb->flags & ORANGEFS_OPT_LOCAL_LOCK) | ||
| 47 | seq_puts(m, ",local_lock"); | ||
| 48 | return 0; | ||
| 49 | } | ||
| 50 | |||
| 38 | static int parse_mount_options(struct super_block *sb, char *options, | 51 | static int parse_mount_options(struct super_block *sb, char *options, |
| 39 | int silent) | 52 | int silent) |
| 40 | { | 53 | { |
| @@ -305,7 +318,7 @@ static const struct super_operations orangefs_s_ops = { | |||
| 305 | .drop_inode = generic_delete_inode, | 318 | .drop_inode = generic_delete_inode, |
| 306 | .statfs = orangefs_statfs, | 319 | .statfs = orangefs_statfs, |
| 307 | .remount_fs = orangefs_remount_fs, | 320 | .remount_fs = orangefs_remount_fs, |
| 308 | .show_options = generic_show_options, | 321 | .show_options = orangefs_show_options, |
| 309 | }; | 322 | }; |
| 310 | 323 | ||
| 311 | static struct dentry *orangefs_fh_to_dentry(struct super_block *sb, | 324 | static struct dentry *orangefs_fh_to_dentry(struct super_block *sb, |
| @@ -739,13 +739,12 @@ int create_pipe_files(struct file **res, int flags) | |||
| 739 | struct inode *inode = get_pipe_inode(); | 739 | struct inode *inode = get_pipe_inode(); |
| 740 | struct file *f; | 740 | struct file *f; |
| 741 | struct path path; | 741 | struct path path; |
| 742 | static struct qstr name = { .name = "" }; | ||
| 743 | 742 | ||
| 744 | if (!inode) | 743 | if (!inode) |
| 745 | return -ENFILE; | 744 | return -ENFILE; |
| 746 | 745 | ||
| 747 | err = -ENOMEM; | 746 | err = -ENOMEM; |
| 748 | path.dentry = d_alloc_pseudo(pipe_mnt->mnt_sb, &name); | 747 | path.dentry = d_alloc_pseudo(pipe_mnt->mnt_sb, &empty_name); |
| 749 | if (!path.dentry) | 748 | if (!path.dentry) |
| 750 | goto err_inode; | 749 | goto err_inode; |
| 751 | path.mnt = mntget(pipe_mnt); | 750 | path.mnt = mntget(pipe_mnt); |
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c index 4d02c3b65061..fefd22611cf6 100644 --- a/fs/pstore/inode.c +++ b/fs/pstore/inode.c | |||
| @@ -283,6 +283,16 @@ static void parse_options(char *options) | |||
| 283 | } | 283 | } |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | /* | ||
| 287 | * Display the mount options in /proc/mounts. | ||
| 288 | */ | ||
| 289 | static int pstore_show_options(struct seq_file *m, struct dentry *root) | ||
| 290 | { | ||
| 291 | if (kmsg_bytes != PSTORE_DEFAULT_KMSG_BYTES) | ||
| 292 | seq_printf(m, ",kmsg_bytes=%lu", kmsg_bytes); | ||
| 293 | return 0; | ||
| 294 | } | ||
| 295 | |||
| 286 | static int pstore_remount(struct super_block *sb, int *flags, char *data) | 296 | static int pstore_remount(struct super_block *sb, int *flags, char *data) |
| 287 | { | 297 | { |
| 288 | sync_filesystem(sb); | 298 | sync_filesystem(sb); |
| @@ -296,7 +306,7 @@ static const struct super_operations pstore_ops = { | |||
| 296 | .drop_inode = generic_delete_inode, | 306 | .drop_inode = generic_delete_inode, |
| 297 | .evict_inode = pstore_evict_inode, | 307 | .evict_inode = pstore_evict_inode, |
| 298 | .remount_fs = pstore_remount, | 308 | .remount_fs = pstore_remount, |
| 299 | .show_options = generic_show_options, | 309 | .show_options = pstore_show_options, |
| 300 | }; | 310 | }; |
| 301 | 311 | ||
| 302 | static struct super_block *pstore_sb; | 312 | static struct super_block *pstore_sb; |
| @@ -448,8 +458,6 @@ static int pstore_fill_super(struct super_block *sb, void *data, int silent) | |||
| 448 | { | 458 | { |
| 449 | struct inode *inode; | 459 | struct inode *inode; |
| 450 | 460 | ||
| 451 | save_mount_options(sb, data); | ||
| 452 | |||
| 453 | pstore_sb = sb; | 461 | pstore_sb = sb; |
| 454 | 462 | ||
| 455 | sb->s_maxbytes = MAX_LFS_FILESIZE; | 463 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
diff --git a/fs/pstore/internal.h b/fs/pstore/internal.h index 58051265626f..7f4e48c8d188 100644 --- a/fs/pstore/internal.h +++ b/fs/pstore/internal.h | |||
| @@ -5,6 +5,9 @@ | |||
| 5 | #include <linux/time.h> | 5 | #include <linux/time.h> |
| 6 | #include <linux/pstore.h> | 6 | #include <linux/pstore.h> |
| 7 | 7 | ||
| 8 | #define PSTORE_DEFAULT_KMSG_BYTES 10240 | ||
| 9 | extern unsigned long kmsg_bytes; | ||
| 10 | |||
| 8 | #ifdef CONFIG_PSTORE_FTRACE | 11 | #ifdef CONFIG_PSTORE_FTRACE |
| 9 | extern void pstore_register_ftrace(void); | 12 | extern void pstore_register_ftrace(void); |
| 10 | extern void pstore_unregister_ftrace(void); | 13 | extern void pstore_unregister_ftrace(void); |
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index 1b6e0ff6bff5..2b21d180157c 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c | |||
| @@ -99,7 +99,7 @@ static char *big_oops_buf; | |||
| 99 | static size_t big_oops_buf_sz; | 99 | static size_t big_oops_buf_sz; |
| 100 | 100 | ||
| 101 | /* How much of the console log to snapshot */ | 101 | /* How much of the console log to snapshot */ |
| 102 | static unsigned long kmsg_bytes = 10240; | 102 | unsigned long kmsg_bytes = PSTORE_DEFAULT_KMSG_BYTES; |
| 103 | 103 | ||
| 104 | void pstore_set_kmsg_bytes(int bytes) | 104 | void pstore_set_kmsg_bytes(int bytes) |
| 105 | { | 105 | { |
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index 26e45863e499..11201b2d06b9 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c | |||
| @@ -38,6 +38,14 @@ | |||
| 38 | #include <linux/uaccess.h> | 38 | #include <linux/uaccess.h> |
| 39 | #include "internal.h" | 39 | #include "internal.h" |
| 40 | 40 | ||
| 41 | struct ramfs_mount_opts { | ||
| 42 | umode_t mode; | ||
| 43 | }; | ||
| 44 | |||
| 45 | struct ramfs_fs_info { | ||
| 46 | struct ramfs_mount_opts mount_opts; | ||
| 47 | }; | ||
| 48 | |||
| 41 | #define RAMFS_DEFAULT_MODE 0755 | 49 | #define RAMFS_DEFAULT_MODE 0755 |
| 42 | 50 | ||
| 43 | static const struct super_operations ramfs_ops; | 51 | static const struct super_operations ramfs_ops; |
| @@ -149,14 +157,22 @@ static const struct inode_operations ramfs_dir_inode_operations = { | |||
| 149 | .rename = simple_rename, | 157 | .rename = simple_rename, |
| 150 | }; | 158 | }; |
| 151 | 159 | ||
| 160 | /* | ||
| 161 | * Display the mount options in /proc/mounts. | ||
| 162 | */ | ||
| 163 | static int ramfs_show_options(struct seq_file *m, struct dentry *root) | ||
| 164 | { | ||
| 165 | struct ramfs_fs_info *fsi = root->d_sb->s_fs_info; | ||
| 166 | |||
| 167 | if (fsi->mount_opts.mode != RAMFS_DEFAULT_MODE) | ||
| 168 | seq_printf(m, ",mode=%o", fsi->mount_opts.mode); | ||
| 169 | return 0; | ||
| 170 | } | ||
| 171 | |||
| 152 | static const struct super_operations ramfs_ops = { | 172 | static const struct super_operations ramfs_ops = { |
| 153 | .statfs = simple_statfs, | 173 | .statfs = simple_statfs, |
| 154 | .drop_inode = generic_delete_inode, | 174 | .drop_inode = generic_delete_inode, |
| 155 | .show_options = generic_show_options, | 175 | .show_options = ramfs_show_options, |
| 156 | }; | ||
| 157 | |||
| 158 | struct ramfs_mount_opts { | ||
| 159 | umode_t mode; | ||
| 160 | }; | 176 | }; |
| 161 | 177 | ||
| 162 | enum { | 178 | enum { |
| @@ -169,10 +185,6 @@ static const match_table_t tokens = { | |||
| 169 | {Opt_err, NULL} | 185 | {Opt_err, NULL} |
| 170 | }; | 186 | }; |
| 171 | 187 | ||
| 172 | struct ramfs_fs_info { | ||
| 173 | struct ramfs_mount_opts mount_opts; | ||
| 174 | }; | ||
| 175 | |||
| 176 | static int ramfs_parse_options(char *data, struct ramfs_mount_opts *opts) | 188 | static int ramfs_parse_options(char *data, struct ramfs_mount_opts *opts) |
| 177 | { | 189 | { |
| 178 | substring_t args[MAX_OPT_ARGS]; | 190 | substring_t args[MAX_OPT_ARGS]; |
| @@ -211,8 +223,6 @@ int ramfs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 211 | struct inode *inode; | 223 | struct inode *inode; |
| 212 | int err; | 224 | int err; |
| 213 | 225 | ||
| 214 | save_mount_options(sb, data); | ||
| 215 | |||
| 216 | fsi = kzalloc(sizeof(struct ramfs_fs_info), GFP_KERNEL); | 226 | fsi = kzalloc(sizeof(struct ramfs_fs_info), GFP_KERNEL); |
| 217 | sb->s_fs_info = fsi; | 227 | sb->s_fs_info = fsi; |
| 218 | if (!fsi) | 228 | if (!fsi) |
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 685f1e056998..306e4e9d172d 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
| @@ -1599,8 +1599,6 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) | |||
| 1599 | } | 1599 | } |
| 1600 | 1600 | ||
| 1601 | out_ok_unlocked: | 1601 | out_ok_unlocked: |
| 1602 | if (new_opts) | ||
| 1603 | replace_mount_options(s, new_opts); | ||
| 1604 | return 0; | 1602 | return 0; |
| 1605 | 1603 | ||
| 1606 | out_err_unlock: | 1604 | out_err_unlock: |
| @@ -1916,8 +1914,6 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) | |||
| 1916 | char *qf_names[REISERFS_MAXQUOTAS] = {}; | 1914 | char *qf_names[REISERFS_MAXQUOTAS] = {}; |
| 1917 | unsigned int qfmt = 0; | 1915 | unsigned int qfmt = 0; |
| 1918 | 1916 | ||
| 1919 | save_mount_options(s, data); | ||
| 1920 | |||
| 1921 | sbi = kzalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL); | 1917 | sbi = kzalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL); |
| 1922 | if (!sbi) | 1918 | if (!sbi) |
| 1923 | return -ENOMEM; | 1919 | return -ENOMEM; |
diff --git a/fs/super.c b/fs/super.c index adb0c0de428c..6bc3352adcf3 100644 --- a/fs/super.c +++ b/fs/super.c | |||
| @@ -168,7 +168,6 @@ static void destroy_super(struct super_block *s) | |||
| 168 | WARN_ON(!list_empty(&s->s_mounts)); | 168 | WARN_ON(!list_empty(&s->s_mounts)); |
| 169 | put_user_ns(s->s_user_ns); | 169 | put_user_ns(s->s_user_ns); |
| 170 | kfree(s->s_subtype); | 170 | kfree(s->s_subtype); |
| 171 | kfree(s->s_options); | ||
| 172 | call_rcu(&s->rcu, destroy_super_rcu); | 171 | call_rcu(&s->rcu, destroy_super_rcu); |
| 173 | } | 172 | } |
| 174 | 173 | ||
| @@ -508,7 +507,7 @@ retry: | |||
| 508 | return ERR_PTR(-ENOMEM); | 507 | return ERR_PTR(-ENOMEM); |
| 509 | goto retry; | 508 | goto retry; |
| 510 | } | 509 | } |
| 511 | 510 | ||
| 512 | err = set(s, data); | 511 | err = set(s, data); |
| 513 | if (err) { | 512 | if (err) { |
| 514 | spin_unlock(&sb_lock); | 513 | spin_unlock(&sb_lock); |
| @@ -771,7 +770,7 @@ restart: | |||
| 771 | spin_unlock(&sb_lock); | 770 | spin_unlock(&sb_lock); |
| 772 | return NULL; | 771 | return NULL; |
| 773 | } | 772 | } |
| 774 | 773 | ||
| 775 | struct super_block *user_get_super(dev_t dev) | 774 | struct super_block *user_get_super(dev_t dev) |
| 776 | { | 775 | { |
| 777 | struct super_block *sb; | 776 | struct super_block *sb; |
diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c index 328e89c2cf83..bea8ad876bf9 100644 --- a/fs/tracefs/inode.c +++ b/fs/tracefs/inode.c | |||
| @@ -270,8 +270,6 @@ static int trace_fill_super(struct super_block *sb, void *data, int silent) | |||
| 270 | struct tracefs_fs_info *fsi; | 270 | struct tracefs_fs_info *fsi; |
| 271 | int err; | 271 | int err; |
| 272 | 272 | ||
| 273 | save_mount_options(sb, data); | ||
| 274 | |||
| 275 | fsi = kzalloc(sizeof(struct tracefs_fs_info), GFP_KERNEL); | 273 | fsi = kzalloc(sizeof(struct tracefs_fs_info), GFP_KERNEL); |
| 276 | sb->s_fs_info = fsi; | 274 | sb->s_fs_info = fsi; |
| 277 | if (!fsi) { | 275 | if (!fsi) { |
diff --git a/include/linux/dcache.h b/include/linux/dcache.h index c706eaac692e..3f3ff4ccdc3f 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h | |||
| @@ -55,6 +55,11 @@ struct qstr { | |||
| 55 | 55 | ||
| 56 | #define QSTR_INIT(n,l) { { { .len = l } }, .name = n } | 56 | #define QSTR_INIT(n,l) { { { .len = l } }, .name = n } |
| 57 | 57 | ||
| 58 | extern const char empty_string[]; | ||
| 59 | extern const struct qstr empty_name; | ||
| 60 | extern const char slash_string[]; | ||
| 61 | extern const struct qstr slash_name; | ||
| 62 | |||
| 58 | struct dentry_stat_t { | 63 | struct dentry_stat_t { |
| 59 | long nr_dentry; | 64 | long nr_dentry; |
| 60 | long nr_unused; | 65 | long nr_unused; |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 976aaa1af82a..7b5d6816542b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
| @@ -1364,11 +1364,6 @@ struct super_block { | |||
| 1364 | */ | 1364 | */ |
| 1365 | char *s_subtype; | 1365 | char *s_subtype; |
| 1366 | 1366 | ||
| 1367 | /* | ||
| 1368 | * Saved mount options for lazy filesystems using | ||
| 1369 | * generic_show_options() | ||
| 1370 | */ | ||
| 1371 | char __rcu *s_options; | ||
| 1372 | const struct dentry_operations *s_d_op; /* default d_op for dentries */ | 1367 | const struct dentry_operations *s_d_op; /* default d_op for dentries */ |
| 1373 | 1368 | ||
| 1374 | /* | 1369 | /* |
| @@ -3046,7 +3041,7 @@ extern int generic_block_fiemap(struct inode *inode, | |||
| 3046 | struct fiemap_extent_info *fieinfo, u64 start, | 3041 | struct fiemap_extent_info *fieinfo, u64 start, |
| 3047 | u64 len, get_block_t *get_block); | 3042 | u64 len, get_block_t *get_block); |
| 3048 | 3043 | ||
| 3049 | extern void get_filesystem(struct file_system_type *fs); | 3044 | extern struct file_system_type *get_filesystem(struct file_system_type *fs); |
| 3050 | extern void put_filesystem(struct file_system_type *fs); | 3045 | extern void put_filesystem(struct file_system_type *fs); |
| 3051 | extern struct file_system_type *get_fs_type(const char *name); | 3046 | extern struct file_system_type *get_fs_type(const char *name); |
| 3052 | extern struct super_block *get_super(struct block_device *); | 3047 | extern struct super_block *get_super(struct block_device *); |
| @@ -3123,10 +3118,6 @@ extern void setattr_copy(struct inode *inode, const struct iattr *attr); | |||
| 3123 | 3118 | ||
| 3124 | extern int file_update_time(struct file *file); | 3119 | extern int file_update_time(struct file *file); |
| 3125 | 3120 | ||
| 3126 | extern int generic_show_options(struct seq_file *m, struct dentry *root); | ||
| 3127 | extern void save_mount_options(struct super_block *sb, char *options); | ||
| 3128 | extern void replace_mount_options(struct super_block *sb, char *options); | ||
| 3129 | |||
| 3130 | static inline bool io_is_direct(struct file *filp) | 3121 | static inline bool io_is_direct(struct file *filp) |
| 3131 | { | 3122 | { |
| 3132 | return (filp->f_flags & O_DIRECT) || IS_DAX(filp->f_mapping->host); | 3123 | return (filp->f_flags & O_DIRECT) || IS_DAX(filp->f_mapping->host); |
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 8d9fe131a240..0ed8e41aaf11 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h | |||
| @@ -268,6 +268,9 @@ struct hugetlbfs_sb_info { | |||
| 268 | spinlock_t stat_lock; | 268 | spinlock_t stat_lock; |
| 269 | struct hstate *hstate; | 269 | struct hstate *hstate; |
| 270 | struct hugepage_subpool *spool; | 270 | struct hugepage_subpool *spool; |
| 271 | kuid_t uid; | ||
| 272 | kgid_t gid; | ||
| 273 | umode_t mode; | ||
| 271 | }; | 274 | }; |
| 272 | 275 | ||
| 273 | static inline struct hugetlbfs_sb_info *HUGETLBFS_SB(struct super_block *sb) | 276 | static inline struct hugetlbfs_sb_info *HUGETLBFS_SB(struct super_block *sb) |
diff --git a/include/linux/string.h b/include/linux/string.h index 049866760e8b..a467e617eeb0 100644 --- a/include/linux/string.h +++ b/include/linux/string.h | |||
| @@ -137,6 +137,7 @@ extern char *kstrdup(const char *s, gfp_t gfp) __malloc; | |||
| 137 | extern const char *kstrdup_const(const char *s, gfp_t gfp); | 137 | extern const char *kstrdup_const(const char *s, gfp_t gfp); |
| 138 | extern char *kstrndup(const char *s, size_t len, gfp_t gfp); | 138 | extern char *kstrndup(const char *s, size_t len, gfp_t gfp); |
| 139 | extern void *kmemdup(const void *src, size_t len, gfp_t gfp); | 139 | extern void *kmemdup(const void *src, size_t len, gfp_t gfp); |
| 140 | extern char *kmemdup_nul(const char *s, size_t len, gfp_t gfp); | ||
| 140 | 141 | ||
| 141 | extern char **argv_split(gfp_t gfp, const char *str, int *argcp); | 142 | extern char **argv_split(gfp_t gfp, const char *str, int *argcp); |
| 142 | extern void argv_free(char **argv); | 143 | extern void argv_free(char **argv); |
diff --git a/include/net/9p/client.h b/include/net/9p/client.h index b582339ccef5..7af9d769b97d 100644 --- a/include/net/9p/client.h +++ b/include/net/9p/client.h | |||
| @@ -157,6 +157,18 @@ struct p9_client { | |||
| 157 | enum p9_trans_status status; | 157 | enum p9_trans_status status; |
| 158 | void *trans; | 158 | void *trans; |
| 159 | 159 | ||
| 160 | union { | ||
| 161 | struct { | ||
| 162 | int rfd; | ||
| 163 | int wfd; | ||
| 164 | } fd; | ||
| 165 | struct { | ||
| 166 | u16 port; | ||
| 167 | bool privport; | ||
| 168 | |||
| 169 | } tcp; | ||
| 170 | } trans_opts; | ||
| 171 | |||
| 160 | struct p9_idpool *fidpool; | 172 | struct p9_idpool *fidpool; |
| 161 | struct list_head fidlist; | 173 | struct list_head fidlist; |
| 162 | 174 | ||
| @@ -213,6 +225,7 @@ struct p9_dirent { | |||
| 213 | 225 | ||
| 214 | struct iov_iter; | 226 | struct iov_iter; |
| 215 | 227 | ||
| 228 | int p9_show_client_options(struct seq_file *m, struct p9_client *clnt); | ||
| 216 | int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb); | 229 | int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb); |
| 217 | int p9_client_rename(struct p9_fid *fid, struct p9_fid *newdirfid, | 230 | int p9_client_rename(struct p9_fid *fid, struct p9_fid *newdirfid, |
| 218 | const char *name); | 231 | const char *name); |
diff --git a/include/net/9p/transport.h b/include/net/9p/transport.h index 5122b5e40f78..1625fb842ac4 100644 --- a/include/net/9p/transport.h +++ b/include/net/9p/transport.h | |||
| @@ -62,6 +62,7 @@ struct p9_trans_module { | |||
| 62 | int (*cancelled)(struct p9_client *, struct p9_req_t *req); | 62 | int (*cancelled)(struct p9_client *, struct p9_req_t *req); |
| 63 | int (*zc_request)(struct p9_client *, struct p9_req_t *, | 63 | int (*zc_request)(struct p9_client *, struct p9_req_t *, |
| 64 | struct iov_iter *, struct iov_iter *, int , int, int); | 64 | struct iov_iter *, struct iov_iter *, int , int, int); |
| 65 | int (*show_options)(struct seq_file *, struct p9_client *); | ||
| 65 | }; | 66 | }; |
| 66 | 67 | ||
| 67 | void v9fs_register_trans(struct p9_trans_module *m); | 68 | void v9fs_register_trans(struct p9_trans_module *m); |
diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c index 9bbd33497d3d..e833ed914358 100644 --- a/kernel/bpf/inode.c +++ b/kernel/bpf/inode.c | |||
| @@ -377,10 +377,22 @@ static void bpf_evict_inode(struct inode *inode) | |||
| 377 | bpf_any_put(inode->i_private, type); | 377 | bpf_any_put(inode->i_private, type); |
| 378 | } | 378 | } |
| 379 | 379 | ||
| 380 | /* | ||
| 381 | * Display the mount options in /proc/mounts. | ||
| 382 | */ | ||
| 383 | static int bpf_show_options(struct seq_file *m, struct dentry *root) | ||
| 384 | { | ||
| 385 | umode_t mode = d_inode(root)->i_mode & S_IALLUGO & ~S_ISVTX; | ||
| 386 | |||
| 387 | if (mode != S_IRWXUGO) | ||
| 388 | seq_printf(m, ",mode=%o", mode); | ||
| 389 | return 0; | ||
| 390 | } | ||
| 391 | |||
| 380 | static const struct super_operations bpf_super_ops = { | 392 | static const struct super_operations bpf_super_ops = { |
| 381 | .statfs = simple_statfs, | 393 | .statfs = simple_statfs, |
| 382 | .drop_inode = generic_delete_inode, | 394 | .drop_inode = generic_delete_inode, |
| 383 | .show_options = generic_show_options, | 395 | .show_options = bpf_show_options, |
| 384 | .evict_inode = bpf_evict_inode, | 396 | .evict_inode = bpf_evict_inode, |
| 385 | }; | 397 | }; |
| 386 | 398 | ||
| @@ -434,8 +446,6 @@ static int bpf_fill_super(struct super_block *sb, void *data, int silent) | |||
| 434 | struct inode *inode; | 446 | struct inode *inode; |
| 435 | int ret; | 447 | int ret; |
| 436 | 448 | ||
| 437 | save_mount_options(sb, data); | ||
| 438 | |||
| 439 | ret = bpf_parse_options(data, &opts); | 449 | ret = bpf_parse_options(data, &opts); |
| 440 | if (ret) | 450 | if (ret) |
| 441 | return ret; | 451 | return ret; |
| @@ -83,6 +83,8 @@ EXPORT_SYMBOL(kstrdup_const); | |||
| 83 | * @s: the string to duplicate | 83 | * @s: the string to duplicate |
| 84 | * @max: read at most @max chars from @s | 84 | * @max: read at most @max chars from @s |
| 85 | * @gfp: the GFP mask used in the kmalloc() call when allocating memory | 85 | * @gfp: the GFP mask used in the kmalloc() call when allocating memory |
| 86 | * | ||
| 87 | * Note: Use kmemdup_nul() instead if the size is known exactly. | ||
| 86 | */ | 88 | */ |
| 87 | char *kstrndup(const char *s, size_t max, gfp_t gfp) | 89 | char *kstrndup(const char *s, size_t max, gfp_t gfp) |
| 88 | { | 90 | { |
| @@ -121,6 +123,28 @@ void *kmemdup(const void *src, size_t len, gfp_t gfp) | |||
| 121 | EXPORT_SYMBOL(kmemdup); | 123 | EXPORT_SYMBOL(kmemdup); |
| 122 | 124 | ||
| 123 | /** | 125 | /** |
| 126 | * kmemdup_nul - Create a NUL-terminated string from unterminated data | ||
| 127 | * @s: The data to stringify | ||
| 128 | * @len: The size of the data | ||
| 129 | * @gfp: the GFP mask used in the kmalloc() call when allocating memory | ||
| 130 | */ | ||
| 131 | char *kmemdup_nul(const char *s, size_t len, gfp_t gfp) | ||
| 132 | { | ||
| 133 | char *buf; | ||
| 134 | |||
| 135 | if (!s) | ||
| 136 | return NULL; | ||
| 137 | |||
| 138 | buf = kmalloc_track_caller(len + 1, gfp); | ||
| 139 | if (buf) { | ||
| 140 | memcpy(buf, s, len); | ||
| 141 | buf[len] = '\0'; | ||
| 142 | } | ||
| 143 | return buf; | ||
| 144 | } | ||
| 145 | EXPORT_SYMBOL(kmemdup_nul); | ||
| 146 | |||
| 147 | /** | ||
| 124 | * memdup_user - duplicate memory region from user space | 148 | * memdup_user - duplicate memory region from user space |
| 125 | * | 149 | * |
| 126 | * @src: source address in user space | 150 | * @src: source address in user space |
diff --git a/net/9p/client.c b/net/9p/client.c index 1218fb3b52da..4674235b0d9b 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | #include <linux/uio.h> | 37 | #include <linux/uio.h> |
| 38 | #include <net/9p/9p.h> | 38 | #include <net/9p/9p.h> |
| 39 | #include <linux/parser.h> | 39 | #include <linux/parser.h> |
| 40 | #include <linux/seq_file.h> | ||
| 40 | #include <net/9p/client.h> | 41 | #include <net/9p/client.h> |
| 41 | #include <net/9p/transport.h> | 42 | #include <net/9p/transport.h> |
| 42 | #include "protocol.h" | 43 | #include "protocol.h" |
| @@ -77,6 +78,30 @@ inline int p9_is_proto_dotu(struct p9_client *clnt) | |||
| 77 | } | 78 | } |
| 78 | EXPORT_SYMBOL(p9_is_proto_dotu); | 79 | EXPORT_SYMBOL(p9_is_proto_dotu); |
| 79 | 80 | ||
| 81 | int p9_show_client_options(struct seq_file *m, struct p9_client *clnt) | ||
| 82 | { | ||
| 83 | if (clnt->msize != 8192) | ||
| 84 | seq_printf(m, ",msize=%u", clnt->msize); | ||
| 85 | seq_printf(m, "trans=%s", clnt->trans_mod->name); | ||
| 86 | |||
| 87 | switch (clnt->proto_version) { | ||
| 88 | case p9_proto_legacy: | ||
| 89 | seq_puts(m, ",noextend"); | ||
| 90 | break; | ||
| 91 | case p9_proto_2000u: | ||
| 92 | seq_puts(m, ",version=9p2000.u"); | ||
| 93 | break; | ||
| 94 | case p9_proto_2000L: | ||
| 95 | /* Default */ | ||
| 96 | break; | ||
| 97 | } | ||
| 98 | |||
| 99 | if (clnt->trans_mod->show_options) | ||
| 100 | return clnt->trans_mod->show_options(m, clnt); | ||
| 101 | return 0; | ||
| 102 | } | ||
| 103 | EXPORT_SYMBOL(p9_show_client_options); | ||
| 104 | |||
| 80 | /* | 105 | /* |
| 81 | * Some error codes are taken directly from the server replies, | 106 | * Some error codes are taken directly from the server replies, |
| 82 | * make sure they are valid. | 107 | * make sure they are valid. |
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index dca3cdd1a014..ddfa86648f95 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c | |||
| @@ -41,6 +41,7 @@ | |||
| 41 | #include <linux/file.h> | 41 | #include <linux/file.h> |
| 42 | #include <linux/parser.h> | 42 | #include <linux/parser.h> |
| 43 | #include <linux/slab.h> | 43 | #include <linux/slab.h> |
| 44 | #include <linux/seq_file.h> | ||
| 44 | #include <net/9p/9p.h> | 45 | #include <net/9p/9p.h> |
| 45 | #include <net/9p/client.h> | 46 | #include <net/9p/client.h> |
| 46 | #include <net/9p/transport.h> | 47 | #include <net/9p/transport.h> |
| @@ -51,6 +52,9 @@ | |||
| 51 | #define MAX_SOCK_BUF (64*1024) | 52 | #define MAX_SOCK_BUF (64*1024) |
| 52 | #define MAXPOLLWADDR 2 | 53 | #define MAXPOLLWADDR 2 |
| 53 | 54 | ||
| 55 | static struct p9_trans_module p9_tcp_trans; | ||
| 56 | static struct p9_trans_module p9_fd_trans; | ||
| 57 | |||
| 54 | /** | 58 | /** |
| 55 | * struct p9_fd_opts - per-transport options | 59 | * struct p9_fd_opts - per-transport options |
| 56 | * @rfd: file descriptor for reading (trans=fd) | 60 | * @rfd: file descriptor for reading (trans=fd) |
| @@ -63,7 +67,7 @@ struct p9_fd_opts { | |||
| 63 | int rfd; | 67 | int rfd; |
| 64 | int wfd; | 68 | int wfd; |
| 65 | u16 port; | 69 | u16 port; |
| 66 | int privport; | 70 | bool privport; |
| 67 | }; | 71 | }; |
| 68 | 72 | ||
| 69 | /* | 73 | /* |
| @@ -720,6 +724,20 @@ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req) | |||
| 720 | return 0; | 724 | return 0; |
| 721 | } | 725 | } |
| 722 | 726 | ||
| 727 | static int p9_fd_show_options(struct seq_file *m, struct p9_client *clnt) | ||
| 728 | { | ||
| 729 | if (clnt->trans_mod == &p9_tcp_trans) { | ||
| 730 | if (clnt->trans_opts.tcp.port != P9_PORT) | ||
| 731 | seq_printf(m, "port=%u", clnt->trans_opts.tcp.port); | ||
| 732 | } else if (clnt->trans_mod == &p9_fd_trans) { | ||
| 733 | if (clnt->trans_opts.fd.rfd != ~0) | ||
| 734 | seq_printf(m, "rfd=%u", clnt->trans_opts.fd.rfd); | ||
| 735 | if (clnt->trans_opts.fd.wfd != ~0) | ||
| 736 | seq_printf(m, "wfd=%u", clnt->trans_opts.fd.wfd); | ||
| 737 | } | ||
| 738 | return 0; | ||
| 739 | } | ||
| 740 | |||
| 723 | /** | 741 | /** |
| 724 | * parse_opts - parse mount options into p9_fd_opts structure | 742 | * parse_opts - parse mount options into p9_fd_opts structure |
| 725 | * @params: options string passed from mount | 743 | * @params: options string passed from mount |
| @@ -738,7 +756,7 @@ static int parse_opts(char *params, struct p9_fd_opts *opts) | |||
| 738 | opts->port = P9_PORT; | 756 | opts->port = P9_PORT; |
| 739 | opts->rfd = ~0; | 757 | opts->rfd = ~0; |
| 740 | opts->wfd = ~0; | 758 | opts->wfd = ~0; |
| 741 | opts->privport = 0; | 759 | opts->privport = false; |
| 742 | 760 | ||
| 743 | if (!params) | 761 | if (!params) |
| 744 | return 0; | 762 | return 0; |
| @@ -776,7 +794,7 @@ static int parse_opts(char *params, struct p9_fd_opts *opts) | |||
| 776 | opts->wfd = option; | 794 | opts->wfd = option; |
| 777 | break; | 795 | break; |
| 778 | case Opt_privport: | 796 | case Opt_privport: |
| 779 | opts->privport = 1; | 797 | opts->privport = true; |
| 780 | break; | 798 | break; |
| 781 | default: | 799 | default: |
| 782 | continue; | 800 | continue; |
| @@ -942,6 +960,8 @@ p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args) | |||
| 942 | 960 | ||
| 943 | csocket = NULL; | 961 | csocket = NULL; |
| 944 | 962 | ||
| 963 | client->trans_opts.tcp.port = opts.port; | ||
| 964 | client->trans_opts.tcp.privport = opts.privport; | ||
| 945 | sin_server.sin_family = AF_INET; | 965 | sin_server.sin_family = AF_INET; |
| 946 | sin_server.sin_addr.s_addr = in_aton(addr); | 966 | sin_server.sin_addr.s_addr = in_aton(addr); |
| 947 | sin_server.sin_port = htons(opts.port); | 967 | sin_server.sin_port = htons(opts.port); |
| @@ -1020,6 +1040,8 @@ p9_fd_create(struct p9_client *client, const char *addr, char *args) | |||
| 1020 | struct p9_fd_opts opts; | 1040 | struct p9_fd_opts opts; |
| 1021 | 1041 | ||
| 1022 | parse_opts(args, &opts); | 1042 | parse_opts(args, &opts); |
| 1043 | client->trans_opts.fd.rfd = opts.rfd; | ||
| 1044 | client->trans_opts.fd.wfd = opts.wfd; | ||
| 1023 | 1045 | ||
| 1024 | if (opts.rfd == ~0 || opts.wfd == ~0) { | 1046 | if (opts.rfd == ~0 || opts.wfd == ~0) { |
| 1025 | pr_err("Insufficient options for proto=fd\n"); | 1047 | pr_err("Insufficient options for proto=fd\n"); |
| @@ -1044,6 +1066,7 @@ static struct p9_trans_module p9_tcp_trans = { | |||
| 1044 | .request = p9_fd_request, | 1066 | .request = p9_fd_request, |
| 1045 | .cancel = p9_fd_cancel, | 1067 | .cancel = p9_fd_cancel, |
| 1046 | .cancelled = p9_fd_cancelled, | 1068 | .cancelled = p9_fd_cancelled, |
| 1069 | .show_options = p9_fd_show_options, | ||
| 1047 | .owner = THIS_MODULE, | 1070 | .owner = THIS_MODULE, |
| 1048 | }; | 1071 | }; |
| 1049 | 1072 | ||
| @@ -1056,6 +1079,7 @@ static struct p9_trans_module p9_unix_trans = { | |||
| 1056 | .request = p9_fd_request, | 1079 | .request = p9_fd_request, |
| 1057 | .cancel = p9_fd_cancel, | 1080 | .cancel = p9_fd_cancel, |
| 1058 | .cancelled = p9_fd_cancelled, | 1081 | .cancelled = p9_fd_cancelled, |
| 1082 | .show_options = p9_fd_show_options, | ||
| 1059 | .owner = THIS_MODULE, | 1083 | .owner = THIS_MODULE, |
| 1060 | }; | 1084 | }; |
| 1061 | 1085 | ||
| @@ -1068,6 +1092,7 @@ static struct p9_trans_module p9_fd_trans = { | |||
| 1068 | .request = p9_fd_request, | 1092 | .request = p9_fd_request, |
| 1069 | .cancel = p9_fd_cancel, | 1093 | .cancel = p9_fd_cancel, |
| 1070 | .cancelled = p9_fd_cancelled, | 1094 | .cancelled = p9_fd_cancelled, |
| 1095 | .show_options = p9_fd_show_options, | ||
| 1071 | .owner = THIS_MODULE, | 1096 | .owner = THIS_MODULE, |
| 1072 | }; | 1097 | }; |
| 1073 | 1098 | ||
diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c index 553ed4ecb6a0..6d8e3031978f 100644 --- a/net/9p/trans_rdma.c +++ b/net/9p/trans_rdma.c | |||
| @@ -43,6 +43,7 @@ | |||
| 43 | #include <linux/parser.h> | 43 | #include <linux/parser.h> |
| 44 | #include <linux/semaphore.h> | 44 | #include <linux/semaphore.h> |
| 45 | #include <linux/slab.h> | 45 | #include <linux/slab.h> |
| 46 | #include <linux/seq_file.h> | ||
| 46 | #include <net/9p/9p.h> | 47 | #include <net/9p/9p.h> |
| 47 | #include <net/9p/client.h> | 48 | #include <net/9p/client.h> |
| 48 | #include <net/9p/transport.h> | 49 | #include <net/9p/transport.h> |
| @@ -70,6 +71,8 @@ | |||
| 70 | * @dm_mr: DMA Memory Region pointer | 71 | * @dm_mr: DMA Memory Region pointer |
| 71 | * @lkey: The local access only memory region key | 72 | * @lkey: The local access only memory region key |
| 72 | * @timeout: Number of uSecs to wait for connection management events | 73 | * @timeout: Number of uSecs to wait for connection management events |
| 74 | * @privport: Whether a privileged port may be used | ||
| 75 | * @port: The port to use | ||
| 73 | * @sq_depth: The depth of the Send Queue | 76 | * @sq_depth: The depth of the Send Queue |
| 74 | * @sq_sem: Semaphore for the SQ | 77 | * @sq_sem: Semaphore for the SQ |
| 75 | * @rq_depth: The depth of the Receive Queue. | 78 | * @rq_depth: The depth of the Receive Queue. |
| @@ -95,6 +98,8 @@ struct p9_trans_rdma { | |||
| 95 | struct ib_qp *qp; | 98 | struct ib_qp *qp; |
| 96 | struct ib_cq *cq; | 99 | struct ib_cq *cq; |
| 97 | long timeout; | 100 | long timeout; |
| 101 | bool privport; | ||
| 102 | u16 port; | ||
| 98 | int sq_depth; | 103 | int sq_depth; |
| 99 | struct semaphore sq_sem; | 104 | struct semaphore sq_sem; |
| 100 | int rq_depth; | 105 | int rq_depth; |
| @@ -133,10 +138,10 @@ struct p9_rdma_context { | |||
| 133 | */ | 138 | */ |
| 134 | struct p9_rdma_opts { | 139 | struct p9_rdma_opts { |
| 135 | short port; | 140 | short port; |
| 141 | bool privport; | ||
| 136 | int sq_depth; | 142 | int sq_depth; |
| 137 | int rq_depth; | 143 | int rq_depth; |
| 138 | long timeout; | 144 | long timeout; |
| 139 | int privport; | ||
| 140 | }; | 145 | }; |
| 141 | 146 | ||
| 142 | /* | 147 | /* |
| @@ -159,6 +164,23 @@ static match_table_t tokens = { | |||
| 159 | {Opt_err, NULL}, | 164 | {Opt_err, NULL}, |
| 160 | }; | 165 | }; |
| 161 | 166 | ||
| 167 | static int p9_rdma_show_options(struct seq_file *m, struct p9_client *clnt) | ||
| 168 | { | ||
| 169 | struct p9_trans_rdma *rdma = clnt->trans; | ||
| 170 | |||
| 171 | if (rdma->port != P9_PORT) | ||
| 172 | seq_printf(m, ",port=%u", rdma->port); | ||
| 173 | if (rdma->sq_depth != P9_RDMA_SQ_DEPTH) | ||
| 174 | seq_printf(m, ",sq=%u", rdma->sq_depth); | ||
| 175 | if (rdma->rq_depth != P9_RDMA_RQ_DEPTH) | ||
| 176 | seq_printf(m, ",rq=%u", rdma->rq_depth); | ||
| 177 | if (rdma->timeout != P9_RDMA_TIMEOUT) | ||
| 178 | seq_printf(m, ",timeout=%lu", rdma->timeout); | ||
| 179 | if (rdma->privport) | ||
| 180 | seq_puts(m, ",privport"); | ||
| 181 | return 0; | ||
| 182 | } | ||
| 183 | |||
| 162 | /** | 184 | /** |
| 163 | * parse_opts - parse mount options into rdma options structure | 185 | * parse_opts - parse mount options into rdma options structure |
| 164 | * @params: options string passed from mount | 186 | * @params: options string passed from mount |
| @@ -177,7 +199,7 @@ static int parse_opts(char *params, struct p9_rdma_opts *opts) | |||
| 177 | opts->sq_depth = P9_RDMA_SQ_DEPTH; | 199 | opts->sq_depth = P9_RDMA_SQ_DEPTH; |
| 178 | opts->rq_depth = P9_RDMA_RQ_DEPTH; | 200 | opts->rq_depth = P9_RDMA_RQ_DEPTH; |
| 179 | opts->timeout = P9_RDMA_TIMEOUT; | 201 | opts->timeout = P9_RDMA_TIMEOUT; |
| 180 | opts->privport = 0; | 202 | opts->privport = false; |
| 181 | 203 | ||
| 182 | if (!params) | 204 | if (!params) |
| 183 | return 0; | 205 | return 0; |
| @@ -218,7 +240,7 @@ static int parse_opts(char *params, struct p9_rdma_opts *opts) | |||
| 218 | opts->timeout = option; | 240 | opts->timeout = option; |
| 219 | break; | 241 | break; |
| 220 | case Opt_privport: | 242 | case Opt_privport: |
| 221 | opts->privport = 1; | 243 | opts->privport = true; |
| 222 | break; | 244 | break; |
| 223 | default: | 245 | default: |
| 224 | continue; | 246 | continue; |
| @@ -560,6 +582,8 @@ static struct p9_trans_rdma *alloc_rdma(struct p9_rdma_opts *opts) | |||
| 560 | if (!rdma) | 582 | if (!rdma) |
| 561 | return NULL; | 583 | return NULL; |
| 562 | 584 | ||
| 585 | rdma->port = opts->port; | ||
| 586 | rdma->privport = opts->privport; | ||
| 563 | rdma->sq_depth = opts->sq_depth; | 587 | rdma->sq_depth = opts->sq_depth; |
| 564 | rdma->rq_depth = opts->rq_depth; | 588 | rdma->rq_depth = opts->rq_depth; |
| 565 | rdma->timeout = opts->timeout; | 589 | rdma->timeout = opts->timeout; |
| @@ -733,6 +757,7 @@ static struct p9_trans_module p9_rdma_trans = { | |||
| 733 | .request = rdma_request, | 757 | .request = rdma_request, |
| 734 | .cancel = rdma_cancel, | 758 | .cancel = rdma_cancel, |
| 735 | .cancelled = rdma_cancelled, | 759 | .cancelled = rdma_cancelled, |
| 760 | .show_options = p9_rdma_show_options, | ||
| 736 | }; | 761 | }; |
| 737 | 762 | ||
| 738 | /** | 763 | /** |
