Commit 78dcf734 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull ->s_options removal from Al Viro:
 "Preparations for fsmount/fsopen stuff (coming next cycle). Everything
  gets moved to explicit ->show_options(), killing ->s_options off +
  some cosmetic bits around fs/namespace.c and friends. Basically, the
  stuff needed to work with fsmount series with minimum of conflicts
  with other work.

  It's not strictly required for this merge window, but it would reduce
  the PITA during the coming cycle, so it would be nice to have those
  bits and pieces out of the way"

* 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  isofs: Fix isofs_show_options()
  VFS: Kill off s_options and helpers
  orangefs: Implement show_options
  9p: Implement show_options
  isofs: Implement show_options
  afs: Implement show_options
  affs: Implement show_options
  befs: Implement show_options
  spufs: Implement show_options
  bpf: Implement show_options
  ramfs: Implement show_options
  pstore: Implement show_options
  omfs: Implement show_options
  hugetlbfs: Implement show_options
  VFS: Don't use save/replace_mount_options if not using generic_show_options
  VFS: Provide empty name qstr
  VFS: Make get_filesystem() return the affected filesystem
  VFS: Clean up whitespace in fs/namespace.c and fs/super.c
  Provide a function to create a NUL-terminated string from unterminated data
parents 93ff8185 fdb254db
...@@ -1225,12 +1225,6 @@ The underlying reason for the above rules is to make sure, that a ...@@ -1225,12 +1225,6 @@ The underlying reason for the above rules is to make sure, that a
mount can be accurately replicated (e.g. umounting and mounting again) mount can be accurately replicated (e.g. umounting and mounting again)
based on the information found in /proc/mounts. based on the information found in /proc/mounts.
A simple method of saving options at mount/remount time and showing
them is provided with the save_mount_options() and
generic_show_options() helper functions. Please note, that using
these may have drawbacks. For more info see header comments for these
functions in fs/namespace.c.
Resources Resources
========= =========
......
...@@ -605,6 +605,24 @@ static const match_table_t spufs_tokens = { ...@@ -605,6 +605,24 @@ static const match_table_t spufs_tokens = {
{ Opt_err, NULL }, { Opt_err, NULL },
}; };
static int spufs_show_options(struct seq_file *m, struct dentry *root)
{
struct spufs_sb_info *sbi = spufs_get_sb_info(root->d_sb);
struct inode *inode = root->d_inode;
if (!uid_eq(inode->i_uid, GLOBAL_ROOT_UID))
seq_printf(m, ",uid=%u",
from_kuid_munged(&init_user_ns, inode->i_uid));
if (!gid_eq(inode->i_gid, GLOBAL_ROOT_GID))
seq_printf(m, ",gid=%u",
from_kgid_munged(&init_user_ns, inode->i_gid));
if ((inode->i_mode & S_IALLUGO) != 0775)
seq_printf(m, ",mode=%o", inode->i_mode);
if (sbi->debug)
seq_puts(m, ",debug");
return 0;
}
static int static int
spufs_parse_options(struct super_block *sb, char *options, struct inode *root) spufs_parse_options(struct super_block *sb, char *options, struct inode *root)
{ {
...@@ -724,11 +742,9 @@ spufs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -724,11 +742,9 @@ spufs_fill_super(struct super_block *sb, void *data, int silent)
.destroy_inode = spufs_destroy_inode, .destroy_inode = spufs_destroy_inode,
.statfs = simple_statfs, .statfs = simple_statfs,
.evict_inode = spufs_evict_inode, .evict_inode = spufs_evict_inode,
.show_options = generic_show_options, .show_options = spufs_show_options,
}; };
save_mount_options(sb, data);
info = kzalloc(sizeof(*info), GFP_KERNEL); info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info) if (!info)
return -ENOMEM; return -ENOMEM;
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <linux/parser.h> #include <linux/parser.h>
#include <linux/idr.h> #include <linux/idr.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/seq_file.h>
#include <net/9p/9p.h> #include <net/9p/9p.h>
#include <net/9p/client.h> #include <net/9p/client.h>
#include <net/9p/transport.h> #include <net/9p/transport.h>
...@@ -82,6 +83,13 @@ static const match_table_t tokens = { ...@@ -82,6 +83,13 @@ static const match_table_t tokens = {
{Opt_err, NULL} {Opt_err, NULL}
}; };
static const char *const v9fs_cache_modes[nr__p9_cache_modes] = {
[CACHE_NONE] = "none",
[CACHE_MMAP] = "mmap",
[CACHE_LOOSE] = "loose",
[CACHE_FSCACHE] = "fscache",
};
/* Interpret mount options for cache mode */ /* Interpret mount options for cache mode */
static int get_cache_mode(char *s) static int get_cache_mode(char *s)
{ {
...@@ -104,6 +112,58 @@ static int get_cache_mode(char *s) ...@@ -104,6 +112,58 @@ static int get_cache_mode(char *s)
return version; return version;
} }
/*
* Display the mount options in /proc/mounts.
*/
int v9fs_show_options(struct seq_file *m, struct dentry *root)
{
struct v9fs_session_info *v9ses = root->d_sb->s_fs_info;
if (v9ses->debug)
seq_printf(m, ",debug=%x", v9ses->debug);
if (!uid_eq(v9ses->dfltuid, V9FS_DEFUID))
seq_printf(m, ",dfltuid=%u",
from_kuid_munged(&init_user_ns, v9ses->dfltuid));
if (!gid_eq(v9ses->dfltgid, V9FS_DEFGID))
seq_printf(m, ",dfltgid=%u",
from_kgid_munged(&init_user_ns, v9ses->dfltgid));
if (v9ses->afid != ~0)
seq_printf(m, ",afid=%u", v9ses->afid);
if (strcmp(v9ses->uname, V9FS_DEFUSER) != 0)
seq_printf(m, ",uname=%s", v9ses->uname);
if (strcmp(v9ses->aname, V9FS_DEFANAME) != 0)
seq_printf(m, ",aname=%s", v9ses->aname);
if (v9ses->nodev)
seq_puts(m, ",nodevmap");
if (v9ses->cache)
seq_printf(m, ",%s", v9fs_cache_modes[v9ses->cache]);
#ifdef CONFIG_9P_FSCACHE
if (v9ses->cachetag && v9ses->cache == CACHE_FSCACHE)
seq_printf(m, ",cachetag=%s", v9ses->cachetag);
#endif
switch (v9ses->flags & V9FS_ACCESS_MASK) {
case V9FS_ACCESS_USER:
seq_puts(m, ",access=user");
break;
case V9FS_ACCESS_ANY:
seq_puts(m, ",access=any");
break;
case V9FS_ACCESS_CLIENT:
seq_puts(m, ",access=client");
break;
case V9FS_ACCESS_SINGLE:
seq_printf(m, ",access=%u",
from_kuid_munged(&init_user_ns, v9ses->uid));
break;
}
if (v9ses->flags & V9FS_POSIX_ACL)
seq_puts(m, ",posixacl");
return p9_show_client_options(m, v9ses->clnt);
}
/** /**
* v9fs_parse_options - parse mount options into session structure * v9fs_parse_options - parse mount options into session structure
* @v9ses: existing v9fs session information * @v9ses: existing v9fs session information
...@@ -230,6 +290,7 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts) ...@@ -230,6 +290,7 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
break; break;
case Opt_cachetag: case Opt_cachetag:
#ifdef CONFIG_9P_FSCACHE #ifdef CONFIG_9P_FSCACHE
kfree(v9ses->cachetag);
v9ses->cachetag = match_strdup(&args[0]); v9ses->cachetag = match_strdup(&args[0]);
#endif #endif
break; break;
......
...@@ -67,6 +67,7 @@ enum p9_cache_modes { ...@@ -67,6 +67,7 @@ enum p9_cache_modes {
CACHE_MMAP, CACHE_MMAP,
CACHE_LOOSE, CACHE_LOOSE,
CACHE_FSCACHE, CACHE_FSCACHE,
nr__p9_cache_modes
}; };
/** /**
...@@ -137,6 +138,8 @@ static inline struct v9fs_inode *V9FS_I(const struct inode *inode) ...@@ -137,6 +138,8 @@ static inline struct v9fs_inode *V9FS_I(const struct inode *inode)
return container_of(inode, struct v9fs_inode, vfs_inode); return container_of(inode, struct v9fs_inode, vfs_inode);
} }
extern int v9fs_show_options(struct seq_file *m, struct dentry *root);
struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *, struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *,
char *); char *);
extern void v9fs_session_close(struct v9fs_session_info *v9ses); extern void v9fs_session_close(struct v9fs_session_info *v9ses);
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/inet.h> #include <linux/inet.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/seq_file.h>
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/idr.h> #include <linux/idr.h>
#include <linux/sched.h> #include <linux/sched.h>
...@@ -104,7 +103,6 @@ v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses, ...@@ -104,7 +103,6 @@ v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses,
sb->s_flags |= MS_POSIXACL; sb->s_flags |= MS_POSIXACL;
#endif #endif
save_mount_options(sb, data);
return 0; return 0;
} }
...@@ -349,7 +347,7 @@ static const struct super_operations v9fs_super_ops = { ...@@ -349,7 +347,7 @@ static const struct super_operations v9fs_super_ops = {
.destroy_inode = v9fs_destroy_inode, .destroy_inode = v9fs_destroy_inode,
.statfs = simple_statfs, .statfs = simple_statfs,
.evict_inode = v9fs_evict_inode, .evict_inode = v9fs_evict_inode,
.show_options = generic_show_options, .show_options = v9fs_show_options,
.umount_begin = v9fs_umount_begin, .umount_begin = v9fs_umount_begin,
.write_inode = v9fs_write_inode, .write_inode = v9fs_write_inode,
}; };
...@@ -360,7 +358,7 @@ static const struct super_operations v9fs_super_ops_dotl = { ...@@ -360,7 +358,7 @@ static const struct super_operations v9fs_super_ops_dotl = {
.statfs = v9fs_statfs, .statfs = v9fs_statfs,
.drop_inode = v9fs_drop_inode, .drop_inode = v9fs_drop_inode,
.evict_inode = v9fs_evict_inode, .evict_inode = v9fs_evict_inode,
.show_options = generic_show_options, .show_options = v9fs_show_options,
.umount_begin = v9fs_umount_begin, .umount_begin = v9fs_umount_begin,
.write_inode = v9fs_write_inode_dotl, .write_inode = v9fs_write_inode_dotl,
}; };
......
...@@ -20,9 +20,11 @@ ...@@ -20,9 +20,11 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/writeback.h> #include <linux/writeback.h>
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/seq_file.h>
#include "affs.h" #include "affs.h"
static int affs_statfs(struct dentry *dentry, struct kstatfs *buf); static int affs_statfs(struct dentry *dentry, struct kstatfs *buf);
static int affs_show_options(struct seq_file *m, struct dentry *root);
static int affs_remount (struct super_block *sb, int *flags, char *data); static int affs_remount (struct super_block *sb, int *flags, char *data);
static void static void
...@@ -159,7 +161,7 @@ static const struct super_operations affs_sops = { ...@@ -159,7 +161,7 @@ static const struct super_operations affs_sops = {
.sync_fs = affs_sync_fs, .sync_fs = affs_sync_fs,
.statfs = affs_statfs, .statfs = affs_statfs,
.remount_fs = affs_remount, .remount_fs = affs_remount,
.show_options = generic_show_options, .show_options = affs_show_options,
}; };
enum { enum {
...@@ -293,6 +295,40 @@ parse_options(char *options, kuid_t *uid, kgid_t *gid, int *mode, int *reserved, ...@@ -293,6 +295,40 @@ parse_options(char *options, kuid_t *uid, kgid_t *gid, int *mode, int *reserved,
return 1; return 1;
} }
static int affs_show_options(struct seq_file *m, struct dentry *root)
{
struct super_block *sb = root->d_sb;
struct affs_sb_info *sbi = AFFS_SB(sb);
if (sb->s_blocksize)
seq_printf(m, ",bs=%lu", sb->s_blocksize);
if (affs_test_opt(sbi->s_flags, SF_SETMODE))
seq_printf(m, ",mode=%o", sbi->s_mode);
if (affs_test_opt(sbi->s_flags, SF_MUFS))
seq_puts(m, ",mufs");
if (affs_test_opt(sbi->s_flags, SF_NO_TRUNCATE))
seq_puts(m, ",nofilenametruncate");
if (affs_test_opt(sbi->s_flags, SF_PREFIX))
seq_printf(m, ",prefix=%s", sbi->s_prefix);
if (affs_test_opt(sbi->s_flags, SF_IMMUTABLE))
seq_puts(m, ",protect");
if (sbi->s_reserved != 2)
seq_printf(m, ",reserved=%u", sbi->s_reserved);
if (sbi->s_root_block != (sbi->s_reserved + sbi->s_partition_size - 1) / 2)
seq_printf(m, ",root=%u", sbi->s_root_block);
if (affs_test_opt(sbi->s_flags, SF_SETGID))
seq_printf(m, ",setgid=%u",
from_kgid_munged(&init_user_ns, sbi->s_gid));
if (affs_test_opt(sbi->s_flags, SF_SETUID))
seq_printf(m, ",setuid=%u",
from_kuid_munged(&init_user_ns, sbi->s_uid));
if (affs_test_opt(sbi->s_flags, SF_VERBOSE))
seq_puts(m, ",verbose");
if (sbi->s_volume[0])
seq_printf(m, ",volume=%s", sbi->s_volume);
return 0;
}
/* This function definitely needs to be split up. Some fine day I'll /* This function definitely needs to be split up. Some fine day I'll
* hopefully have the guts to do so. Until then: sorry for the mess. * hopefully have the guts to do so. Until then: sorry for the mess.
*/ */
...@@ -316,8 +352,6 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -316,8 +352,6 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent)
u8 sig[4]; u8 sig[4];
int ret; int ret;
save_mount_options(sb, data);
pr_debug("read_super(%s)\n", data ? (const char *)data : "no options"); pr_debug("read_super(%s)\n", data ? (const char *)data : "no options");
sb->s_magic = AFFS_SUPER_MAGIC; sb->s_magic = AFFS_SUPER_MAGIC;
...@@ -548,8 +582,6 @@ affs_remount(struct super_block *sb, int *flags, char *data) ...@@ -548,8 +582,6 @@ affs_remount(struct super_block *sb, int *flags, char *data)
} }
flush_delayed_work(&sbi->sb_work); flush_delayed_work(&sbi->sb_work);
if (new_opts)
replace_mount_options(sb, new_opts);
sbi->s_flags = mount_flags; sbi->s_flags = mount_flags;
sbi->s_mode = mode; sbi->s_mode = mode;
......
...@@ -37,6 +37,8 @@ static void afs_kill_super(struct super_block *sb); ...@@ -37,6 +37,8 @@ static void afs_kill_super(struct super_block *sb);
static struct inode *afs_alloc_inode(struct super_block *sb); static struct inode *afs_alloc_inode(struct super_block *sb);
static void afs_destroy_inode(struct inode *inode); static void afs_destroy_inode(struct inode *inode);
static int afs_statfs(struct dentry *dentry, struct kstatfs *buf); static int afs_statfs(struct dentry *dentry, struct kstatfs *buf);
static int afs_show_devname(struct seq_file *m, struct dentry *root);
static int afs_show_options(struct seq_file *m, struct dentry *root);
struct file_system_type afs_fs_type = { struct file_system_type afs_fs_type = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
...@@ -53,7 +55,8 @@ static const struct super_operations afs_super_ops = { ...@@ -53,7 +55,8 @@ static const struct super_operations afs_super_ops = {
.drop_inode = afs_drop_inode, .drop_inode = afs_drop_inode,
.destroy_inode = afs_destroy_inode, .destroy_inode = afs_destroy_inode,
.evict_inode = afs_evict_inode, .evict_inode = afs_evict_inode,
.show_options = generic_show_options, .show_devname = afs_show_devname,
.show_options = afs_show_options,
}; };
static struct kmem_cache *afs_inode_cachep; static struct kmem_cache *afs_inode_cachep;
...@@ -135,6 +138,45 @@ void __exit afs_fs_exit(void) ...@@ -135,6 +138,45 @@ void __exit afs_fs_exit(void)
_leave(""); _leave("");
} }
/*
* Display the mount device name in /proc/mounts.
*/
static int afs_show_devname(struct seq_file *m, struct dentry *root)
{
struct afs_super_info *as = root->d_sb->s_fs_info;
struct afs_volume *volume = as->volume;
struct afs_cell *cell = volume->cell;
const char *suf = "";
char pref = '%';
switch (volume->type) {
case AFSVL_RWVOL:
break;
case AFSVL_ROVOL:
pref = '#';
if (volume->type_force)
suf = ".readonly";
break;
case AFSVL_BACKVOL:
pref = '#';
suf = ".backup";
break;
}
seq_printf(m, "%c%s:%s%s", pref, cell->name, volume->vlocation->vldb.name, suf);
return 0;
}
/*
* Display the mount options in /proc/mounts.
*/
static int afs_show_options(struct seq_file *m, struct dentry *root)
{
if (test_bit(AFS_VNODE_AUTOCELL, &AFS_FS_I(d_inode(root))->flags))
seq_puts(m, "autocell");
return 0;
}
/* /*
* parse the mount options * parse the mount options
* - this function has been shamelessly adapted from the ext3 fs which * - this function has been shamelessly adapted from the ext3 fs which
...@@ -427,7 +469,6 @@ static struct dentry *afs_mount(struct file_system_type *fs_type, ...@@ -427,7 +469,6 @@ static struct dentry *afs_mount(struct file_system_type *fs_type,
deactivate_locked_super(sb); deactivate_locked_super(sb);
goto error; goto error;
} }
save_mount_options(sb, new_opts);
sb->s_flags |= MS_ACTIVE; sb->s_flags |= MS_ACTIVE;
} else { } else {
_debug("reuse"); _debug("reuse");
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/cred.h> #include <linux/cred.h>
#include <linux/exportfs.h> #include <linux/exportfs.h>
#include <linux/seq_file.h>
#include "befs.h" #include "befs.h"
#include "btree.h" #include "btree.h"
...@@ -53,6 +54,7 @@ static int befs_nls2utf(struct super_block *sb, const char *in, int in_len, ...@@ -53,6 +54,7 @@ static int befs_nls2utf(struct super_block *sb, const char *in, int in_len,
static void befs_put_super(struct super_block *); static void befs_put_super(struct super_block *);
static int befs_remount(struct super_block *, int *, char *); static int befs_remount(struct super_block *, int *, char *);
static int befs_statfs(struct dentry *, struct kstatfs *); static int befs_statfs(struct dentry *, struct kstatfs *);
static int befs_show_options(struct seq_file *, struct dentry *);
static int parse_options(char *, struct befs_mount_options *); static int parse_options(char *, struct befs_mount_options *);
static struct dentry *befs_fh_to_dentry(struct super_block *sb, static struct dentry *befs_fh_to_dentry(struct super_block *sb,
struct fid *fid, int fh_len, int fh_type); struct fid *fid, int fh_len, int fh_type);
...@@ -66,7 +68,7 @@ static const struct super_operations befs_sops = { ...@@ -66,7 +68,7 @@ static const struct super_operations befs_sops = {
.put_super = befs_put_super, /* uninit super */ .put_super = befs_put_super, /* uninit super */
.statfs = befs_statfs, /* statfs */ .statfs = befs_statfs, /* statfs */
.remount_fs = befs_remount, .remount_fs = befs_remount,
.show_options = generic_show_options, .show_options = befs_show_options,
}; };
/* slab cache for befs_inode_info objects */ /* slab cache for befs_inode_info objects */
...@@ -771,6 +773,24 @@ parse_options(char *options, struct befs_mount_options *opts) ...@@ -771,6 +773,24 @@ parse_options(char *options, struct befs_mount_options *opts)
return 1; return 1;
} }
static int befs_show_options(struct seq_file *m, struct dentry *root)
{
struct befs_sb_info *befs_sb = BEFS_SB(root->d_sb);
struct befs_mount_options *opts = &befs_sb->mount_opts;
if (!uid_eq(opts->uid, GLOBAL_ROOT_UID))
seq_printf(m, ",uid=%u",
from_kuid_munged(&init_user_ns, opts->uid));
if (!gid_eq(opts->gid, GLOBAL_ROOT_GID))
seq_printf(m, ",gid=%u",
from_kgid_munged(&init_user_ns, opts->gid));
if (opts->iocharset)
seq_printf(m, ",charset=%s", opts->iocharset);
if (opts->debug)
seq_puts(m, ",debug");
return 0;
}
/* This function has the responsibiltiy of getting the /* This function has the responsibiltiy of getting the
* filesystem ready for unmounting. * filesystem ready for unmounting.
* Basically, we free everything that we allocated in * Basically, we free everything that we allocated in
...@@ -804,8 +824,6 @@ befs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -804,8 +824,6 @@ befs_fill_super(struct super_block *sb, void *data, int silent)
const off_t x86_sb_off = 512; const off_t x86_sb_off = 512;
int blocksize; int blocksize;
save_mount_options(sb, data);
sb->s_fs_info = kzalloc(sizeof(*befs_sb), GFP_KERNEL); sb->s_fs_info = kzalloc(sizeof(*befs_sb), GFP_KERNEL);
if (sb->s_fs_info == NULL) if (sb->s_fs_info == NULL)
goto unacquire_none; goto unacquire_none;
......
...@@ -1154,7 +1154,6 @@ static int btrfs_fill_super(struct super_block *sb, ...@@ -1154,7 +1154,6 @@ static int btrfs_fill_super(struct super_block *sb,
goto fail_close; goto fail_close;
} }
save_mount_options(sb, data);
cleancache_init_fs(sb); cleancache_init_fs(sb);
sb->s_flags |= MS_ACTIVE; sb->s_flags |= MS_ACTIVE;
return 0; return 0;
......
...@@ -90,6 +90,11 @@ EXPORT_SYMBOL(rename_lock); ...@@ -90,6 +90,11 @@ EXPORT_SYMBOL(rename_lock);
static struct kmem_cache *dentry_cache __read_mostly; static struct kmem_cache *dentry_cache __read_mostly;
const struct qstr empty_name = QSTR_INIT("", 0);
EXPORT_SYMBOL(empty_name);
const struct qstr slash_name = QSTR_INIT("/", 1);
EXPORT_SYMBOL(slash_name);
/* /*
* This is the single most critical data structure when it comes * This is the single most critical data structure when it comes
* to the dcache: the hashtable for lookups. Somebody should try * 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,8 +1611,7 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name)
*/ */
dentry->d_iname[DNAME_INLINE_LEN-1] = 0; dentry->d_iname[DNAME_INLINE_LEN-1] = 0;
if (unlikely(!name)) { if (unlikely(!name)) {
static const struct qstr anon = QSTR_INIT("/", 1); name = &slash_name;
name = &anon;
dname = dentry->d_iname; dname = dentry->d_iname;
} else if (name->len > DNAME_INLINE_LEN-1) { } else if (name->len > DNAME_INLINE_LEN-1) {
size_t size = offsetof(struct external_name, name[1]); size_t size = offsetof(struct external_name, name[1]);
......
...@@ -203,8 +203,6 @@ static int debug_fill_super(struct super_block *sb, void *data, int silent) ...@@ -203,8 +203,6 @@ static int debug_fill_super(struct super_block *sb, void *data, int silent)
struct debugfs_fs_info *fsi; struct debugfs_fs_info *fsi;
int err; int err;
save_mount_options(sb, data);
fsi = kzalloc(sizeof(struct debugfs_fs_info), GFP_KERNEL); fsi = kzalloc(sizeof(struct debugfs_fs_info), GFP_KERNEL);
sb->s_fs_info = fsi; sb->s_fs_info = fsi;
if (!fsi) { if (!fsi) {
......
...@@ -29,7 +29,6 @@ static const struct super_operations efivarfs_ops = { ...@@ -29,7 +29,6 @@ static const struct super_operations efivarfs_ops = {
.statfs = simple_statfs, .statfs = simple_statfs,
.drop_inode = generic_delete_inode, .drop_inode = generic_delete_inode,
.evict_inode = efivarfs_evict_inode, .evict_inode = efivarfs_evict_inode,
.show_options = generic_show_options,
}; };
static struct super_block *efivarfs_sb; static struct super_block *efivarfs_sb;
......
...@@ -33,9 +33,10 @@ static struct file_system_type *file_systems; ...@@ -33,9 +33,10 @@ static struct file_system_type *file_systems;
static DEFINE_RWLOCK(file_systems_lock); static DEFINE_RWLOCK(file_systems_lock);
/* WARNING: This can be used only if we _already_ own a reference */ /* WARNING: This can be used only if we _already_ own a reference */
void get_filesystem(struct file_system_type *fs) struct file_system_type *get_filesystem(struct file_system_type *fs)
{ {
__module_get(fs->owner); __module_get(fs->owner);
return fs;
} }
void put_filesystem(struct file_system_type *fs) void put_filesystem(struct file_system_type *fs)
......
...@@ -872,7 +872,6 @@ static struct gfs2_leaf *new_leaf(struct inode *inode, struct buffer_head **pbh, ...@@ -872,7 +872,6 @@ static struct gfs2_leaf *new_leaf(struct inode *inode, struct buffer_head **pbh,
struct buffer_head *bh; struct buffer_head *bh;
struct gfs2_leaf *leaf; struct gfs2_leaf *leaf;
struct gfs2_dirent *dent; struct gfs2_dirent *dent;
struct qstr name = { .name = "" };
struct timespec tv = current_time(inode); struct timespec tv = current_time(inode);
error = gfs2_alloc_blocks(ip, &bn, &n, 0, NULL); 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,7 +895,7 @@ static struct gfs2_leaf *new_leaf(struct inode *inode, struct buffer_head **pbh,
leaf->lf_sec = cpu_to_be64(tv.tv_sec); leaf->lf_sec = cpu_to_be64(tv.tv_sec);
memset(leaf->lf_reserved2, 0, sizeof(leaf->lf_reserved2)); memset(leaf->lf_reserved2, 0, sizeof(leaf->lf_reserved2));
dent = (struct gfs2_dirent *)(leaf+1); dent = (struct gfs2_dirent *)(leaf+1);
gfs2_qstr2dirent(&name, bh->b_size - sizeof(struct gfs2_leaf), dent); gfs2_qstr2dirent(&empty_name, bh->b_size - sizeof(struct gfs2_leaf), dent);
*pbh = bh; *pbh = bh;
return leaf; return leaf;
} }
......
...@@ -46,13 +46,13 @@ static const struct inode_operations hugetlbfs_dir_inode_operations; ...@@ -46,13 +46,13 @@ static const struct inode_operations hugetlbfs_dir_inode_operations;
static const struct inode_operations hugetlbfs_inode_operations; static const struct inode_operations hugetlbfs_inode_operations;
struct hugetlbfs_config { struct hugetlbfs_config {
kuid_t uid; struct hstate *hstate;
kgid_t gid; long max_hpages;
umode_t mode; long nr_inodes;
long max_hpages; long min_hpages;
long nr_inodes; kuid_t uid;
struct hstate *hstate; kgid_t gid;
long min_hpages; umode_t mode;
}; };
struct hugetlbfs_inode_info { struct hugetlbfs_inode_info {
...@@ -861,6 +861,46 @@ static int hugetlbfs_error_remove_page(struct address_space *mapping, ...@@ -861,6 +861,46 @@ static int hugetlbfs_error_remove_page(struct address_space *mapping,
return 0; return 0;
} }
/*
* Display the mount options in /proc/mounts.
*/
static int hugetlbfs_show_options(struct seq_file *m, struct dentry *root)
{
struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(root->d_sb);
struct hugepage_subpool *spool = sbinfo->spool;
unsigned long hpage_size = huge_page_size(sbinfo->hstate);
unsigned hpage_shift = huge_page_shift(sbinfo->hstate);
char mod;
if (!uid_eq(sbinfo->uid, GLOBAL_ROOT_UID))
seq_printf(m, ",uid=%u",
from_kuid_munged(&init_user_ns, sbinfo->uid));
if (!gid_eq(sbinfo->gid, GLOBAL_ROOT_GID))
seq_printf(m, ",gid=%u",
from_kgid_munged(&init_user_ns, sbinfo->gid));
if (sbinfo->mode != 0755)
seq_printf(m, ",mode=%o", sbinfo->mode);
if (sbinfo->max_inodes != -1)
seq_printf(m, ",nr_inodes=%lu", sbinfo->max_inodes);
hpage_size /= 1024;
mod = 'K';
if (hpage_size >= 1024) {
hpage_size /= 1024;
mod = 'M';
}
seq_printf(m, ",pagesize=%lu%c", hpage_size, mod);
if (spool) {
if (spool->max_hpages != -1)
seq_printf(m, ",size=%llu",
(unsigned long long)spool->max_hpages << hpage_shift);
if (spool->min_hpages != -1)
seq_printf(m, ",min_size=%llu",
(unsigned long long)spool->min_hpages << hpage_shift);
}
return 0;
}
static int hugetlbfs_statfs(struct dentry *dentry, struct kstatfs *buf) static int hugetlbfs_statfs(struct dentry *dentry, struct kstatfs *buf)
{ {
struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(dentry->d_sb); struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(dentry->d_sb);
...@@ -1019,19 +1059,19 @@ static const struct super_operations hugetlbfs_ops = { ...@@ -1019,19 +1059,19 @@ static const struct super_operations hugetlbfs_ops = {
.evict_inode = hugetlbfs_evict_inode, .evict_inode = hugetlbfs_evict_inode,
.statfs = hugetlbfs_statfs, .statfs = hugetlbfs_statfs,
.put_super = hugetlbfs_put_super, .put_super = hugetlbfs_put_super,
.show_options = generic_show_options, .show_options = hugetlbfs_show_options,
}; };
enum { NO_SIZE, SIZE_STD, SIZE_PERCENT }; enum hugetlbfs_size_type { NO_SIZE, SIZE_STD, SIZE_PERCENT };
/* /*
* Convert size option passed from command line to number of huge pages * Convert size option passed from command line to number of huge pages
* in the pool specified by hstate. Size option could be in bytes * in the pool specified by hstate. Size option could be in bytes
* (val_type == SIZE_STD) or percentage of the pool (val_type == SIZE_PERCENT). * (val_type == SIZE_STD) or percentage of the pool (val_type == SIZE_PERCENT).
*/ */
static long long static long
hugetlbfs_size_to_hpages(struct hstate *h, unsigned long long size_opt, hugetlbfs_size_to_hpages(struct hstate *h, unsigned long long size_opt,
int val_type) enum hugetlbfs_size_type val_type)
{ {
if (val_type == NO_SIZE) if (val_type == NO_SIZE)
return -1; return -1;
...@@ -1053,7 +1093,7 @@ hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig) ...@@ -1053,7 +1093,7 @@ hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig)
substring_t args[MAX_OPT_ARGS]; substring_t args[MAX_OPT_ARGS];
int option; int option;
unsigned long long max_size_opt = 0, min_size_opt = 0; unsigned long long max_size_opt = 0, min_size_opt = 0;
int max_val_type = NO_SIZE, min_val_type = NO_SIZE; enum hugetlbfs_size_type max_val_type = NO_SIZE, min_val_type = NO_SIZE;
if (!options) if (!options)
return 0; return 0;
...@@ -1167,8 +1207,6 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -1167,8 +1207,6 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent)
struct hugetlbfs_config config; struct hugetlbfs_config config;
struct hugetlbfs_sb_info *sbinfo; struct hugetlbfs_sb_info *sbinfo;
save_mount_options(sb, data);
config.max_hpages = -1; /* No limit on size by default */ config.max_hpages = -1; /* No limit on size by default */
config.nr_inodes = -1; /* No limit on number of inodes by default */ config.nr_inodes = -1; /* No limit on number of inodes by default */
config.uid = current_fsuid(); config.uid = current_fsuid();
...@@ -1189,6 +1227,10 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -1189,6 +1227,10 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent)
sbinfo->max_inodes = config.nr_inodes; sbinfo->max_inodes = config.nr_inodes;
sbinfo->free_inodes = config.nr_inodes; sbinfo->free_inodes = config.nr_inodes;
sbinfo->spool = NULL; sbinfo->spool = NULL;
sbinfo->uid = config.uid;
sbinfo->gid = config.gid;
sbinfo->mode = config.mode;
/* /*
* Allocate and initialize subpool if maximum or minimum size is * Allocate and initialize subpool if maximum or minimum size is
* specified. Any needed reservations (for minimim size) are taken * specified. Any needed reservations (for minimim size) are taken
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/parser.h> #include <linux/parser.h>
#include <linux/mpage.h> #include <linux/mpage.h>
#include <linux/user_namespace.h> #include <linux/user_namespace.h>
#include <linux/seq_file.h>
#include "isofs.h" #include "isofs.h"
#include "zisofs.h" #include "zisofs.h"
...@@ -57,6 +58,7 @@ static void isofs_put_super(struct super_block *sb) ...@@ -57,6 +58,7 @@ static void isofs_put_super(struct super_block *sb)
static int isofs_read_inode(struct inode *, int relocated); static int isofs_read_inode(struct inode *, int relocated);
static int isofs_statfs (struct dentry *, struct kstatfs *); static int isofs_statfs (struct dentry *, struct kstatfs *);
static int isofs_show_options(struct seq_file *, struct dentry *);
static struct kmem_cache *isofs_inode_cachep; static struct kmem_cache *isofs_inode_cachep;
...@@ -123,7 +125,7 @@ static const struct super_operations isofs_sops = { ...@@ -123,7 +125,7 @@ static const struct super_operations isofs_sops = {
.put_super = isofs_put_super, .put_super = isofs_put_super,
.statfs = isofs_statfs, .statfs = isofs_statfs,
.remount_fs = isofs_remount, .remount_fs = isofs_remount,
.show_options = generic_show_options, .show_options = isofs_show_options,
}; };
...@@ -472,6 +474,48 @@ static int parse_options(char *options, struct iso9660_options *popt) ...@@ -472,6 +474,48 @@ static int parse_options(char *options, struct iso9660_options *popt)
return 1; return 1;
} }
/*
* Display the mount options in /proc/mounts.
*/
static int isofs_show_options(struct seq_file *m, struct dentry *root)
{
struct isofs_sb_info *sbi = ISOFS_SB(root->d_sb);
if (!sbi->s_rock) seq_puts(m, ",norock");
else if (!sbi->s_joliet_level) seq_puts(m, ",nojoliet");
if (sbi->s_cruft) seq_puts(m, ",cruft");
if (sbi->s_hide) seq_puts(m, ",hide");
if (sbi->s_nocompress) seq_puts(m, ",nocompress");
if (sbi->s_overriderockperm) seq_puts(m, ",overriderockperm");
if (sbi->s_showassoc) seq_puts(m, ",showassoc");
if (sbi->s_utf8) seq_puts(m, ",utf8");
if (sbi->s_check) seq_printf(m, ",check=%c", sbi->s_check);
if (sbi->s_mapping) seq_printf(m, ",map=%c", sbi->s_mapping);
if (sbi->s_session != 255) seq_printf(m, ",session=%u", sbi->s_session - 1);
if (sbi->s_sbsector != -1) seq_printf(m, ",sbsector=%u", sbi->s_sbsector);
if (root->d_sb->s_blocksize != 1024)
seq_printf(m, ",blocksize=%lu", root->d_sb->s_blocksize);
if (sbi->s_uid_set)
seq_printf(m, ",uid=%u",
from_kuid_munged(&init_user_ns, sbi->s_uid));
if (sbi->s_gid_set)
seq_printf(m, ",gid=%u",
from_kgid_munged(&init_user_ns, sbi->s_gid));
if (sbi->s_dmode != ISOFS_INVALID_MODE)
seq_printf(m, ",dmode=%o", sbi->s_dmode);
if (sbi->s_fmode != ISOFS_INVALID_MODE)
seq_printf(m, ",fmode=%o", sbi->s_fmode);
if (sbi->s_nls_iocharset &&
strcmp(sbi->s_nls_iocharset->charset, CONFIG_NLS_DEFAULT) != 0)
seq_printf(m, ",iocharset=%s", sbi->s_nls_iocharset->charset);
return 0;
}
/* /*
* look if the driver can tell the multi session redirection value * look if the driver can tell the multi session redirection value
* *
...@@ -583,8 +627,6 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) ...@@ -583,8 +627,6 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent)
int table, error = -EINVAL; int table, error = -EINVAL;
unsigned int vol_desc_start; unsigned int vol_desc_start;
save_mount_options(s, data);
sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
if (!sbi) if (!sbi)
return -ENOMEM; return -ENOMEM;
...@@ -605,6 +647,8 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) ...@@ -605,6 +647,8 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent)
opt.blocksize = sb_min_blocksize(s, opt.blocksize); opt.blocksize = sb_min_blocksize(s, opt.blocksize);
sbi->s_high_sierra = 0; /* default is iso9660 */ sbi->s_high_sierra = 0; /* default is iso9660 */
sbi->s_session = opt.session;
sbi->s_sbsector = opt.sbsector;
vol_desc_start = (opt.sbsector != -1) ? vol_desc_start = (opt.sbsector != -1) ?
opt.sbsector : isofs_get_last_session(s,opt.session); opt.sbsector : isofs_get_last_session(s,opt.session);
...@@ -911,6 +955,7 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) ...@@ -911,6 +955,7 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent)
table += 2; table += 2;
if (opt.check == 'r') if (opt.check == 'r')
table++; table++;
sbi->s_check = opt.check;
if (table) if (table)
s->s_d_op = &isofs_dentry_ops[table - 1]; s->s_d_op = &isofs_dentry_ops[table - 1];
......
...@@ -36,8 +36,11 @@ struct isofs_sb_info { ...@@ -36,8 +36,11 @@ struct isofs_sb_info {
unsigned long s_max_size; unsigned long s_max_size;
int s_rock_offset; /* offset of SUSP fields within SU area */ int s_rock_offset; /* offset of SUSP fields within SU area */
s32 s_sbsector;
unsigned char s_joliet_level; unsigned char s_joliet_level;
unsigned char s_mapping; unsigned char s_mapping;
unsigned char s_check;
unsigned char s_session;
unsigned int s_high_sierra:1; unsigned int s_high_sierra:1;
unsigned int s_rock:2; unsigned int s_rock:2;
unsigned int s_utf8:1; unsigned int s_utf8:1;
......
...@@ -3400,7 +3400,6 @@ static int do_last(struct nameidata *nd, ...@@ -3400,7 +3400,6 @@ static int do_last(struct nameidata *nd,
struct dentry *vfs_tmpfile(struct dentry *dentry, umode_t mode, int open_flag) struct dentry *vfs_tmpfile(struct dentry *dentry, umode_t mode, int open_flag)
{ {
static const struct qstr name = QSTR_INIT("/", 1);
struct dentry *child = NULL; struct dentry *child = NULL;
struct inode *dir = dentry->d_inode; struct inode *dir = dentry->d_inode;
struct inode *inode; struct inode *inode;
...@@ -3414,7 +3413,7 @@ struct dentry *vfs_tmpfile(struct dentry *dentry, umode_t mode, int open_flag) ...@@ -3414,7 +3413,7 @@ struct dentry *vfs_tmpfile(struct dentry *dentry, umode_t mode, int open_flag)
if (!dir->i_op->tmpfile) if (!dir->i_op->tmpfile)
goto out_err; goto out_err;
error = -ENOMEM; error = -ENOMEM;
child = d_alloc(dentry, &name); child = d_alloc(dentry, &slash_name);
if (unlikely(!child)) if (unlikely(!child))
goto out_err; goto out_err;
error = dir->i_op->tmpfile(dir, child, mode); error = dir->i_op->tmpfile(dir, child, mode);
......
...@@ -1238,65 +1238,6 @@ struct vfsmount *mnt_clone_internal(const struct path *path) ...@@ -1238,65 +1238,6 @@ struct vfsmount *mnt_clone_internal(const struct path *path)
return &p->mnt; return &p->mnt;
} }
static inline void mangle(struct seq_file *m, const char *s)
{
seq_escape(m, s, " \t\n\\");
}
/*
* Simple .show_options callback for filesystems which don't want to
* implement more complex mount option showing.
*
* See also save_mount_options().
*/
int generic_show_options(struct seq_file *m, struct dentry *root)
{
const char *options;
rcu_read_lock();
options = rcu_dereference(root->d_sb->s_options);
if (options != NULL && options[0]) {
seq_putc(m, ',');
mangle(m, options);
}
rcu_read_unlock();
return 0;
}
EXPORT_SYMBOL(generic_show_options);
/*
* If filesystem uses generic_show_options(), this function should be
* called from the fill_super() callback.
*
* The .remount_fs callback usually needs to be handled in a special
* way, to make sure, that previous options are not overwritten if the
* remount fails.
*
* Also note, that if the filesystem's .remount_fs function doesn't
* reset all options to their default value, but changes only newly
* given options, then the displayed options will not reflect reality
* any more.
*/
void save_mount_options(struct super_block *sb, char *options)
{
BUG_ON(sb->s_options);
rcu_assign_pointer(sb->s_options, kstrdup(options, GFP_KERNEL));
}
EXPORT_SYMBOL(save_mount_options);
void replace_mount_options(struct super_block *sb, char *options)
{
char *old = sb->s_options;
rcu_assign_pointer(sb->s_options, options);
if (old) {
synchronize_rcu();
kfree(old);
}
}
EXPORT_SYMBOL(replace_mount_options);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
/* iterator; we want it to have access to namespace_sem, thus here... */ /* iterator; we want it to have access to namespace_sem, thus here... */
static void *m_start(struct seq_file *m, loff_t *pos) static void *m_start(struct seq_file *m, loff_t *pos)
...@@ -1657,7 +1598,7 @@ void __detach_mounts(struct dentry *dentry) ...@@ -1657,7 +1598,7 @@ void __detach_mounts(struct dentry *dentry)
namespace_unlock(); namespace_unlock();
} }
/* /*
* Is the caller allowed to modify his namespace? * Is the caller allowed to modify his namespace?
*/ */
static inline bool may_mount(void) static inline bool may_mount(void)
...@@ -2211,7 +2152,7 @@ static int do_loopback(struct path *path, const char *old_name, ...@@ -2211,7 +2152,7 @@ static int do_loopback(struct path *path, const char *old_name,
err = -EINVAL; err = -EINVAL;
if (mnt_ns_loop(old_path.dentry)) if (mnt_ns_loop(old_path.dentry))
goto out; goto out;
mp = lock_mount(path); mp = lock_mount(path);
err = PTR_ERR(mp); err = PTR_ERR(mp);
......
...@@ -53,7 +53,6 @@ static void nsfs_evict(struct inode *inode) ...@@ -53,7 +53,6 @@ static void nsfs_evict(struct inode *inode)
static void *__ns_get_path(struct path *path, struct ns_common *ns) static void *__ns_get_path(struct path *path, struct ns_common *ns)
{ {
struct vfsmount *mnt = nsfs_mnt; struct vfsmount *mnt = nsfs_mnt;
struct qstr qname = { .name = "", };
struct dentry *dentry; struct dentry *dentry;
struct inode *inode; struct inode *inode;
unsigned long d; unsigned long d;
...@@ -85,7 +84,7 @@ static void *__ns_get_path(struct path *path, struct ns_common *ns) ...@@ -85,7 +84,7 @@ static void *__ns_get_path(struct path *path, struct ns_common *ns)
inode->i_fop = &ns_file_operations; inode->i_fop = &ns_file_operations;
inode->i_private = ns; inode->i_private = ns;
dentry = d_alloc_pseudo(mnt->mnt_sb, &qname); dentry = d_alloc_pseudo(mnt->mnt_sb, &empty_name);
if (!dentry) { if (!dentry) {
iput(inode); iput(inode);
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/writeback.h> #include <linux/writeback.h>
#include <linux/seq_file.h>
#include <linux/crc-itu-t.h> #include <linux/crc-itu-t.h>
#include "omfs.h" #include "omfs.h"
...@@ -290,12 +291,40 @@ static int omfs_statfs(struct dentry *dentry, struct kstatfs *buf) ...@@ -290,12 +291,40 @@ static int omfs_statfs(struct dentry *dentry, struct kstatfs *buf)
return 0; return 0;
} }
/*
* Display the mount options in /proc/mounts.
*/
static int omfs_show_options(struct seq_file *m, struct dentry *root)
{
struct omfs_sb_info *sbi = OMFS_SB(root->d_sb);
umode_t cur_umask = current_umask();
if (!uid_eq(sbi->s_uid, current_uid()))
seq_printf(m, ",uid=%u",
from_kuid_munged(&init_user_ns, sbi->s_uid));
if (!gid_eq(sbi->s_gid, current_gid()))
seq_printf(m, ",gid=%u",
from_kgid_munged(&init_user_ns, sbi->s_gid));
if (sbi->s_dmask == sbi->s_fmask) {
if (sbi->s_fmask != cur_umask)
seq_printf(m, ",umask=%o", sbi->s_fmask);
} else {
if (sbi->s_dmask != cur_umask)
seq_printf(m, ",dmask=%o", sbi->s_dmask);
if (sbi->s_fmask != cur_umask)
seq_printf(m, ",fmask=%o", sbi->s_fmask);
}
return 0;
}
static const struct super_operations omfs_sops = { static const struct super_operations omfs_sops = {
.write_inode = omfs_write_inode, .write_inode = omfs_write_inode,
.evict_inode = omfs_evict_inode, .evict_inode = omfs_evict_inode,
.put_super = omfs_put_super, .put_super = omfs_put_super,
.statfs = omfs_statfs, .statfs = omfs_statfs,
.show_options = generic_show_options, .show_options = omfs_show_options,
}; };
/* /*
...@@ -434,8 +463,6 @@ static int omfs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -434,8 +463,6 @@ static int omfs_fill_super(struct super_block *sb, void *data, int silent)
struct inode *root; struct inode *root;
int ret = -EINVAL; int ret = -EINVAL;
save_mount_options(sb, (char *) data);
sbi = kzalloc(sizeof(struct omfs_sb_info), GFP_KERNEL); sbi = kzalloc(sizeof(struct omfs_sb_info), GFP_KERNEL);
if (!sbi) if (!sbi)
return -ENOMEM; return -ENOMEM;
......
...@@ -35,6 +35,19 @@ static const match_table_t tokens = { ...@@ -35,6 +35,19 @@ static const match_table_t tokens = {
uint64_t orangefs_features; uint64_t orangefs_features;
static int orangefs_show_options(struct seq_file *m, struct dentry *root)
{
struct orangefs_sb_info_s *orangefs_sb = ORANGEFS_SB(root->d_sb);
if (root->d_sb->s_flags & MS_POSIXACL)
seq_puts(m, ",acl");
if (orangefs_sb->flags & ORANGEFS_OPT_INTR)
seq_puts(m, ",intr");
if (orangefs_sb->flags & ORANGEFS_OPT_LOCAL_LOCK)
seq_puts(m, ",local_lock");
return 0;
}
static int parse_mount_options(struct super_block *sb, char *options, static int parse_mount_options(struct super_block *sb, char *options,
int silent) int silent)
{ {
...@@ -305,7 +318,7 @@ static const struct super_operations orangefs_s_ops = { ...@@ -305,7 +318,7 @@ static const struct super_operations orangefs_s_ops = {
.drop_inode = generic_delete_inode, .drop_inode = generic_delete_inode,
.statfs = orangefs_statfs, .statfs = orangefs_statfs,
.remount_fs = orangefs_remount_fs, .remount_fs = orangefs_remount_fs,
.show_options = generic_show_options, .show_options = orangefs_show_options,
}; };
static struct dentry *orangefs_fh_to_dentry(struct super_block *sb, 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,13 +739,12 @@ int create_pipe_files(struct file **res, int flags)
struct inode *inode = get_pipe_inode(); struct inode *inode = get_pipe_inode();
struct file *f; struct file *f;
struct path path; struct path path;
static struct qstr name = { .name = "" };
if (!inode) if (!inode)
return -ENFILE; return -ENFILE;
err = -ENOMEM; err = -ENOMEM;
path.dentry = d_alloc_pseudo(pipe_mnt->mnt_sb, &name); path.dentry = d_alloc_pseudo(pipe_mnt->mnt_sb, &empty_name);
if (!path.dentry) if (!path.dentry)
goto err_inode; goto err_inode;
path.mnt = mntget(pipe_mnt); path.mnt = mntget(pipe_mnt);
......
...@@ -283,6 +283,16 @@ static void parse_options(char *options) ...@@ -283,6 +283,16 @@ static void parse_options(char *options)
} }
} }
/*
* Display the mount options in /proc/mounts.
*/
static int pstore_show_options(struct seq_file *m, struct dentry *root)
{
if (kmsg_bytes != PSTORE_DEFAULT_KMSG_BYTES)
seq_printf(m, ",kmsg_bytes=%lu", kmsg_bytes);
return 0;
}
static int pstore_remount(struct super_block *sb, int *flags, char *data) static int pstore_remount(struct super_block *sb, int *flags, char *data)
{ {
sync_filesystem(sb); sync_filesystem(sb);
...@@ -296,7 +306,7 @@ static const struct super_operations pstore_ops = { ...@@ -296,7 +306,7 @@ static const struct super_operations pstore_ops = {
.drop_inode = generic_delete_inode, .drop_inode = generic_delete_inode,
.evict_inode = pstore_evict_inode, .evict_inode = pstore_evict_inode,
.remount_fs = pstore_remount, .remount_fs = pstore_remount,
.show_options = generic_show_options, .show_options = pstore_show_options,
}; };
static struct super_block *pstore_sb; static struct super_block *pstore_sb;
...@@ -448,8 +458,6 @@ static int pstore_fill_super(struct super_block *sb, void *data, int silent) ...@@ -448,8 +458,6 @@ static int pstore_fill_super(struct super_block *sb, void *data, int silent)
{ {
struct inode *inode; struct inode *inode;
save_mount_options(sb, data);
pstore_sb = sb; pstore_sb = sb;
sb->s_maxbytes = MAX_LFS_FILESIZE; sb->s_maxbytes = MAX_LFS_FILESIZE;
......
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
#include <linux/time.h> #include <linux/time.h>
#include <linux/pstore.h> #include <linux/pstore.h>
#define PSTORE_DEFAULT_KMSG_BYTES 10240
extern unsigned long kmsg_bytes;
#ifdef CONFIG_PSTORE_FTRACE #ifdef CONFIG_PSTORE_FTRACE
extern void pstore_register_ftrace(void); extern void pstore_register_ftrace(void);
extern void pstore_unregister_ftrace(void); extern void pstore_unregister_ftrace(void);
......
...@@ -99,7 +99,7 @@ static char *big_oops_buf; ...@@ -99,7 +99,7 @@ static char *big_oops_buf;
static size_t big_oops_buf_sz; static size_t big_oops_buf_sz;
/* How much of the console log to snapshot */ /* How much of the console log to snapshot */
static unsigned long kmsg_bytes = 10240; unsigned long kmsg_bytes = PSTORE_DEFAULT_KMSG_BYTES;
void pstore_set_kmsg_bytes(int bytes) void pstore_set_kmsg_bytes(int bytes)
{ {
......
...@@ -38,6 +38,14 @@ ...@@ -38,6 +38,14 @@
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include "internal.h" #include "internal.h"
struct ramfs_mount_opts {
umode_t mode;
};
struct ramfs_fs_info {
struct ramfs_mount_opts mount_opts;
};
#define RAMFS_DEFAULT_MODE 0755 #define RAMFS_DEFAULT_MODE 0755
static const struct super_operations ramfs_ops; static const struct super_operations ramfs_ops;
...@@ -149,14 +157,22 @@ static const struct inode_operations ramfs_dir_inode_operations = { ...@@ -149,14 +157,22 @@ static const struct inode_operations ramfs_dir_inode_operations = {
.rename = simple_rename, .rename = simple_rename,
}; };
/*
* Display the mount options in /proc/mounts.
*/
static int ramfs_show_options(struct seq_file *m, struct dentry *root)
{
struct ramfs_fs_info *fsi = root->d_sb->s_fs_info;
if (fsi->mount_opts.mode != RAMFS_DEFAULT_MODE)
seq_printf(m, ",mode=%o", fsi->mount_opts.mode);
return 0;
}
static const struct super_operations ramfs_ops = { static const struct super_operations ramfs_ops = {
.statfs = simple_statfs, .statfs = simple_statfs,
.drop_inode = generic_delete_inode, .drop_inode = generic_delete_inode,
.show_options = generic_show_options, .show_options = ramfs_show_options,
};
struct ramfs_mount_opts {
umode_t mode;
}; };
enum { enum {
...@@ -169,10 +185,6 @@ static const match_table_t tokens = { ...@@ -169,10 +185,6 @@ static const match_table_t tokens = {
{Opt_err, NULL} {Opt_err, NULL}
}; };
struct ramfs_fs_info {
struct ramfs_mount_opts mount_opts;
};
static int ramfs_parse_options(char *data, struct ramfs_mount_opts *opts) static int ramfs_parse_options(char *data, struct ramfs_mount_opts *opts)
{ {
substring_t args[MAX_OPT_ARGS]; substring_t args[MAX_OPT_ARGS];
...@@ -211,8 +223,6 @@ int ramfs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -211,8 +223,6 @@ int ramfs_fill_super(struct super_block *sb, void *data, int silent)
struct inode *inode; struct inode *inode;
int err; int err;
save_mount_options(sb, data);
fsi = kzalloc(sizeof(struct ramfs_fs_info), GFP_KERNEL); fsi = kzalloc(sizeof(struct ramfs_fs_info), GFP_KERNEL);
sb->s_fs_info = fsi; sb->s_fs_info = fsi;
if (!fsi) if (!fsi)
......
...@@ -1599,8 +1599,6 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) ...@@ -1599,8 +1599,6 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
} }
out_ok_unlocked: out_ok_unlocked:
if (new_opts)
replace_mount_options(s, new_opts);
return 0; return 0;
out_err_unlock: out_err_unlock:
...@@ -1916,8 +1914,6 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) ...@@ -1916,8 +1914,6 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
char *qf_names[REISERFS_MAXQUOTAS] = {}; char *qf_names[REISERFS_MAXQUOTAS] = {};
unsigned int qfmt = 0; unsigned int qfmt = 0;
save_mount_options(s, data);
sbi = kzalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL); sbi = kzalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL);
if (!sbi) if (!sbi)
return -ENOMEM; return -ENOMEM;
......
...@@ -168,7 +168,6 @@ static void destroy_super(struct super_block *s) ...@@ -168,7 +168,6 @@ static void destroy_super(struct super_block *s)
WARN_ON(!list_empty(&s->s_mounts)); WARN_ON(!list_empty(&s->s_mounts));
put_user_ns(s->s_user_ns); put_user_ns(s->s_user_ns);
kfree(s->s_subtype); kfree(s->s_subtype);
kfree(s->s_options);
call_rcu(&s->rcu, destroy_super_rcu); call_rcu(&s->rcu, destroy_super_rcu);
} }
...@@ -508,7 +507,7 @@ struct super_block *sget_userns(struct file_system_type *type, ...@@ -508,7 +507,7 @@ struct super_block *sget_userns(struct file_system_type *type,
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
goto retry; goto retry;
} }
err = set(s, data); err = set(s, data);
if (err) { if (err) {
spin_unlock(&sb_lock); spin_unlock(&sb_lock);
...@@ -771,7 +770,7 @@ struct super_block *get_active_super(struct block_device *bdev) ...@@ -771,7 +770,7 @@ struct super_block *get_active_super(struct block_device *bdev)
spin_unlock(&sb_lock); spin_unlock(&sb_lock);
return NULL; return NULL;
} }
struct super_block *user_get_super(dev_t dev) struct super_block *user_get_super(dev_t dev)
{ {
struct super_block *sb; struct super_block *sb;
......
...@@ -270,8 +270,6 @@ static int trace_fill_super(struct super_block *sb, void *data, int silent) ...@@ -270,8 +270,6 @@ static int trace_fill_super(struct super_block *sb, void *data, int silent)
struct tracefs_fs_info *fsi; struct tracefs_fs_info *fsi;
int err; int err;
save_mount_options(sb, data);
fsi = kzalloc(sizeof(struct tracefs_fs_info), GFP_KERNEL); fsi = kzalloc(sizeof(struct tracefs_fs_info), GFP_KERNEL);
sb->s_fs_info = fsi; sb->s_fs_info = fsi;
if (!fsi) { if (!fsi) {
......
...@@ -55,6 +55,11 @@ struct qstr { ...@@ -55,6 +55,11 @@ struct qstr {
#define QSTR_INIT(n,l) { { { .len = l } }, .name = n } #define QSTR_INIT(n,l) { { { .len = l } }, .name = n }
extern const char empty_string[];
extern const struct qstr empty_name;
extern const char slash_string[];
extern const struct qstr slash_name;
struct dentry_stat_t { struct dentry_stat_t {
long nr_dentry; long nr_dentry;
long nr_unused; long nr_unused;
......
...@@ -1364,11 +1364,6 @@ struct super_block { ...@@ -1364,11 +1364,6 @@ struct super_block {
*/ */
char *s_subtype; char *s_subtype;
/*
* Saved mount options for lazy filesystems using
* generic_show_options()
*/
char __rcu *s_options;
const struct dentry_operations *s_d_op; /* default d_op for dentries */ const struct dentry_operations *s_d_op; /* default d_op for dentries */
/* /*
...@@ -3046,7 +3041,7 @@ extern int generic_block_fiemap(struct inode *inode, ...@@ -3046,7 +3041,7 @@ extern int generic_block_fiemap(struct inode *inode,
struct fiemap_extent_info *fieinfo, u64 start, struct fiemap_extent_info *fieinfo, u64 start,
u64 len, get_block_t *get_block); u64 len, get_block_t *get_block);
extern void get_filesystem(struct file_system_type *fs); extern struct file_system_type *get_filesystem(struct file_system_type *fs);
extern void put_filesystem(struct file_system_type *fs); extern void put_filesystem(struct file_system_type *fs);
extern struct file_system_type *get_fs_type(const char *name); extern struct file_system_type *get_fs_type(const char *name);
extern struct super_block *get_super(struct block_device *); 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,10 +3118,6 @@ extern void setattr_copy(struct inode *inode, const struct iattr *attr);
extern int file_update_time(struct file *file); extern int file_update_time(struct file *file);
extern int generic_show_options(struct seq_file *m, struct dentry *root);
extern void save_mount_options(struct super_block *sb, char *options);
extern void replace_mount_options(struct super_block *sb, char *options);
static inline bool io_is_direct(struct file *filp) static inline bool io_is_direct(struct file *filp)
{ {
return (filp->f_flags & O_DIRECT) || IS_DAX(filp->f_mapping->host); return (filp->f_flags & O_DIRECT) || IS_DAX(filp->f_mapping->host);
......
...@@ -268,6 +268,9 @@ struct hugetlbfs_sb_info { ...@@ -268,6 +268,9 @@ struct hugetlbfs_sb_info {
spinlock_t stat_lock; spinlock_t stat_lock;
struct hstate *hstate; struct hstate *hstate;
struct hugepage_subpool *spool; struct hugepage_subpool *spool;
kuid_t uid;
kgid_t gid;
umode_t mode;
}; };
static inline struct hugetlbfs_sb_info *HUGETLBFS_SB(struct super_block *sb) static inline struct hugetlbfs_sb_info *HUGETLBFS_SB(struct super_block *sb)
......
...@@ -137,6 +137,7 @@ extern char *kstrdup(const char *s, gfp_t gfp) __malloc; ...@@ -137,6 +137,7 @@ extern char *kstrdup(const char *s, gfp_t gfp) __malloc;
extern const char *kstrdup_const(const char *s, gfp_t gfp); extern const char *kstrdup_const(const char *s, gfp_t gfp);
extern char *kstrndup(const char *s, size_t len, gfp_t gfp); extern char *kstrndup(const char *s, size_t len, gfp_t gfp);
extern void *kmemdup(const void *src, size_t len, gfp_t gfp); extern void *kmemdup(const void *src, size_t len, gfp_t gfp);
extern char *kmemdup_nul(const char *s, size_t len, gfp_t gfp);
extern char **argv_split(gfp_t gfp, const char *str, int *argcp); extern char **argv_split(gfp_t gfp, const char *str, int *argcp);
extern void argv_free(char **argv); extern void argv_free(char **argv);
......
...@@ -157,6 +157,18 @@ struct p9_client { ...@@ -157,6 +157,18 @@ struct p9_client {
enum p9_trans_status status; enum p9_trans_status status;
void *trans; void *trans;
union {
struct {
int rfd;
int wfd;
} fd;
struct {
u16 port;
bool privport;
} tcp;
} trans_opts;
struct p9_idpool *fidpool; struct p9_idpool *fidpool;
struct list_head fidlist; struct list_head fidlist;
...@@ -213,6 +225,7 @@ struct p9_dirent { ...@@ -213,6 +225,7 @@ struct p9_dirent {
struct iov_iter; struct iov_iter;
int p9_show_client_options(struct seq_file *m, struct p9_client *clnt);
int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb); int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb);
int p9_client_rename(struct p9_fid *fid, struct p9_fid *newdirfid, int p9_client_rename(struct p9_fid *fid, struct p9_fid *newdirfid,
const char *name); const char *name);
......
...@@ -62,6 +62,7 @@ struct p9_trans_module { ...@@ -62,6 +62,7 @@ struct p9_trans_module {
int (*cancelled)(struct p9_client *, struct p9_req_t *req); int (*cancelled)(struct p9_client *, struct p9_req_t *req);
int (*zc_request)(struct p9_client *, struct p9_req_t *, int (*zc_request)(struct p9_client *, struct p9_req_t *,
struct iov_iter *, struct iov_iter *, int , int, int); struct iov_iter *, struct iov_iter *, int , int, int);
int (*show_options)(struct seq_file *, struct p9_client *);
}; };
void v9fs_register_trans(struct p9_trans_module *m); void v9fs_register_trans(struct p9_trans_module *m);
......
...@@ -377,10 +377,22 @@ static void bpf_evict_inode(struct inode *inode) ...@@ -377,10 +377,22 @@ static void bpf_evict_inode(struct inode *inode)
bpf_any_put(inode->i_private, type); bpf_any_put(inode->i_private, type);
} }
/*
* Display the mount options in /proc/mounts.
*/
static int bpf_show_options(struct seq_file *m, struct dentry *root)
{
umode_t mode = d_inode(root)->i_mode & S_IALLUGO & ~S_ISVTX;
if (mode != S_IRWXUGO)
seq_printf(m, ",mode=%o", mode);
return 0;
}
static const struct super_operations bpf_super_ops = { static const struct super_operations bpf_super_ops = {
.statfs = simple_statfs, .statfs = simple_statfs,
.drop_inode = generic_delete_inode, .drop_inode = generic_delete_inode,
.show_options = generic_show_options, .show_options = bpf_show_options,
.evict_inode = bpf_evict_inode, .evict_inode = bpf_evict_inode,
}; };
...@@ -434,8 +446,6 @@ static int bpf_fill_super(struct super_block *sb, void *data, int silent) ...@@ -434,8 +446,6 @@ static int bpf_fill_super(struct super_block *sb, void *data, int silent)
struct inode *inode; struct inode *inode;
int ret; int ret;
save_mount_options(sb, data);
ret = bpf_parse_options(data, &opts); ret = bpf_parse_options(data, &opts);
if (ret) if (ret)
return ret; return ret;
......
...@@ -83,6 +83,8 @@ EXPORT_SYMBOL(kstrdup_const); ...@@ -83,6 +83,8 @@ EXPORT_SYMBOL(kstrdup_const);
* @s: the string to duplicate * @s: the string to duplicate
* @max: read at most @max chars from @s * @max: read at most @max chars from @s
* @gfp: the GFP mask used in the kmalloc() call when allocating memory * @gfp: the GFP mask used in the kmalloc() call when allocating memory
*
* Note: Use kmemdup_nul() instead if the size is known exactly.
*/ */
char *kstrndup(const char *s, size_t max, gfp_t gfp) char *kstrndup(const char *s, size_t max, gfp_t gfp)
{ {
...@@ -120,6 +122,28 @@ void *kmemdup(const void *src, size_t len, gfp_t gfp) ...@@ -120,6 +122,28 @@ void *kmemdup(const void *src, size_t len, gfp_t gfp)
} }
EXPORT_SYMBOL(kmemdup); EXPORT_SYMBOL(kmemdup);
/**
* kmemdup_nul - Create a NUL-terminated string from unterminated data
* @s: The data to stringify
* @len: The size of the data
* @gfp: the GFP mask used in the kmalloc() call when allocating memory
*/
char *kmemdup_nul(const char *s, size_t len, gfp_t gfp)
{
char *buf;
if (!s)
return NULL;
buf = kmalloc_track_caller(len + 1, gfp);
if (buf) {
memcpy(buf, s, len);
buf[len] = '\0';
}
return buf;
}
EXPORT_SYMBOL(kmemdup_nul);
/** /**
* memdup_user - duplicate memory region from user space * memdup_user - duplicate memory region from user space
* *
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <linux/uio.h> #include <linux/uio.h>
#include <net/9p/9p.h> #include <net/9p/9p.h>
#include <linux/parser.h> #include <linux/parser.h>
#include <linux/seq_file.h>
#include <net/9p/client.h> #include <net/9p/client.h>
#include <net/9p/transport.h> #include <net/9p/transport.h>
#include "protocol.h" #include "protocol.h"
...@@ -77,6 +78,30 @@ inline int p9_is_proto_dotu(struct p9_client *clnt) ...@@ -77,6 +78,30 @@ inline int p9_is_proto_dotu(struct p9_client *clnt)
} }
EXPORT_SYMBOL(p9_is_proto_dotu); EXPORT_SYMBOL(p9_is_proto_dotu);
int p9_show_client_options(struct seq_file *m, struct p9_client *clnt)
{
if (clnt->msize != 8192)
seq_printf(m, ",msize=%u", clnt->msize);
seq_printf(m, "trans=%s", clnt->trans_mod->name);
switch (clnt->proto_version) {
case p9_proto_legacy:
seq_puts(m, ",noextend");
break;
case p9_proto_2000u:
seq_puts(m, ",version=9p2000.u");
break;
case p9_proto_2000L:
/* Default */
break;
}
if (clnt->trans_mod->show_options)
return clnt->trans_mod->show_options(m, clnt);
return 0;
}
EXPORT_SYMBOL(p9_show_client_options);
/* /*
* Some error codes are taken directly from the server replies, * Some error codes are taken directly from the server replies,
* make sure they are valid. * make sure they are valid.
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include <linux/file.h> #include <linux/file.h>
#include <linux/parser.h> #include <linux/parser.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/seq_file.h>
#include <net/9p/9p.h> #include <net/9p/9p.h>
#include <net/9p/client.h> #include <net/9p/client.h>
#include <net/9p/transport.h> #include <net/9p/transport.h>
...@@ -51,6 +52,9 @@ ...@@ -51,6 +52,9 @@
#define MAX_SOCK_BUF (64*1024) #define MAX_SOCK_BUF (64*1024)
#define MAXPOLLWADDR 2 #define MAXPOLLWADDR 2
static struct p9_trans_module p9_tcp_trans;
static struct p9_trans_module p9_fd_trans;
/** /**
* struct p9_fd_opts - per-transport options * struct p9_fd_opts - per-transport options
* @rfd: file descriptor for reading (trans=fd) * @rfd: file descriptor for reading (trans=fd)
...@@ -63,7 +67,7 @@ struct p9_fd_opts { ...@@ -63,7 +67,7 @@ struct p9_fd_opts {
int rfd; int rfd;
int wfd; int wfd;
u16 port; u16 port;
int privport; bool privport;
}; };
/* /*
...@@ -720,6 +724,20 @@ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req) ...@@ -720,6 +724,20 @@ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req)
return 0; return 0;
} }
static int p9_fd_show_options(struct seq_file *m, struct p9_client *clnt)
{
if (clnt->trans_mod == &p9_tcp_trans) {
if (clnt->trans_opts.tcp.port != P9_PORT)
seq_printf(m, "port=%u", clnt->trans_opts.tcp.port);
} else if (clnt->trans_mod == &p9_fd_trans) {
if (clnt->trans_opts.fd.rfd != ~0)
seq_printf(m, "rfd=%u", clnt->trans_opts.fd.rfd);
if (clnt->trans_opts.fd.wfd != ~0)
seq_printf(m, "wfd=%u", clnt->trans_opts.fd.wfd);
}
return 0;
}
/** /**
* parse_opts - parse mount options into p9_fd_opts structure * parse_opts - parse mount options into p9_fd_opts structure
* @params: options string passed from mount * @params: options string passed from mount
...@@ -738,7 +756,7 @@ static int parse_opts(char *params, struct p9_fd_opts *opts) ...@@ -738,7 +756,7 @@ static int parse_opts(char *params, struct p9_fd_opts *opts)
opts->port = P9_PORT; opts->port = P9_PORT;
opts->rfd = ~0; opts->rfd = ~0;
opts->wfd = ~0; opts->wfd = ~0;
opts->privport = 0; opts->privport = false;
if (!params) if (!params)
return 0; return 0;
...@@ -776,7 +794,7 @@ static int parse_opts(char *params, struct p9_fd_opts *opts) ...@@ -776,7 +794,7 @@ static int parse_opts(char *params, struct p9_fd_opts *opts)
opts->wfd = option; opts->wfd = option;
break; break;
case Opt_privport: case Opt_privport:
opts->privport = 1; opts->privport = true;
break; break;
default: default:
continue; continue;
...@@ -942,6 +960,8 @@ p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args) ...@@ -942,6 +960,8 @@ p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args)
csocket = NULL; csocket = NULL;
client->trans_opts.tcp.port = opts.port;
client->trans_opts.tcp.privport = opts.privport;
sin_server.sin_family = AF_INET; sin_server.sin_family = AF_INET;
sin_server.sin_addr.s_addr = in_aton(addr); sin_server.sin_addr.s_addr = in_aton(addr);
sin_server.sin_port = htons(opts.port); sin_server.sin_port = htons(opts.port);
...@@ -1020,6 +1040,8 @@ p9_fd_create(struct p9_client *client, const char *addr, char *args) ...@@ -1020,6 +1040,8 @@ p9_fd_create(struct p9_client *client, const char *addr, char *args)
struct p9_fd_opts opts; struct p9_fd_opts opts;
parse_opts(args, &opts); parse_opts(args, &opts);
client->trans_opts.fd.rfd = opts.rfd;
client->trans_opts.fd.wfd = opts.wfd;
if (opts.rfd == ~0 || opts.wfd == ~0) { if (opts.rfd == ~0 || opts.wfd == ~0) {
pr_err("Insufficient options for proto=fd\n"); pr_err("Insufficient options for proto=fd\n");
...@@ -1044,6 +1066,7 @@ static struct p9_trans_module p9_tcp_trans = { ...@@ -1044,6 +1066,7 @@ static struct p9_trans_module p9_tcp_trans = {
.request = p9_fd_request, .request = p9_fd_request,
.cancel = p9_fd_cancel, .cancel = p9_fd_cancel,
.cancelled = p9_fd_cancelled, .cancelled = p9_fd_cancelled,
.show_options = p9_fd_show_options,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
...@@ -1056,6 +1079,7 @@ static struct p9_trans_module p9_unix_trans = { ...@@ -1056,6 +1079,7 @@ static struct p9_trans_module p9_unix_trans = {
.request = p9_fd_request, .request = p9_fd_request,
.cancel = p9_fd_cancel, .cancel = p9_fd_cancel,
.cancelled = p9_fd_cancelled, .cancelled = p9_fd_cancelled,
.show_options = p9_fd_show_options,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
...@@ -1068,6 +1092,7 @@ static struct p9_trans_module p9_fd_trans = { ...@@ -1068,6 +1092,7 @@ static struct p9_trans_module p9_fd_trans = {
.request = p9_fd_request, .request = p9_fd_request,
.cancel = p9_fd_cancel, .cancel = p9_fd_cancel,
.cancelled = p9_fd_cancelled, .cancelled = p9_fd_cancelled,
.show_options = p9_fd_show_options,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include <linux/parser.h> #include <linux/parser.h>
#include <linux/semaphore.h> #include <linux/semaphore.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/seq_file.h>
#include <net/9p/9p.h> #include <net/9p/9p.h>
#include <net/9p/client.h> #include <net/9p/client.h>
#include <net/9p/transport.h> #include <net/9p/transport.h>
...@@ -70,6 +71,8 @@ ...@@ -70,6 +71,8 @@
* @dm_mr: DMA Memory Region pointer * @dm_mr: DMA Memory Region pointer
* @lkey: The local access only memory region key * @lkey: The local access only memory region key
* @timeout: Number of uSecs to wait for connection management events * @timeout: Number of uSecs to wait for connection management events
* @privport: Whether a privileged port may be used
* @port: The port to use
* @sq_depth: The depth of the Send Queue * @sq_depth: The depth of the Send Queue
* @sq_sem: Semaphore for the SQ * @sq_sem: Semaphore for the SQ
* @rq_depth: The depth of the Receive Queue. * @rq_depth: The depth of the Receive Queue.
...@@ -95,6 +98,8 @@ struct p9_trans_rdma { ...@@ -95,6 +98,8 @@ struct p9_trans_rdma {
struct ib_qp *qp; struct ib_qp *qp;
struct ib_cq *cq; struct ib_cq *cq;
long timeout; long timeout;
bool privport;
u16 port;
int sq_depth; int sq_depth;
struct semaphore sq_sem; struct semaphore sq_sem;
int rq_depth; int rq_depth;
...@@ -133,10 +138,10 @@ struct p9_rdma_context { ...@@ -133,10 +138,10 @@ struct p9_rdma_context {
*/ */
struct p9_rdma_opts { struct p9_rdma_opts {
short port; short port;
bool privport;
int sq_depth; int sq_depth;
int rq_depth; int rq_depth;
long timeout; long timeout;
int privport;
}; };
/* /*
...@@ -159,6 +164,23 @@ static match_table_t tokens = { ...@@ -159,6 +164,23 @@ static match_table_t tokens = {
{Opt_err, NULL}, {Opt_err, NULL},
}; };
static int p9_rdma_show_options(struct seq_file *m, struct p9_client *clnt)
{
struct p9_trans_rdma *rdma = clnt->trans;
if (rdma->port != P9_PORT)
seq_printf(m, ",port=%u", rdma->port);
if (rdma->sq_depth != P9_RDMA_SQ_DEPTH)
seq_printf(m, ",sq=%u", rdma->sq_depth);
if (rdma->rq_depth != P9_RDMA_RQ_DEPTH)
seq_printf(m, ",rq=%u", rdma->rq_depth);
if (rdma->timeout != P9_RDMA_TIMEOUT)
seq_printf(m, ",timeout=%lu", rdma->timeout);
if (rdma->privport)
seq_puts(m, ",privport");
return 0;
}
/** /**
* parse_opts - parse mount options into rdma options structure * parse_opts - parse mount options into rdma options structure
* @params: options string passed from mount * @params: options string passed from mount
...@@ -177,7 +199,7 @@ static int parse_opts(char *params, struct p9_rdma_opts *opts) ...@@ -177,7 +199,7 @@ static int parse_opts(char *params, struct p9_rdma_opts *opts)
opts->sq_depth = P9_RDMA_SQ_DEPTH; opts->sq_depth = P9_RDMA_SQ_DEPTH;
opts->rq_depth = P9_RDMA_RQ_DEPTH; opts->rq_depth = P9_RDMA_RQ_DEPTH;
opts->timeout = P9_RDMA_TIMEOUT; opts->timeout = P9_RDMA_TIMEOUT;
opts->privport = 0; opts->privport = false;
if (!params) if (!params)
return 0; return 0;
...@@ -218,7 +240,7 @@ static int parse_opts(char *params, struct p9_rdma_opts *opts) ...@@ -218,7 +240,7 @@ static int parse_opts(char *params, struct p9_rdma_opts *opts)
opts->timeout = option; opts->timeout = option;
break; break;
case Opt_privport: case Opt_privport:
opts->privport = 1; opts->privport = true;
break; break;
default: default:
continue; continue;
...@@ -560,6 +582,8 @@ static struct p9_trans_rdma *alloc_rdma(struct p9_rdma_opts *opts) ...@@ -560,6 +582,8 @@ static struct p9_trans_rdma *alloc_rdma(struct p9_rdma_opts *opts)
if (!rdma) if (!rdma)
return NULL; return NULL;
rdma->port = opts->port;
rdma->privport = opts->privport;
rdma->sq_depth = opts->sq_depth; rdma->sq_depth = opts->sq_depth;
rdma->rq_depth = opts->rq_depth; rdma->rq_depth = opts->rq_depth;
rdma->timeout = opts->timeout; rdma->timeout = opts->timeout;
...@@ -733,6 +757,7 @@ static struct p9_trans_module p9_rdma_trans = { ...@@ -733,6 +757,7 @@ static struct p9_trans_module p9_rdma_trans = {
.request = rdma_request, .request = rdma_request,
.cancel = rdma_cancel, .cancel = rdma_cancel,
.cancelled = rdma_cancelled, .cancelled = rdma_cancelled,
.show_options = p9_rdma_show_options,
}; };
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment