On Tue 25-03-14 17:41:59, Linus Torvalds wrote: > On Tue, Mar 25, 2014 at 2:12 PM, Jan Kara <jack@xxxxxxx> wrote: > > > > Can you try whether the following patch fixes the issue for you? > > Good catch, Honza. > > I hate how fragile that code ends up being and would love to see that > "anon_inode_inode" allocation and assignment just once in > anon_inode_init(), but considering that it wants the superblock > pointer, I suspect it's not cleanly doable. Oh well. Your patch looks > like it should make the issue moot, I just dread this happening again > due to the layout of the code. Well, I think it could be done relatively cleanly... How about the attached patch (it boots for me)? Honza -- Jan Kara <jack@xxxxxxx> SUSE Labs, CR
>From de87b1e6c3613d92f659c632be57461e87828e42 Mon Sep 17 00:00:00 2001 From: Jan Kara <jack@xxxxxxx> Date: Wed, 26 Mar 2014 06:20:14 +0100 Subject: [PATCH] vfs: Allocate anon_inode_inode in anon_inode_init() Currently we allocated anon_inode_inode in anon_inodefs_mount. This is somewhat fragile as if that function ever gets called again, it will overwrite anon_inode_inode pointer. So move the initialization of anon_inode_inode to anon_inode_init(). Signed-off-by: Jan Kara <jack@xxxxxxx> --- fs/anon_inodes.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c index 4b4543b8b894..7f34f7702204 100644 --- a/fs/anon_inodes.c +++ b/fs/anon_inodes.c @@ -41,19 +41,8 @@ static const struct dentry_operations anon_inodefs_dentry_operations = { static struct dentry *anon_inodefs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) { - struct dentry *root; - root = mount_pseudo(fs_type, "anon_inode:", NULL, + return mount_pseudo(fs_type, "anon_inode:", NULL, &anon_inodefs_dentry_operations, ANON_INODE_FS_MAGIC); - if (!IS_ERR(root)) { - struct super_block *s = root->d_sb; - anon_inode_inode = alloc_anon_inode(s); - if (IS_ERR(anon_inode_inode)) { - dput(root); - deactivate_locked_super(s); - root = ERR_CAST(anon_inode_inode); - } - } - return root; } static struct file_system_type anon_inode_fs_type = { @@ -180,12 +169,15 @@ static int __init anon_inode_init(void) anon_inode_mnt = kern_mount(&anon_inode_fs_type); if (IS_ERR(anon_inode_mnt)) { error = PTR_ERR(anon_inode_mnt); - goto err_unregister_filesystem; + goto err_exit; + } + anon_inode_inode = alloc_anon_inode(anon_inode_mnt->mnt_sb); + if (IS_ERR(anon_inode_inode)) { + error = PTR_ERR(anon_inode_inode); + goto err_exit; } return 0; -err_unregister_filesystem: - unregister_filesystem(&anon_inode_fs_type); err_exit: panic(KERN_ERR "anon_inode_init() failed (%d)\n", error); } -- 1.8.1.4