summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--fs/ext2/super.c13
-rw-r--r--fs/ext3/super.c11
-rw-r--r--fs/ext4/super.c10
-rw-r--r--fs/jfs/super.c10
-rw-r--r--fs/reiserfs/super.c8
-rw-r--r--fs/super.c9
-rw-r--r--fs/udf/super.c25
-rw-r--r--fs/ufs/super.c12
8 files changed, 84 insertions, 14 deletions
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 71e9eb1fa696..73346de9af5c 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -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;
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 0fc1293d0e96..d0f8837b6255 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -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;
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index e14d22c170d5..fb1e191d0fa9 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -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:
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index b66832ac33ac..5329d66a9704 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -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();
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 59125fb36d42..49a8ba02bc17 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -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);
 	}
diff --git a/fs/super.c b/fs/super.c
index 69688b15f1fa..a38e6e9b6f69 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -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
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 1e4543cbcd27..9ab4e259404b 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -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) */
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index 14743d935a93..be1f7b05bc28 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -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;
 }