quota: Add support for ->get_nextdqblk() for VFS quota
authorJan Kara <jack@suse.cz>
Mon, 25 Jan 2016 18:24:50 +0000 (19:24 +0100)
committerJan Kara <jack@suse.cz>
Tue, 9 Feb 2016 12:05:23 +0000 (13:05 +0100)
Add infrastructure for supporting get_nextdqblk() callback for VFS
quotas. Translate the operation into a callback to appropriate
filesystem and consequently to quota format callback.

Signed-off-by: Jan Kara <jack@suse.cz>
fs/ext4/super.c
fs/quota/dquot.c
fs/reiserfs/super.c
include/linux/quota.h
include/linux/quotaops.h

index 3ed01ec011d75067579a4b894b4b0623af265a2d..b5bcbddceb91c981a43cb5ae66802d1e35eca5a1 100644 (file)
@@ -1132,6 +1132,7 @@ static const struct dquot_operations ext4_quota_operations = {
        .alloc_dquot    = dquot_alloc,
        .destroy_dquot  = dquot_destroy,
        .get_projid     = ext4_get_projid,
+       .get_next_id    = dquot_get_next_id,
 };
 
 static const struct quotactl_ops ext4_qctl_operations = {
index 3c3b81bb6dfebbd3d6c3f1f8f1252e46308bf9c9..7e0137bde6d6f23ed44d3ab82c9d32b6aecc8cc3 100644 (file)
@@ -2031,6 +2031,21 @@ int dquot_commit_info(struct super_block *sb, int type)
 }
 EXPORT_SYMBOL(dquot_commit_info);
 
+int dquot_get_next_id(struct super_block *sb, struct kqid *qid)
+{
+       struct quota_info *dqopt = sb_dqopt(sb);
+       int err;
+
+       if (!dqopt->ops[qid->type]->get_next_id)
+               return -ENOSYS;
+       mutex_lock(&dqopt->dqio_mutex);
+       err = dqopt->ops[qid->type]->get_next_id(sb, qid);
+       mutex_unlock(&dqopt->dqio_mutex);
+
+       return err;
+}
+EXPORT_SYMBOL(dquot_get_next_id);
+
 /*
  * Definitions of diskquota operations.
  */
@@ -2042,6 +2057,7 @@ const struct dquot_operations dquot_operations = {
        .write_info     = dquot_commit_info,
        .alloc_dquot    = dquot_alloc,
        .destroy_dquot  = dquot_destroy,
+       .get_next_id    = dquot_get_next_id,
 };
 EXPORT_SYMBOL(dquot_operations);
 
@@ -2565,6 +2581,27 @@ int dquot_get_dqblk(struct super_block *sb, struct kqid qid,
 }
 EXPORT_SYMBOL(dquot_get_dqblk);
 
+int dquot_get_next_dqblk(struct super_block *sb, struct kqid *qid,
+                        struct qc_dqblk *di)
+{
+       struct dquot *dquot;
+       int err;
+
+       if (!sb->dq_op->get_next_id)
+               return -ENOSYS;
+       err = sb->dq_op->get_next_id(sb, qid);
+       if (err < 0)
+               return err;
+       dquot = dqget(sb, *qid);
+       if (IS_ERR(dquot))
+               return PTR_ERR(dquot);
+       do_get_dqblk(dquot, di);
+       dqput(dquot);
+
+       return 0;
+}
+EXPORT_SYMBOL(dquot_get_next_dqblk);
+
 #define VFS_QC_MASK \
        (QC_SPACE | QC_SPC_SOFT | QC_SPC_HARD | \
         QC_INO_COUNT | QC_INO_SOFT | QC_INO_HARD | \
@@ -2765,6 +2802,7 @@ const struct quotactl_ops dquot_quotactl_ops = {
        .get_state      = dquot_get_state,
        .set_info       = dquot_set_dqinfo,
        .get_dqblk      = dquot_get_dqblk,
+       .get_nextdqblk  = dquot_get_next_dqblk,
        .set_dqblk      = dquot_set_dqblk
 };
 EXPORT_SYMBOL(dquot_quotactl_ops);
@@ -2776,6 +2814,7 @@ const struct quotactl_ops dquot_quotactl_sysfile_ops = {
        .get_state      = dquot_get_state,
        .set_info       = dquot_set_dqinfo,
        .get_dqblk      = dquot_get_dqblk,
+       .get_nextdqblk  = dquot_get_next_dqblk,
        .set_dqblk      = dquot_set_dqblk
 };
 EXPORT_SYMBOL(dquot_quotactl_sysfile_ops);
index c0306ec8ed7b8f5d4eef97fd1cf4c7653c2b1f20..b8f2d1e8c6453c373655be98c03c1118acd71f2c 100644 (file)
@@ -802,6 +802,7 @@ static const struct dquot_operations reiserfs_quota_operations = {
        .write_info = reiserfs_write_info,
        .alloc_dquot    = dquot_alloc,
        .destroy_dquot  = dquot_destroy,
+       .get_next_id    = dquot_get_next_id,
 };
 
 static const struct quotactl_ops reiserfs_qctl_operations = {
index fba92f5c1a631a7c43552a357a51d8d3eb896a01..9dfb6bce8c9eb08f0c45a8d1b76f86b0b489b30e 100644 (file)
@@ -306,6 +306,7 @@ struct quota_format_ops {
        int (*read_dqblk)(struct dquot *dquot);         /* Read structure for one user */
        int (*commit_dqblk)(struct dquot *dquot);       /* Write structure for one user */
        int (*release_dqblk)(struct dquot *dquot);      /* Called when last reference to dquot is being dropped */
+       int (*get_next_id)(struct super_block *sb, struct kqid *qid);   /* Get next ID with existing structure in the quota file */
 };
 
 /* Operations working with dquots */
@@ -321,6 +322,8 @@ struct dquot_operations {
         * quota code only */
        qsize_t *(*get_reserved_space) (struct inode *);
        int (*get_projid) (struct inode *, kprojid_t *);/* Get project ID */
+       /* Get next ID with active quota structure */
+       int (*get_next_id) (struct super_block *sb, struct kqid *qid);
 };
 
 struct path;
index 7a57c28eb5e708d0346760818533d7b6f8665096..f00fa86ac9660ad79e243f9c9e590bf854dcb48d 100644 (file)
@@ -82,6 +82,7 @@ int dquot_commit(struct dquot *dquot);
 int dquot_acquire(struct dquot *dquot);
 int dquot_release(struct dquot *dquot);
 int dquot_commit_info(struct super_block *sb, int type);
+int dquot_get_next_id(struct super_block *sb, struct kqid *qid);
 int dquot_mark_dquot_dirty(struct dquot *dquot);
 
 int dquot_file_open(struct inode *inode, struct file *file);
@@ -99,6 +100,8 @@ int dquot_get_state(struct super_block *sb, struct qc_state *state);
 int dquot_set_dqinfo(struct super_block *sb, int type, struct qc_info *ii);
 int dquot_get_dqblk(struct super_block *sb, struct kqid id,
                struct qc_dqblk *di);
+int dquot_get_next_dqblk(struct super_block *sb, struct kqid *id,
+               struct qc_dqblk *di);
 int dquot_set_dqblk(struct super_block *sb, struct kqid id,
                struct qc_dqblk *di);