quota: move remount handling into the filesystem
authorChristoph Hellwig <hch@infradead.org>
Wed, 19 May 2010 11:16:40 +0000 (07:16 -0400)
committerJan Kara <jack@suse.cz>
Mon, 24 May 2010 12:06:39 +0000 (14:06 +0200)
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 rid of overloading
the quotactl calls and allows to unify the VFS and XFS codepaths in
that area later.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jan Kara <jack@suse.cz>
fs/ext2/super.c
fs/ext3/super.c
fs/ext4/super.c
fs/jfs/super.c
fs/reiserfs/super.c
fs/super.c
fs/udf/super.c
fs/ufs/super.c

index 71e9eb1fa69680e6a029f90064d485c28070c0bc..73346de9af5ced09d0ba2ed68526db032bc745e7 100644 (file)
@@ -1241,6 +1241,7 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
                        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_block * sb, int * flags, char * data)
                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_block * sb, int * flags, char * data)
                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 0fc1293d0e96140b07f232b0934b161931599fbe..d0f8837b6255666ea37de7b5fc374d2eaa3a1e62 100644 (file)
@@ -2551,6 +2551,7 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
        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_block * sb, int * flags, char * data)
                }
 
                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_block * sb, int * flags, char * data)
                                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_block * sb, int * flags, char * data)
 #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 e14d22c170d542f3d65b7b50065f0256e0c940b3..fb1e191d0fa9c9ef4663dedeb768974a504f4869 100644 (file)
@@ -3574,6 +3574,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
        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_block *sb, int *flags, char *data)
                }
 
                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_block *sb, int *flags, char *data)
                                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_block *sb, int *flags, char *data)
 #endif
        unlock_super(sb);
        unlock_kernel();
+       if (enable_quota)
+               vfs_dq_quota_on_remount(sb);
        return 0;
 
 restore_opts:
index b66832ac33ac5d5869d90084227a321174e0b95d..5329d66a970427cd5a421b11e387ee2e0d85043a 100644 (file)
@@ -396,10 +396,20 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data)
 
                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 59125fb36d42482fd8fc3b6cfc9d63576890ca8e..49a8ba02bc1771911d8482b9f13a9220597f3a00 100644 (file)
@@ -1242,6 +1242,13 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
                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) {
@@ -1295,6 +1302,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
        s->s_dirt = 0;
 
        if (!(*mount_flags & MS_RDONLY)) {
+               vfs_dq_quota_on_remount(s);
                finish_unfinished(s);
                reiserfs_xattr_init(s, *mount_flags);
        }
index 69688b15f1fa928002584b1504cfe2146ba3b67f..a38e6e9b6f690af839c83d54cb5bb13e2a8eb97b 100644 (file)
@@ -524,7 +524,7 @@ rescan:
 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;
@@ -540,7 +540,6 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
        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 */
@@ -549,9 +548,6 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
                        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) {
@@ -560,8 +556,7 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
                        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 1e4543cbcd276decb1b43942e999b9f2f851b145..9ab4e259404bbc1a7f383ccbf8ced5888bc99786 100644 (file)
@@ -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_block *sb, int *flags, char *options)
 {
        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_block *sb, int *flags, char *options)
                        *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) */
index 14743d935a93f88a41691d122cc7f353fe102b17..be1f7b05bc28c0d9dbdfee29838bdc36336f99f9 100644 (file)
@@ -1248,7 +1248,9 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
        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_block *sb, int *mount_flags, char *data)
         * 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_block *sb, int *mount_flags, char *data)
                        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;
 }