Commit 9279e3b6 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] (2/14) resync

FS_NOMOUNT is gone, initialization for pseudo-filesystems
(bdev, pipe, sock) switched to use of a common helper.
parent c162e8ec
...@@ -215,3 +215,9 @@ not protected by the conditions above is risky even in the old tree - you ...@@ -215,3 +215,9 @@ not protected by the conditions above is risky even in the old tree - you
had been relying on BKL and that's prone to screwups. Old tree had quite had been relying on BKL and that's prone to screwups. Old tree had quite
a few holes of that kind - unprotected access to ->d_parent leading to a few holes of that kind - unprotected access to ->d_parent leading to
anything from oops to silent memory corruption. anything from oops to silent memory corruption.
---
[mandatory]
FS_NOMOUNT is gone. If you use it - just set MS_NOUSER in flags
(see rootfs for one kind of solution and bdev/socket/pipe for another).
...@@ -181,44 +181,16 @@ static int block_fsync(struct file *filp, struct dentry *dentry, int datasync) ...@@ -181,44 +181,16 @@ static int block_fsync(struct file *filp, struct dentry *dentry, int datasync)
* pseudo-fs * pseudo-fs
*/ */
static int bd_fill_super(struct super_block *sb, void *data, int silent)
{
static struct super_operations sops = {};
struct inode *root;
sb->s_maxbytes = ~0ULL;
sb->s_blocksize = 1024;
sb->s_blocksize_bits = 10;
sb->s_magic = 0x62646576;
sb->s_op = &sops;
root = new_inode(sb);
if (!root)
return -ENOMEM;
root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
root->i_uid = root->i_gid = 0;
root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
sb->s_root = d_alloc(NULL, &(const struct qstr) { "bdev:", 5, 0 });
if (!sb->s_root) {
iput(root);
return -ENOMEM;
}
sb->s_root->d_sb = sb;
sb->s_root->d_parent = sb->s_root;
d_instantiate(sb->s_root, root);
return 0;
}
static struct super_block *bd_get_sb(struct file_system_type *fs_type, static struct super_block *bd_get_sb(struct file_system_type *fs_type,
int flags, char *dev_name, void *data) int flags, char *dev_name, void *data)
{ {
return get_sb_nodev(fs_type, flags, data, bd_fill_super); return get_sb_pseudo(fs_type, "bdev:", NULL, 0x62646576);
} }
static struct file_system_type bd_type = { static struct file_system_type bd_type = {
name: "bdev", name: "bdev",
get_sb: bd_get_sb, get_sb: bd_get_sb,
kill_sb: kill_anon_super, kill_sb: kill_anon_super,
fs_flags: FS_NOMOUNT,
}; };
static struct vfsmount *bd_mnt; static struct vfsmount *bd_mnt;
......
...@@ -155,3 +155,50 @@ struct file_operations simple_dir_operations = { ...@@ -155,3 +155,50 @@ struct file_operations simple_dir_operations = {
struct inode_operations simple_dir_inode_operations = { struct inode_operations simple_dir_inode_operations = {
lookup: simple_lookup, lookup: simple_lookup,
}; };
/*
* Common helper for pseudo-filesystems (sockfs, pipefs, bdev - stuff that
* will never be mountable)
*/
struct super_block *
get_sb_pseudo(struct file_system_type *fs_type, char *name,
struct super_operations *ops, unsigned long magic)
{
struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL);
static struct super_operations default_ops = {statfs: simple_statfs};
struct dentry *dentry;
struct inode *root;
struct qstr d_name = {name:name, len:strlen(name)};
if (IS_ERR(s))
return s;
s->s_flags = MS_NOUSER;
s->s_maxbytes = ~0ULL;
s->s_blocksize = 1024;
s->s_blocksize_bits = 10;
s->s_magic = magic;
s->s_op = ops ? ops : &default_ops;
root = new_inode(s);
if (!root)
goto Enomem;
root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
root->i_uid = root->i_gid = 0;
root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
dentry = d_alloc(NULL, &d_name);
if (!dentry) {
iput(root);
goto Enomem;
}
dentry->d_sb = s;
dentry->d_parent = dentry;
d_instantiate(dentry, root);
s->s_root = dentry;
s->s_flags |= MS_ACTIVE;
return s;
Enomem:
up_write(&s->s_umount);
deactivate_super(s);
return ERR_PTR(-ENOMEM);
}
...@@ -665,46 +665,16 @@ int do_pipe(int *fd) ...@@ -665,46 +665,16 @@ int do_pipe(int *fd)
* d_name - pipe: will go nicely and kill the special-casing in procfs. * d_name - pipe: will go nicely and kill the special-casing in procfs.
*/ */
static struct super_operations pipefs_ops = {
statfs: simple_statfs,
};
static int pipefs_fill_super(struct super_block *sb, void *data, int silent)
{
struct inode *root;
sb->s_blocksize = 1024;
sb->s_blocksize_bits = 10;
sb->s_magic = PIPEFS_MAGIC;
sb->s_op = &pipefs_ops;
root = new_inode(sb);
if (!root)
return -ENOMEM;
root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
root->i_uid = root->i_gid = 0;
root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
sb->s_root = d_alloc(NULL, &(const struct qstr) { "pipe:", 5, 0 });
if (!sb->s_root) {
iput(root);
return -ENOMEM;
}
sb->s_root->d_sb = sb;
sb->s_root->d_parent = sb->s_root;
d_instantiate(sb->s_root, root);
return 0;
}
static struct super_block *pipefs_get_sb(struct file_system_type *fs_type, static struct super_block *pipefs_get_sb(struct file_system_type *fs_type,
int flags, char *dev_name, void *data) int flags, char *dev_name, void *data)
{ {
return get_sb_nodev(fs_type, flags, data, pipefs_fill_super); return get_sb_pseudo(fs_type, "pipe:", NULL, PIPEFS_MAGIC);
} }
static struct file_system_type pipe_fs_type = { static struct file_system_type pipe_fs_type = {
name: "pipefs", name: "pipefs",
get_sb: pipefs_get_sb, get_sb: pipefs_get_sb,
kill_sb: kill_anon_super, kill_sb: kill_anon_super,
fs_flags: FS_NOMOUNT,
}; };
static int __init init_pipe_fs(void) static int __init init_pipe_fs(void)
......
...@@ -308,6 +308,12 @@ static struct super_block *ramfs_get_sb(struct file_system_type *fs_type, ...@@ -308,6 +308,12 @@ static struct super_block *ramfs_get_sb(struct file_system_type *fs_type,
return get_sb_nodev(fs_type, flags, data, ramfs_fill_super); return get_sb_nodev(fs_type, flags, data, ramfs_fill_super);
} }
static struct super_block *rootfs_get_sb(struct file_system_type *fs_type,
int flags, char *dev_name, void *data)
{
return get_sb_nodev(fs_type, flags|MS_NOUSER, data, ramfs_fill_super);
}
static struct file_system_type ramfs_fs_type = { static struct file_system_type ramfs_fs_type = {
name: "ramfs", name: "ramfs",
get_sb: ramfs_get_sb, get_sb: ramfs_get_sb,
...@@ -315,9 +321,8 @@ static struct file_system_type ramfs_fs_type = { ...@@ -315,9 +321,8 @@ static struct file_system_type ramfs_fs_type = {
}; };
static struct file_system_type rootfs_fs_type = { static struct file_system_type rootfs_fs_type = {
name: "rootfs", name: "rootfs",
get_sb: ramfs_get_sb, get_sb: rootfs_get_sb,
kill_sb: kill_litter_super, kill_sb: kill_litter_super,
fs_flags: FS_NOMOUNT,
}; };
static int __init init_ramfs_fs(void) static int __init init_ramfs_fs(void)
...@@ -339,4 +344,3 @@ int __init init_rootfs(void) ...@@ -339,4 +344,3 @@ int __init init_rootfs(void)
} }
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -618,8 +618,6 @@ do_kern_mount(const char *fstype, int flags, char *name, void *data) ...@@ -618,8 +618,6 @@ do_kern_mount(const char *fstype, int flags, char *name, void *data)
sb = type->get_sb(type, flags, name, data); sb = type->get_sb(type, flags, name, data);
if (IS_ERR(sb)) if (IS_ERR(sb))
goto out_mnt; goto out_mnt;
if (type->fs_flags & FS_NOMOUNT)
sb->s_flags |= MS_NOUSER;
mnt->mnt_sb = sb; mnt->mnt_sb = sb;
mnt->mnt_root = dget(sb->s_root); mnt->mnt_root = dget(sb->s_root);
mnt->mnt_mountpoint = sb->s_root; mnt->mnt_mountpoint = sb->s_root;
......
...@@ -89,11 +89,6 @@ extern int leases_enable, dir_notify_enable, lease_break_time; ...@@ -89,11 +89,6 @@ extern int leases_enable, dir_notify_enable, lease_break_time;
/* public flags for file_system_type */ /* public flags for file_system_type */
#define FS_REQUIRES_DEV 1 #define FS_REQUIRES_DEV 1
#define FS_NO_DCACHE 2 /* Only dcache the necessary things. */
#define FS_NO_PRELIM 4 /* prevent preloading of dentries, even if
* FS_NO_DCACHE is not set.
*/
#define FS_NOMOUNT 16 /* Never mount from userland */
#define FS_ODD_RENAME 32768 /* Temporary stuff; will go away as soon #define FS_ODD_RENAME 32768 /* Temporary stuff; will go away as soon
* as nfs_rename() will be cleaned up * as nfs_rename() will be cleaned up
*/ */
...@@ -969,6 +964,8 @@ struct super_block *sget(struct file_system_type *type, ...@@ -969,6 +964,8 @@ struct super_block *sget(struct file_system_type *type,
int (*test)(struct super_block *,void *), int (*test)(struct super_block *,void *),
int (*set)(struct super_block *,void *), int (*set)(struct super_block *,void *),
void *data); void *data);
struct super_block *get_sb_pseudo(struct file_system_type *, char *,
struct super_operations *ops, unsigned long);
/* Alas, no aliases. Too much hassle with bringing module.h everywhere */ /* Alas, no aliases. Too much hassle with bringing module.h everywhere */
#define fops_get(fops) \ #define fops_get(fops) \
......
...@@ -1358,6 +1358,8 @@ static int shmem_fill_super(struct super_block * sb, void * data, int silent) ...@@ -1358,6 +1358,8 @@ static int shmem_fill_super(struct super_block * sb, void * data, int silent)
err = -EINVAL; err = -EINVAL;
goto failed; goto failed;
} }
#else
sb->s_flags |= MS_NOUSER;
#endif #endif
spin_lock_init (&sbinfo->stat_lock); spin_lock_init (&sbinfo->stat_lock);
...@@ -1505,21 +1507,13 @@ static struct file_system_type shmem_fs_type = { ...@@ -1505,21 +1507,13 @@ static struct file_system_type shmem_fs_type = {
get_sb: shmem_get_sb, get_sb: shmem_get_sb,
kill_sb: kill_litter_super, kill_sb: kill_litter_super,
}; };
#endif
static struct file_system_type tmpfs_fs_type = { static struct file_system_type tmpfs_fs_type = {
owner: THIS_MODULE, owner: THIS_MODULE,
name: "tmpfs", name: "tmpfs",
get_sb: shmem_get_sb, get_sb: shmem_get_sb,
kill_sb: kill_litter_super, kill_sb: kill_litter_super,
}; };
#else
static struct file_system_type tmpfs_fs_type = {
owner: THIS_MODULE,
name: "tmpfs",
get_sb: shmem_get_sb,
kill_sb: kill_litter_super,
fs_flags: FS_NOMOUNT,
};
#endif
static struct vfsmount *shm_mnt; static struct vfsmount *shm_mnt;
static int __init init_shmem_fs(void) static int __init init_shmem_fs(void)
......
...@@ -317,34 +317,10 @@ static struct super_operations sockfs_ops = { ...@@ -317,34 +317,10 @@ static struct super_operations sockfs_ops = {
statfs: simple_statfs, statfs: simple_statfs,
}; };
static int sockfs_fill_super(struct super_block *sb, void *data, int silent)
{
struct inode *root;
sb->s_blocksize = 1024;
sb->s_blocksize_bits = 10;
sb->s_magic = SOCKFS_MAGIC;
sb->s_op = &sockfs_ops;
root = new_inode(sb);
if (!root)
return -ENOMEM;
root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
root->i_uid = root->i_gid = 0;
root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
sb->s_root = d_alloc(NULL, &(const struct qstr) { "socket:", 7, 0 });
if (!sb->s_root) {
iput(root);
return -ENOMEM;
}
sb->s_root->d_sb = sb;
sb->s_root->d_parent = sb->s_root;
d_instantiate(sb->s_root, root);
return 0;
}
static struct super_block *sockfs_get_sb(struct file_system_type *fs_type, static struct super_block *sockfs_get_sb(struct file_system_type *fs_type,
int flags, char *dev_name, void *data) int flags, char *dev_name, void *data)
{ {
return get_sb_nodev(fs_type, flags, data, sockfs_fill_super); return get_sb_pseudo(fs_type, "socket:", &sockfs_ops, SOCKFS_MAGIC);
} }
static struct vfsmount *sock_mnt; static struct vfsmount *sock_mnt;
...@@ -353,7 +329,6 @@ static struct file_system_type sock_fs_type = { ...@@ -353,7 +329,6 @@ static struct file_system_type sock_fs_type = {
name: "sockfs", name: "sockfs",
get_sb: sockfs_get_sb, get_sb: sockfs_get_sb,
kill_sb: kill_anon_super, kill_sb: kill_anon_super,
fs_flags: FS_NOMOUNT,
}; };
static int sockfs_delete_dentry(struct dentry *dentry) static int sockfs_delete_dentry(struct dentry *dentry)
{ {
......
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