Currently do_remount_sb calls into the dquot code to tell it about going from rw to ro and ro to rw. Move this code into the filesystem to not depend on the dquot code in the VFS - note ocfs2 already ignores these calls and handles remount by itself. This gets rif of overloading the quotactl calls and allows to unify the VFS and XFS codepathes in that area later. Signed-off-by: Christoph Hellwig <hch@xxxxxx> Index: linux-2.6/fs/ext2/super.c =================================================================== --- linux-2.6.orig/fs/ext2/super.c 2010-05-19 10:47:34.563253960 +0200 +++ linux-2.6/fs/ext2/super.c 2010-05-19 12:53:30.546008046 +0200 @@ -1241,6 +1241,7 @@ static int ext2_remount (struct super_bl spin_unlock(&sbi->s_lock); return 0; } + /* * OK, we are remounting a valid rw partition rdonly, so set * the rdonly flag and then mark the partition as valid again. @@ -1248,6 +1249,14 @@ static int ext2_remount (struct super_bl es->s_state = cpu_to_le16(sbi->s_mount_state); es->s_mtime = cpu_to_le32(get_seconds()); spin_unlock(&sbi->s_lock); + + err = vfs_dq_off(sb, 1); + if (err < 0 && err != -ENOSYS) { + err = -EBUSY; + spin_lock(&sbi->s_lock); + goto restore_opts; + } + ext2_sync_super(sb, es, 1); } else { __le32 ret = EXT2_HAS_RO_COMPAT_FEATURE(sb, @@ -1269,8 +1278,12 @@ static int ext2_remount (struct super_bl if (!ext2_setup_super (sb, es, 0)) sb->s_flags &= ~MS_RDONLY; spin_unlock(&sbi->s_lock); + ext2_write_super(sb); + + vfs_dq_quota_on_remount(sb); } + return 0; restore_opts: sbi->s_mount_opt = old_opts.s_mount_opt; Index: linux-2.6/fs/ext3/super.c =================================================================== --- linux-2.6.orig/fs/ext3/super.c 2010-05-19 10:47:34.566253960 +0200 +++ linux-2.6/fs/ext3/super.c 2010-05-19 12:43:25.619254659 +0200 @@ -2551,6 +2551,7 @@ static int ext3_remount (struct super_bl ext3_fsblk_t n_blocks_count = 0; unsigned long old_sb_flags; struct ext3_mount_options old_opts; + int enable_quota = 0; int err; #ifdef CONFIG_QUOTA int i; @@ -2597,6 +2598,12 @@ static int ext3_remount (struct super_bl } if (*flags & MS_RDONLY) { + err = vfs_dq_off(sb, 1); + if (err < 0 && err != -ENOSYS) { + err = -EBUSY; + goto restore_opts; + } + /* * First of all, the unconditional stuff we have to do * to disable replay of the journal when we next remount @@ -2651,6 +2658,7 @@ static int ext3_remount (struct super_bl goto restore_opts; if (!ext3_setup_super (sb, es, 0)) sb->s_flags &= ~MS_RDONLY; + enable_quota = 1; } } #ifdef CONFIG_QUOTA @@ -2662,6 +2670,9 @@ static int ext3_remount (struct super_bl #endif unlock_super(sb); unlock_kernel(); + + if (enable_quota) + vfs_dq_quota_on_remount(sb); return 0; restore_opts: sb->s_flags = old_sb_flags; Index: linux-2.6/fs/ext4/super.c =================================================================== --- linux-2.6.orig/fs/ext4/super.c 2010-05-19 09:59:58.796003925 +0200 +++ linux-2.6/fs/ext4/super.c 2010-05-19 12:43:25.626004205 +0200 @@ -3574,6 +3574,7 @@ static int ext4_remount(struct super_blo ext4_fsblk_t n_blocks_count = 0; unsigned long old_sb_flags; struct ext4_mount_options old_opts; + int enable_quota = 0; ext4_group_t g; unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO; int err; @@ -3630,6 +3631,12 @@ static int ext4_remount(struct super_blo } if (*flags & MS_RDONLY) { + err = vfs_dq_off(sb, 1); + if (err < 0 && err != -ENOSYS) { + err = -EBUSY; + goto restore_opts; + } + /* * First of all, the unconditional stuff we have to do * to disable replay of the journal when we next remount @@ -3698,6 +3705,7 @@ static int ext4_remount(struct super_blo goto restore_opts; if (!ext4_setup_super(sb, es, 0)) sb->s_flags &= ~MS_RDONLY; + enable_quota = 1; } } ext4_setup_system_zone(sb); @@ -3713,6 +3721,8 @@ static int ext4_remount(struct super_blo #endif unlock_super(sb); unlock_kernel(); + if (enable_quota) + vfs_dq_quota_on_remount(sb); return 0; restore_opts: Index: linux-2.6/fs/jfs/super.c =================================================================== --- linux-2.6.orig/fs/jfs/super.c 2010-05-19 10:47:34.571253820 +0200 +++ linux-2.6/fs/jfs/super.c 2010-05-19 12:50:17.873214499 +0200 @@ -396,10 +396,20 @@ static int jfs_remount(struct super_bloc JFS_SBI(sb)->flag = flag; ret = jfs_mount_rw(sb, 1); + + /* mark the fs r/w for quota activity */ + sb->s_flags &= ~MS_RDONLY; + unlock_kernel(); + vfs_dq_quota_on_remount(sb); return ret; } if ((!(sb->s_flags & MS_RDONLY)) && (*flags & MS_RDONLY)) { + rc = vfs_dq_off(sb, 1); + if (rc < 0 && rc != -ENOSYS) { + unlock_kernel(); + return -EBUSY; + } rc = jfs_umount_rw(sb); JFS_SBI(sb)->flag = flag; unlock_kernel(); Index: linux-2.6/fs/reiserfs/super.c =================================================================== --- linux-2.6.orig/fs/reiserfs/super.c 2010-05-19 09:59:59.117004065 +0200 +++ linux-2.6/fs/reiserfs/super.c 2010-05-19 12:43:25.636003367 +0200 @@ -1242,6 +1242,13 @@ static int reiserfs_remount(struct super if (s->s_flags & MS_RDONLY) /* it is read-only already */ goto out_ok; + + err = vfs_dq_off(s, 1); + if (err < 0 && err != -ENOSYS) { + err = -EBUSY; + goto out_err; + } + /* try to remount file system with read-only permissions */ if (sb_umount_state(rs) == REISERFS_VALID_FS || REISERFS_SB(s)->s_mount_state != REISERFS_VALID_FS) { @@ -1297,6 +1304,7 @@ static int reiserfs_remount(struct super if (!(*mount_flags & MS_RDONLY)) { finish_unfinished(s); reiserfs_xattr_init(s, *mount_flags); + vfs_dq_quota_on_remount(s); } out_ok: Index: linux-2.6/fs/ufs/super.c =================================================================== --- linux-2.6.orig/fs/ufs/super.c 2010-05-19 09:59:59.173275471 +0200 +++ linux-2.6/fs/ufs/super.c 2010-05-19 12:43:25.643003786 +0200 @@ -1248,7 +1248,9 @@ static int ufs_remount (struct super_blo struct ufs_super_block_first * usb1; struct ufs_super_block_third * usb3; unsigned new_mount_opt, ufstype; + int enable_quota = 0; unsigned flags; + int err; lock_kernel(); lock_super(sb); @@ -1289,6 +1291,13 @@ static int ufs_remount (struct super_blo * fs was mouted as rw, remounting ro */ if (*mount_flags & MS_RDONLY) { + err = vfs_dq_off(sb, 1); + if (err < 0 && err != -ENOSYS) { + unlock_super(sb); + unlock_kernel(); + return -EBUSY; + } + ufs_put_super_internal(sb); usb1->fs_time = cpu_to_fs32(sb, get_seconds()); if ((flags & UFS_ST_MASK) == UFS_ST_SUN @@ -1327,11 +1336,14 @@ static int ufs_remount (struct super_blo return -EPERM; } sb->s_flags &= ~MS_RDONLY; + enable_quota = 1; #endif } UFS_SB(sb)->s_mount_opt = new_mount_opt; unlock_super(sb); unlock_kernel(); + if (enable_quota) + vfs_dq_quota_on_remount(sb); return 0; } Index: linux-2.6/fs/super.c =================================================================== --- linux-2.6.orig/fs/super.c 2010-05-19 10:47:34.597253401 +0200 +++ linux-2.6/fs/super.c 2010-05-19 12:43:25.650003367 +0200 @@ -568,7 +568,7 @@ out: int do_remount_sb(struct super_block *sb, int flags, void *data, int force) { int retval; - int remount_rw, remount_ro; + int remount_ro; if (sb->s_frozen != SB_UNFROZEN) return -EBUSY; @@ -584,7 +584,6 @@ int do_remount_sb(struct super_block *sb sync_filesystem(sb); remount_ro = (flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY); - remount_rw = !(flags & MS_RDONLY) && (sb->s_flags & MS_RDONLY); /* If we are remounting RDONLY and current sb is read/write, make sure there are no rw files opened */ @@ -593,9 +592,6 @@ int do_remount_sb(struct super_block *sb mark_files_ro(sb); else if (!fs_may_remount_ro(sb)) return -EBUSY; - retval = vfs_dq_off(sb, 1); - if (retval < 0 && retval != -ENOSYS) - return -EBUSY; } if (sb->s_op->remount_fs) { @@ -604,8 +600,7 @@ int do_remount_sb(struct super_block *sb return retval; } sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK); - if (remount_rw) - vfs_dq_quota_on_remount(sb); + /* * Some filesystems modify their metadata via some other path than the * bdev buffer cache (eg. use a private mapping, or directories in Index: linux-2.6/fs/udf/super.c =================================================================== --- linux-2.6.orig/fs/udf/super.c 2010-05-19 12:45:17.269011887 +0200 +++ linux-2.6/fs/udf/super.c 2010-05-19 12:53:46.671007906 +0200 @@ -54,6 +54,7 @@ #include <linux/vmalloc.h> #include <linux/errno.h> #include <linux/mount.h> +#include <linux/quotaops.h> #include <linux/seq_file.h> #include <linux/bitmap.h> #include <linux/crc-itu-t.h> @@ -557,6 +558,7 @@ static int udf_remount_fs(struct super_b { struct udf_options uopt; struct udf_sb_info *sbi = UDF_SB(sb); + int error = 0; uopt.flags = sbi->s_flags; uopt.uid = sbi->s_uid; @@ -582,17 +584,26 @@ static int udf_remount_fs(struct super_b *flags |= MS_RDONLY; } - if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) { - unlock_kernel(); - return 0; - } - if (*flags & MS_RDONLY) + if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) + goto out_unlock; + + if (*flags & MS_RDONLY) { udf_close_lvid(sb); - else + + error = vfs_dq_off(sb, 1); + if (error < 0 && error != -ENOSYS) + error = -EBUSY; + } else { udf_open_lvid(sb); + /* mark the fs r/w for quota activity */ + sb->s_flags &= ~MS_RDONLY; + vfs_dq_quota_on_remount(sb); + } + +out_unlock: unlock_kernel(); - return 0; + return error; } /* Check Volume Structure Descriptors (ECMA 167 2/9.1) */ -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html