[1/3] quota: Add support for ->get_nextdqblk() for VFS quota
diff mbox

Message ID 1454596087-6814-2-git-send-email-jack@suse.cz
State New
Headers show

Commit Message

Jan Kara Feb. 4, 2016, 2:28 p.m. UTC
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          |  1 +
 fs/quota/dquot.c         | 39 +++++++++++++++++++++++++++++++++++++++
 fs/reiserfs/super.c      |  1 +
 include/linux/quota.h    |  3 +++
 include/linux/quotaops.h |  3 +++
 5 files changed, 47 insertions(+)

Comments

Dave Chinner Feb. 5, 2016, 1:05 a.m. UTC | #1
On Thu, Feb 04, 2016 at 03:28:05PM +0100, Jan Kara wrote:
> 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>

I'm a little confused here. What patchset is this dependent on? i.e.
what introduces the ->get_nextdqblk method?

The patches I currently have in my XFS working tree introduce this
(quota: add new quotactl Q_XGETNEXTQUOTA) and everythign else is
dependent on this. I looked a coupl eof days ago and I wasnt' able
to find this in your tree.

I'd much prefer that one of us publish a stable branch with just the
quotactl() infrastructure (i.e. commands and bits up to the
->get_nextdqblk() callback) that we can then both base the different
subsystem implementations off, rather than one of us having to pull
in a whole tree of changes just to get the one commit we need...

Cheers,

Dave.
Dave Chinner Feb. 8, 2016, 6:15 a.m. UTC | #2
On Fri, Feb 05, 2016 at 12:05:19PM +1100, Dave Chinner wrote:
> On Thu, Feb 04, 2016 at 03:28:05PM +0100, Jan Kara wrote:
> > 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>
> 
> I'm a little confused here. What patchset is this dependent on? i.e.
> what introduces the ->get_nextdqblk method?
> 
> The patches I currently have in my XFS working tree introduce this
> (quota: add new quotactl Q_XGETNEXTQUOTA) and everythign else is
> dependent on this. I looked a coupl eof days ago and I wasnt' able
> to find this in your tree.
> 
> I'd much prefer that one of us publish a stable branch with just the
> quotactl() infrastructure (i.e. commands and bits up to the
> ->get_nextdqblk() callback) that we can then both base the different
> subsystem implementations off, rather than one of us having to pull
> in a whole tree of changes just to get the one commit we need...

Jan, I've posted a stable branch with the quotactl() changes and
the XFS implementation here:

git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs.git xfs-get-next-dquot-4.6

It's currently in the xfs for-next branch for wider testing - I've
done this because I want to get all the pending XFS code out into
for-next land early in this cycle so I can move on and concentrate
on rmap/reflink for the rest of the cycle.

If you want to do this through your tree instead of the XFS tree
then let me know when you publish a branch with quotactl changes in
it so I can rebuild the XFS for-next branch to use that.
Alternatively, i can pull the rest of the generic changes in this
patch set into the branch I already have, so it's all in one place
for ease of testing....

Cheeers,

Dave.
Jan Kara Feb. 8, 2016, 2:27 p.m. UTC | #3
On Fri 05-02-16 12:05:19, Dave Chinner wrote:
> On Thu, Feb 04, 2016 at 03:28:05PM +0100, Jan Kara wrote:
> > 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>
> 
> I'm a little confused here. What patchset is this dependent on? i.e.
> what introduces the ->get_nextdqblk method?

It depends on the patches Eric sent which introduce ->get_nextdqblk.

> The patches I currently have in my XFS working tree introduce this
> (quota: add new quotactl Q_XGETNEXTQUOTA) and everythign else is
> dependent on this. I looked a coupl eof days ago and I wasnt' able
> to find this in your tree.

Yeah, I have this patch as well, I just didn't push out.

> I'd much prefer that one of us publish a stable branch with just the
> quotactl() infrastructure (i.e. commands and bits up to the
> ->get_nextdqblk() callback) that we can then both base the different
> subsystem implementations off, rather than one of us having to pull
> in a whole tree of changes just to get the one commit we need...

Sure, I have pushed out:

'getnextquota' branch into my tree

git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs.git 

which contains the patches from Eric I carry (including fixups in comments
other minor stuff I have found during final review). Can you please base
XFS patches on top of this branch? Thanks!

								Honza
