dqptr_sem hasn't any thing in common with quota files, quota file load protected with dqonoff_mutex, so we have to use it for reading fmt info. Signed-off-by: Dmitry Monakhov <dmonakhov@xxxxxxxxxx> --- fs/ext3/super.c | 1 + fs/ext4/super.c | 1 + fs/ocfs2/super.c | 1 + fs/quota/dquot.c | 14 ++++++++++++++ fs/quota/quota.c | 16 ++++++---------- fs/reiserfs/super.c | 1 + include/linux/quota.h | 1 + include/linux/quotaops.h | 1 + 8 files changed, 26 insertions(+), 10 deletions(-) diff --git a/fs/ext3/super.c b/fs/ext3/super.c index e9fd676..e0f68f0 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -773,6 +773,7 @@ static const struct quotactl_ops ext3_qctl_operations = { .quota_sync = dquot_quota_sync, .get_info = dquot_get_dqinfo, .set_info = dquot_set_dqinfo, + .get_fmt = dquot_get_dqfmt, .get_dqblk = dquot_get_dqblk, .set_dqblk = dquot_set_dqblk }; diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 4062fbe..a2e68f9 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1150,6 +1150,7 @@ static const struct quotactl_ops ext4_qctl_operations = { .quota_sync = dquot_quota_sync, .get_info = dquot_get_dqinfo, .set_info = dquot_set_dqinfo, + .get_fmt = dquot_get_dqfmt, .get_dqblk = dquot_get_dqblk, .set_dqblk = dquot_set_dqblk }; diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 26bd015..8e6a20c 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -986,6 +986,7 @@ static const struct quotactl_ops ocfs2_quotactl_ops = { .quota_sync = dquot_quota_sync, .get_info = dquot_get_dqinfo, .set_info = dquot_set_dqinfo, + .get_fmt = dquot_get_dqfmt, .get_dqblk = dquot_get_dqblk, .set_dqblk = dquot_set_dqblk, }; diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 06157aa..d1d1c51 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -1890,6 +1890,19 @@ int dquot_file_open(struct inode *inode, struct file *file) } EXPORT_SYMBOL(dquot_file_open); +int dquot_get_dqfmt(struct super_block *sb, int type, unsigned int *fmt) +{ + mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); + if (!sb_has_quota_active(sb, type)) { + mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); + return -ESRCH; + } + *fmt = sb_dqopt(sb)->info[type].dqi_format->qf_fmt_id; + mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); + return 0; +} +EXPORT_SYMBOL(dquot_get_dqfmt); + /* * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount) */ @@ -2502,6 +2515,7 @@ const struct quotactl_ops dquot_quotactl_ops = { .quota_sync = dquot_quota_sync, .get_info = dquot_get_dqinfo, .set_info = dquot_set_dqinfo, + .get_fmt = dquot_get_dqfmt, .get_dqblk = dquot_get_dqblk, .set_dqblk = dquot_set_dqblk }; diff --git a/fs/quota/quota.c b/fs/quota/quota.c index b34bdb2..3b1d315 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c @@ -78,17 +78,13 @@ static int quota_quotaon(struct super_block *sb, int type, int cmd, qid_t id, static int quota_getfmt(struct super_block *sb, int type, void __user *addr) { __u32 fmt; - - down_read(&sb_dqopt(sb)->dqptr_sem); - if (!sb_has_quota_active(sb, type)) { - up_read(&sb_dqopt(sb)->dqptr_sem); - return -ESRCH; - } - fmt = sb_dqopt(sb)->info[type].dqi_format->qf_fmt_id; - up_read(&sb_dqopt(sb)->dqptr_sem); - if (copy_to_user(addr, &fmt, sizeof(fmt))) + int ret; + if (!sb->s_qcop->get_fmt) + return -ENOSYS; + ret = sb->s_qcop->get_fmt(sb, type, &fmt); + if (!ret && copy_to_user(addr, &fmt, sizeof(fmt))) return -EFAULT; - return 0; + return ret; } static int quota_getinfo(struct super_block *sb, int type, void __user *addr) diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 73c000f..d4d32df 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -644,6 +644,7 @@ static const struct quotactl_ops reiserfs_qctl_operations = { .quota_sync = dquot_quota_sync, .get_info = dquot_get_dqinfo, .set_info = dquot_set_dqinfo, + .get_fmt = dquot_get_dqfmt, .get_dqblk = dquot_get_dqblk, .set_dqblk = dquot_set_dqblk, }; diff --git a/include/linux/quota.h b/include/linux/quota.h index 9a85412..2767e4c 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h @@ -331,6 +331,7 @@ struct quotactl_ops { int (*quota_off)(struct super_block *, int); int (*quota_sync)(struct super_block *, int, int); int (*get_info)(struct super_block *, int, struct if_dqinfo *); + int (*get_fmt)(struct super_block*, int, unsigned int*); int (*set_info)(struct super_block *, int, struct if_dqinfo *); int (*get_dqblk)(struct super_block *, int, qid_t, struct fs_disk_quota *); int (*set_dqblk)(struct super_block *, int, qid_t, struct fs_disk_quota *); diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index 9e09c9a..45ae255 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -85,6 +85,7 @@ int dquot_quota_off(struct super_block *sb, int type); int dquot_quota_sync(struct super_block *sb, int type, int wait); int dquot_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); +int dquot_get_dqfmt(struct super_block *sb, int type, unsigned int *fmt); int dquot_get_dqblk(struct super_block *sb, int type, qid_t id, struct fs_disk_quota *di); int dquot_set_dqblk(struct super_block *sb, int type, qid_t id, -- 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