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