Jan Kara Feb. 8, 2016, 2:34 p.m. UTC | #4
On Mon 08-02-16 15:27:49, Jan Kara wrote:
> On Fri 05-02-16 12:05:19, Dave Chinner wrote:
> > On Thu, Feb 04, 2016 at 03:28:05PM +0100, Jan Kara wrote:
> > > 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>
> > 
> > I'm a little confused here. What patchset is this dependent on? i.e.
> > what introduces the ->get_nextdqblk method?
> 
> It depends on the patches Eric sent which introduce ->get_nextdqblk.
> 
> > The patches I currently have in my XFS working tree introduce this
> > (quota: add new quotactl Q_XGETNEXTQUOTA) and everythign else is
> > dependent on this. I looked a coupl eof days ago and I wasnt' able
> > to find this in your tree.
> 
> Yeah, I have this patch as well, I just didn't push out.
> 
> > I'd much prefer that one of us publish a stable branch with just the
> > quotactl() infrastructure (i.e. commands and bits up to the
> > ->get_nextdqblk() callback) that we can then both base the different
> > subsystem implementations off, rather than one of us having to pull
> > in a whole tree of changes just to get the one commit we need...
> 
> Sure, I have pushed out:
> 
> 'getnextquota' branch into my tree
> 
> git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs.git 
> 
> which contains the patches from Eric I carry (including fixups in comments
> other minor stuff I have found during final review). Can you please base
> XFS patches on top of this branch? Thanks!

Ah, now I saw your next email and you already created the stable branch.
OK, since I didn't push out anything yet, I will base my branches on top of
yours. I have made some small fixups in the comments but I can push these
as a separate patch.

								Honza
Eric Sandeen Feb. 19, 2016, 5:31 p.m. UTC | #5
On 2/4/16 8:28 AM, Jan Kara wrote:
> 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          |  1 +
>  fs/quota/dquot.c         | 39 +++++++++++++++++++++++++++++++++++++++
>  fs/reiserfs/super.c      |  1 +
>  include/linux/quota.h    |  3 +++
>  include/linux/quotaops.h |  3 +++
>  5 files changed, 47 insertions(+)
> 
> diff --git a/fs/ext4/super.c b/fs/ext4/super.c
> index f1b56ff01208..51649f442bf6 100644
> --- a/fs/ext4/super.c
> +++ b/fs/ext4/super.c
> @@ -1100,6 +1100,7 @@ static const struct dquot_operations ext4_quota_operations = {
>  	.write_info	= ext4_write_info,
>  	.alloc_dquot	= dquot_alloc,
>  	.destroy_dquot	= dquot_destroy,
> +	.get_next_id	= dquot_get_next_id,
>  };

Hi Jan, doesn't this also need to set:


+       .get_nextdqblk  = dquot_get_next_dqblk,

in ext4_qctl_sysfile_operations?

Thanks,
-Eric
Jan Kara Feb. 19, 2016, 6:33 p.m. UTC | #6
On Fri 19-02-16 11:31:58, Eric Sandeen wrote:
> 
> 
> On 2/4/16 8:28 AM, Jan Kara wrote:
> > 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          |  1 +
> >  fs/quota/dquot.c         | 39 +++++++++++++++++++++++++++++++++++++++
> >  fs/reiserfs/super.c      |  1 +
> >  include/linux/quota.h    |  3 +++
> >  include/linux/quotaops.h |  3 +++
> >  5 files changed, 47 insertions(+)
> > 
> > diff --git a/fs/ext4/super.c b/fs/ext4/super.c
> > index f1b56ff01208..51649f442bf6 100644
> > --- a/fs/ext4/super.c
> > +++ b/fs/ext4/super.c
> > @@ -1100,6 +1100,7 @@ static const struct dquot_operations ext4_quota_operations = {
> >  	.write_info	= ext4_write_info,
> >  	.alloc_dquot	= dquot_alloc,
> >  	.destroy_dquot	= dquot_destroy,
> > +	.get_next_id	= dquot_get_next_id,
> >  };
> 
> Hi Jan, doesn't this also need to set:
> 
> 
> +       .get_nextdqblk  = dquot_get_next_dqblk,
> 
> in ext4_qctl_sysfile_operations?

Indeed, thanks for catching this. Patch added (with your authorship and
sign-off) into my tree and this time I've properly tested Q_GETNEXTQUOTA
for ext4 with quota in hidden inodes indeed works (previously I've tested
only visible quota files).

								Honza
Eric Sandeen Feb. 19, 2016, 6:43 p.m. UTC | #7
On 2/19/16 12:33 PM, Jan Kara wrote:
> On Fri 19-02-16 11:31:58, Eric Sandeen wrote:
>>
>>
>> On 2/4/16 8:28 AM, Jan Kara wrote:
>>> 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          |  1 +
>>>  fs/quota/dquot.c         | 39 +++++++++++++++++++++++++++++++++++++++
>>>  fs/reiserfs/super.c      |  1 +
>>>  include/linux/quota.h    |  3 +++
>>>  include/linux/quotaops.h |  3 +++
>>>  5 files changed, 47 insertions(+)
>>>
>>> diff --git a/fs/ext4/super.c b/fs/ext4/super.c
>>> index f1b56ff01208..51649f442bf6 100644
>>> --- a/fs/ext4/super.c
>>> +++ b/fs/ext4/super.c
>>> @@ -1100,6 +1100,7 @@ static const struct dquot_operations ext4_quota_operations = {
>>>  	.write_info	= ext4_write_info,
>>>  	.alloc_dquot	= dquot_alloc,
>>>  	.destroy_dquot	= dquot_destroy,
>>> +	.get_next_id	= dquot_get_next_id,
>>>  };
>>
>> Hi Jan, doesn't this also need to set:
>>
>>
>> +       .get_nextdqblk  = dquot_get_next_dqblk,
>>
>> in ext4_qctl_sysfile_operations?
> 
> Indeed, thanks for catching this. Patch added (with your authorship and
> sign-off) into my tree and this time I've properly tested Q_GETNEXTQUOTA
> for ext4 with quota in hidden inodes indeed works (previously I've tested
> only visible quota files).

Thanks Jan, I wasn't quite sure what it should be doing, but this seemed
right.  ;)  Sorry for not sending a proper patch.

So, when you tested visible quota files, I assume it was just falling
back to the non-next variants of the quotactl, right?  We should not
be hooking up the call for the visible quota files, right?

FWIW, there is a test in [x]fstests now for the [X]GETNEXT calls, it's
generic/244

Thanks!
-Eric

> 								Honza
>
Jan Kara Feb. 22, 2016, 8:01 a.m. UTC | #8
On Fri 19-02-16 12:43:13, Eric Sandeen wrote:
> 
> 
> On 2/19/16 12:33 PM, Jan Kara wrote:
> > On Fri 19-02-16 11:31:58, Eric Sandeen wrote:
> >>
> >>
> >> On 2/4/16 8:28 AM, Jan Kara wrote:
> >>> 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          |  1 +
> >>>  fs/quota/dquot.c         | 39 +++++++++++++++++++++++++++++++++++++++
> >>>  fs/reiserfs/super.c      |  1 +
> >>>  include/linux/quota.h    |  3 +++
> >>>  include/linux/quotaops.h |  3 +++
> >>>  5 files changed, 47 insertions(+)
> >>>
> >>> diff --git a/fs/ext4/super.c b/fs/ext4/super.c
> >>> index f1b56ff01208..51649f442bf6 100644
> >>> --- a/fs/ext4/super.c
> >>> +++ b/fs/ext4/super.c
> >>> @@ -1100,6 +1100,7 @@ static const struct dquot_operations ext4_quota_operations = {
> >>>  	.write_info	= ext4_write_info,
> >>>  	.alloc_dquot	= dquot_alloc,
> >>>  	.destroy_dquot	= dquot_destroy,
> >>> +	.get_next_id	= dquot_get_next_id,
> >>>  };
> >>
> >> Hi Jan, doesn't this also need to set:
> >>
> >>
> >> +       .get_nextdqblk  = dquot_get_next_dqblk,
> >>
> >> in ext4_qctl_sysfile_operations?
> > 
> > Indeed, thanks for catching this. Patch added (with your authorship and
> > sign-off) into my tree and this time I've properly tested Q_GETNEXTQUOTA
> > for ext4 with quota in hidden inodes indeed works (previously I've tested
> > only visible quota files).
> 
> Thanks Jan, I wasn't quite sure what it should be doing, but this seemed
> right.  ;)  Sorry for not sending a proper patch.
> 
> So, when you tested visible quota files, I assume it was just falling
> back to the non-next variants of the quotactl, right?  We should not
> be hooking up the call for the visible quota files, right?

We are hooking up the call for visible quota files since it works without
issues. It is upto userspace to decide whether it wants to read the quota
file directly or use Q_GETNEXTQUOTA call to iterate over all dquots.

> FWIW, there is a test in [x]fstests now for the [X]GETNEXT calls, it's
> generic/244

Great, thanks!

								Honza

Patch
diff mbox

diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index f1b56ff01208..51649f442bf6 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1100,6 +1100,7 @@  static const struct dquot_operations ext4_quota_operations = {
 	.write_info	= ext4_write_info,
 	.alloc_dquot	= dquot_alloc,
 	.destroy_dquot	= dquot_destroy,
+	.get_next_id	= dquot_get_next_id,
 };
 
 static const struct quotactl_ops ext4_qctl_operations = {
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index fbd70af98820..f5c4967b62f1 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -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);
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 05db7473bcb5..b62f495add62 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -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 = {
diff --git a/include/linux/quota.h b/include/linux/quota.h
index fba92f5c1a63..9dfb6bce8c9e 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -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;
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index 7a57c28eb5e7..f00fa86ac966 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -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);