[PATCH 05/19] quota: mode quota internals from sb to quota_info

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Most super_blocks don't use quota. So it is reasonable to hide quota internals
under a sb pointer. The only fields are steel on sb are:
*flags      indicate state, checked without locks
*onoff_mutex
*dq_op
*qcop
We can hide dq_op/qcop inside pointer too, but IMHO it is not necessary.

Signed-off-by: Dmitry Monakhov <dmonakhov@xxxxxxxxxx>
---
 fs/ext2/super.c              |    4 +-
 fs/ext3/super.c              |    4 +-
 fs/ext4/super.c              |    4 +-
 fs/gfs2/ops_fstype.c         |    4 +-
 fs/jfs/super.c               |    4 +-
 fs/ocfs2/quota_local.c       |    4 +-
 fs/ocfs2/super.c             |    6 +-
 fs/quota/dquot.c             |  217 ++++++++++++++++++++++++++----------------
 fs/quota/quota.c             |   58 ++++++------
 fs/reiserfs/super.c          |    4 +-
 fs/super.c                   |   10 --
 fs/sync.c                    |    4 +-
 fs/xfs/linux-2.6/xfs_super.c |    2 +-
 include/linux/fs.h           |    4 +-
 include/linux/quota.h        |   21 +++--
 include/linux/quotaops.h     |   15 ++-
 16 files changed, 210 insertions(+), 155 deletions(-)

diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 7727491..de8d2c4 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -1055,8 +1055,8 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
 	sb->s_xattr = ext2_xattr_handlers;
 
 #ifdef CONFIG_QUOTA
-	sb->dq_op = &dquot_operations;
-	sb->s_qcop = &dquot_quotactl_ops;
+	dqctl(sb)->dq_op = &dquot_operations;
+	dqctl(sb)->qcop = &dquot_quotactl_ops;
 #endif
 
 	root = ext2_iget(sb, EXT2_ROOT_INO);
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 5cd148a..9ed767d 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -1930,8 +1930,8 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
 	sb->s_export_op = &ext3_export_ops;
 	sb->s_xattr = ext3_xattr_handlers;
 #ifdef CONFIG_QUOTA
-	sb->s_qcop = &ext3_qctl_operations;
-	sb->dq_op = &ext3_quota_operations;
+	dqctl(sb)->qcop = &ext3_qctl_operations;
+	dqctl(sb)->dq_op = &ext3_quota_operations;
 #endif
 	INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */
 	mutex_init(&sbi->s_orphan_lock);
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 053aee4..698dc6d 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -2939,8 +2939,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 	sb->s_export_op = &ext4_export_ops;
 	sb->s_xattr = ext4_xattr_handlers;
 #ifdef CONFIG_QUOTA
-	sb->s_qcop = &ext4_qctl_operations;
-	sb->dq_op = &ext4_quota_operations;
+	dqctl(sb)->qcop = &ext4_qctl_operations;
+	dqctl(sb)->dq_op = &ext4_quota_operations;
 #endif
 	INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */
 	mutex_init(&sbi->s_orphan_lock);
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 1e52207..43d0a24 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -1167,8 +1167,8 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent
 	sb->s_op = &gfs2_super_ops;
 	sb->s_export_op = &gfs2_export_ops;
 	sb->s_xattr = gfs2_xattr_handlers;
-	sb->s_qcop = &gfs2_quotactl_ops;
-	dqopts(sb)->flags |= DQUOT_QUOTA_SYS_FILE;
+	dqctl(sb)->qcop = &gfs2_quotactl_ops;
+	dqctl(sb)->flags |= DQUOT_QUOTA_SYS_FILE;
 	sb->s_time_gran = 1;
 	sb->s_maxbytes = MAX_LFS_FILESIZE;
 
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index b612adf..a8a94e6 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -477,8 +477,8 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
 	sb->s_op = &jfs_super_operations;
 	sb->s_export_op = &jfs_export_operations;
 #ifdef CONFIG_QUOTA
-	sb->dq_op = &dquot_operations;
-	sb->s_qcop = &dquot_quotactl_ops;
+	dqctl(sb)->dq_op = &dquot_operations;
+	dqctl(sb)->qcop = &dquot_quotactl_ops;
 #endif
 
 	/*
diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c
index 056cb24..7c30ba3 100644
--- a/fs/ocfs2/quota_local.c
+++ b/fs/ocfs2/quota_local.c
@@ -596,7 +596,7 @@ int ocfs2_finish_quota_recovery(struct ocfs2_super *osb,
 	unsigned int flags;
 
 	mlog(ML_NOTICE, "Finishing quota recovery in slot %u\n", slot_num);
-	mutex_lock(&dqopts(sb)->dqonoff_mutex);
+	mutex_lock(&dqctl(sb)->dqonoff_mutex);
 	for (type = 0; type < MAXQUOTAS; type++) {
 		if (list_empty(&(rec->r_list[type])))
 			continue;
@@ -672,7 +672,7 @@ out_put:
 			break;
 	}
 out:
-	mutex_unlock(&dqopts(sb)->dqonoff_mutex);
+	mutex_unlock(&dqctl(sb)->dqonoff_mutex);
 	kfree(rec);
 	return status;
 }
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 16065ae..b6dcb65 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -907,7 +907,7 @@ static int ocfs2_enable_quotas(struct ocfs2_super *osb)
 	int status;
 	int type;
 
-	dqopts(sb)->flags |= DQUOT_QUOTA_SYS_FILE | DQUOT_NEGATIVE_USAGE;
+	dqctl(sb)->flags |= DQUOT_QUOTA_SYS_FILE | DQUOT_NEGATIVE_USAGE;
 	for (type = 0; type < MAXQUOTAS; type++) {
 		if (!OCFS2_HAS_RO_COMPAT_FEATURE(sb, feature[type]))
 			continue;
@@ -2015,8 +2015,8 @@ static int ocfs2_initialize_super(struct super_block *sb,
 	sb->s_fs_info = osb;
 	sb->s_op = &ocfs2_sops;
 	sb->s_export_op = &ocfs2_export_ops;
-	sb->s_qcop = &ocfs2_quotactl_ops;
-	sb->dq_op = &ocfs2_quota_operations;
+	dqctl(sb)->qcop = &ocfs2_quotactl_ops;
+	dqctl(sb)->dq_op = &ocfs2_quota_operations;
 	sb->s_xattr = ocfs2_xattr_handlers;
 	sb->s_time_gran = 1;
 	sb->s_flags |= MS_NOATIME;
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 7e937b0..78e48f3 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -332,7 +332,7 @@ static inline int dquot_dirty(struct dquot *dquot)
 
 static inline int mark_dquot_dirty(struct dquot *dquot)
 {
-	return dquot->dq_sb->dq_op->mark_dirty(dquot);
+	return dqctl(dquot->dq_sb)->dq_op->mark_dirty(dquot);
 }
 
 /* Mark dquot dirty in atomic manner, and return it's old dirty flag state */
