From 73422811d290c628b4ddbf6830e5cd6fa42e84f1 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Sun, 10 May 2009 16:05:39 -0400 Subject: reiserfs: allow exposing privroot w/ xattrs enabled This patch adds an -oexpose_privroot option to allow access to the privroot. Signed-off-by: Jeff Mahoney Signed-off-by: Al Viro --- fs/reiserfs/super.c | 1 + 1 file changed, 1 insertion(+) (limited to 'fs/reiserfs/super.c') diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 3567fb9e3fb..9dbdcfb5d31 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -898,6 +898,7 @@ static int reiserfs_parse_options(struct super_block *s, char *options, /* strin {"conv",.setmask = 1 << REISERFS_CONVERT}, {"attrs",.setmask = 1 << REISERFS_ATTRS}, {"noattrs",.clrmask = 1 << REISERFS_ATTRS}, + {"expose_privroot", .setmask = 1 << REISERFS_EXPOSE_PRIVROOT}, #ifdef CONFIG_REISERFS_FS_XATTR {"user_xattr",.setmask = 1 << REISERFS_XATTRS_USER}, {"nouser_xattr",.clrmask = 1 << REISERFS_XATTRS_USER}, -- cgit v1.2.3-70-g09d2 From 8c85e125124a473d6f3e9bb187b0b84207f81d91 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 28 Apr 2009 18:00:26 +0200 Subject: remove ->write_super call in generic_shutdown_super We just did a full fs writeout using sync_filesystem before, and if that's not enough for the filesystem it can perform it's own writeout in ->put_super, which many filesystems already do. Move a call to foofs_write_super into every foofs_put_super for now to guarantee identical behaviour until it's cleaned up by the individual filesystem maintainers. Exceptions: - affs already has identical copy & pasted code at the beginning of affs_put_super so no need to do it twice. - xfs does the right thing without it and I have changes pending for the xfs tree touching this are so I don't really need conflicts here.. Signed-off-by: Christoph Hellwig Signed-off-by: Al Viro --- fs/bfs/inode.c | 4 ++++ fs/exofs/super.c | 3 +++ fs/ext2/super.c | 3 +++ fs/ext4/super.c | 3 +++ fs/fat/inode.c | 3 +++ fs/hfs/super.c | 2 ++ fs/hfsplus/super.c | 2 ++ fs/jffs2/super.c | 3 +++ fs/nilfs2/super.c | 4 ++++ fs/reiserfs/super.c | 3 +++ fs/super.c | 2 -- fs/sysv/inode.c | 3 +++ fs/ufs/super.c | 3 +++ 13 files changed, 36 insertions(+), 2 deletions(-) (limited to 'fs/reiserfs/super.c') diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index cc4062d12ca..4cf3d269e27 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c @@ -30,6 +30,7 @@ MODULE_LICENSE("GPL"); #define dprintf(x...) #endif +static void bfs_write_super(struct super_block *s); void dump_imap(const char *prefix, struct super_block *s); struct inode *bfs_iget(struct super_block *sb, unsigned long ino) @@ -216,6 +217,9 @@ static void bfs_put_super(struct super_block *s) if (!info) return; + if (s->s_dirt) + bfs_write_super(s); + brelse(info->si_sbh); mutex_destroy(&info->bfs_lock); kfree(info->si_imap); diff --git a/fs/exofs/super.c b/fs/exofs/super.c index 9f1985e857e..3cdb761db8a 100644 --- a/fs/exofs/super.c +++ b/fs/exofs/super.c @@ -258,6 +258,9 @@ static void exofs_put_super(struct super_block *sb) int num_pend; struct exofs_sb_info *sbi = sb->s_fs_info; + if (sb->s_dirt) + exofs_write_super(sb); + /* make sure there are no pending commands */ for (num_pend = atomic_read(&sbi->s_curr_pending); num_pend > 0; num_pend = atomic_read(&sbi->s_curr_pending)) { diff --git a/fs/ext2/super.c b/fs/ext2/super.c index e3c748faf2d..932a2bcb690 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -114,6 +114,9 @@ static void ext2_put_super (struct super_block * sb) int i; struct ext2_sb_info *sbi = EXT2_SB(sb); + if (sb->s_dirt) + ext2_write_super(sb); + ext2_xattr_put_super(sb); if (!(sb->s_flags & MS_RDONLY)) { struct ext2_super_block *es = sbi->s_es; diff --git a/fs/ext4/super.c b/fs/ext4/super.c index f016707597a..c7b8f8d9b7a 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -576,6 +576,9 @@ static void ext4_put_super(struct super_block *sb) struct ext4_super_block *es = sbi->s_es; int i, err; + if (sb->s_dirt) + ext4_write_super(sb); + ext4_release_system_zone(sb); ext4_mb_release(sb); ext4_ext_release(sb); diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 296785a0dec..4978621511b 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -451,6 +451,9 @@ static void fat_put_super(struct super_block *sb) { struct msdos_sb_info *sbi = MSDOS_SB(sb); + if (sb->s_dirt) + fat_write_super(sb); + if (sbi->nls_disk) { unload_nls(sbi->nls_disk); sbi->nls_disk = NULL; diff --git a/fs/hfs/super.c b/fs/hfs/super.c index a36bb749926..e071e6d0646 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c @@ -65,6 +65,8 @@ static void hfs_write_super(struct super_block *sb) */ static void hfs_put_super(struct super_block *sb) { + if (sb->s_dirt) + hfs_write_super(sb); hfs_mdb_close(sb); /* release the MDB's resources */ hfs_mdb_put(sb); diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index f2a64020f42..40bdab79dae 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c @@ -199,6 +199,8 @@ static void hfsplus_put_super(struct super_block *sb) dprint(DBG_SUPER, "hfsplus_put_super\n"); if (!sb->s_fs_info) return; + if (sb->s_dirt) + hfsplus_write_super(sb); if (!(sb->s_flags & MS_RDONLY) && HFSPLUS_SB(sb).s_vhdr) { struct hfsplus_vh *vhdr = HFSPLUS_SB(sb).s_vhdr; diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index 4c4e18c54a5..5059e9633ed 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c @@ -174,6 +174,9 @@ static void jffs2_put_super (struct super_block *sb) D2(printk(KERN_DEBUG "jffs2: jffs2_put_super()\n")); + if (sb->s_dirt) + jffs2_write_super(sb); + mutex_lock(&c->alloc_sem); jffs2_flush_wbuf_pad(c); mutex_unlock(&c->alloc_sem); diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 6989b03e97a..7901d8cbb9b 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c @@ -65,6 +65,7 @@ MODULE_DESCRIPTION("A New Implementation of the Log-structured Filesystem " "(NILFS)"); MODULE_LICENSE("GPL"); +static void nilfs_write_super(struct super_block *sb); static int nilfs_remount(struct super_block *sb, int *flags, char *data); static int test_exclusive_mount(struct file_system_type *fs_type, struct block_device *bdev, int flags); @@ -315,6 +316,9 @@ static void nilfs_put_super(struct super_block *sb) struct nilfs_sb_info *sbi = NILFS_SB(sb); struct the_nilfs *nilfs = sbi->s_nilfs; + if (sb->s_dirt) + nilfs_write_super(sb); + nilfs_detach_segment_constructor(sbi); if (!(sb->s_flags & MS_RDONLY)) { diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 9dbdcfb5d31..1b52daa351c 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -468,6 +468,9 @@ static void reiserfs_put_super(struct super_block *s) struct reiserfs_transaction_handle th; th.t_trans_id = 0; + if (s->s_dirt) + reiserfs_write_super(s); + /* change file system state to current state if it was mounted with read-write permissions */ if (!(s->s_flags & MS_RDONLY)) { if (!journal_begin(&th, s, 10)) { diff --git a/fs/super.c b/fs/super.c index 721236e6177..d9a29d5b1d2 100644 --- a/fs/super.c +++ b/fs/super.c @@ -311,8 +311,6 @@ void generic_shutdown_super(struct super_block *sb) invalidate_inodes(sb); lock_kernel(); - if (sop->write_super && sb->s_dirt) - sop->write_super(sb); if (sop->put_super) sop->put_super(sb); diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c index da20b48d350..cd80316302c 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c @@ -72,6 +72,9 @@ static void sysv_put_super(struct super_block *sb) { struct sysv_sb_info *sbi = SYSV_SB(sb); + if (sb->s_dirt) + sysv_write_super(sb); + if (!(sb->s_flags & MS_RDONLY)) { /* XXX ext2 also updates the state here */ mark_buffer_dirty(sbi->s_bh1); diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 60359291761..74afb9fbf58 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -1152,6 +1152,9 @@ static void ufs_put_super(struct super_block *sb) UFSD("ENTER\n"); + if (sb->s_dirt) + ufs_write_super(sb); + if (!(sb->s_flags & MS_RDONLY)) ufs_put_super_internal(sb); -- cgit v1.2.3-70-g09d2 From 5af7926ff33b68b3ba46531471c6e0564b285efc Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 5 May 2009 15:41:25 +0200 Subject: enforce ->sync_fs is only called for rw superblock Make sure a superblock really is writeable by checking MS_RDONLY under s_umount. sync_filesystems needed some re-arragement for that, but all but one sync_filesystem caller had the correct locking already so that we could add that check there. cachefiles grew s_umount locking. I've also added a WARN_ON to sync_filesystem to assert this for future callers. Signed-off-by: Christoph Hellwig Signed-off-by: Al Viro --- fs/btrfs/super.c | 3 --- fs/cachefiles/interface.c | 2 ++ fs/reiserfs/super.c | 21 +++++++++------------ fs/sync.c | 23 ++++++++++++++++------- fs/ubifs/super.c | 3 --- 5 files changed, 27 insertions(+), 25 deletions(-) (limited to 'fs/reiserfs/super.c') diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 52d84522c2c..9f179d4832d 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -394,9 +394,6 @@ int btrfs_sync_fs(struct super_block *sb, int wait) struct btrfs_root *root = btrfs_sb(sb); int ret; - if (sb->s_flags & MS_RDONLY) - return 0; - if (!wait) { filemap_flush(root->fs_info->btree_inode->i_mapping); return 0; diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index dafd484d7bd..431accd475a 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -354,7 +354,9 @@ static void cachefiles_sync_cache(struct fscache_cache *_cache) /* make sure all pages pinned by operations on behalf of the netfs are * written to disc */ cachefiles_begin_secure(cache, &saved_cred); + down_read(&cache->mnt->mnt_sb->s_umount); ret = sync_filesystem(cache->mnt->mnt_sb); + up_read(&cache->mnt->mnt_sb->s_umount); cachefiles_end_secure(cache, saved_cred); if (ret == -EIO) diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 1b52daa351c..3da0401c0a9 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -64,18 +64,15 @@ static int reiserfs_statfs(struct dentry *dentry, struct kstatfs *buf); static int reiserfs_sync_fs(struct super_block *s, int wait) { - if (!(s->s_flags & MS_RDONLY)) { - struct reiserfs_transaction_handle th; - reiserfs_write_lock(s); - if (!journal_begin(&th, s, 1)) - if (!journal_end_sync(&th, s, 1)) - reiserfs_flush_old_commits(s); - s->s_dirt = 0; /* Even if it's not true. - * We'll loop forever in sync_supers otherwise */ - reiserfs_write_unlock(s); - } else { - s->s_dirt = 0; - } + struct reiserfs_transaction_handle th; + + reiserfs_write_lock(s); + if (!journal_begin(&th, s, 1)) + if (!journal_end_sync(&th, s, 1)) + reiserfs_flush_old_commits(s); + s->s_dirt = 0; /* Even if it's not true. + * We'll loop forever in sync_supers otherwise */ + reiserfs_write_unlock(s); return 0; } diff --git a/fs/sync.c b/fs/sync.c index 4487b5560dc..89c37f732af 100644 --- a/fs/sync.c +++ b/fs/sync.c @@ -51,6 +51,18 @@ int sync_filesystem(struct super_block *sb) { int ret; + /* + * We need to be protected against the filesystem going from + * r/o to r/w or vice versa. + */ + WARN_ON(!rwsem_is_locked(&sb->s_umount)); + + /* + * No point in syncing out anything if the filesystem is read-only. + */ + if (sb->s_flags & MS_RDONLY) + return 0; + ret = __sync_filesystem(sb, 0); if (ret < 0) return ret; @@ -79,25 +91,22 @@ static void sync_filesystems(int wait) mutex_lock(&mutex); /* Could be down_interruptible */ spin_lock(&sb_lock); - list_for_each_entry(sb, &super_blocks, s_list) { - if (sb->s_flags & MS_RDONLY) - continue; + list_for_each_entry(sb, &super_blocks, s_list) sb->s_need_sync = 1; - } restart: list_for_each_entry(sb, &super_blocks, s_list) { if (!sb->s_need_sync) continue; sb->s_need_sync = 0; - if (sb->s_flags & MS_RDONLY) - continue; /* hm. Was remounted r/o meanwhile */ sb->s_count++; spin_unlock(&sb_lock); + down_read(&sb->s_umount); - if (sb->s_root) + if (!(sb->s_flags & MS_RDONLY) && sb->s_root) __sync_filesystem(sb, wait); up_read(&sb->s_umount); + /* restart only when sb is no longer on the list */ spin_lock(&sb_lock); if (__put_super_and_need_restart(sb)) diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index e9f7a754c4f..84f3c7fd155 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -447,9 +447,6 @@ static int ubifs_sync_fs(struct super_block *sb, int wait) if (!wait) return 0; - if (sb->s_flags & MS_RDONLY) - return 0; - /* * VFS calls '->sync_fs()' before synchronizing all dirty inodes and * pages, so synchronize them first, then commit the journal. Strictly -- cgit v1.2.3-70-g09d2 From 6cfd0148425e528b859b26e436b01f23f6926224 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 5 May 2009 15:40:36 +0200 Subject: push BKL down into ->put_super Move BKL into ->put_super from the only caller. A couple of filesystems had trivial enough ->put_super (only kfree and NULLing of s_fs_info + stuff in there) to not get any locking: coda, cramfs, efs, hugetlbfs, omfs, qnx4, shmem, all others got the full treatment. Most of them probably don't need it, but I'd rather sort that out individually. Preferably after all the other BKL pushdowns in that area. [AV: original used to move lock_super() down as well; these changes are removed since we don't do lock_super() at all in generic_shutdown_super() now] [AV: fuse, btrfs and xfs are known to need no damn BKL, exempt] Signed-off-by: Christoph Hellwig Signed-off-by: Al Viro --- fs/adfs/super.c | 4 ++++ fs/affs/super.c | 5 ++++- fs/afs/super.c | 4 ++++ fs/befs/linuxvfs.c | 5 ++++- fs/bfs/inode.c | 4 ++++ fs/cifs/cifsfs.c | 6 +++++- fs/ecryptfs/super.c | 5 +++++ fs/exofs/super.c | 4 ++++ fs/ext2/super.c | 4 +++- fs/ext3/super.c | 5 ++++- fs/ext4/super.c | 2 +- fs/fat/inode.c | 4 ++++ fs/freevxfs/vxfs_super.c | 4 ++++ fs/gfs2/super.c | 4 ++++ fs/hfs/super.c | 4 ++++ fs/hfsplus/super.c | 5 +++++ fs/hpfs/super.c | 5 +++++ fs/isofs/inode.c | 5 +++++ fs/jffs2/super.c | 4 ++++ fs/jfs/super.c | 5 +++++ fs/minix/inode.c | 4 +++- fs/ncpfs/inode.c | 4 ++++ fs/nilfs2/super.c | 4 ++++ fs/ntfs/super.c | 6 +++++- fs/ocfs2/super.c | 4 ++++ fs/reiserfs/super.c | 4 +++- fs/smbfs/inode.c | 4 ++++ fs/squashfs/super.c | 4 ++++ fs/super.c | 3 --- fs/sysv/inode.c | 4 ++++ fs/ubifs/super.c | 5 +++++ fs/udf/super.c | 5 +++++ fs/ufs/super.c | 6 ++++++ 33 files changed, 133 insertions(+), 12 deletions(-) (limited to 'fs/reiserfs/super.c') diff --git a/fs/adfs/super.c b/fs/adfs/super.c index dd9becca424..0ec5aaf47aa 100644 --- a/fs/adfs/super.c +++ b/fs/adfs/super.c @@ -132,11 +132,15 @@ static void adfs_put_super(struct super_block *sb) int i; struct adfs_sb_info *asb = ADFS_SB(sb); + lock_kernel(); + for (i = 0; i < asb->s_map_size; i++) brelse(asb->s_map[i].dm_bh); kfree(asb->s_map); kfree(asb); sb->s_fs_info = NULL; + + unlock_kernel(); } static int adfs_show_options(struct seq_file *seq, struct vfsmount *mnt) diff --git a/fs/affs/super.c b/fs/affs/super.c index 63f5183f263..d7386462a8e 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c @@ -29,6 +29,8 @@ affs_put_super(struct super_block *sb) struct affs_sb_info *sbi = AFFS_SB(sb); pr_debug("AFFS: put_super()\n"); + lock_kernel(); + if (!(sb->s_flags & MS_RDONLY)) { AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->bm_flag = cpu_to_be32(1); secs_to_datestamp(get_seconds(), @@ -42,7 +44,8 @@ affs_put_super(struct super_block *sb) affs_brelse(sbi->s_root_bh); kfree(sbi); sb->s_fs_info = NULL; - return; + + unlock_kernel(); } static void diff --git a/fs/afs/super.c b/fs/afs/super.c index 76828e5f8a3..ad0514d0115 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c @@ -440,8 +440,12 @@ static void afs_put_super(struct super_block *sb) _enter(""); + lock_kernel(); + afs_put_volume(as->volume); + unlock_kernel(); + _leave(""); } diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index 76afd0d6b86..9367b6297d8 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c @@ -737,6 +737,8 @@ parse_options(char *options, befs_mount_options * opts) static void befs_put_super(struct super_block *sb) { + lock_kernel(); + kfree(BEFS_SB(sb)->mount_opts.iocharset); BEFS_SB(sb)->mount_opts.iocharset = NULL; @@ -747,7 +749,8 @@ befs_put_super(struct super_block *sb) kfree(sb->s_fs_info); sb->s_fs_info = NULL; - return; + + unlock_kernel(); } /* Allocate private field of the superblock, fill it. diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index 4cf3d269e27..3a9a1361fdc 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c @@ -217,6 +217,8 @@ static void bfs_put_super(struct super_block *s) if (!info) return; + lock_kernel(); + if (s->s_dirt) bfs_write_super(s); @@ -225,6 +227,8 @@ static void bfs_put_super(struct super_block *s) kfree(info->si_imap); kfree(info); s->s_fs_info = NULL; + + unlock_kernel(); } static int bfs_statfs(struct dentry *dentry, struct kstatfs *buf) diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 0a10a59b639..0d92114195a 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -204,6 +204,9 @@ cifs_put_super(struct super_block *sb) cFYI(1, ("Empty cifs superblock info passed to unmount")); return; } + + lock_kernel(); + rc = cifs_umount(sb, cifs_sb); if (rc) cERROR(1, ("cifs_umount failed with return code %d", rc)); @@ -216,7 +219,8 @@ cifs_put_super(struct super_block *sb) unload_nls(cifs_sb->local_nls); kfree(cifs_sb); - return; + + unlock_kernel(); } static int diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c index fa4c7e7d15d..12d649602d3 100644 --- a/fs/ecryptfs/super.c +++ b/fs/ecryptfs/super.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include "ecryptfs_kernel.h" @@ -120,9 +121,13 @@ static void ecryptfs_put_super(struct super_block *sb) { struct ecryptfs_sb_info *sb_info = ecryptfs_superblock_to_private(sb); + lock_kernel(); + ecryptfs_destroy_mount_crypt_stat(&sb_info->mount_crypt_stat); kmem_cache_free(ecryptfs_sb_info_cache, sb_info); ecryptfs_set_superblock_private(sb, NULL); + + unlock_kernel(); } /** diff --git a/fs/exofs/super.c b/fs/exofs/super.c index 3cdb761db8a..cd1f8b18a21 100644 --- a/fs/exofs/super.c +++ b/fs/exofs/super.c @@ -258,6 +258,8 @@ static void exofs_put_super(struct super_block *sb) int num_pend; struct exofs_sb_info *sbi = sb->s_fs_info; + lock_kernel(); + if (sb->s_dirt) exofs_write_super(sb); @@ -274,6 +276,8 @@ static void exofs_put_super(struct super_block *sb) osduld_put_device(sbi->s_dev); kfree(sb->s_fs_info); sb->s_fs_info = NULL; + + unlock_kernel(); } /* diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 932a2bcb690..a44963d8edb 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -114,6 +114,8 @@ static void ext2_put_super (struct super_block * sb) int i; struct ext2_sb_info *sbi = EXT2_SB(sb); + lock_kernel(); + if (sb->s_dirt) ext2_write_super(sb); @@ -138,7 +140,7 @@ static void ext2_put_super (struct super_block * sb) kfree(sbi->s_blockgroup_lock); kfree(sbi); - return; + unlock_kernel(); } static struct kmem_cache * ext2_inode_cachep; diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 1efd958687e..546b8d732bf 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -398,6 +398,8 @@ static void ext3_put_super (struct super_block * sb) struct ext3_super_block *es = sbi->s_es; int i, err; + lock_kernel(); + ext3_xattr_put_super(sb); err = journal_destroy(sbi->s_journal); sbi->s_journal = NULL; @@ -446,7 +448,8 @@ static void ext3_put_super (struct super_block * sb) sb->s_fs_info = NULL; kfree(sbi->s_blockgroup_lock); kfree(sbi); - return; + + unlock_kernel(); } static struct kmem_cache *ext3_inode_cachep; diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 0d3034c5e8a..1d4180b8677 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -577,6 +577,7 @@ static void ext4_put_super(struct super_block *sb) int i, err; lock_super(sb); + lock_kernel(); if (sb->s_dirt) ext4_write_super(sb); @@ -646,7 +647,6 @@ static void ext4_put_super(struct super_block *sb) unlock_super(sb); kobject_put(&sbi->s_kobj); wait_for_completion(&sbi->s_kobj_unregister); - lock_kernel(); kfree(sbi->s_blockgroup_lock); kfree(sbi); } diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 4978621511b..2b88c93af22 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -451,6 +451,8 @@ static void fat_put_super(struct super_block *sb) { struct msdos_sb_info *sbi = MSDOS_SB(sb); + lock_kernel(); + if (sb->s_dirt) fat_write_super(sb); @@ -470,6 +472,8 @@ static void fat_put_super(struct super_block *sb) sb->s_fs_info = NULL; kfree(sbi); + + unlock_kernel(); } static struct kmem_cache *fat_inode_cachep; diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c index 1dacda83157..cdbd1654e4c 100644 --- a/fs/freevxfs/vxfs_super.c +++ b/fs/freevxfs/vxfs_super.c @@ -80,12 +80,16 @@ vxfs_put_super(struct super_block *sbp) { struct vxfs_sb_info *infp = VXFS_SBI(sbp); + lock_kernel(); + vxfs_put_fake_inode(infp->vsi_fship); vxfs_put_fake_inode(infp->vsi_ilist); vxfs_put_fake_inode(infp->vsi_stilist); brelse(infp->vsi_bp); kfree(infp); + + unlock_kernel(); } /** diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 0a680133647..c8930b31cdf 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -719,6 +719,8 @@ static void gfs2_put_super(struct super_block *sb) int error; struct gfs2_jdesc *jd; + lock_kernel(); + /* Unfreeze the filesystem, if we need to */ mutex_lock(&sdp->sd_freeze_lock); @@ -785,6 +787,8 @@ restart: /* At this point, we're through participating in the lockspace */ gfs2_sys_fs_del(sdp); + + unlock_kernel(); } /** diff --git a/fs/hfs/super.c b/fs/hfs/super.c index e071e6d0646..9f5eaa01cc7 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c @@ -65,11 +65,15 @@ static void hfs_write_super(struct super_block *sb) */ static void hfs_put_super(struct super_block *sb) { + lock_kernel(); + if (sb->s_dirt) hfs_write_super(sb); hfs_mdb_close(sb); /* release the MDB's resources */ hfs_mdb_put(sb); + + unlock_kernel(); } /* diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 40bdab79dae..9b292dcc39c 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c @@ -199,6 +199,9 @@ static void hfsplus_put_super(struct super_block *sb) dprint(DBG_SUPER, "hfsplus_put_super\n"); if (!sb->s_fs_info) return; + + lock_kernel(); + if (sb->s_dirt) hfsplus_write_super(sb); if (!(sb->s_flags & MS_RDONLY) && HFSPLUS_SB(sb).s_vhdr) { @@ -220,6 +223,8 @@ static void hfsplus_put_super(struct super_block *sb) unload_nls(HFSPLUS_SB(sb).nls); kfree(sb->s_fs_info); sb->s_fs_info = NULL; + + unlock_kernel(); } static int hfsplus_statfs(struct dentry *dentry, struct kstatfs *buf) diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c index fc77965be84..437a32e9dea 100644 --- a/fs/hpfs/super.c +++ b/fs/hpfs/super.c @@ -99,11 +99,16 @@ int hpfs_stop_cycles(struct super_block *s, int key, int *c1, int *c2, static void hpfs_put_super(struct super_block *s) { struct hpfs_sb_info *sbi = hpfs_sb(s); + + lock_kernel(); + kfree(sbi->sb_cp_table); kfree(sbi->sb_bmp_dir); unmark_dirty(s); s->s_fs_info = NULL; kfree(sbi); + + unlock_kernel(); } unsigned hpfs_count_one_bitmap(struct super_block *s, secno secno) diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index b4cbe9603c7..068b34b5a10 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -42,11 +42,16 @@ static int isofs_dentry_cmp_ms(struct dentry *dentry, struct qstr *a, struct qst static void isofs_put_super(struct super_block *sb) { struct isofs_sb_info *sbi = ISOFS_SB(sb); + #ifdef CONFIG_JOLIET + lock_kernel(); + if (sbi->s_nls_iocharset) { unload_nls(sbi->s_nls_iocharset); sbi->s_nls_iocharset = NULL; } + + unlock_kernel(); #endif kfree(sbi); diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index 5059e9633ed..37b12125c12 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c @@ -174,6 +174,8 @@ static void jffs2_put_super (struct super_block *sb) D2(printk(KERN_DEBUG "jffs2: jffs2_put_super()\n")); + lock_kernel(); + if (sb->s_dirt) jffs2_write_super(sb); @@ -195,6 +197,8 @@ static void jffs2_put_super (struct super_block *sb) if (c->mtd->sync) c->mtd->sync(c->mtd); + unlock_kernel(); + D1(printk(KERN_DEBUG "jffs2_put_super returning\n")); } diff --git a/fs/jfs/super.c b/fs/jfs/super.c index d9b0e92b360..3eb13adf386 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -183,6 +183,9 @@ static void jfs_put_super(struct super_block *sb) int rc; jfs_info("In jfs_put_super"); + + lock_kernel(); + rc = jfs_umount(sb); if (rc) jfs_err("jfs_umount failed with return code %d", rc); @@ -195,6 +198,8 @@ static void jfs_put_super(struct super_block *sb) sbi->direct_inode = NULL; kfree(sbi); + + unlock_kernel(); } enum { diff --git a/fs/minix/inode.c b/fs/minix/inode.c index daad3c2740d..7eb53970f4b 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -35,6 +35,8 @@ static void minix_put_super(struct super_block *sb) int i; struct minix_sb_info *sbi = minix_sb(sb); + lock_kernel(); + if (!(sb->s_flags & MS_RDONLY)) { if (sbi->s_version != MINIX_V3) /* s_state is now out from V3 sb */ sbi->s_ms->s_state = sbi->s_mount_state; @@ -49,7 +51,7 @@ static void minix_put_super(struct super_block *sb) sb->s_fs_info = NULL; kfree(sbi); - return; + unlock_kernel(); } static struct kmem_cache * minix_inode_cachep; diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index d642f0e5b36..b99ce205b1b 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c @@ -736,6 +736,8 @@ static void ncp_put_super(struct super_block *sb) { struct ncp_server *server = NCP_SBP(sb); + lock_kernel(); + ncp_lock_server(server); ncp_disconnect(server); ncp_unlock_server(server); @@ -769,6 +771,8 @@ static void ncp_put_super(struct super_block *sb) vfree(server->packet); sb->s_fs_info = NULL; kfree(server); + + unlock_kernel(); } static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf) diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 7901d8cbb9b..7262e8427c2 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c @@ -316,6 +316,8 @@ static void nilfs_put_super(struct super_block *sb) struct nilfs_sb_info *sbi = NILFS_SB(sb); struct the_nilfs *nilfs = sbi->s_nilfs; + lock_kernel(); + if (sb->s_dirt) nilfs_write_super(sb); @@ -333,6 +335,8 @@ static void nilfs_put_super(struct super_block *sb) sbi->s_super = NULL; sb->s_fs_info = NULL; kfree(sbi); + + unlock_kernel(); } /** diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 6aa7c471353..a9ec4e1084e 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c @@ -2246,6 +2246,9 @@ static void ntfs_put_super(struct super_block *sb) ntfs_volume *vol = NTFS_SB(sb); ntfs_debug("Entering."); + + lock_kernel(); + #ifdef NTFS_RW /* * Commit all inodes while they are still open in case some of them @@ -2444,7 +2447,8 @@ static void ntfs_put_super(struct super_block *sb) } sb->s_fs_info = NULL; kfree(vol); - return; + + unlock_kernel(); } /** diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 3eb076ce4c0..02737596b59 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -1536,9 +1536,13 @@ static void ocfs2_put_super(struct super_block *sb) { mlog_entry("(0x%p)\n", sb); + lock_kernel(); + ocfs2_sync_blockdev(sb); ocfs2_dismount_volume(sb, 0); + unlock_kernel(); + mlog_exit_void(); } diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 3da0401c0a9..90dcb7b033e 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -465,6 +465,8 @@ static void reiserfs_put_super(struct super_block *s) struct reiserfs_transaction_handle th; th.t_trans_id = 0; + lock_kernel(); + if (s->s_dirt) reiserfs_write_super(s); @@ -500,7 +502,7 @@ static void reiserfs_put_super(struct super_block *s) kfree(s->s_fs_info); s->s_fs_info = NULL; - return; + unlock_kernel(); } static struct kmem_cache *reiserfs_inode_cachep; diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c index fc27fbfc539..1402d2d54f5 100644 --- a/fs/smbfs/inode.c +++ b/fs/smbfs/inode.c @@ -474,6 +474,8 @@ smb_put_super(struct super_block *sb) { struct smb_sb_info *server = SMB_SB(sb); + lock_kernel(); + smb_lock_server(server); server->state = CONN_INVALID; smbiod_unregister_server(server); @@ -489,6 +491,8 @@ smb_put_super(struct super_block *sb) smb_unlock_server(server); put_pid(server->conn_pid); kfree(server); + + unlock_kernel(); } static int smb_fill_super(struct super_block *sb, void *raw_data, int silent) diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c index 0adc624c956..3b52770f46f 100644 --- a/fs/squashfs/super.c +++ b/fs/squashfs/super.c @@ -338,6 +338,8 @@ static int squashfs_remount(struct super_block *sb, int *flags, char *data) static void squashfs_put_super(struct super_block *sb) { + lock_kernel(); + if (sb->s_fs_info) { struct squashfs_sb_info *sbi = sb->s_fs_info; squashfs_cache_delete(sbi->block_cache); @@ -350,6 +352,8 @@ static void squashfs_put_super(struct super_block *sb) kfree(sb->s_fs_info); sb->s_fs_info = NULL; } + + unlock_kernel(); } diff --git a/fs/super.c b/fs/super.c index 54fd331f0ca..bdd7158b785 100644 --- a/fs/super.c +++ b/fs/super.c @@ -309,7 +309,6 @@ void generic_shutdown_super(struct super_block *sb) /* bad name - it should be evict_inodes() */ invalidate_inodes(sb); - lock_kernel(); if (sop->put_super) sop->put_super(sb); @@ -320,8 +319,6 @@ void generic_shutdown_super(struct super_block *sb) "Self-destruct in 5 seconds. Have a nice day...\n", sb->s_id); } - - unlock_kernel(); put_fs_excl(); } spin_lock(&sb_lock); diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c index cd80316302c..a8189864c24 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c @@ -72,6 +72,8 @@ static void sysv_put_super(struct super_block *sb) { struct sysv_sb_info *sbi = SYSV_SB(sb); + lock_kernel(); + if (sb->s_dirt) sysv_write_super(sb); @@ -87,6 +89,8 @@ static void sysv_put_super(struct super_block *sb) brelse(sbi->s_bh2); kfree(sbi); + + unlock_kernel(); } static int sysv_statfs(struct dentry *dentry, struct kstatfs *buf) diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 84f3c7fd155..522c3fd7eb3 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -1684,6 +1684,9 @@ static void ubifs_put_super(struct super_block *sb) ubifs_msg("un-mount UBI device %d, volume %d", c->vi.ubi_num, c->vi.vol_id); + + lock_kernel(); + /* * The following asserts are only valid if there has not been a failure * of the media. For example, there will be dirty inodes if we failed @@ -1750,6 +1753,8 @@ static void ubifs_put_super(struct super_block *sb) ubi_close_volume(c->ubi); mutex_unlock(&c->umount_mutex); kfree(c); + + unlock_kernel(); } static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data) diff --git a/fs/udf/super.c b/fs/udf/super.c index 0ba44107d8f..04802cc39b1 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -2062,6 +2062,9 @@ static void udf_put_super(struct super_block *sb) struct udf_sb_info *sbi; sbi = UDF_SB(sb); + + lock_kernel(); + if (sbi->s_vat_inode) iput(sbi->s_vat_inode); if (sbi->s_partitions) @@ -2077,6 +2080,8 @@ static void udf_put_super(struct super_block *sb) kfree(sbi->s_partmaps); kfree(sb->s_fs_info); sb->s_fs_info = NULL; + + unlock_kernel(); } static int udf_sync_fs(struct super_block *sb, int wait) diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 74afb9fbf58..2b4d2b6234d 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -594,6 +594,9 @@ static void ufs_put_super_internal(struct super_block *sb) UFSD("ENTER\n"); + + lock_kernel(); + ufs_put_cstotal(sb); size = uspi->s_cssize; blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift; @@ -621,6 +624,9 @@ static void ufs_put_super_internal(struct super_block *sb) brelse (sbi->s_ucg[i]); kfree (sbi->s_ucg); kfree (base); + + unlock_kernel(); + UFSD("EXIT\n"); } -- cgit v1.2.3-70-g09d2 From 337eb00a2c3a421999c39c94ce7e33545ee8baa7 Mon Sep 17 00:00:00 2001 From: Alessio Igor Bogani Date: Tue, 12 May 2009 15:10:54 +0200 Subject: Push BKL down into ->remount_fs() [xfs, btrfs, capifs, shmem don't need BKL, exempt] Signed-off-by: Alessio Igor Bogani Signed-off-by: Al Viro --- drivers/usb/core/inode.c | 5 +++++ fs/affs/super.c | 7 ++++++- fs/ext2/super.c | 12 ++++++++++-- fs/ext3/super.c | 4 ++++ fs/ext4/super.c | 4 ++++ fs/hpfs/super.c | 4 ++++ fs/jffs2/fs.c | 3 +++ fs/jfs/super.c | 22 ++++++++++++++++++---- fs/nfs/super.c | 2 ++ fs/nilfs2/super.c | 4 ++++ fs/ntfs/super.c | 15 ++++++++++++++- fs/ocfs2/super.c | 4 ++++ fs/reiserfs/super.c | 4 ++++ fs/super.c | 2 -- fs/ubifs/super.c | 9 ++++++++- fs/udf/super.c | 6 +++++- fs/ufs/super.c | 11 ++++++++++- kernel/cgroup.c | 3 +++ 18 files changed, 108 insertions(+), 13 deletions(-) (limited to 'fs/reiserfs/super.c') diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c index dff5760a37f..ffe75e83787 100644 --- a/drivers/usb/core/inode.c +++ b/drivers/usb/core/inode.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include "usb.h" #include "hcd.h" @@ -265,9 +266,13 @@ static int remount(struct super_block *sb, int *flags, char *data) return -EINVAL; } + lock_kernel(); + if (usbfs_mount && usbfs_mount->mnt_sb) update_sb(usbfs_mount->mnt_sb); + unlock_kernel(); + return 0; } diff --git a/fs/affs/super.c b/fs/affs/super.c index 280d361af41..c4814937c96 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "affs.h" extern struct timezone sys_tz; @@ -512,6 +513,7 @@ affs_remount(struct super_block *sb, int *flags, char *data) kfree(new_opts); return -EINVAL; } + lock_kernel(); replace_mount_options(sb, new_opts); sbi->s_flags = mount_flags; @@ -519,8 +521,10 @@ affs_remount(struct super_block *sb, int *flags, char *data) sbi->s_uid = uid; sbi->s_gid = gid; - if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) + if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) { + unlock_kernel(); return 0; + } if (*flags & MS_RDONLY) { sb->s_dirt = 1; while (sb->s_dirt) @@ -529,6 +533,7 @@ affs_remount(struct super_block *sb, int *flags, char *data) } else res = affs_init_bitmap(sb, flags); + unlock_kernel(); return res; } diff --git a/fs/ext2/super.c b/fs/ext2/super.c index a44963d8edb..f8cbdf56919 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -1162,6 +1162,8 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data) unsigned long old_sb_flags; int err; + lock_kernel(); + /* Store the old options */ old_sb_flags = sb->s_flags; old_opts.s_mount_opt = sbi->s_mount_opt; @@ -1197,12 +1199,16 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data) sbi->s_mount_opt &= ~EXT2_MOUNT_XIP; sbi->s_mount_opt |= old_mount_opt & EXT2_MOUNT_XIP; } - if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) + if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) { + unlock_kernel(); return 0; + } if (*flags & MS_RDONLY) { if (le16_to_cpu(es->s_state) & EXT2_VALID_FS || - !(sbi->s_mount_state & EXT2_VALID_FS)) + !(sbi->s_mount_state & EXT2_VALID_FS)) { + unlock_kernel(); return 0; + } /* * OK, we are remounting a valid rw partition rdonly, so set * the rdonly flag and then mark the partition as valid again. @@ -1229,12 +1235,14 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data) sb->s_flags &= ~MS_RDONLY; } ext2_sync_super(sb, es); + unlock_kernel(); return 0; restore_opts: sbi->s_mount_opt = old_opts.s_mount_opt; sbi->s_resuid = old_opts.s_resuid; sbi->s_resgid = old_opts.s_resgid; sb->s_flags = old_sb_flags; + unlock_kernel(); return err; } diff --git a/fs/ext3/super.c b/fs/ext3/super.c index e213a2613a5..26aa64dee6a 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -2490,6 +2490,8 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data) int i; #endif + lock_kernel(); + /* Store the original options */ lock_super(sb); old_sb_flags = sb->s_flags; @@ -2600,6 +2602,7 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data) kfree(old_opts.s_qf_names[i]); #endif unlock_super(sb); + unlock_kernel(); return 0; restore_opts: sb->s_flags = old_sb_flags; @@ -2617,6 +2620,7 @@ restore_opts: } #endif unlock_super(sb); + unlock_kernel(); return err; } diff --git a/fs/ext4/super.c b/fs/ext4/super.c index c17200a4230..012c4251397 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -3422,6 +3422,8 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) int i; #endif + lock_kernel(); + /* Store the original options */ lock_super(sb); old_sb_flags = sb->s_flags; @@ -3558,6 +3560,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) kfree(old_opts.s_qf_names[i]); #endif unlock_super(sb); + unlock_kernel(); return 0; restore_opts: @@ -3578,6 +3581,7 @@ restore_opts: } #endif unlock_super(sb); + unlock_kernel(); return err; } diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c index f68193cf081..f2feaa06bf2 100644 --- a/fs/hpfs/super.c +++ b/fs/hpfs/super.c @@ -13,6 +13,7 @@ #include #include #include +#include /* Mark the filesystem dirty, so that chkdsk checks it when os/2 booted */ @@ -398,6 +399,7 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data) *flags |= MS_NOATIME; + lock_kernel(); lock_super(s); uid = sbi->sb_uid; gid = sbi->sb_gid; umask = 0777 & ~sbi->sb_mode; @@ -432,10 +434,12 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data) replace_mount_options(s, new_opts); unlock_super(s); + unlock_kernel(); return 0; out_err: unlock_super(s); + unlock_kernel(); kfree(new_opts); return -EINVAL; } diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index 237b27a3d57..3451a81b214 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "nodelist.h" static int jffs2_flash_setup(struct jffs2_sb_info *c); @@ -387,6 +388,7 @@ int jffs2_remount_fs (struct super_block *sb, int *flags, char *data) This also catches the case where it was stopped and this is just a remount to restart it. Flush the writebuffer, if neccecary, else we loose it */ + lock_kernel(); if (!(sb->s_flags & MS_RDONLY)) { jffs2_stop_garbage_collect_thread(c); mutex_lock(&c->alloc_sem); @@ -399,6 +401,7 @@ int jffs2_remount_fs (struct super_block *sb, int *flags, char *data) *flags |= MS_NOATIME; + unlock_kernel(); return 0; } diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 3eb13adf386..09b1b6ee218 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "jfs_incore.h" #include "jfs_filsys.h" @@ -375,19 +376,24 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data) s64 newLVSize = 0; int rc = 0; int flag = JFS_SBI(sb)->flag; + int ret; if (!parse_options(data, sb, &newLVSize, &flag)) { return -EINVAL; } + lock_kernel(); if (newLVSize) { if (sb->s_flags & MS_RDONLY) { printk(KERN_ERR "JFS: resize requires volume to be mounted read-write\n"); + unlock_kernel(); return -EROFS; } rc = jfs_extendfs(sb, newLVSize, 0); - if (rc) + if (rc) { + unlock_kernel(); return rc; + } } if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) { @@ -398,23 +404,31 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data) truncate_inode_pages(JFS_SBI(sb)->direct_inode->i_mapping, 0); JFS_SBI(sb)->flag = flag; - return jfs_mount_rw(sb, 1); + ret = jfs_mount_rw(sb, 1); + unlock_kernel(); + return ret; } if ((!(sb->s_flags & MS_RDONLY)) && (*flags & MS_RDONLY)) { rc = jfs_umount_rw(sb); JFS_SBI(sb)->flag = flag; + unlock_kernel(); return rc; } if ((JFS_SBI(sb)->flag & JFS_NOINTEGRITY) != (flag & JFS_NOINTEGRITY)) if (!(sb->s_flags & MS_RDONLY)) { rc = jfs_umount_rw(sb); - if (rc) + if (rc) { + unlock_kernel(); return rc; + } JFS_SBI(sb)->flag = flag; - return jfs_mount_rw(sb, 1); + ret = jfs_mount_rw(sb, 1); + unlock_kernel(); + return ret; } JFS_SBI(sb)->flag = flag; + unlock_kernel(); return 0; } diff --git a/fs/nfs/super.c b/fs/nfs/super.c index d2d67781c57..26127b69a27 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1813,6 +1813,7 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data) if (data == NULL) return -ENOMEM; + lock_kernel(); /* fill out struct with values from existing mount */ data->flags = nfss->flags; data->rsize = nfss->rsize; @@ -1837,6 +1838,7 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data) error = nfs_compare_remount_data(nfss, data); out: kfree(data); + unlock_kernel(); return error; } diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 7262e8427c2..11151eaa2c4 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c @@ -906,6 +906,8 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) struct nilfs_mount_options old_opts; int err; + lock_kernel(); + old_sb_flags = sb->s_flags; old_opts.mount_opt = sbi->s_mount_opt; old_opts.snapshot_cno = sbi->s_snapshot_cno; @@ -985,6 +987,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) up(&sb->s_bdev->bd_mount_sem); } out: + unlock_kernel(); return 0; rw_remount_failed: @@ -993,6 +996,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) sb->s_flags = old_sb_flags; sbi->s_mount_opt = old_opts.mount_opt; sbi->s_snapshot_cno = old_opts.snapshot_cno; + unlock_kernel(); return err; } diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 7a7b0d32639..abaaa1cbf8d 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c @@ -443,6 +443,8 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt) ntfs_volume *vol = NTFS_SB(sb); ntfs_debug("Entering with remount options string: %s", opt); + + lock_kernel(); #ifndef NTFS_RW /* For read-only compiled driver, enforce read-only flag. */ *flags |= MS_RDONLY; @@ -466,15 +468,18 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt) if (NVolErrors(vol)) { ntfs_error(sb, "Volume has errors and is read-only%s", es); + unlock_kernel(); return -EROFS; } if (vol->vol_flags & VOLUME_IS_DIRTY) { ntfs_error(sb, "Volume is dirty and read-only%s", es); + unlock_kernel(); return -EROFS; } if (vol->vol_flags & VOLUME_MODIFIED_BY_CHKDSK) { ntfs_error(sb, "Volume has been modified by chkdsk " "and is read-only%s", es); + unlock_kernel(); return -EROFS; } if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) { @@ -482,11 +487,13 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt) "(0x%x) and is read-only%s", (unsigned)le16_to_cpu(vol->vol_flags), es); + unlock_kernel(); return -EROFS; } if (ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY)) { ntfs_error(sb, "Failed to set dirty bit in volume " "information flags%s", es); + unlock_kernel(); return -EROFS; } #if 0 @@ -506,18 +513,21 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt) ntfs_error(sb, "Failed to empty journal $LogFile%s", es); NVolSetErrors(vol); + unlock_kernel(); return -EROFS; } if (!ntfs_mark_quotas_out_of_date(vol)) { ntfs_error(sb, "Failed to mark quotas out of date%s", es); NVolSetErrors(vol); + unlock_kernel(); return -EROFS; } if (!ntfs_stamp_usnjrnl(vol)) { ntfs_error(sb, "Failed to stamp transation log " "($UsnJrnl)%s", es); NVolSetErrors(vol); + unlock_kernel(); return -EROFS; } } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) { @@ -533,8 +543,11 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt) // TODO: Deal with *flags. - if (!parse_options(vol, opt)) + if (!parse_options(vol, opt)) { + unlock_kernel(); return -EINVAL; + } + unlock_kernel(); ntfs_debug("Done."); return 0; } diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 02737596b59..201b40a441f 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -42,6 +42,7 @@ #include #include #include +#include #define MLOG_MASK_PREFIX ML_SUPER #include @@ -581,6 +582,8 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data) struct mount_options parsed_options; struct ocfs2_super *osb = OCFS2_SB(sb); + lock_kernel(); + if (!ocfs2_parse_options(sb, data, &parsed_options, 1)) { ret = -EINVAL; goto out; @@ -684,6 +687,7 @@ unlock_osb: ocfs2_set_journal_params(osb); } out: + unlock_kernel(); return ret; } diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 90dcb7b033e..2969773cfc2 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -28,6 +28,7 @@ #include #include #include +#include struct file_system_type reiserfs_fs_type; @@ -1196,6 +1197,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) memcpy(qf_names, REISERFS_SB(s)->s_qf_names, sizeof(qf_names)); #endif + lock_kernel(); rs = SB_DISK_SUPER_BLOCK(s); if (!reiserfs_parse_options @@ -1318,10 +1320,12 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) out_ok: replace_mount_options(s, new_opts); + unlock_kernel(); return 0; out_err: kfree(new_opts); + unlock_kernel(); return err; } diff --git a/fs/super.c b/fs/super.c index 1905f4af01c..83b47416d00 100644 --- a/fs/super.c +++ b/fs/super.c @@ -540,7 +540,6 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) shrink_dcache_sb(sb); sync_filesystem(sb); - lock_kernel(); /* If we are remounting RDONLY and current sb is read/write, make sure there are no rw files opened */ if ((flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY)) { @@ -566,7 +565,6 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) } } sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK); - unlock_kernel(); if (remount_rw) vfs_dq_quota_on_remount(sb); return 0; diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 522c3fd7eb3..3589eab02a2 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "ubifs.h" /* @@ -1770,17 +1771,22 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data) return err; } + lock_kernel(); if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) { if (c->ro_media) { ubifs_msg("cannot re-mount due to prior errors"); + unlock_kernel(); return -EROFS; } err = ubifs_remount_rw(c); - if (err) + if (err) { + unlock_kernel(); return err; + } } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) { if (c->ro_media) { ubifs_msg("cannot re-mount due to prior errors"); + unlock_kernel(); return -EROFS; } ubifs_remount_ro(c); @@ -1795,6 +1801,7 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data) } ubifs_assert(c->lst.taken_empty_lebs > 0); + unlock_kernel(); return 0; } diff --git a/fs/udf/super.c b/fs/udf/super.c index 04802cc39b1..6832135159b 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -568,6 +568,7 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options) if (!udf_parse_options(options, &uopt, true)) return -EINVAL; + lock_kernel(); sbi->s_flags = uopt.flags; sbi->s_uid = uopt.uid; sbi->s_gid = uopt.gid; @@ -581,13 +582,16 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options) *flags |= MS_RDONLY; } - if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) + if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) { + unlock_kernel(); return 0; + } if (*flags & MS_RDONLY) udf_close_lvid(sb); else udf_open_lvid(sb); + unlock_kernel(); return 0; } diff --git a/fs/ufs/super.c b/fs/ufs/super.c index c97210ee067..6560dda7b18 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -263,6 +263,7 @@ void ufs_panic (struct super_block * sb, const char * function, struct ufs_super_block_first * usb1; va_list args; + lock_kernel(); uspi = UFS_SB(sb)->s_uspi; usb1 = ubh_get_usb_first(uspi); @@ -1182,7 +1183,8 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) struct ufs_super_block_third * usb3; unsigned new_mount_opt, ufstype; unsigned flags; - + + lock_kernel(); lock_super(sb); uspi = UFS_SB(sb)->s_uspi; flags = UFS_SB(sb)->s_flags; @@ -1198,6 +1200,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) ufs_set_opt (new_mount_opt, ONERROR_LOCK); if (!ufs_parse_options (data, &new_mount_opt)) { unlock_super(sb); + unlock_kernel(); return -EINVAL; } if (!(new_mount_opt & UFS_MOUNT_UFSTYPE)) { @@ -1205,12 +1208,14 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) } else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) { printk("ufstype can't be changed during remount\n"); unlock_super(sb); + unlock_kernel(); return -EINVAL; } if ((*mount_flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) { UFS_SB(sb)->s_mount_opt = new_mount_opt; unlock_super(sb); + unlock_kernel(); return 0; } @@ -1236,6 +1241,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) printk("ufs was compiled with read-only support, " "can't be mounted as read-write\n"); unlock_super(sb); + unlock_kernel(); return -EINVAL; #else if (ufstype != UFS_MOUNT_UFSTYPE_SUN && @@ -1245,11 +1251,13 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) ufstype != UFS_MOUNT_UFSTYPE_UFS2) { printk("this ufstype is read-only supported\n"); unlock_super(sb); + unlock_kernel(); return -EINVAL; } if (!ufs_read_cylinder_structures(sb)) { printk("failed during remounting\n"); unlock_super(sb); + unlock_kernel(); return -EPERM; } sb->s_flags &= ~MS_RDONLY; @@ -1257,6 +1265,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) } UFS_SB(sb)->s_mount_opt = new_mount_opt; unlock_super(sb); + unlock_kernel(); return 0; } diff --git a/kernel/cgroup.c b/kernel/cgroup.c index a7267bfd376..3fb789f6df9 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -46,6 +46,7 @@ #include #include #include +#include #include @@ -900,6 +901,7 @@ static int cgroup_remount(struct super_block *sb, int *flags, char *data) struct cgroup *cgrp = &root->top_cgroup; struct cgroup_sb_opts opts; + lock_kernel(); mutex_lock(&cgrp->dentry->d_inode->i_mutex); mutex_lock(&cgroup_mutex); @@ -927,6 +929,7 @@ static int cgroup_remount(struct super_block *sb, int *flags, char *data) kfree(opts.release_agent); mutex_unlock(&cgroup_mutex); mutex_unlock(&cgrp->dentry->d_inode->i_mutex); + unlock_kernel(); return ret; } -- cgit v1.2.3-70-g09d2