During some quota oparations we have to determine quota_id for given inode according to quota_type. But only USRQUOTA/GRPQUOTA id are intermediately accessible from generic vfs-inode. This patch introduce new per_sb quota operation for this purpose. Signed-off-by: Dmitry Monakhov <dmonakhov@xxxxxxxxxx> --- fs/ext3/super.c | 1 + fs/ext4/super.c | 1 + fs/ocfs2/quota_global.c | 1 + fs/quota/dquot.c | 39 +++++++++++++++++++++++++++++---------- fs/reiserfs/super.c | 1 + include/linux/quota.h | 1 + include/linux/quotaops.h | 1 + 7 files changed, 35 insertions(+), 10 deletions(-) diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 241c520..82bf9c8 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -757,6 +757,7 @@ static const struct dquot_operations ext3_quota_operations = { .free_space = dquot_free_space, .free_inode = dquot_free_inode, .transfer = dquot_transfer, + .get_id = dquot_get_id, .write_dquot = ext3_write_dquot, .acquire_dquot = ext3_acquire_dquot, .release_dquot = ext3_release_dquot, diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 735c20d..cd0dffa 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1025,6 +1025,7 @@ static const struct dquot_operations ext4_quota_operations = { .free_space = dquot_free_space, .free_inode = dquot_free_inode, .transfer = dquot_transfer, + .get_id = dquot_get_id, .write_dquot = ext4_write_dquot, .acquire_dquot = ext4_acquire_dquot, .release_dquot = ext4_release_dquot, diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c index b437dc0..1ede78f 100644 --- a/fs/ocfs2/quota_global.c +++ b/fs/ocfs2/quota_global.c @@ -858,6 +858,7 @@ const struct dquot_operations ocfs2_quota_operations = { .free_space = dquot_free_space, .free_inode = dquot_free_inode, .transfer = dquot_transfer, + .get_id = dquot_get_id, .write_dquot = ocfs2_write_dquot, .acquire_dquot = ocfs2_acquire_dquot, .release_dquot = ocfs2_release_dquot, diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 6768584..22bf600 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -298,6 +298,26 @@ static inline void remove_inuse(struct dquot *dquot) dqstats.allocated_dquots--; list_del(&dquot->dq_inuse); } + +qid_t dquot_get_id(struct inode *inode, int type, qid_t *new) +{ + switch (type) { + case USRQUOTA: + if (new) + return new[USRQUOTA]; + else + return inode->i_uid; + case GRPQUOTA: + if (new) + return new[GRPQUOTA]; + else + return inode->i_gid; + default: + BUG(); + } +} +EXPORT_SYMBOL(dquot_get_id); + /* * End of list functions needing dq_list_lock */ @@ -1288,14 +1308,9 @@ int dquot_initialize(struct inode *inode, int type) got[cnt] = NULL; if (type != -1 && cnt != type) continue; - switch (cnt) { - case USRQUOTA: - id = inode->i_uid; - break; - case GRPQUOTA: - id = inode->i_gid; - break; - } + if (!sb_has_quota_active(sb, cnt)) + continue; + id = inode->i_sb->dq_op->get_id(inode, cnt, NULL); got[cnt] = dqget(sb, id, cnt); } @@ -1677,6 +1692,7 @@ int dquot_transfer(struct inode *inode, qid_t *chid, unsigned long mask) int cnt, ret = QUOTA_OK; char warntype_to[MAXQUOTAS]; char warntype_from_inodes[MAXQUOTAS], warntype_from_space[MAXQUOTAS]; + qid_t id; /* First test before acquiring mutex - solves deadlocks when we * re-enter the quota code and are already holding the mutex */ @@ -1689,8 +1705,10 @@ int dquot_transfer(struct inode *inode, qid_t *chid, unsigned long mask) warntype_to[cnt] = QUOTA_NL_NOWARN; } for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (mask & (1 << cnt)) - transfer_to[cnt] = dqget(inode->i_sb, chid[cnt], cnt); + if (mask & (1 << cnt)) { + id = inode->i_sb->dq_op->get_id(inode, cnt, chid); + transfer_to[cnt] = dqget(inode->i_sb, id, cnt); + } } down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); if (IS_NOQUOTA(inode)) { /* File without quota accounting? */ @@ -1818,6 +1836,7 @@ const struct dquot_operations dquot_operations = { .free_space = dquot_free_space, .free_inode = dquot_free_inode, .transfer = dquot_transfer, + .get_id = dquot_get_id, .write_dquot = dquot_commit, .acquire_dquot = dquot_acquire, .release_dquot = dquot_release, diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index b4a7dd0..897f2bc 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -623,6 +623,7 @@ static const struct dquot_operations reiserfs_quota_operations = { .free_space = dquot_free_space, .free_inode = dquot_free_inode, .transfer = dquot_transfer, + .get_id = dquot_get_id, .write_dquot = reiserfs_write_dquot, .acquire_dquot = reiserfs_acquire_dquot, .release_dquot = reiserfs_release_dquot, diff --git a/include/linux/quota.h b/include/linux/quota.h index 74738e9..abf6a5a 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h @@ -303,6 +303,7 @@ struct dquot_operations { int (*free_inode) (const struct inode *, qsize_t); int (*transfer) (struct inode *, qid_t *, unsigned long); int (*write_dquot) (struct dquot *); /* Ordinary dquot write */ + qid_t (*get_id)(struct inode *, int, qid_t *new); /* Quota id for given type */ struct dquot *(*alloc_dquot)(struct super_block *, int); /* Allocate memory for new dquot */ void (*destroy_dquot)(struct dquot *); /* Free memory for dquot */ int (*acquire_dquot) (struct dquot *); /* Quota is going to be created on disk */ diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index d045a07..e4c6d6e 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -30,6 +30,7 @@ void inode_add_rsv_space(struct inode *inode, qsize_t number); void inode_claim_rsv_space(struct inode *inode, qsize_t number); void inode_sub_rsv_space(struct inode *inode, qsize_t number); +qid_t dquot_get_id(struct inode *inode, int type, qid_t *new); int dquot_initialize(struct inode *inode, int type); int dquot_drop(struct inode *inode); struct dquot *dqget(struct super_block *sb, unsigned int id, int type); -- 1.6.6 -- 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