@@ -406,16 +406,16 @@ int dquot_acquire(struct dquot *dquot)
 	mutex_lock(&dquot->dq_lock);
 	mutex_lock(&dqopt->dqio_mutex);
 	if (!test_bit(DQ_READ_B, &dquot->dq_flags))
-		ret = dqopt->ops[dquot->dq_type]->read_dqblk(dquot);
+		ret = dqopt->fmt_ops[dquot->dq_type]->read_dqblk(dquot);
 	if (ret < 0)
 		goto out_iolock;
 	set_bit(DQ_READ_B, &dquot->dq_flags);
 	/* Instantiate dquot if needed */
 	if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && !dquot->dq_off) {
-		ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot);
+		ret = dqopt->fmt_ops[dquot->dq_type]->commit_dqblk(dquot);
 		/* Write the info if needed */
 		if (info_dirty(&dqopt->info[dquot->dq_type])) {
-			ret2 = dqopt->ops[dquot->dq_type]->write_file_info(
+			ret2 = dqopt->fmt_ops[dquot->dq_type]->write_file_info(
 						dquot->dq_sb, dquot->dq_type);
 		}
 		if (ret < 0)
@@ -451,9 +451,9 @@ int dquot_commit(struct dquot *dquot)
 	/* Inactive dquot can be only if there was error during read/init
 	 * => we have better not writing it */
 	if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
-		ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot);
+		ret = dqopt->fmt_ops[dquot->dq_type]->commit_dqblk(dquot);
 		if (info_dirty(&dqopt->info[dquot->dq_type])) {
-			ret2 = dqopt->ops[dquot->dq_type]->write_file_info(
+			ret2 = dqopt->fmt_ops[dquot->dq_type]->write_file_info(
 						dquot->dq_sb, dquot->dq_type);
 		}
 		if (ret >= 0)
@@ -478,11 +478,11 @@ int dquot_release(struct dquot *dquot)
 	if (atomic_read(&dquot->dq_count) > 1)
 		goto out_dqlock;
 	mutex_lock(&dqopt->dqio_mutex);
-	if (dqopt->ops[dquot->dq_type]->release_dqblk) {
-		ret = dqopt->ops[dquot->dq_type]->release_dqblk(dquot);
+	if (dqopt->fmt_ops[dquot->dq_type]->release_dqblk) {
+		ret = dqopt->fmt_ops[dquot->dq_type]->release_dqblk(dquot);
 		/* Write the info */
 		if (info_dirty(&dqopt->info[dquot->dq_type])) {
-			ret2 = dqopt->ops[dquot->dq_type]->write_file_info(
+			ret2 = dqopt->fmt_ops[dquot->dq_type]->write_file_info(
 						dquot->dq_sb, dquot->dq_type);
 		}
 		if (ret >= 0)
@@ -504,7 +504,7 @@ EXPORT_SYMBOL(dquot_destroy);
 
 static inline void do_destroy_dquot(struct dquot *dquot)
 {
-	dquot->dq_sb->dq_op->destroy_dquot(dquot);
+	dqctl(dquot->dq_sb)->dq_op->destroy_dquot(dquot);
 }
 
 /* Invalidate all dquots on the list. Note that this function is called after
@@ -568,7 +568,7 @@ int dquot_scan_active(struct super_block *sb,
 	struct dquot *dquot, *old_dquot = NULL;
 	int ret = 0;
 
-	mutex_lock(&dqopts(sb)->dqonoff_mutex);
+	mutex_lock(&dqctl(sb)->dqonoff_mutex);
 	spin_lock(&dq_list_lock);
 	list_for_each_entry(dquot, &inuse_list, dq_inuse) {
 		if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags))
@@ -591,7 +591,7 @@ int dquot_scan_active(struct super_block *sb,
 	spin_unlock(&dq_list_lock);
 out:
 	dqput(old_dquot);
-	mutex_unlock(&dqopts(sb)->dqonoff_mutex);
+	mutex_unlock(&dqctl(sb)->dqonoff_mutex);
 	return ret;
 }
 EXPORT_SYMBOL(dquot_scan_active);
@@ -600,10 +600,11 @@ int dquot_quota_sync(struct super_block *sb, int type, int wait)
 {
 	struct list_head *dirty;
 	struct dquot *dquot;
-	struct quota_info *dqopt = dqopts(sb);
+	struct quota_info *dqopt;
 	int cnt;
 
-	mutex_lock(&dqopt->dqonoff_mutex);
+	mutex_lock(&dqctl(sb)->dqonoff_mutex);
+	dqopt = dqopts(sb);
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 		if (type != -1 && cnt != type)
 			continue;
@@ -625,7 +626,7 @@ int dquot_quota_sync(struct super_block *sb, int type, int wait)
 			atomic_inc(&dquot->dq_count);
 			spin_unlock(&dq_list_lock);
 			dqstats_inc(DQST_LOOKUPS);
-			sb->dq_op->write_dquot(dquot);
+			dqctl(sb)->dq_op->write_dquot(dquot);
 			dqput(dquot);
 			spin_lock(&dq_list_lock);
 		}
@@ -635,11 +636,11 @@ int dquot_quota_sync(struct super_block *sb, int type, int wait)
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
 		if ((cnt == type || type == -1) && sb_has_quota_active(sb, cnt)
 		    && info_dirty(&dqopt->info[cnt]))
-			sb->dq_op->write_info(sb, cnt);
+			dqctl(sb)->dq_op->write_info(sb, cnt);
 	dqstats_inc(DQST_SYNCS);
-	mutex_unlock(&dqopt->dqonoff_mutex);
+	mutex_unlock(&dqctl(sb)->dqonoff_mutex);
 
-	if (!wait || (dqopts(sb)->flags & DQUOT_QUOTA_SYS_FILE))
+	if (!wait || (dqctl(sb)->flags & DQUOT_QUOTA_SYS_FILE))
 		return 0;
 
 	/* This is not very clever (and fast) but currently I don't know about
@@ -653,18 +654,19 @@ int dquot_quota_sync(struct super_block *sb, int type, int wait)
 	 * Now when everything is written we can discard the pagecache so
 	 * that userspace sees the changes.
 	 */
-	mutex_lock(&dqopts(sb)->dqonoff_mutex);
+	mutex_lock(&dqctl(sb)->dqonoff_mutex);
+	dqopt = dqopts(sb);
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 		if (type != -1 && cnt != type)
 			continue;
 		if (!sb_has_quota_active(sb, cnt))
 			continue;
-		mutex_lock_nested(&dqopts(sb)->files[cnt]->i_mutex,
+		mutex_lock_nested(&dqopt->files[cnt]->i_mutex,
 				  I_MUTEX_QUOTA);
-		truncate_inode_pages(&dqopts(sb)->files[cnt]->i_data, 0);
-		mutex_unlock(&dqopts(sb)->files[cnt]->i_mutex);
+		truncate_inode_pages(&dqopt->files[cnt]->i_data, 0);
+		mutex_unlock(&dqopt->files[cnt]->i_mutex);
 	}
-	mutex_unlock(&dqopts(sb)->dqonoff_mutex);
+	mutex_unlock(&dqctl(sb)->dqonoff_mutex);
 
 	return 0;
 }
@@ -743,7 +745,7 @@ we_slept:
 	if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && dquot_dirty(dquot)) {
 		spin_unlock(&dq_list_lock);
 		/* Commit dquot before releasing */
-		ret = dquot->dq_sb->dq_op->write_dquot(dquot);
+		ret = dqctl(dquot->dq_sb)->dq_op->write_dquot(dquot);
 		if (ret < 0) {
 			quota_error(dquot->dq_sb, "Can't write quota structure"
 				    " (error %d). Quota may get out of sync!",
@@ -762,7 +764,7 @@ we_slept:
 	clear_dquot_dirty(dquot);
 	if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
 		spin_unlock(&dq_list_lock);
-		dquot->dq_sb->dq_op->release_dquot(dquot);
+		dqctl(dquot->dq_sb)->dq_op->release_dquot(dquot);
 		goto we_slept;
 	}
 	atomic_dec(&dquot->dq_count);
@@ -785,7 +787,7 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type)
 {
 	struct dquot *dquot;
 
-	dquot = sb->dq_op->alloc_dquot(sb, type);
+	dquot = dqctl(sb)->dq_op->alloc_dquot(sb, type);
 	if(!dquot)
 		return NULL;
 
@@ -864,7 +866,7 @@ we_slept:
 	wait_on_dquot(dquot);
 	/* Read the dquot / allocate space in quota file */
 	if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) &&
-	    sb->dq_op->acquire_dquot(dquot) < 0) {
+	    dqctl(sb)->dq_op->acquire_dquot(dquot) < 0) {
 		dqput(dquot);
 		dquot = NULL;
 		goto out;
@@ -1039,7 +1041,7 @@ static void drop_dquot_ref(struct super_block *sb, int type)
 {
 	LIST_HEAD(tofree_head);
 
-	if (sb->dq_op) {
+	if (dqctl(sb)->dq_op) {
 		down_write(&dqopts(sb)->dqptr_sem);
 		remove_dquot_ref(sb, type, &tofree_head);
 		up_write(&dqopts(sb)->dqptr_sem);
@@ -1088,7 +1090,7 @@ void dquot_free_reserved_space(struct dquot *dquot, qsize_t number)
 
 static void dquot_decr_inodes(struct dquot *dquot, qsize_t number)
 {
-	if (sb_dqopts(dquot)->flags & DQUOT_NEGATIVE_USAGE ||
+	if (dqctl(dquot->dq_sb)->flags & DQUOT_NEGATIVE_USAGE ||
 	    dquot->dq_dqb.dqb_curinodes >= number)
 		dquot->dq_dqb.dqb_curinodes -= number;
 	else
@@ -1100,7 +1102,7 @@ static void dquot_decr_inodes(struct dquot *dquot, qsize_t number)
 
 static void dquot_decr_space(struct dquot *dquot, qsize_t number)
 {
-	if (sb_dqopts(dquot)->flags & DQUOT_NEGATIVE_USAGE ||
+	if (dqctl(dquot->dq_sb)->flags & DQUOT_NEGATIVE_USAGE ||
 	    dquot->dq_dqb.dqb_curspace >= number)
 		dquot->dq_dqb.dqb_curspace -= number;
 	else
@@ -1479,8 +1481,8 @@ static qsize_t *inode_reserved_space(struct inode * inode)
 {
 	/* Filesystem must explicitly define it's own method in order to use
 	 * quota reservation interface */
-	BUG_ON(!inode->i_sb->dq_op->get_reserved_space);
-	return inode->i_sb->dq_op->get_reserved_space(inode);
+	BUG_ON(!dqctl(inode->i_sb)->dq_op->get_reserved_space);
+	return dqctl(inode->i_sb)->dq_op->get_reserved_space(inode);
 }
 
 void inode_add_rsv_space(struct inode *inode, qsize_t number)
@@ -1512,7 +1514,7 @@ static qsize_t inode_get_rsv_space(struct inode *inode)
 {
 	qsize_t ret;
 
-	if (!inode->i_sb->dq_op->get_reserved_space)
+	if (!dqctl(inode->i_sb)->dq_op->get_reserved_space)
 		return 0;
 	spin_lock(&inode->i_lock);
 	ret = *inode_reserved_space(inode);
@@ -1906,7 +1908,7 @@ int dquot_commit_info(struct super_block *sb, int type)
 	struct quota_info *dqopt = dqopts(sb);
 
 	mutex_lock(&dqopt->dqio_mutex);
-	ret = dqopt->ops[type]->write_file_info(sb, type);
+	ret = dqopt->fmt_ops[type]->write_file_info(sb, type);
 	mutex_unlock(&dqopt->dqio_mutex);
 	return ret;
 }
@@ -1942,24 +1944,55 @@ EXPORT_SYMBOL(dquot_file_open);
 
 int dquot_get_dqfmt(struct super_block *sb, int type, unsigned int *fmt)
 {
-	mutex_lock(&dqopts(sb)->dqonoff_mutex);
+	mutex_lock(&dqctl(sb)->dqonoff_mutex);
 	if (!sb_has_quota_active(sb, type)) {
-		mutex_unlock(&dqopts(sb)->dqonoff_mutex);
+		mutex_unlock(&dqctl(sb)->dqonoff_mutex);
 		return -ESRCH;
 	}
 	*fmt = dqopts(sb)->info[type].dqi_format->qf_fmt_id;
-	mutex_unlock(&dqopts(sb)->dqonoff_mutex);
+	mutex_unlock(&dqctl(sb)->dqonoff_mutex);
 	return 0;
 }
 EXPORT_SYMBOL(dquot_get_dqfmt);
 
+/* Next two helpers called with dqonoff_mutex held */
+static int alloc_quota_info(struct quota_ctl_info *dqctl) {
+	int err = -ENOMEM;
+	struct quota_info *dqopt;
+	BUG_ON(dqctl->dq_opt);
+
+	dqopt = kzalloc(sizeof(*dqopt), GFP_NOFS);
+	if (!dqopt)
+		return err;
+
+	err = init_srcu_struct(&dqopt->dq_srcu);
+	if (err) {
+		kfree(dqopt);
+		return err;
+	}
+	mutex_init(&dqopt->dqio_mutex);
+	init_rwsem(&dqopt->dqptr_sem);
+	dqctl->dq_opt = dqopt;
+	return 0;
+}
+
+static void free_quota_info(struct quota_ctl_info *dqctl)
+{
+	if (dqctl->dq_opt) {
+		cleanup_srcu_struct(&dqctl->dq_opt->dq_srcu);
+		kfree(dqctl->dq_opt);
+		dqctl->dq_opt = NULL;
+	}
+}
+
 /*
  * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount)
  */
 int dquot_disable(struct super_block *sb, int type, unsigned int flags)
 {
 	int cnt, ret = 0;
-	struct quota_info *dqopt = dqopts(sb);
+	struct quota_ctl_info *qctl = dqctl(sb);
+	struct quota_info *dqopt;
 	struct inode *toputinode[MAXQUOTAS];
 
 	/* Cannot turn off usage accounting without turning off limits, or
@@ -1970,15 +2003,15 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
 		return -EINVAL;
 
 	/* We need to serialize quota_off() for device */
-	mutex_lock(&dqopt->dqonoff_mutex);
-
+	mutex_lock(&qctl->dqonoff_mutex);
+	dqopt = dqopts(sb);
 	/*
 	 * Skip everything if there's nothing to do. We have to do this because
 	 * sometimes we are called when fill_super() failed and calling
 	 * sync_fs() in such cases does no good.
 	 */
 	if (!sb_any_quota_loaded(sb)) {
-		mutex_unlock(&dqopt->dqonoff_mutex);
+		mutex_unlock(&qctl->dqonoff_mutex);
 		return 0;
 	}
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
@@ -1990,16 +2023,16 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
 
 		if (flags & DQUOT_SUSPENDED) {
 			spin_lock(&dq_state_lock);
-			dqopt->flags |=
+			qctl->flags |=
 				dquot_state_flag(DQUOT_SUSPENDED, cnt);
 			spin_unlock(&dq_state_lock);
 		} else {
 			spin_lock(&dq_state_lock);
-			dqopt->flags &= ~dquot_state_flag(flags, cnt);
+			qctl->flags &= ~dquot_state_flag(flags, cnt);
 			/* Turning off suspended quotas? */
 			if (!sb_has_quota_loaded(sb, cnt) &&
 			    sb_has_quota_suspended(sb, cnt)) {
-				dqopt->flags &=	~dquot_state_flag(
+				qctl->flags &=	~dquot_state_flag(
 							DQUOT_SUSPENDED, cnt);
 				spin_unlock(&dq_state_lock);
 				iput(dqopt->files[cnt]);
@@ -2037,9 +2070,9 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
 		 * should be only users of the info. No locks needed.
 		 */
 		if (info_dirty(&dqopt->info[cnt]))
-			sb->dq_op->write_info(sb, cnt);
-		if (dqopt->ops[cnt]->free_file_info)
-			dqopt->ops[cnt]->free_file_info(sb, cnt);
+			qctl->dq_op->write_info(sb, cnt);
+		if (dqopt->fmt_ops[cnt]->free_file_info)
+			dqopt->fmt_ops[cnt]->free_file_info(sb, cnt);
 		put_quota_format(dqopt->info[cnt].dqi_format);
 
 		if (!sb_has_quota_loaded(sb, cnt))
@@ -2047,12 +2080,15 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
 		dqopt->info[cnt].dqi_flags = 0;
 		dqopt->info[cnt].dqi_igrace = 0;
 		dqopt->info[cnt].dqi_bgrace = 0;
-		dqopt->ops[cnt] = NULL;
+		dqopt->fmt_ops[cnt] = NULL;
 	}
-	mutex_unlock(&dqopt->dqonoff_mutex);
+	if (!sb_any_quota_loaded(sb))
+		free_quota_info(qctl);
+
+	mutex_unlock(&qctl->dqonoff_mutex);
 
 	/* Skip syncing and setting flags if quota files are hidden */
-	if (dqopt->flags & DQUOT_QUOTA_SYS_FILE)
+	if (qctl->flags & DQUOT_QUOTA_SYS_FILE)
 		goto put_inodes;
 
 	/* Sync the superblock so that buffers with quota data are written to
@@ -2067,7 +2103,7 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
 	 * changes done by userspace on the next quotaon() */
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
 		if (toputinode[cnt]) {
-			mutex_lock(&dqopt->dqonoff_mutex);
+			mutex_lock(&qctl->dqonoff_mutex);
 			/* If quota was reenabled in the meantime, we have
 			 * nothing to do */
 			if (!sb_has_quota_loaded(sb, cnt)) {
@@ -2080,7 +2116,7 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
 				mutex_unlock(&toputinode[cnt]->i_mutex);
 				mark_inode_dirty_sync(toputinode[cnt]);
 			}
-			mutex_unlock(&dqopt->dqonoff_mutex);
+			mutex_unlock(&qctl->dqonoff_mutex);
 		}
 	if (sb->s_bdev)
 		invalidate_bdev(sb->s_bdev);
@@ -2123,7 +2159,7 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
 {
 	struct quota_format_type *fmt = find_quota_format(format_id);
 	struct super_block *sb = inode->i_sb;
-	struct quota_info *dqopt = dqopts(sb);
+	struct quota_info *dqopt;
 	int error;
 	int oldflags = -1;
 
@@ -2147,7 +2183,7 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
 		goto out_fmt;
 	}
 
-	if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) {
+	if (!(dqctl(sb)->flags & DQUOT_QUOTA_SYS_FILE)) {
 		/* As we bypass the pagecache we must now flush all the
 		 * dirty data and invalidate caches so that kernel sees
 		 * changes from userspace. It is not enough to just flush
@@ -2157,13 +2193,14 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
 		sync_filesystem(sb);
 		invalidate_bdev(sb->s_bdev);
 	}
-	mutex_lock(&dqopt->dqonoff_mutex);
+	mutex_lock(&dqctl(sb)->dqonoff_mutex);
+	dqopt = dqopts(sb);
 	if (sb_has_quota_loaded(sb, type)) {
 		error = -EBUSY;
 		goto out_lock;
 	}
 
-	if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) {
+	if (!(dqctl(sb)->flags & DQUOT_QUOTA_SYS_FILE)) {
 		/* We don't want quota and atime on quota files (deadlocks
 		 * possible) Also nobody should write to the file - we use
 		 * special IO operations which ignore the immutable bit. */
@@ -2187,23 +2224,23 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
 	if (!fmt->qf_ops->check_quota_file(sb, type))
 		goto out_file_init;
 
-	dqopt->ops[type] = fmt->qf_ops;
+	dqopt->fmt_ops[type] = fmt->qf_ops;
 	dqopt->info[type].dqi_format = fmt;
 	dqopt->info[type].dqi_fmt_id = format_id;
 	INIT_LIST_HEAD(&dqopt->info[type].dqi_dirty_list);
 	mutex_lock(&dqopt->dqio_mutex);
-	error = dqopt->ops[type]->read_file_info(sb, type);
+	error = dqopt->fmt_ops[type]->read_file_info(sb, type);
 	if (error < 0) {
 		mutex_unlock(&dqopt->dqio_mutex);
 		goto out_file_init;
 	}
 	mutex_unlock(&dqopt->dqio_mutex);
 	spin_lock(&dq_state_lock);
-	dqopt->flags |= dquot_state_flag(flags, type);
+	dqctl(sb)->flags |= dquot_state_flag(flags, type);
 	spin_unlock(&dq_state_lock);
 
 	add_dquot_ref(sb, type);
-	mutex_unlock(&dqopt->dqonoff_mutex);
+	mutex_unlock(&dqctl(sb)->dqonoff_mutex);
 
 	return 0;
 
@@ -2219,7 +2256,15 @@ out_lock:
 		inode->i_flags |= oldflags;
 		mutex_unlock(&inode->i_mutex);
 	}
-	mutex_unlock(&dqopt->dqonoff_mutex);
+	/* We have failed to enable quota, so quota flags doesn't changed.
+	 * If all quota is disabled then it was disabled before the call.
+	 * So there is no any quota_info user exits and we can skip
+	 * synchronization stage.
+	 */
+	if (!sb_any_quota_loaded(sb))
+		free_quota_info(dqctl(sb));
+
+	mutex_unlock(&dqctl(sb)->dqonoff_mutex);
 out_fmt:
 	put_quota_format(fmt);
 
@@ -2229,7 +2274,7 @@ out_fmt:
 /* Reenable quotas on remount RW */
 int dquot_resume(struct super_block *sb, int type)
 {
-	struct quota_info *dqopt = dqopts(sb);
+	struct quota_ctl_info *qctl = dqctl(sb);
 	struct inode *inode;
 	int ret = 0, cnt;
 	unsigned int flags;
@@ -2238,24 +2283,24 @@ int dquot_resume(struct super_block *sb, int type)
 		if (type != -1 && cnt != type)
 			continue;
 
-		mutex_lock(&dqopt->dqonoff_mutex);
+		mutex_lock(&qctl->dqonoff_mutex);
 		if (!sb_has_quota_suspended(sb, cnt)) {
-			mutex_unlock(&dqopt->dqonoff_mutex);
+			mutex_unlock(&qctl->dqonoff_mutex);
 			continue;
 		}
-		inode = dqopt->files[cnt];
-		dqopt->files[cnt] = NULL;
+		inode = qctl->dq_opt->files[cnt];
+		qctl->dq_opt->files[cnt] = NULL;
 		spin_lock(&dq_state_lock);
-		flags = dqopt->flags & dquot_state_flag(DQUOT_USAGE_ENABLED |
+		flags = qctl->flags & dquot_state_flag(DQUOT_USAGE_ENABLED |
 							DQUOT_LIMITS_ENABLED,
 							cnt);
-		dqopt->flags &= ~dquot_state_flag(DQUOT_STATE_FLAGS, cnt);
+		qctl->flags &= ~dquot_state_flag(DQUOT_STATE_FLAGS, cnt);
 		spin_unlock(&dq_state_lock);
-		mutex_unlock(&dqopt->dqonoff_mutex);
+		mutex_unlock(&qctl->dqonoff_mutex);
 
 		flags = dquot_generic_flag(flags, cnt);
 		ret = vfs_load_quota_inode(inode, cnt,
-				dqopt->info[cnt].dqi_fmt_id, flags);
+				dqopts(sb)->info[cnt].dqi_fmt_id, flags);
 		iput(inode);
 	}
 
@@ -2266,9 +2311,18 @@ EXPORT_SYMBOL(dquot_resume);
 int dquot_quota_on(struct super_block *sb, int type, int format_id,
 		   struct path *path)
 {
+	struct quota_ctl_info *qctl = dqctl(sb);
 	int error = security_quota_on(path->dentry);
 	if (error)
 		return error;
+
+	mutex_lock(&qctl->dqonoff_mutex);
+	if (!sb_any_quota_loaded(sb))
+		error = alloc_quota_info(qctl);
+	mutex_unlock(&qctl->dqonoff_mutex);
+	if (error)
+		goto out;
+
 	/* Quota file not on the same filesystem? */
 	if (path->mnt->mnt_sb != sb)
 		error = -EXDEV;
@@ -2276,6 +2330,7 @@ int dquot_quota_on(struct super_block *sb, int type, int format_id,
 		error = vfs_load_quota_inode(path->dentry->d_inode, type,
 					     format_id, DQUOT_USAGE_ENABLED |
 					     DQUOT_LIMITS_ENABLED);
+out:
 	return error;
 }
 EXPORT_SYMBOL(dquot_quota_on);
@@ -2289,7 +2344,7 @@ int dquot_enable(struct inode *inode, int type, int format_id,
 {
 	int ret = 0;
 	struct super_block *sb = inode->i_sb;
-	struct quota_info *dqopt = dqopts(sb);
+	struct quota_ctl_info *qctl = dqctl(sb);
 
 	/* Just unsuspend quotas? */
 	BUG_ON(flags & DQUOT_SUSPENDED);
@@ -2298,10 +2353,10 @@ int dquot_enable(struct inode *inode, int type, int format_id,
 		return 0;
 	/* Just updating flags needed? */
 	if (sb_has_quota_loaded(sb, type)) {
-		mutex_lock(&dqopt->dqonoff_mutex);
+		mutex_lock(&qctl->dqonoff_mutex);
 		/* Now do a reliable test... */
 		if (!sb_has_quota_loaded(sb, type)) {
-			mutex_unlock(&dqopt->dqonoff_mutex);
+			mutex_unlock(&qctl->dqonoff_mutex);
 			goto load_quota;
 		}
 		if (flags & DQUOT_USAGE_ENABLED &&
@@ -2315,10 +2370,10 @@ int dquot_enable(struct inode *inode, int type, int format_id,
 			goto out_lock;
 		}
 		spin_lock(&dq_state_lock);
-		dqopts(sb)->flags |= dquot_state_flag(flags, type);
+		qctl->flags |= dquot_state_flag(flags, type);
 		spin_unlock(&dq_state_lock);
 out_lock:
-		mutex_unlock(&dqopt->dqonoff_mutex);
+		mutex_unlock(&qctl->dqonoff_mutex);
 		return ret;
 	}
 
@@ -2527,9 +2582,9 @@ int dquot_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
 {
 	struct mem_dqinfo *mi;
   
-	mutex_lock(&dqopts(sb)->dqonoff_mutex);
+	mutex_lock(&dqctl(sb)->dqonoff_mutex);
 	if (!sb_has_quota_active(sb, type)) {
-		mutex_unlock(&dqopts(sb)->dqonoff_mutex);
+		mutex_unlock(&dqctl(sb)->dqonoff_mutex);
 		return -ESRCH;
 	}
 	mi = dqopts(sb)->info + type;
@@ -2539,7 +2594,7 @@ int dquot_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
 	ii->dqi_flags = mi->dqi_flags & DQF_MASK;
 	ii->dqi_valid = IIF_ALL;
 	spin_unlock(&dq_data_lock);
-	mutex_unlock(&dqopts(sb)->dqonoff_mutex);
+	mutex_unlock(&dqctl(sb)->dqonoff_mutex);
 	return 0;
 }
 EXPORT_SYMBOL(dquot_get_dqinfo);
@@ -2550,7 +2605,7 @@ int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
 	struct mem_dqinfo *mi;
 	int err = 0;
 
-	mutex_lock(&dqopts(sb)->dqonoff_mutex);
+	mutex_lock(&dqctl(sb)->dqonoff_mutex);
 	if (!sb_has_quota_active(sb, type)) {
 		err = -ESRCH;
 		goto out;
@@ -2567,9 +2622,9 @@ int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
 	spin_unlock(&dq_data_lock);
 	mark_info_dirty(sb, type);
 	/* Force write to disk */
-	sb->dq_op->write_info(sb, type);
+	dqctl(sb)->dq_op->write_info(sb, type);
 out:
-	mutex_unlock(&dqopts(sb)->dqonoff_mutex);
+	mutex_unlock(&dqctl(sb)->dqonoff_mutex);
 	return err;
 }
 EXPORT_SYMBOL(dquot_set_dqinfo);
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index 3b1d315..4fc38d0 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -47,8 +47,8 @@ static int check_quotactl_permission(struct super_block *sb, int type, int cmd,
 
 static void quota_sync_one(struct super_block *sb, void *arg)
 {
-	if (sb->s_qcop && sb->s_qcop->quota_sync)
-		sb->s_qcop->quota_sync(sb, *(int *)arg, 1);
+	if (dqctl(sb)->qcop && dqctl(sb)->qcop->quota_sync)
+		dqctl(sb)->qcop->quota_sync(sb, *(int *)arg, 1);
 }
 
 static int quota_sync_all(int type)
@@ -66,22 +66,22 @@ static int quota_sync_all(int type)
 static int quota_quotaon(struct super_block *sb, int type, int cmd, qid_t id,
 		         struct path *path)
 {
-	if (!sb->s_qcop->quota_on && !sb->s_qcop->quota_on_meta)
+	if (!dqctl(sb)->qcop->quota_on && !dqctl(sb)->qcop->quota_on_meta)
 		return -ENOSYS;
-	if (sb->s_qcop->quota_on_meta)
-		return sb->s_qcop->quota_on_meta(sb, type, id);
+	if (dqctl(sb)->qcop->quota_on_meta)
+		return dqctl(sb)->qcop->quota_on_meta(sb, type, id);
 	if (IS_ERR(path))
 		return PTR_ERR(path);
-	return sb->s_qcop->quota_on(sb, type, id, path);
+	return dqctl(sb)->qcop->quota_on(sb, type, id, path);
 }
 
 static int quota_getfmt(struct super_block *sb, int type, void __user *addr)
 {
 	__u32 fmt;
 	int ret;
-	if (!sb->s_qcop->get_fmt)
+	if (!dqctl(sb)->qcop->get_fmt)
 		return -ENOSYS;
-	ret = sb->s_qcop->get_fmt(sb, type, &fmt);
+	ret = dqctl(sb)->qcop->get_fmt(sb, type, &fmt);
 	if (!ret && copy_to_user(addr, &fmt, sizeof(fmt)))
 		return -EFAULT;
 	return ret;
@@ -92,9 +92,9 @@ static int quota_getinfo(struct super_block *sb, int type, void __user *addr)
 	struct if_dqinfo info;
 	int ret;
 
-	if (!sb->s_qcop->get_info)
+	if (!dqctl(sb)->qcop->get_info)
 		return -ENOSYS;
-	ret = sb->s_qcop->get_info(sb, type, &info);
+	ret = dqctl(sb)->qcop->get_info(sb, type, &info);
 	if (!ret && copy_to_user(addr, &info, sizeof(info)))
 		return -EFAULT;
 	return ret;
@@ -106,9 +106,9 @@ static int quota_setinfo(struct super_block *sb, int type, void __user *addr)
 
 	if (copy_from_user(&info, addr, sizeof(info)))
 		return -EFAULT;
-	if (!sb->s_qcop->set_info)
+	if (!dqctl(sb)->qcop->set_info)
 		return -ENOSYS;
-	return sb->s_qcop->set_info(sb, type, &info);
+	return dqctl(sb)->qcop->set_info(sb, type, &info);
 }
 
 static void copy_to_if_dqblk(struct if_dqblk *dst, struct fs_disk_quota *src)
@@ -131,9 +131,9 @@ static int quota_getquota(struct super_block *sb, int type, qid_t id,
 	struct if_dqblk idq;
 	int ret;
 
-	if (!sb->s_qcop->get_dqblk)
+	if (!dqctl(sb)->qcop->get_dqblk)
 		return -ENOSYS;
-	ret = sb->s_qcop->get_dqblk(sb, type, id, &fdq);
+	ret = dqctl(sb)->qcop->get_dqblk(sb, type, id, &fdq);
 	if (ret)
 		return ret;
 	copy_to_if_dqblk(&idq, &fdq);
@@ -176,10 +176,10 @@ static int quota_setquota(struct super_block *sb, int type, qid_t id,
 
 	if (copy_from_user(&idq, addr, sizeof(idq)))
 		return -EFAULT;
-	if (!sb->s_qcop->set_dqblk)
+	if (!dqctl(sb)->qcop->set_dqblk)
 		return -ENOSYS;
 	copy_from_if_dqblk(&fdq, &idq);
-	return sb->s_qcop->set_dqblk(sb, type, id, &fdq);
+	return dqctl(sb)->qcop->set_dqblk(sb, type, id, &fdq);
 }
 
 static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr)
@@ -188,9 +188,9 @@ static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr)
 
 	if (copy_from_user(&flags, addr, sizeof(flags)))
 		return -EFAULT;
-	if (!sb->s_qcop->set_xstate)
+	if (!dqctl(sb)->qcop->set_xstate)
 		return -ENOSYS;
-	return sb->s_qcop->set_xstate(sb, flags, cmd);
+	return dqctl(sb)->qcop->set_xstate(sb, flags, cmd);
 }
 
 static int quota_getxstate(struct super_block *sb, void __user *addr)
@@ -198,9 +198,9 @@ static int quota_getxstate(struct super_block *sb, void __user *addr)
 	struct fs_quota_stat fqs;
 	int ret;
 
-	if (!sb->s_qcop->get_xstate)
+	if (!dqctl(sb)->qcop->get_xstate)
 		return -ENOSYS;
-	ret = sb->s_qcop->get_xstate(sb, &fqs);
+	ret = dqctl(sb)->qcop->get_xstate(sb, &fqs);
 	if (!ret && copy_to_user(addr, &fqs, sizeof(fqs)))
 		return -EFAULT;
 	return ret;
@@ -213,9 +213,9 @@ static int quota_setxquota(struct super_block *sb, int type, qid_t id,
 
 	if (copy_from_user(&fdq, addr, sizeof(fdq)))
 		return -EFAULT;
-	if (!sb->s_qcop->set_dqblk)
+	if (!dqctl(sb)->qcop->set_dqblk)
 		return -ENOSYS;
-	return sb->s_qcop->set_dqblk(sb, type, id, &fdq);
+	return dqctl(sb)->qcop->set_dqblk(sb, type, id, &fdq);
 }
 
 static int quota_getxquota(struct super_block *sb, int type, qid_t id,
@@ -224,9 +224,9 @@ static int quota_getxquota(struct super_block *sb, int type, qid_t id,
 	struct fs_disk_quota fdq;
 	int ret;
 
-	if (!sb->s_qcop->get_dqblk)
+	if (!dqctl(sb)->qcop->get_dqblk)
 		return -ENOSYS;
-	ret = sb->s_qcop->get_dqblk(sb, type, id, &fdq);
+	ret = dqctl(sb)->qcop->get_dqblk(sb, type, id, &fdq);
 	if (!ret && copy_to_user(addr, &fdq, sizeof(fdq)))
 		return -EFAULT;
 	return ret;
@@ -240,7 +240,7 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
 
 	if (type >= (XQM_COMMAND(cmd) ? XQM_MAXQUOTAS : MAXQUOTAS))
 		return -EINVAL;
-	if (!sb->s_qcop)
+	if (!dqctl(sb)->qcop)
 		return -ENOSYS;
 
 	ret = check_quotactl_permission(sb, type, cmd, id);
@@ -251,9 +251,9 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
 	case Q_QUOTAON:
 		return quota_quotaon(sb, type, cmd, id, path);
 	case Q_QUOTAOFF:
-		if (!sb->s_qcop->quota_off)
+		if (!dqctl(sb)->qcop->quota_off)
 			return -ENOSYS;
-		return sb->s_qcop->quota_off(sb, type);
+		return dqctl(sb)->qcop->quota_off(sb, type);
 	case Q_GETFMT:
 		return quota_getfmt(sb, type, addr);
 	case Q_GETINFO:
@@ -265,9 +265,9 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
 	case Q_SETQUOTA:
 		return quota_setquota(sb, type, id, addr);
 	case Q_SYNC:
-		if (!sb->s_qcop->quota_sync)
+		if (!dqctl(sb)->qcop->quota_sync)
 			return -ENOSYS;
-		return sb->s_qcop->quota_sync(sb, type, 1);
+		return dqctl(sb)->qcop->quota_sync(sb, type, 1);
 	case Q_XQUOTAON:
 	case Q_XQUOTAOFF:
 	case Q_XQUOTARM:
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index a07f30a..1fbd0d9 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -1408,8 +1408,8 @@ static int read_super_block(struct super_block *s, int offset)
 	s->s_op = &reiserfs_sops;
 	s->s_export_op = &reiserfs_export_ops;
 #ifdef CONFIG_QUOTA
-	s->s_qcop = &reiserfs_qctl_operations;
-	s->dq_op = &reiserfs_quota_operations;
+	dqctl(s)->qcop = &reiserfs_qctl_operations;
+	dqctl(s)->dq_op = &reiserfs_quota_operations;
 #endif
 
 	/* new format is limited by the 32 bit wide i_blocks field, want to
diff --git a/fs/super.c b/fs/super.c
index 473bdf6..60edc1f 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -54,16 +54,9 @@ static struct super_block *alloc_super(struct file_system_type *type)
 			s = NULL;
 			goto out;
 		}
-		if (init_srcu_struct(&s->s_dquot.dq_srcu)) {
-			security_sb_free(s);
-			kfree(s);
-			s = NULL;
-			goto out;
-		}
 #ifdef CONFIG_SMP
 		s->s_files = alloc_percpu(struct list_head);
 		if (!s->s_files) {
-			cleanup_srcu_struct(&s->s_dquot.dq_srcu);
 			security_sb_free(s);
 			kfree(s);
 			s = NULL;
@@ -110,9 +103,7 @@ static struct super_block *alloc_super(struct file_system_type *type)
 		atomic_set(&s->s_active, 1);
 		mutex_init(&s->s_vfs_rename_mutex);
 		lockdep_set_class(&s->s_vfs_rename_mutex, &type->s_vfs_rename_key);
-		mutex_init(&s->s_dquot.dqio_mutex);
 		mutex_init(&s->s_dquot.dqonoff_mutex);
-		init_rwsem(&s->s_dquot.dqptr_sem);
 
 		init_waitqueue_head(&s->s_wait_unfrozen);
 		s->s_maxbytes = MAX_NON_LFS;
@@ -134,7 +125,6 @@ static inline void destroy_super(struct super_block *s)
 #ifdef CONFIG_SMP
 	free_percpu(s->s_files);
 #endif
-	cleanup_srcu_struct(&s->s_dquot.dq_srcu);
 	security_sb_free(s);
 	kfree(s->s_subtype);
 	kfree(s->s_options);
diff --git a/fs/sync.c b/fs/sync.c
index ba76b96..891e8ef 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -36,8 +36,8 @@ static int __sync_filesystem(struct super_block *sb, int wait)
 	if (!sb->s_bdi || sb->s_bdi == &noop_backing_dev_info)
 		return 0;
 
-	if (sb->s_qcop && sb->s_qcop->quota_sync)
-		sb->s_qcop->quota_sync(sb, -1, wait);
+	if (sb->s_dquot.qcop && sb->s_dquot.qcop->quota_sync)
+		sb->s_dquot.qcop->quota_sync(sb, -1, wait);
 
 	if (wait)
 		sync_inodes_sb(sb);
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index a4e0797..4e59a08 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -1510,7 +1510,7 @@ xfs_fs_fill_super(
 	sb->s_xattr = xfs_xattr_handlers;
 	sb->s_export_op = &xfs_export_operations;
 #ifdef CONFIG_XFS_QUOTA
-	sb->s_qcop = &xfs_quotactl_operations;
+	sb->s_dquot.qcop = &xfs_quotactl_operations;
 #endif
 	sb->s_op = &xfs_super_operations;
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 63d069b..e87694a 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1324,8 +1324,6 @@ struct super_block {
 	loff_t			s_maxbytes;	/* Max file size */
 	struct file_system_type	*s_type;
 	const struct super_operations	*s_op;
-	const struct dquot_operations	*dq_op;
-	const struct quotactl_ops	*s_qcop;
 	const struct export_operations *s_export_op;
 	unsigned long		s_flags;
 	unsigned long		s_magic;
@@ -1354,7 +1352,7 @@ struct super_block {
 	struct backing_dev_info *s_bdi;
 	struct mtd_info		*s_mtd;
 	struct list_head	s_instances;
-	struct quota_info	s_dquot;	/* Diskquota specific options */
+	struct quota_ctl_info	s_dquot;	/* Diskquota specific options */
 
 	int			s_frozen;
 	wait_queue_head_t	s_wait_unfrozen;
diff --git a/include/linux/quota.h b/include/linux/quota.h
index 7e859eb..7170730 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -325,7 +325,7 @@ struct dquot_operations {
 };
 
 struct path;
-
+struct quota_info;
 /* Operations handling requests from userspace */
 struct quotactl_ops {
 	int (*quota_on)(struct super_block *, int, int, struct path *);
@@ -394,16 +394,23 @@ static inline void quota_send_warning(short type, unsigned int id, dev_t dev,
 	return;
 }
 #endif /* CONFIG_QUOTA_NETLINK_INTERFACE */
+struct quota_ctl_info {
+	unsigned int flags;			/* Flags for diskquotas on this device */
+
+	struct mutex dqonoff_mutex;		/* Serialize quotaon & quotaoff */
+	const struct quotactl_ops *qcop;
+	const struct dquot_operations *dq_op;
+	struct quota_info *dq_opt;
+};
 
 struct quota_info {
-	unsigned int flags;			/* Flags for diskquotas on this device */
 	struct mutex dqio_mutex;		/* lock device while I/O in progress */
-	struct mutex dqonoff_mutex;		/* Serialize quotaon & quotaoff */
-	struct rw_semaphore dqptr_sem;		/* serialize ops using quota_info struct, pointers from inode to dquots */
-	struct inode *files[MAXQUOTAS];		/* inodes of quotafiles */
 	struct mem_dqinfo info[MAXQUOTAS];	/* Information for each quota type */
-	const struct quota_format_ops *ops[MAXQUOTAS];	/* Operations for each type */
-	struct srcu_struct dq_srcu;
+	struct inode *files[MAXQUOTAS];	/* inodes of quotafiles */
+	const struct quota_format_ops *fmt_ops[MAXQUOTAS];	/* Operations for each type */
+	struct srcu_struct dq_srcu;	/* use count read lock */
+	struct rw_semaphore dqptr_sem;	/* serialize ops using quota_info struct, pointers from inode to dquots */
+
 };
 
 int register_quota_format(struct quota_format_type *fmt);
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index 9750d86..68ceef5 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -13,15 +13,20 @@
 #define DQUOT_SPACE_RESERVE	0x2
 #define DQUOT_SPACE_NOFAIL	0x4
 
-static inline struct quota_info *dqopts(struct super_block *sb)
+static inline struct quota_ctl_info* dqctl( struct super_block *sb)
 {
 	return &sb->s_dquot;
 }
-static inline struct quota_info* sb_dqopts(struct dquot *dq)
+static inline struct quota_info *dqopts(const struct super_block *sb)
+{
+	return sb->s_dquot.dq_opt;
+}
+static inline struct quota_info* sb_dqopts(const struct dquot *dq)
 {
 	return dqopts(dq->dq_sb);
 }
 
+
 /* i_mutex must being held */
 static inline bool is_quota_modification(struct inode *inode, struct iattr *ia)
 {
@@ -109,19 +114,19 @@ static inline struct mem_dqinfo *sb_dqinfo(struct super_block *sb, int type)
 
 static inline bool sb_has_quota_usage_enabled(struct super_block *sb, int type)
 {
-	return dqopts(sb)->flags &
+	return dqctl(sb)->flags &
 				dquot_state_flag(DQUOT_USAGE_ENABLED, type);
 }
 
 static inline bool sb_has_quota_limits_enabled(struct super_block *sb, int type)
 {
-	return dqopts(sb)->flags &
+	return dqctl(sb)->flags &
 				dquot_state_flag(DQUOT_LIMITS_ENABLED, type);
 }
 
 static inline bool sb_has_quota_suspended(struct super_block *sb, int type)
 {
-	return dqopts(sb)->flags &
+	return dqctl(sb)->flags &
 				dquot_state_flag(DQUOT_SUSPENDED, type);
 }
 
-- 
1.6.5.2

--
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


[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux