All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v10 00/11] Allow pquota and gquota to be used together
@ 2013-06-27 22:25 Chandra Seetharaman
  2013-06-27 22:25 ` [PATCH v10 01/11] xfs: Define a new function xfs_is_quota_inode() Chandra Seetharaman
                   ` (11 more replies)
  0 siblings, 12 replies; 40+ messages in thread
From: Chandra Seetharaman @ 2013-06-27 22:25 UTC (permalink / raw)
  To: xfs

Hello All,

This is the version 10 of the changes to allow pquota and gquota to be used
together.

Patchset applies cleanly on top of 80a4049813a2ae0977d8e5db78e711c7f21c420b
in xfs git tree.

Ran xfstests against it with DEBUG and do not see any regressions.
---

Chandra Seetharaman (11):
  xfs: Define a new function xfs_is_quota_inode()
  xfs: Replace macro XFS_DQUOT_TREE with a function
  xfs: Replace macro XFS_DQ_TO_QIP with a function
  xfs: Code cleanup and removal of some typedef usage
  xfs: Do some whitespace cleanup in the data structure xfs_quotainfo
  xfs: Change xfs_dquot_acct to be a 2-dimensional array
  xfs: Remove incore use of XFS_OQUOTA_ENFD and XFS_OQUOTA_CHKD
  xfs: Add pquota fields where gquota is used.
  xfs: Start using pquotaino from the superblock.
  xfs: Add proper versioning support to fs_quota_stat
  xfs: Use new qs_pquota field in fs_quota_stat for Q_XGETQSTAT

 fs/gfs2/quota.c                |    3 -
 fs/quota/quota.c               |   49 +++++-
 fs/xfs/xfs_dquot.c             |   31 ++-
 fs/xfs/xfs_dquot.h             |   11 +-
 fs/xfs/xfs_fsops.c             |    3 +-
 fs/xfs/xfs_icache.c            |    4 +-
 fs/xfs/xfs_inode.h             |    1 +
 fs/xfs/xfs_ioctl.c             |   14 +-
 fs/xfs/xfs_iops.c              |    4 +-
 fs/xfs/xfs_itable.c            |    2 +-
 fs/xfs/xfs_mount.c             |   83 ++++++++
 fs/xfs/xfs_qm.c                |  409 ++++++++++++++++++++++++++--------------
 fs/xfs/xfs_qm.h                |  143 +++++++++-----
 fs/xfs/xfs_qm_bhv.c            |    2 +-
 fs/xfs/xfs_qm_syscalls.c       |  126 ++++++++----
 fs/xfs/xfs_quota.h             |   79 +++++----
 fs/xfs/xfs_quotaops.c          |    6 +-
 fs/xfs/xfs_sb.h                |   20 ++
 fs/xfs/xfs_super.c             |   35 ++--
 fs/xfs/xfs_symlink.c           |   13 +-
 fs/xfs/xfs_trans_dquot.c       |  113 ++++++------
 fs/xfs/xfs_vnodeops.c          |   13 +-
 include/uapi/linux/dqblk_xfs.h |   54 +++++-
 23 files changed, 821 insertions(+), 397 deletions(-)

---

Changes from version 9 to version 10:
 - Split prep into 6 patches as per Ben and Dave's suggestion
 - Added xfs_sb_quota_from_disk() as per Dave's suggestion
 - Made u/g/p ordering consistent
 - Fixed fields in fs_quota_stat as per Dave's suggestion
 - Moved few ASSERTs to be inside error check as per Ben's suggestion
 - Few cosmetic changes

Version 9 can be found at:
http://oss.sgi.com/archives/xfs/2013-06/msg00770.html

Changes from verion 8 to version 9:
 - Made all the changes suggested by Dave
 - Rearranged code to make the functional changes to
   not be cluttered.

Version 8 can be found at:
http://oss.sgi.com/archives/xfs/2013-05/msg00296.html

Changes from version 7 to version 8:
 - Rebased to the current code.
 - Modified code to use the new pquotino field in version 5
   of the superblock.

Version 7 can be found at:
http://oss.sgi.com/archives/xfs/2013-03/msg00671.html

Changes from version 6 to version 7:
 - Made all the changes suggested by Dave Chinner
 - Added padding to fs_quota_stat, which made the new
   data structure field ordering different from the old data
   structure field ordering. So, copied the old version
   to be _v1 version and used that if old version of data
   structure was provided from user space.

Version 6 can be found at:
http://oss.sgi.com/archives/xfs/2012-07/msg00286.html

Changes from version 5 to version 6:
- Use radix tree instead of hash table

Version 5 can be found at:
http://oss.sgi.com/archives/xfs/2012-03/msg00310.html

Changes fron version 4 to version 5:
rebase with the current tree one simple change.

Version 4 can be found at
http://oss.sgi.com/archives/xfs/2012-02/msg00528.html

Changes from version 3 to version 4:
- Remove save_flags with storing the value (in to superblock) 
  based on field type info
- fix checkpatch.pl warnings and errors

Version 3 of the posting can be found at
http://oss.sgi.com/archives/xfs/2012-01/msg00309.html

Changes from version 2 to version 3:
 - hash table for pquota is added.
 - changes to apply cleanly with the latest tree

version 2 of the posting can be found at
http://oss.sgi.com/archives/xfs/2011-10/msg00470.html

Changes from version 1 to version 2:

 - Created a new prep patch to accomodate some generic changes that ease
   the later patches.
 - Created a new patch to add a new field qs_pquota to fs_quota_stat
   with appropriate versioning changes
 - Changed the logic to allow XFS_OQUOTA.* flags to be allowed only in
   the older versions.
 - Changed couple of places where PQUOTA checking was on the else if
   construct so as to allow both GQUOTA and PQUOTA in those places.
 - Fixed comments in xfs_quota.h to reflect the current changes.
 - Changed the name of the macro XFS_SB_VERSION2_SEPER_PQUOTA to 
   XFS_SB_VERSION2_NO_OQUOTA
 - got rid of the macros XFS_MOUNT_QUOTA_SET1 and XFS_MOUNT_QUOTA_SET2
 - added a new inline function xfs_inode_dquot(ip, type) to simplify
   the error path in xfs_qm_dqget()
 - got rid of the macro XFS_IS_THIS_QUOTA_OFF
 - added comment to explain why sb_qflags is saved and restored in 
   xfs_sb_to_disk()

version 1 of the posting can be found at
http://oss.sgi.com/archives/xfs/2011-10/msg00341.html

Thanks & Regards,

chandra

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH v10 01/11] xfs: Define a new function xfs_is_quota_inode()
  2013-06-27 22:25 [PATCH v10 00/11] Allow pquota and gquota to be used together Chandra Seetharaman
@ 2013-06-27 22:25 ` Chandra Seetharaman
  2013-06-27 22:43   ` Ben Myers
  2013-06-27 22:25 ` [PATCH v10 02/11] xfs: Replace macro XFS_DQUOT_TREE with a function Chandra Seetharaman
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 40+ messages in thread
From: Chandra Seetharaman @ 2013-06-27 22:25 UTC (permalink / raw)
  To: xfs; +Cc: Chandra Seetharaman

In preparation for combined pquota/gquota support, define
a new function to check if the fiven inode is a quota inode.

Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
---
 fs/xfs/xfs_itable.c      |    2 +-
 fs/xfs/xfs_qm.c          |    8 +++-----
 fs/xfs/xfs_sb.h          |    6 ++++++
 fs/xfs/xfs_trans_dquot.c |    6 ++----
 4 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index 2ea7d40..9cbf9e0 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -43,7 +43,7 @@ xfs_internal_inum(
 {
 	return (ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino ||
 		(xfs_sb_version_hasquota(&mp->m_sb) &&
-		 (ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino)));
+		 xfs_is_quota_inode(&mp->m_sb, ino)));
 }
 
 /*
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index b75c9bb..28a5e8a 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -489,8 +489,7 @@ xfs_qm_need_dqattach(
 		return false;
 	if (!XFS_NOT_DQATTACHED(mp, ip))
 		return false;
-	if (ip->i_ino == mp->m_sb.sb_uquotino ||
-	    ip->i_ino == mp->m_sb.sb_gquotino)
+	if (xfs_is_quota_inode(&mp->m_sb, ip->i_ino))
 		return false;
 	return true;
 }
@@ -606,8 +605,7 @@ xfs_qm_dqdetach(
 
 	trace_xfs_dquot_dqdetach(ip);
 
-	ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_uquotino);
-	ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_gquotino);
+	ASSERT(!xfs_is_quota_inode(&ip->i_mount->m_sb, ip->i_ino));
 	if (ip->i_udquot) {
 		xfs_qm_dqrele(ip->i_udquot);
 		ip->i_udquot = NULL;
@@ -1152,7 +1150,7 @@ xfs_qm_dqusage_adjust(
 	 * rootino must have its resources accounted for, not so with the quota
 	 * inodes.
 	 */
-	if (ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino) {
+	if (xfs_is_quota_inode(&mp->m_sb, ino)) {
 		*res = BULKSTAT_RV_NOTHING;
 		return XFS_ERROR(EINVAL);
 	}
diff --git a/fs/xfs/xfs_sb.h b/fs/xfs/xfs_sb.h
index 2de58a8..78f9e70 100644
--- a/fs/xfs/xfs_sb.h
+++ b/fs/xfs/xfs_sb.h
@@ -618,6 +618,12 @@ xfs_sb_has_incompat_log_feature(
 	return (sbp->sb_features_log_incompat & feature) != 0;
 }
 
+static inline bool
+xfs_is_quota_inode(struct xfs_sb *sbp, xfs_ino_t ino)
+{
+	return (ino == sbp->sb_uquotino || ino == sbp->sb_gquotino);
+}
+
 /*
  * end of superblock version macros
  */
diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
index fec75d0..3fa369c 100644
--- a/fs/xfs/xfs_trans_dquot.c
+++ b/fs/xfs/xfs_trans_dquot.c
@@ -157,8 +157,7 @@ xfs_trans_mod_dquot_byino(
 
 	if (!XFS_IS_QUOTA_RUNNING(mp) ||
 	    !XFS_IS_QUOTA_ON(mp) ||
-	    ip->i_ino == mp->m_sb.sb_uquotino ||
-	    ip->i_ino == mp->m_sb.sb_gquotino)
+	    xfs_is_quota_inode(&mp->m_sb, ip->i_ino))
 		return;
 
 	if (tp->t_dqinfo == NULL)
@@ -816,8 +815,7 @@ xfs_trans_reserve_quota_nblks(
 	if (XFS_IS_PQUOTA_ON(mp))
 		flags |= XFS_QMOPT_ENOSPC;
 
-	ASSERT(ip->i_ino != mp->m_sb.sb_uquotino);
-	ASSERT(ip->i_ino != mp->m_sb.sb_gquotino);
+	ASSERT(!xfs_is_quota_inode(&mp->m_sb, ip->i_ino));
 
 	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
 	ASSERT((flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) ==
-- 
1.7.1

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v10 02/11] xfs: Replace macro XFS_DQUOT_TREE with a function
  2013-06-27 22:25 [PATCH v10 00/11] Allow pquota and gquota to be used together Chandra Seetharaman
  2013-06-27 22:25 ` [PATCH v10 01/11] xfs: Define a new function xfs_is_quota_inode() Chandra Seetharaman
@ 2013-06-27 22:25 ` Chandra Seetharaman
  2013-06-27 23:19   ` Ben Myers
  2013-06-27 22:25 ` [PATCH v10 03/11] xfs: Replace macro XFS_DQ_TO_QIP " Chandra Seetharaman
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 40+ messages in thread
From: Chandra Seetharaman @ 2013-06-27 22:25 UTC (permalink / raw)
  To: xfs; +Cc: Chandra Seetharaman

In preparation for combined pquota/gquota support, for the sake
of readability, change the macro to an inline function.

Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
---
 fs/xfs/xfs_dquot.c |    2 +-
 fs/xfs/xfs_qm.c    |    6 +++---
 fs/xfs/xfs_qm.h    |   22 ++++++++++++++++------
 3 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 044e97a..09af322 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -804,7 +804,7 @@ xfs_qm_dqget(
 	xfs_dquot_t	**O_dqpp) /* OUT : locked incore dquot */
 {
 	struct xfs_quotainfo	*qi = mp->m_quotainfo;
-	struct radix_tree_root *tree = XFS_DQUOT_TREE(qi, type);
+	struct radix_tree_root *tree = xfs_dquot_tree(qi, type);
 	struct xfs_dquot	*dqp;
 	int			error;
 
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 28a5e8a..8e707d3 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -70,7 +70,7 @@ xfs_qm_dquot_walk(
 	void			*data)
 {
 	struct xfs_quotainfo	*qi = mp->m_quotainfo;
-	struct radix_tree_root	*tree = XFS_DQUOT_TREE(qi, type);
+	struct radix_tree_root	*tree = xfs_dquot_tree(qi, type);
 	uint32_t		next_index;
 	int			last_error = 0;
 	int			skipped;
@@ -189,7 +189,7 @@ xfs_qm_dqpurge(
 	xfs_dqfunlock(dqp);
 	xfs_dqunlock(dqp);
 
-	radix_tree_delete(XFS_DQUOT_TREE(qi, dqp->q_core.d_flags),
+	radix_tree_delete(xfs_dquot_tree(qi, dqp->q_core.d_flags),
 			  be32_to_cpu(dqp->q_core.d_id));
 	qi->qi_dquots--;
 
@@ -1471,7 +1471,7 @@ xfs_qm_dqfree_one(
 	struct xfs_quotainfo	*qi = mp->m_quotainfo;
 
 	mutex_lock(&qi->qi_tree_lock);
-	radix_tree_delete(XFS_DQUOT_TREE(qi, dqp->q_core.d_flags),
+	radix_tree_delete(xfs_dquot_tree(qi, dqp->q_core.d_flags),
 			  be32_to_cpu(dqp->q_core.d_id));
 
 	qi->qi_dquots--;
diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
index 5d16a6e..96568c2 100644
--- a/fs/xfs/xfs_qm.h
+++ b/fs/xfs/xfs_qm.h
@@ -69,12 +69,22 @@ typedef struct xfs_quotainfo {
 	struct shrinker  qi_shrinker;
 } xfs_quotainfo_t;
 
-#define XFS_DQUOT_TREE(qi, type) \
-	((type & XFS_DQ_USER) ? \
-	 &((qi)->qi_uquota_tree) : \
-	 &((qi)->qi_gquota_tree))
-
-
+static inline struct radix_tree_root *
+xfs_dquot_tree(
+	struct xfs_quotainfo	*qi,
+	int			type)
+{
+	switch (type) {
+	case XFS_DQ_USER:
+		return &qi->qi_uquota_tree;
+	case XFS_DQ_GROUP:
+	case XFS_DQ_PROJ:
+		return &qi->qi_gquota_tree;
+	default:
+		ASSERT(0);
+	}
+	return NULL;
+}
 extern int	xfs_qm_calc_dquots_per_chunk(struct xfs_mount *mp,
 					     unsigned int nbblks);
 extern void	xfs_trans_mod_dquot(xfs_trans_t *, xfs_dquot_t *, uint, long);
-- 
1.7.1

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v10 03/11] xfs: Replace macro XFS_DQ_TO_QIP with a function
  2013-06-27 22:25 [PATCH v10 00/11] Allow pquota and gquota to be used together Chandra Seetharaman
  2013-06-27 22:25 ` [PATCH v10 01/11] xfs: Define a new function xfs_is_quota_inode() Chandra Seetharaman
  2013-06-27 22:25 ` [PATCH v10 02/11] xfs: Replace macro XFS_DQUOT_TREE with a function Chandra Seetharaman
@ 2013-06-27 22:25 ` Chandra Seetharaman
  2013-06-27 23:23   ` Ben Myers
  2013-06-27 22:25 ` [PATCH v10 04/11] xfs: Code cleanup and removal of some typedef usage Chandra Seetharaman
                   ` (8 subsequent siblings)
  11 siblings, 1 reply; 40+ messages in thread
From: Chandra Seetharaman @ 2013-06-27 22:25 UTC (permalink / raw)
  To: xfs; +Cc: Chandra Seetharaman

In preparation for combined pquota/gquota support, for the sake
of readability, change the macro to an inline function.

Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
---
 fs/xfs/xfs_dquot.c |    2 +-
 fs/xfs/xfs_dquot.h |    4 ----
 fs/xfs/xfs_qm.h    |   16 ++++++++++++++++
 3 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 09af322..7d184de 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -573,7 +573,7 @@ xfs_qm_dqtobp(
 	xfs_bmbt_irec_t map;
 	int		nmaps = 1, error;
 	xfs_buf_t	*bp;
-	xfs_inode_t	*quotip = XFS_DQ_TO_QIP(dqp);
+	struct xfs_inode	*quotip = xfs_dq_to_quota_inode(dqp);
 	xfs_mount_t	*mp = dqp->q_mount;
 	xfs_dqid_t	id = be32_to_cpu(dqp->q_core.d_id);
 	xfs_trans_t	*tp = (tpp ? *tpp : NULL);
diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
index 4f0ebfc..b596626 100644
--- a/fs/xfs/xfs_dquot.h
+++ b/fs/xfs/xfs_dquot.h
@@ -143,10 +143,6 @@ static inline xfs_dquot_t *xfs_inode_dquot(struct xfs_inode *ip, int type)
 #define XFS_QM_ISUDQ(dqp)	((dqp)->dq_flags & XFS_DQ_USER)
 #define XFS_QM_ISPDQ(dqp)	((dqp)->dq_flags & XFS_DQ_PROJ)
 #define XFS_QM_ISGDQ(dqp)	((dqp)->dq_flags & XFS_DQ_GROUP)
-#define XFS_DQ_TO_QINF(dqp)	((dqp)->q_mount->m_quotainfo)
-#define XFS_DQ_TO_QIP(dqp)	(XFS_QM_ISUDQ(dqp) ? \
-				 XFS_DQ_TO_QINF(dqp)->qi_uquotaip : \
-				 XFS_DQ_TO_QINF(dqp)->qi_gquotaip)
 
 extern int		xfs_qm_dqread(struct xfs_mount *, xfs_dqid_t, uint,
 					uint, struct xfs_dquot	**);
diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
index 96568c2..051e43a 100644
--- a/fs/xfs/xfs_qm.h
+++ b/fs/xfs/xfs_qm.h
@@ -85,6 +85,22 @@ xfs_dquot_tree(
 	}
 	return NULL;
 }
+
+static inline struct xfs_inode *
+xfs_dq_to_quota_inode(struct xfs_dquot *dqp)
+{
+	switch (dqp->dq_flags & XFS_DQ_ALLTYPES) {
+	case XFS_DQ_USER:
+		return dqp->q_mount->m_quotainfo->qi_uquotaip;
+	case XFS_DQ_GROUP:
+	case XFS_DQ_PROJ:
+		return dqp->q_mount->m_quotainfo->qi_gquotaip;
+	default:
+		ASSERT(0);
+	}
+	return NULL;
+}
+
 extern int	xfs_qm_calc_dquots_per_chunk(struct xfs_mount *mp,
 					     unsigned int nbblks);
 extern void	xfs_trans_mod_dquot(xfs_trans_t *, xfs_dquot_t *, uint, long);
-- 
1.7.1

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v10 04/11] xfs: Code cleanup and removal of some typedef usage
  2013-06-27 22:25 [PATCH v10 00/11] Allow pquota and gquota to be used together Chandra Seetharaman
                   ` (2 preceding siblings ...)
  2013-06-27 22:25 ` [PATCH v10 03/11] xfs: Replace macro XFS_DQ_TO_QIP " Chandra Seetharaman
@ 2013-06-27 22:25 ` Chandra Seetharaman
  2013-06-27 23:50   ` Ben Myers
  2013-06-27 22:25 ` [PATCH v10 05/11] xfs: Do some whitespace cleanup in the data structure xfs_quotainfo Chandra Seetharaman
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 40+ messages in thread
From: Chandra Seetharaman @ 2013-06-27 22:25 UTC (permalink / raw)
  To: xfs; +Cc: Chandra Seetharaman

In preparation for combined pquota/gquota support, for the sake
of readability, do some code cleanup surrounding the affected
code.

Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
---
 fs/xfs/xfs_dquot.c       |   12 ++--
 fs/xfs/xfs_icache.c      |    3 +-
 fs/xfs/xfs_qm.c          |  152 ++++++++++++++++++++++++----------------------
 fs/xfs/xfs_qm.h          |   37 ++++++-----
 fs/xfs/xfs_qm_syscalls.c |    8 +-
 fs/xfs/xfs_symlink.c     |    3 +-
 fs/xfs/xfs_trans_dquot.c |   46 ++++++--------
 7 files changed, 135 insertions(+), 126 deletions(-)

diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 7d184de..f01012d 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -570,13 +570,13 @@ xfs_qm_dqtobp(
 	xfs_buf_t		**O_bpp,
 	uint			flags)
 {
-	xfs_bmbt_irec_t map;
-	int		nmaps = 1, error;
-	xfs_buf_t	*bp;
+	struct xfs_bmbt_irec	map;
+	int			nmaps = 1, error;
+	struct xfs_buf		*bp;
 	struct xfs_inode	*quotip = xfs_dq_to_quota_inode(dqp);
-	xfs_mount_t	*mp = dqp->q_mount;
-	xfs_dqid_t	id = be32_to_cpu(dqp->q_core.d_id);
-	xfs_trans_t	*tp = (tpp ? *tpp : NULL);
+	struct xfs_mount	*mp = dqp->q_mount;
+	xfs_dqid_t		id = be32_to_cpu(dqp->q_core.d_id);
+	struct xfs_trans	*tp = (tpp ? *tpp : NULL);
 
 	dqp->q_fileoffset = (xfs_fileoff_t)id / mp->m_quotainfo->qi_dqperchunk;
 
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index 96e344e..9560dc1 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -335,7 +335,8 @@ xfs_iget_cache_miss(
 	iflags = XFS_INEW;
 	if (flags & XFS_IGET_DONTCACHE)
 		iflags |= XFS_IDONTCACHE;
-	ip->i_udquot = ip->i_gdquot = NULL;
+	ip->i_udquot = NULL;
+	ip->i_gdquot = NULL;
 	xfs_iflags_set(ip, iflags);
 
 	/* insert the new inode */
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 8e707d3..cf09aa8 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -1260,19 +1260,20 @@ int
 xfs_qm_quotacheck(
 	xfs_mount_t	*mp)
 {
-	int		done, count, error, error2;
-	xfs_ino_t	lastino;
-	size_t		structsz;
-	xfs_inode_t	*uip, *gip;
-	uint		flags;
-	LIST_HEAD	(buffer_list);
+	int			done, count, error, error2;
+	xfs_ino_t		lastino;
+	size_t			structsz;
+	uint			flags;
+	LIST_HEAD		(buffer_list);
+	struct xfs_inode	*uip = mp->m_quotainfo->qi_uquotaip;
+	struct xfs_inode	*gip = mp->m_quotainfo->qi_gquotaip;
 
 	count = INT_MAX;
 	structsz = 1;
 	lastino = 0;
 	flags = 0;
 
-	ASSERT(mp->m_quotainfo->qi_uquotaip || mp->m_quotainfo->qi_gquotaip);
+	ASSERT(uip || gip);
 	ASSERT(XFS_IS_QUOTA_RUNNING(mp));
 
 	xfs_notice(mp, "Quotacheck needed: Please wait.");
@@ -1282,7 +1283,6 @@ xfs_qm_quotacheck(
 	 * their counters to zero. We need a clean slate.
 	 * We don't log our changes till later.
 	 */
-	uip = mp->m_quotainfo->qi_uquotaip;
 	if (uip) {
 		error = xfs_qm_dqiterate(mp, uip, XFS_QMOPT_UQUOTA,
 					 &buffer_list);
@@ -1291,7 +1291,6 @@ xfs_qm_quotacheck(
 		flags |= XFS_UQUOTA_CHKD;
 	}
 
-	gip = mp->m_quotainfo->qi_gquotaip;
 	if (gip) {
 		error = xfs_qm_dqiterate(mp, gip, XFS_IS_GQUOTA_ON(mp) ?
 					 XFS_QMOPT_GQUOTA : XFS_QMOPT_PQUOTA,
@@ -1393,15 +1392,13 @@ STATIC int
 xfs_qm_init_quotainos(
 	xfs_mount_t	*mp)
 {
-	xfs_inode_t	*uip, *gip;
-	int		error;
-	__int64_t	sbflags;
-	uint		flags;
+	struct xfs_inode	*uip = NULL;
+	struct xfs_inode	*gip = NULL;
+	int			error;
+	__int64_t		sbflags = 0;
+	uint			flags = 0;
 
 	ASSERT(mp->m_quotainfo);
-	uip = gip = NULL;
-	sbflags = 0;
-	flags = 0;
 
 	/*
 	 * Get the uquota and gquota inodes
@@ -1410,19 +1407,18 @@ xfs_qm_init_quotainos(
 		if (XFS_IS_UQUOTA_ON(mp) &&
 		    mp->m_sb.sb_uquotino != NULLFSINO) {
 			ASSERT(mp->m_sb.sb_uquotino > 0);
-			if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_uquotino,
-					     0, 0, &uip)))
+			error = xfs_iget(mp, NULL, mp->m_sb.sb_uquotino,
+					     0, 0, &uip);
+			if (error)
 				return XFS_ERROR(error);
 		}
 		if (XFS_IS_OQUOTA_ON(mp) &&
 		    mp->m_sb.sb_gquotino != NULLFSINO) {
 			ASSERT(mp->m_sb.sb_gquotino > 0);
-			if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
-					     0, 0, &gip))) {
-				if (uip)
-					IRELE(uip);
-				return XFS_ERROR(error);
-			}
+			error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
+					     0, 0, &gip);
+			if (error)
+				goto error_rele;
 		}
 	} else {
 		flags |= XFS_QMOPT_SBVERSION;
@@ -1437,10 +1433,11 @@ xfs_qm_init_quotainos(
 	 * temporarily switch to read-write to do this.
 	 */
 	if (XFS_IS_UQUOTA_ON(mp) && uip == NULL) {
-		if ((error = xfs_qm_qino_alloc(mp, &uip,
+		error = xfs_qm_qino_alloc(mp, &uip,
 					      sbflags | XFS_SB_UQUOTINO,
-					      flags | XFS_QMOPT_UQUOTA)))
-			return XFS_ERROR(error);
+					      flags | XFS_QMOPT_UQUOTA);
+		if (error)
+			goto error_rele;
 
 		flags &= ~XFS_QMOPT_SBVERSION;
 	}
@@ -1449,18 +1446,21 @@ xfs_qm_init_quotainos(
 				XFS_QMOPT_GQUOTA : XFS_QMOPT_PQUOTA);
 		error = xfs_qm_qino_alloc(mp, &gip,
 					  sbflags | XFS_SB_GQUOTINO, flags);
-		if (error) {
-			if (uip)
-				IRELE(uip);
-
-			return XFS_ERROR(error);
-		}
+		if (error)
+			goto error_rele;
 	}
 
 	mp->m_quotainfo->qi_uquotaip = uip;
 	mp->m_quotainfo->qi_gquotaip = gip;
 
 	return 0;
+
+error_rele:
+	if (uip)
+		IRELE(uip);
+	if (gip)
+		IRELE(gip);
+	return XFS_ERROR(error);
 }
 
 STATIC void
@@ -1657,7 +1657,8 @@ xfs_qm_vop_dqalloc(
 	struct xfs_dquot	**O_gdqpp)
 {
 	struct xfs_mount	*mp = ip->i_mount;
-	struct xfs_dquot	*uq, *gq;
+	struct xfs_dquot	*uq = NULL;
+	struct xfs_dquot	*gq = NULL;
 	int			error;
 	uint			lockflags;
 
@@ -1682,7 +1683,6 @@ xfs_qm_vop_dqalloc(
 		}
 	}
 
-	uq = gq = NULL;
 	if ((flags & XFS_QMOPT_UQUOTA) && XFS_IS_UQUOTA_ON(mp)) {
 		if (ip->i_d.di_uid != uid) {
 			/*
@@ -1695,11 +1695,12 @@ xfs_qm_vop_dqalloc(
 			 * holding ilock.
 			 */
 			xfs_iunlock(ip, lockflags);
-			if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t) uid,
+			error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t) uid,
 						 XFS_DQ_USER,
 						 XFS_QMOPT_DQALLOC |
 						 XFS_QMOPT_DOWARN,
-						 &uq))) {
+						 &uq);
+			if (error) {
 				ASSERT(error != ENOENT);
 				return error;
 			}
@@ -1721,15 +1722,14 @@ xfs_qm_vop_dqalloc(
 	if ((flags & XFS_QMOPT_GQUOTA) && XFS_IS_GQUOTA_ON(mp)) {
 		if (ip->i_d.di_gid != gid) {
 			xfs_iunlock(ip, lockflags);
-			if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)gid,
+			error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)gid,
 						 XFS_DQ_GROUP,
 						 XFS_QMOPT_DQALLOC |
 						 XFS_QMOPT_DOWARN,
-						 &gq))) {
-				if (uq)
-					xfs_qm_dqrele(uq);
+						 &gq);
+			if (error) {
 				ASSERT(error != ENOENT);
-				return error;
+				goto error_rele;
 			}
 			xfs_dqunlock(gq);
 			lockflags = XFS_ILOCK_SHARED;
@@ -1741,15 +1741,14 @@ xfs_qm_vop_dqalloc(
 	} else if ((flags & XFS_QMOPT_PQUOTA) && XFS_IS_PQUOTA_ON(mp)) {
 		if (xfs_get_projid(ip) != prid) {
 			xfs_iunlock(ip, lockflags);
-			if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)prid,
+			error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)prid,
 						 XFS_DQ_PROJ,
 						 XFS_QMOPT_DQALLOC |
 						 XFS_QMOPT_DOWARN,
-						 &gq))) {
-				if (uq)
-					xfs_qm_dqrele(uq);
+						 &gq);
+			if (error) {
 				ASSERT(error != ENOENT);
-				return (error);
+				goto error_rele;
 			}
 			xfs_dqunlock(gq);
 			lockflags = XFS_ILOCK_SHARED;
@@ -1772,6 +1771,11 @@ xfs_qm_vop_dqalloc(
 	else if (gq)
 		xfs_qm_dqrele(gq);
 	return 0;
+
+error_rele:
+	if (uq)
+		xfs_qm_dqrele(uq);
+	return error;
 }
 
 /*
@@ -1819,29 +1823,31 @@ xfs_qm_vop_chown(
  */
 int
 xfs_qm_vop_chown_reserve(
-	xfs_trans_t	*tp,
-	xfs_inode_t	*ip,
-	xfs_dquot_t	*udqp,
-	xfs_dquot_t	*gdqp,
-	uint		flags)
+	struct xfs_trans	*tp,
+	struct xfs_inode	*ip,
+	struct xfs_dquot	*udqp,
+	struct xfs_dquot	*gdqp,
+	uint			flags)
 {
-	xfs_mount_t	*mp = ip->i_mount;
-	uint		delblks, blkflags, prjflags = 0;
-	xfs_dquot_t	*unresudq, *unresgdq, *delblksudq, *delblksgdq;
-	int		error;
+	struct xfs_mount	*mp = ip->i_mount;
+	uint			delblks, blkflags, prjflags = 0;
+	struct xfs_dquot	*udq_unres = NULL;
+	struct xfs_dquot	*gdq_unres = NULL;
+	struct xfs_dquot	*udq_delblks = NULL;
+	struct xfs_dquot	*gdq_delblks = NULL;
+	int			error;
 
 
 	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED));
 	ASSERT(XFS_IS_QUOTA_RUNNING(mp));
 
 	delblks = ip->i_delayed_blks;
-	delblksudq = delblksgdq = unresudq = unresgdq = NULL;
 	blkflags = XFS_IS_REALTIME_INODE(ip) ?
 			XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS;
 
 	if (XFS_IS_UQUOTA_ON(mp) && udqp &&
 	    ip->i_d.di_uid != (uid_t)be32_to_cpu(udqp->q_core.d_id)) {
-		delblksudq = udqp;
+		udq_delblks = udqp;
 		/*
 		 * If there are delayed allocation blocks, then we have to
 		 * unreserve those from the old dquot, and add them to the
@@ -1849,7 +1855,7 @@ xfs_qm_vop_chown_reserve(
 		 */
 		if (delblks) {
 			ASSERT(ip->i_udquot);
-			unresudq = ip->i_udquot;
+			udq_unres = ip->i_udquot;
 		}
 	}
 	if (XFS_IS_OQUOTA_ON(ip->i_mount) && gdqp) {
@@ -1860,18 +1866,19 @@ xfs_qm_vop_chown_reserve(
 		if (prjflags ||
 		    (XFS_IS_GQUOTA_ON(ip->i_mount) &&
 		     ip->i_d.di_gid != be32_to_cpu(gdqp->q_core.d_id))) {
-			delblksgdq = gdqp;
+			gdq_delblks = gdqp;
 			if (delblks) {
 				ASSERT(ip->i_gdquot);
-				unresgdq = ip->i_gdquot;
+				gdq_unres = ip->i_gdquot;
 			}
 		}
 	}
 
-	if ((error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount,
-				delblksudq, delblksgdq, ip->i_d.di_nblocks, 1,
-				flags | blkflags | prjflags)))
-		return (error);
+	error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount,
+				udq_delblks, gdq_delblks, ip->i_d.di_nblocks, 1,
+				flags | blkflags | prjflags);
+	if (error)
+		return error;
 
 	/*
 	 * Do the delayed blks reservations/unreservations now. Since, these
@@ -1883,14 +1890,15 @@ xfs_qm_vop_chown_reserve(
 		/*
 		 * Do the reservations first. Unreservation can't fail.
 		 */
-		ASSERT(delblksudq || delblksgdq);
-		ASSERT(unresudq || unresgdq);
-		if ((error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
-				delblksudq, delblksgdq, (xfs_qcnt_t)delblks, 0,
-				flags | blkflags | prjflags)))
-			return (error);
+		ASSERT(udq_delblks || gdq_delblks);
+		ASSERT(udq_unres || gdq_unres);
+		error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
+			    udq_delblks, gdq_delblks, (xfs_qcnt_t)delblks, 0,
+			    flags | blkflags | prjflags);
+		if (error)
+			return error;
 		xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
-				unresudq, unresgdq, -((xfs_qcnt_t)delblks), 0,
+				udq_unres, gdq_unres, -((xfs_qcnt_t)delblks), 0,
 				blkflags);
 	}
 
diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
index 051e43a..978bbb1 100644
--- a/fs/xfs/xfs_qm.h
+++ b/fs/xfs/xfs_qm.h
@@ -103,11 +103,13 @@ xfs_dq_to_quota_inode(struct xfs_dquot *dqp)
 
 extern int	xfs_qm_calc_dquots_per_chunk(struct xfs_mount *mp,
 					     unsigned int nbblks);
-extern void	xfs_trans_mod_dquot(xfs_trans_t *, xfs_dquot_t *, uint, long);
-extern int	xfs_trans_reserve_quota_bydquots(xfs_trans_t *, xfs_mount_t *,
-			xfs_dquot_t *, xfs_dquot_t *, long, long, uint);
-extern void	xfs_trans_dqjoin(xfs_trans_t *, xfs_dquot_t *);
-extern void	xfs_trans_log_dquot(xfs_trans_t *, xfs_dquot_t *);
+extern void	xfs_trans_mod_dquot(struct xfs_trans *,
+					struct xfs_dquot *, uint, long);
+extern int	xfs_trans_reserve_quota_bydquots(struct xfs_trans *,
+			struct xfs_mount *, struct xfs_dquot *,
+			struct xfs_dquot *, long, long, uint);
+extern void	xfs_trans_dqjoin(struct xfs_trans *, struct xfs_dquot *);
+extern void	xfs_trans_log_dquot(struct xfs_trans *, struct xfs_dquot *);
 
 /*
  * We keep the usr and grp dquots separately so that locking will be easier
@@ -132,22 +134,23 @@ typedef struct xfs_dquot_acct {
 #define XFS_QM_IWARNLIMIT	5
 #define XFS_QM_RTBWARNLIMIT	5
 
-extern void		xfs_qm_destroy_quotainfo(xfs_mount_t *);
-extern int		xfs_qm_quotacheck(xfs_mount_t *);
-extern int		xfs_qm_write_sb_changes(xfs_mount_t *, __int64_t);
+extern void		xfs_qm_destroy_quotainfo(struct xfs_mount *);
+extern int		xfs_qm_quotacheck(struct xfs_mount *);
+extern int		xfs_qm_write_sb_changes(struct xfs_mount *, __int64_t);
 
 /* dquot stuff */
-extern void		xfs_qm_dqpurge_all(xfs_mount_t *, uint);
-extern void		xfs_qm_dqrele_all_inodes(xfs_mount_t *, uint);
+extern void		xfs_qm_dqpurge_all(struct xfs_mount *, uint);
+extern void		xfs_qm_dqrele_all_inodes(struct xfs_mount *, uint);
 
 /* quota ops */
-extern int		xfs_qm_scall_trunc_qfiles(xfs_mount_t *, uint);
-extern int		xfs_qm_scall_getquota(xfs_mount_t *, xfs_dqid_t, uint,
-					fs_disk_quota_t *);
+extern int		xfs_qm_scall_trunc_qfiles(struct xfs_mount *, uint);
+extern int		xfs_qm_scall_getquota(struct xfs_mount *, xfs_dqid_t,
+					uint, struct fs_disk_quota *);
 extern int		xfs_qm_scall_setqlim(struct xfs_mount *, xfs_dqid_t, uint,
-					fs_disk_quota_t *);
-extern int		xfs_qm_scall_getqstat(xfs_mount_t *, fs_quota_stat_t *);
-extern int		xfs_qm_scall_quotaon(xfs_mount_t *, uint);
-extern int		xfs_qm_scall_quotaoff(xfs_mount_t *, uint);
+					struct fs_disk_quota *);
+extern int		xfs_qm_scall_getqstat(struct xfs_mount *,
+					struct fs_quota_stat *);
+extern int		xfs_qm_scall_quotaon(struct xfs_mount *, uint);
+extern int		xfs_qm_scall_quotaoff(struct xfs_mount *, uint);
 
 #endif /* __XFS_QM_H__ */
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index 6cdf6ff..b03b2ab 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -407,11 +407,11 @@ xfs_qm_scall_getqstat(
 	struct fs_quota_stat	*out)
 {
 	struct xfs_quotainfo	*q = mp->m_quotainfo;
-	struct xfs_inode	*uip, *gip;
-	bool                    tempuqip, tempgqip;
+	struct xfs_inode	*uip = NULL;
+	struct xfs_inode	*gip = NULL;
+	bool                    tempuqip = false;
+	bool                    tempgqip = false;
 
-	uip = gip = NULL;
-	tempuqip = tempgqip = false;
 	memset(out, 0, sizeof(fs_quota_stat_t));
 
 	out->qs_version = FS_QSTAT_VERSION;
diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c
index 738c04b..e830fb5 100644
--- a/fs/xfs/xfs_symlink.c
+++ b/fs/xfs/xfs_symlink.c
@@ -358,7 +358,8 @@ xfs_symlink(
 	int			n;
 	xfs_buf_t		*bp;
 	prid_t			prid;
-	struct xfs_dquot	*udqp, *gdqp;
+	struct xfs_dquot	*udqp = NULL;
+	struct xfs_dquot	*gdqp = NULL;
 	uint			resblks;
 
 	*ipp = NULL;
diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
index 3fa369c..45b3e2d 100644
--- a/fs/xfs/xfs_trans_dquot.c
+++ b/fs/xfs/xfs_trans_dquot.c
@@ -169,13 +169,13 @@ xfs_trans_mod_dquot_byino(
 		(void) xfs_trans_mod_dquot(tp, ip->i_gdquot, field, delta);
 }
 
-STATIC xfs_dqtrx_t *
+STATIC struct xfs_dqtrx *
 xfs_trans_get_dqtrx(
-	xfs_trans_t	*tp,
-	xfs_dquot_t	*dqp)
+	struct xfs_trans	*tp,
+	struct xfs_dquot	*dqp)
 {
-	int		i;
-	xfs_dqtrx_t	*qa;
+	int			i;
+	struct xfs_dqtrx	*qa;
 
 	qa = XFS_QM_ISUDQ(dqp) ?
 		tp->t_dqinfo->dqa_usrdquots : tp->t_dqinfo->dqa_grpdquots;
@@ -747,15 +747,15 @@ error_return:
  */
 int
 xfs_trans_reserve_quota_bydquots(
-	xfs_trans_t	*tp,
-	xfs_mount_t	*mp,
-	xfs_dquot_t	*udqp,
-	xfs_dquot_t	*gdqp,
-	long		nblks,
-	long		ninos,
-	uint		flags)
+	struct xfs_trans	*tp,
+	struct xfs_mount	*mp,
+	struct xfs_dquot	*udqp,
+	struct xfs_dquot	*gdqp,
+	long			nblks,
+	long			ninos,
+	uint			flags)
 {
-	int		resvd = 0, error;
+	int		error;
 
 	if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp))
 		return 0;
@@ -770,28 +770,24 @@ xfs_trans_reserve_quota_bydquots(
 					(flags & ~XFS_QMOPT_ENOSPC));
 		if (error)
 			return error;
-		resvd = 1;
 	}
 
 	if (gdqp) {
 		error = xfs_trans_dqresv(tp, mp, gdqp, nblks, ninos, flags);
-		if (error) {
-			/*
-			 * can't do it, so backout previous reservation
-			 */
-			if (resvd) {
-				flags |= XFS_QMOPT_FORCE_RES;
-				xfs_trans_dqresv(tp, mp, udqp,
-						 -nblks, -ninos, flags);
-			}
-			return error;
-		}
+		if (error)
+			goto unwind_usr;
 	}
 
 	/*
 	 * Didn't change anything critical, so, no need to log
 	 */
 	return 0;
+
+unwind_usr:
+	flags |= XFS_QMOPT_FORCE_RES;
+	if (udqp)
+		xfs_trans_dqresv(tp, mp, udqp, -nblks, -ninos, flags);
+	return error;
 }
 
 
-- 
1.7.1

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v10 05/11] xfs: Do some whitespace cleanup in the data structure xfs_quotainfo
  2013-06-27 22:25 [PATCH v10 00/11] Allow pquota and gquota to be used together Chandra Seetharaman
                   ` (3 preceding siblings ...)
  2013-06-27 22:25 ` [PATCH v10 04/11] xfs: Code cleanup and removal of some typedef usage Chandra Seetharaman
@ 2013-06-27 22:25 ` Chandra Seetharaman
  2013-06-28 16:30   ` Ben Myers
  2013-06-27 22:25 ` [PATCH v10 06/11] xfs: Change xfs_dquot_acct to be a 2-dimensional array Chandra Seetharaman
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 40+ messages in thread
From: Chandra Seetharaman @ 2013-06-27 22:25 UTC (permalink / raw)
  To: xfs; +Cc: Chandra Seetharaman

In preparation for combined pquota/gquota support, do some
whitespace cleanups.

Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
---
 fs/xfs/xfs_qm.h |   50 +++++++++++++++++++++++++-------------------------
 1 files changed, 25 insertions(+), 25 deletions(-)

diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
index 978bbb1..d6d71f0 100644
--- a/fs/xfs/xfs_qm.h
+++ b/fs/xfs/xfs_qm.h
@@ -42,31 +42,31 @@ extern struct kmem_zone	*xfs_qm_dqtrxzone;
  * The mount structure keeps a pointer to this.
  */
 typedef struct xfs_quotainfo {
-	struct radix_tree_root qi_uquota_tree;
-	struct radix_tree_root qi_gquota_tree;
-	struct mutex qi_tree_lock;
-	xfs_inode_t	*qi_uquotaip;	 /* user quota inode */
-	xfs_inode_t	*qi_gquotaip;	 /* group quota inode */
-	struct list_head qi_lru_list;
-	struct mutex	 qi_lru_lock;
-	int		 qi_lru_count;
-	int		 qi_dquots;
-	time_t		 qi_btimelimit;	 /* limit for blks timer */
-	time_t		 qi_itimelimit;	 /* limit for inodes timer */
-	time_t		 qi_rtbtimelimit;/* limit for rt blks timer */
-	xfs_qwarncnt_t	 qi_bwarnlimit;	 /* limit for blks warnings */
-	xfs_qwarncnt_t	 qi_iwarnlimit;	 /* limit for inodes warnings */
-	xfs_qwarncnt_t	 qi_rtbwarnlimit;/* limit for rt blks warnings */
-	struct mutex	 qi_quotaofflock;/* to serialize quotaoff */
-	xfs_filblks_t	 qi_dqchunklen;	 /* # BBs in a chunk of dqs */
-	uint		 qi_dqperchunk;	 /* # ondisk dqs in above chunk */
-	xfs_qcnt_t	 qi_bhardlimit;	 /* default data blk hard limit */
-	xfs_qcnt_t	 qi_bsoftlimit;	 /* default data blk soft limit */
-	xfs_qcnt_t	 qi_ihardlimit;	 /* default inode count hard limit */
-	xfs_qcnt_t	 qi_isoftlimit;	 /* default inode count soft limit */
-	xfs_qcnt_t	 qi_rtbhardlimit;/* default realtime blk hard limit */
-	xfs_qcnt_t	 qi_rtbsoftlimit;/* default realtime blk soft limit */
-	struct shrinker  qi_shrinker;
+	struct radix_tree_root	qi_uquota_tree;
+	struct radix_tree_root	qi_gquota_tree;
+	struct mutex		qi_tree_lock;
+	struct xfs_inode	*qi_uquotaip;
+	struct xfs_inode	*qi_gquotaip;
+	struct list_head	qi_lru_list;
+	struct mutex		qi_lru_lock;
+	int			qi_lru_count;
+	int			qi_dquots;
+	time_t			qi_btimelimit;
+	time_t			qi_itimelimit;
+	time_t			qi_rtbtimelimit;
+	xfs_qwarncnt_t		qi_bwarnlimit;
+	xfs_qwarncnt_t		qi_iwarnlimit;
+	xfs_qwarncnt_t		qi_rtbwarnlimit;
+	struct mutex		qi_quotaofflock;/* to serialize quotaoff */
+	xfs_filblks_t		qi_dqchunklen;	/* #BBs in a chunk of dqs */
+	uint			qi_dqperchunk;	/* #ondisk dqs in above chunk */
+	xfs_qcnt_t		qi_bhardlimit;
+	xfs_qcnt_t		qi_bsoftlimit;
+	xfs_qcnt_t		qi_ihardlimit;
+	xfs_qcnt_t		qi_isoftlimit;
+	xfs_qcnt_t		qi_rtbhardlimit;
+	xfs_qcnt_t		qi_rtbsoftlimit;
+	struct shrinker		qi_shrinker;
 } xfs_quotainfo_t;
 
 static inline struct radix_tree_root *
-- 
1.7.1

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v10 06/11] xfs: Change xfs_dquot_acct to be a 2-dimensional array
  2013-06-27 22:25 [PATCH v10 00/11] Allow pquota and gquota to be used together Chandra Seetharaman
                   ` (4 preceding siblings ...)
  2013-06-27 22:25 ` [PATCH v10 05/11] xfs: Do some whitespace cleanup in the data structure xfs_quotainfo Chandra Seetharaman
@ 2013-06-27 22:25 ` Chandra Seetharaman
  2013-06-28 19:06   ` Ben Myers
  2013-06-27 22:25 ` [PATCH v10 07/11] xfs: Remove incore use of XFS_OQUOTA_ENFD and XFS_OQUOTA_CHKD Chandra Seetharaman
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 40+ messages in thread
From: Chandra Seetharaman @ 2013-06-27 22:25 UTC (permalink / raw)
  To: xfs; +Cc: Chandra Seetharaman

In preparation for combined pquota/gquota support, for the sake
of readability, change xfs_dquot_acct to be a 2-dimensional array.

Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
---
 fs/xfs/xfs_qm.h          |   12 ++++++++----
 fs/xfs/xfs_trans_dquot.c |   31 ++++++++++++-------------------
 2 files changed, 20 insertions(+), 23 deletions(-)

diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
index d6d71f0..9efec02 100644
--- a/fs/xfs/xfs_qm.h
+++ b/fs/xfs/xfs_qm.h
@@ -116,11 +116,15 @@ extern void	xfs_trans_log_dquot(struct xfs_trans *, struct xfs_dquot *);
  * to do at commit time. All transactions that we know of at this point
  * affect no more than two dquots of one type. Hence, the TRANS_MAXDQS value.
  */
+enum {
+	XFS_QM_TRANS_USR = 0,
+	XFS_QM_TRANS_GRP,
+	XFS_QM_TRANS_DQTYPES
+};
 #define XFS_QM_TRANS_MAXDQS		2
-typedef struct xfs_dquot_acct {
-	xfs_dqtrx_t	dqa_usrdquots[XFS_QM_TRANS_MAXDQS];
-	xfs_dqtrx_t	dqa_grpdquots[XFS_QM_TRANS_MAXDQS];
-} xfs_dquot_acct_t;
+struct xfs_dquot_acct {
+	struct xfs_dqtrx	dqs[XFS_QM_TRANS_DQTYPES][XFS_QM_TRANS_MAXDQS];
+};
 
 /*
  * Users are allowed to have a usage exceeding their softlimit for
diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
index 45b3e2d..7ea7485 100644
--- a/fs/xfs/xfs_trans_dquot.c
+++ b/fs/xfs/xfs_trans_dquot.c
@@ -103,8 +103,6 @@ xfs_trans_dup_dqinfo(
 		return;
 
 	xfs_trans_alloc_dqinfo(ntp);
-	oqa = otp->t_dqinfo->dqa_usrdquots;
-	nqa = ntp->t_dqinfo->dqa_usrdquots;
 
 	/*
 	 * Because the quota blk reservation is carried forward,
@@ -113,7 +111,9 @@ xfs_trans_dup_dqinfo(
 	if(otp->t_flags & XFS_TRANS_DQ_DIRTY)
 		ntp->t_flags |= XFS_TRANS_DQ_DIRTY;
 
-	for (j = 0; j < 2; j++) {
+	for (j = 0; j < XFS_QM_TRANS_DQTYPES; j++) {
+		oqa = otp->t_dqinfo->dqs[j];
+		nqa = ntp->t_dqinfo->dqs[j];
 		for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
 			if (oqa[i].qt_dquot == NULL)
 				break;
@@ -138,8 +138,6 @@ xfs_trans_dup_dqinfo(
 			oq->qt_ino_res = oq->qt_ino_res_used;
 
 		}
-		oqa = otp->t_dqinfo->dqa_grpdquots;
-		nqa = ntp->t_dqinfo->dqa_grpdquots;
 	}
 }
 
@@ -177,8 +175,10 @@ xfs_trans_get_dqtrx(
 	int			i;
 	struct xfs_dqtrx	*qa;
 
-	qa = XFS_QM_ISUDQ(dqp) ?
-		tp->t_dqinfo->dqa_usrdquots : tp->t_dqinfo->dqa_grpdquots;
+	if (XFS_QM_ISUDQ(dqp))
+		qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_USR];
+	else
+		qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_GRP];
 
 	for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
 		if (qa[i].qt_dquot == NULL ||
@@ -338,12 +338,10 @@ xfs_trans_apply_dquot_deltas(
 		return;
 
 	ASSERT(tp->t_dqinfo);
-	qa = tp->t_dqinfo->dqa_usrdquots;
-	for (j = 0; j < 2; j++) {
-		if (qa[0].qt_dquot == NULL) {
-			qa = tp->t_dqinfo->dqa_grpdquots;
+	for (j = 0; j < XFS_QM_TRANS_DQTYPES; j++) {
+		qa = tp->t_dqinfo->dqs[j];
+		if (qa[0].qt_dquot == NULL)
 			continue;
-		}
 
 		/*
 		 * Lock all of the dquots and join them to the transaction.
@@ -494,10 +492,6 @@ xfs_trans_apply_dquot_deltas(
 			ASSERT(dqp->q_res_rtbcount >=
 				be64_to_cpu(dqp->q_core.d_rtbcount));
 		}
-		/*
-		 * Do the group quotas next
-		 */
-		qa = tp->t_dqinfo->dqa_grpdquots;
 	}
 }
 
@@ -520,9 +514,9 @@ xfs_trans_unreserve_and_mod_dquots(
 	if (!tp->t_dqinfo || !(tp->t_flags & XFS_TRANS_DQ_DIRTY))
 		return;
 
-	qa = tp->t_dqinfo->dqa_usrdquots;
+	for (j = 0; j < XFS_QM_TRANS_DQTYPES; j++) {
+		qa = tp->t_dqinfo->dqs[j];
 
-	for (j = 0; j < 2; j++) {
 		for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
 			qtrx = &qa[i];
 			/*
@@ -564,7 +558,6 @@ xfs_trans_unreserve_and_mod_dquots(
 				xfs_dqunlock(dqp);
 
 		}
-		qa = tp->t_dqinfo->dqa_grpdquots;
 	}
 }
 
-- 
1.7.1

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v10 07/11] xfs: Remove incore use of XFS_OQUOTA_ENFD and XFS_OQUOTA_CHKD
  2013-06-27 22:25 [PATCH v10 00/11] Allow pquota and gquota to be used together Chandra Seetharaman
                   ` (5 preceding siblings ...)
  2013-06-27 22:25 ` [PATCH v10 06/11] xfs: Change xfs_dquot_acct to be a 2-dimensional array Chandra Seetharaman
@ 2013-06-27 22:25 ` Chandra Seetharaman
  2013-06-28 22:36   ` Ben Myers
  2013-06-27 22:25 ` [PATCH v10 08/11] xfs: Add pquota fields where gquota is used Chandra Seetharaman
                   ` (4 subsequent siblings)
  11 siblings, 1 reply; 40+ messages in thread
From: Chandra Seetharaman @ 2013-06-27 22:25 UTC (permalink / raw)
  To: xfs; +Cc: Chandra Seetharaman

Remove all incore use of XFS_OQUOTA_ENFD and XFS_OQUOTA_CHKD. Instead,
start using XFS_GQUOTA_.* XFS_PQUOTA_.* counterparts for GQUOTA and
PQUOTA respectively.

On-disk copy still uses XFS_OQUOTA_ENFD and XFS_OQUOTA_CHKD.

Read and write of the superblock does the conversion from *OQUOTA*
to *[PG]QUOTA*.

Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
---
 fs/xfs/xfs_mount.c       |   51 ++++++++++++++++++++++++++++++++++++++++++++++
 fs/xfs/xfs_qm.c          |    9 +++++--
 fs/xfs/xfs_qm_syscalls.c |   43 ++++++++++++++++++++------------------
 fs/xfs/xfs_quota.h       |   47 ++++++++++++++++++++++++++----------------
 fs/xfs/xfs_quotaops.c    |    6 +++-
 fs/xfs/xfs_super.c       |   16 +++++++-------
 fs/xfs/xfs_trans_dquot.c |    4 +-
 7 files changed, 123 insertions(+), 53 deletions(-)

diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 2978bb4..2b0ba35 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -336,6 +336,14 @@ xfs_mount_validate_sb(
 		return XFS_ERROR(EWRONGFS);
 	}
 
+	if ((sbp->sb_qflags & (XFS_OQUOTA_ENFD | XFS_OQUOTA_CHKD)) &&
+			(sbp->sb_qflags & (XFS_PQUOTA_ENFD | XFS_GQUOTA_ENFD |
+				XFS_PQUOTA_CHKD | XFS_GQUOTA_CHKD))) {
+		xfs_notice(mp,
+"Super block has XFS_OQUOTA bits along with XFS_PQUOTA and/or XFS_GQUOTA bits.\n");
+		return XFS_ERROR(EFSCORRUPTED);
+	}
+
 	/*
 	 * Version 5 superblock feature mask validation. Reject combinations the
 	 * kernel cannot support up front before checking anything else. For
@@ -561,6 +569,18 @@ out_unwind:
 	return error;
 }
 
+static void
+xfs_sb_quota_from_disk(struct xfs_sb *sbp)
+{
+	if (sbp->sb_qflags & XFS_OQUOTA_ENFD)
+		sbp->sb_qflags |= (sbp->sb_qflags & XFS_PQUOTA_ACCT) ?
+					XFS_PQUOTA_ENFD : XFS_GQUOTA_ENFD;
+	if (sbp->sb_qflags & XFS_OQUOTA_CHKD)
+		sbp->sb_qflags |= (sbp->sb_qflags & XFS_PQUOTA_ACCT) ?
+					XFS_PQUOTA_CHKD : XFS_GQUOTA_CHKD;
+	sbp->sb_qflags &= ~(XFS_OQUOTA_ENFD | XFS_OQUOTA_CHKD);
+}
+
 void
 xfs_sb_from_disk(
 	struct xfs_sb	*to,
@@ -622,6 +642,35 @@ xfs_sb_from_disk(
 	to->sb_lsn = be64_to_cpu(from->sb_lsn);
 }
 
+static inline void
+xfs_sb_quota_to_disk(
+	xfs_dsb_t	*to,
+	xfs_sb_t	*from,
+	__int64_t	*fields)
+{
+	__uint16_t	qflags = from->sb_qflags;
+
+	if (*fields & XFS_SB_QFLAGS) {
+		/*
+		 * The in-core version of sb_qflags do not have
+		 * XFS_OQUOTA_* flags, whereas the on-disk version
+		 * does.  So, convert incore XFS_{PG}QUOTA_* flags
+		 * to on-disk XFS_OQUOTA_* flags.
+		 */
+		qflags &= ~(XFS_PQUOTA_ENFD | XFS_PQUOTA_CHKD |
+				XFS_GQUOTA_ENFD | XFS_GQUOTA_CHKD);
+
+		if (from->sb_qflags &
+				(XFS_PQUOTA_ENFD | XFS_GQUOTA_ENFD))
+			qflags |= XFS_OQUOTA_ENFD;
+		if (from->sb_qflags &
+				(XFS_PQUOTA_CHKD | XFS_GQUOTA_CHKD))
+			qflags |= XFS_OQUOTA_CHKD;
+		to->sb_qflags = cpu_to_be16(qflags);
+		*fields &= ~XFS_SB_QFLAGS;
+	}
+}
+
 /*
  * Copy in core superblock to ondisk one.
  *
@@ -643,6 +692,7 @@ xfs_sb_to_disk(
 	if (!fields)
 		return;
 
+	xfs_sb_quota_to_disk(to, from, &fields);
 	while (fields) {
 		f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields);
 		first = xfs_sb_info[f].offset;
@@ -835,6 +885,7 @@ reread:
 	 */
 	xfs_sb_from_disk(&mp->m_sb, XFS_BUF_TO_SBP(bp));
 
+	xfs_sb_quota_from_disk(&mp->m_sb);
 	/*
 	 * We must be able to do sector-sized and sector-aligned IO.
 	 */
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index cf09aa8..7a3e007 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -299,8 +299,10 @@ xfs_qm_mount_quotas(
 	 */
 	if (!XFS_IS_UQUOTA_ON(mp))
 		mp->m_qflags &= ~XFS_UQUOTA_CHKD;
-	if (!(XFS_IS_GQUOTA_ON(mp) || XFS_IS_PQUOTA_ON(mp)))
-		mp->m_qflags &= ~XFS_OQUOTA_CHKD;
+	if (!XFS_IS_GQUOTA_ON(mp))
+		mp->m_qflags &= ~XFS_GQUOTA_CHKD;
+	if (!XFS_IS_PQUOTA_ON(mp))
+		mp->m_qflags &= ~XFS_PQUOTA_CHKD;
 
  write_changes:
 	/*
@@ -1297,7 +1299,8 @@ xfs_qm_quotacheck(
 					 &buffer_list);
 		if (error)
 			goto error_return;
-		flags |= XFS_OQUOTA_CHKD;
+		flags |= XFS_IS_GQUOTA_ON(mp) ?
+					XFS_GQUOTA_CHKD : XFS_PQUOTA_CHKD;
 	}
 
 	do {
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index b03b2ab..a08801a 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -117,11 +117,11 @@ xfs_qm_scall_quotaoff(
 	}
 	if (flags & XFS_GQUOTA_ACCT) {
 		dqtype |= XFS_QMOPT_GQUOTA;
-		flags |= (XFS_OQUOTA_CHKD | XFS_OQUOTA_ENFD);
+		flags |= (XFS_GQUOTA_CHKD | XFS_GQUOTA_ENFD);
 		inactivate_flags |= XFS_GQUOTA_ACTIVE;
 	} else if (flags & XFS_PQUOTA_ACCT) {
 		dqtype |= XFS_QMOPT_PQUOTA;
-		flags |= (XFS_OQUOTA_CHKD | XFS_OQUOTA_ENFD);
+		flags |= (XFS_PQUOTA_CHKD | XFS_PQUOTA_ENFD);
 		inactivate_flags |= XFS_PQUOTA_ACTIVE;
 	}
 
@@ -335,14 +335,14 @@ xfs_qm_scall_quotaon(
 	 * quota acct on ondisk without m_qflags' knowing.
 	 */
 	if (((flags & XFS_UQUOTA_ACCT) == 0 &&
-	    (mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 &&
-	    (flags & XFS_UQUOTA_ENFD))
-	    ||
+	     (mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 &&
+	     (flags & XFS_UQUOTA_ENFD)) ||
+	    ((flags & XFS_GQUOTA_ACCT) == 0 &&
+	     (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 &&
+	     (flags & XFS_GQUOTA_ENFD)) ||
 	    ((flags & XFS_PQUOTA_ACCT) == 0 &&
-	    (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) == 0 &&
-	    (flags & XFS_GQUOTA_ACCT) == 0 &&
-	    (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 &&
-	    (flags & XFS_OQUOTA_ENFD))) {
+	     (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) == 0 &&
+	     (flags & XFS_PQUOTA_ENFD))) {
 		xfs_debug(mp,
 			"%s: Can't enforce without acct, flags=%x sbflags=%x\n",
 			__func__, flags, mp->m_sb.sb_qflags);
@@ -776,9 +776,12 @@ xfs_qm_scall_getquota(
 	 * gets turned off. No need to confuse the user level code,
 	 * so return zeroes in that case.
 	 */
-	if ((!XFS_IS_UQUOTA_ENFORCED(mp) && dqp->q_core.d_flags == XFS_DQ_USER) ||
-	    (!XFS_IS_OQUOTA_ENFORCED(mp) &&
-			(dqp->q_core.d_flags & (XFS_DQ_PROJ | XFS_DQ_GROUP)))) {
+	if ((!XFS_IS_UQUOTA_ENFORCED(mp) &&
+	     dqp->q_core.d_flags == XFS_DQ_USER) ||
+	    (!XFS_IS_GQUOTA_ENFORCED(mp) &&
+	     dqp->q_core.d_flags == XFS_DQ_GROUP) ||
+	    (!XFS_IS_PQUOTA_ENFORCED(mp) &&
+	     dqp->q_core.d_flags == XFS_DQ_PROJ)) {
 		dst->d_btimer = 0;
 		dst->d_itimer = 0;
 		dst->d_rtbtimer = 0;
@@ -786,8 +789,8 @@ xfs_qm_scall_getquota(
 
 #ifdef DEBUG
 	if (((XFS_IS_UQUOTA_ENFORCED(mp) && dst->d_flags == FS_USER_QUOTA) ||
-	     (XFS_IS_OQUOTA_ENFORCED(mp) &&
-			(dst->d_flags & (FS_PROJ_QUOTA | FS_GROUP_QUOTA)))) &&
+	     (XFS_IS_GQUOTA_ENFORCED(mp) && dst->d_flags == FS_GROUP_QUOTA) ||
+	     (XFS_IS_PQUOTA_ENFORCED(mp) && dst->d_flags == FS_PROJ_QUOTA)) &&
 	    dst->d_id != 0) {
 		if ((dst->d_bcount > dst->d_blk_softlimit) &&
 		    (dst->d_blk_softlimit > 0)) {
@@ -833,16 +836,16 @@ xfs_qm_export_flags(
 	uflags = 0;
 	if (flags & XFS_UQUOTA_ACCT)
 		uflags |= FS_QUOTA_UDQ_ACCT;
-	if (flags & XFS_PQUOTA_ACCT)
-		uflags |= FS_QUOTA_PDQ_ACCT;
 	if (flags & XFS_GQUOTA_ACCT)
 		uflags |= FS_QUOTA_GDQ_ACCT;
+	if (flags & XFS_PQUOTA_ACCT)
+		uflags |= FS_QUOTA_PDQ_ACCT;
 	if (flags & XFS_UQUOTA_ENFD)
 		uflags |= FS_QUOTA_UDQ_ENFD;
-	if (flags & (XFS_OQUOTA_ENFD)) {
-		uflags |= (flags & XFS_GQUOTA_ACCT) ?
-			FS_QUOTA_GDQ_ENFD : FS_QUOTA_PDQ_ENFD;
-	}
+	if (flags & XFS_GQUOTA_ENFD)
+		uflags |= FS_QUOTA_GDQ_ENFD;
+	if (flags & XFS_PQUOTA_ENFD)
+		uflags |= FS_QUOTA_PDQ_ENFD;
 	return (uflags);
 }
 
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h
index c38068f..c3483ba 100644
--- a/fs/xfs/xfs_quota.h
+++ b/fs/xfs/xfs_quota.h
@@ -161,30 +161,42 @@ typedef struct xfs_qoff_logformat {
 #define XFS_GQUOTA_ACCT	0x0040  /* group quota accounting ON */
 
 /*
+ * Conversion to and from the combined OQUOTA flag (if necessary)
+ * is done only in xfs_sb_qflags_to_disk() and xfs_sb_qflags_from_disk()
+ */
+#define XFS_GQUOTA_ENFD	0x0080  /* group quota limits enforced */
+#define XFS_GQUOTA_CHKD	0x0100  /* quotacheck run on group quotas */
+#define XFS_PQUOTA_ENFD	0x0200  /* project quota limits enforced */
+#define XFS_PQUOTA_CHKD	0x0400  /* quotacheck run on project quotas */
+
+/*
  * Quota Accounting/Enforcement flags
  */
 #define XFS_ALL_QUOTA_ACCT	\
 		(XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT | XFS_PQUOTA_ACCT)
-#define XFS_ALL_QUOTA_ENFD	(XFS_UQUOTA_ENFD | XFS_OQUOTA_ENFD)
-#define XFS_ALL_QUOTA_CHKD	(XFS_UQUOTA_CHKD | XFS_OQUOTA_CHKD)
+#define XFS_ALL_QUOTA_ENFD	\
+		(XFS_UQUOTA_ENFD | XFS_GQUOTA_ENFD | XFS_PQUOTA_ENFD)
+#define XFS_ALL_QUOTA_CHKD	\
+		(XFS_UQUOTA_CHKD | XFS_GQUOTA_CHKD | XFS_PQUOTA_CHKD)
 
 #define XFS_IS_QUOTA_RUNNING(mp)	((mp)->m_qflags & XFS_ALL_QUOTA_ACCT)
 #define XFS_IS_UQUOTA_RUNNING(mp)	((mp)->m_qflags & XFS_UQUOTA_ACCT)
 #define XFS_IS_PQUOTA_RUNNING(mp)	((mp)->m_qflags & XFS_PQUOTA_ACCT)
 #define XFS_IS_GQUOTA_RUNNING(mp)	((mp)->m_qflags & XFS_GQUOTA_ACCT)
 #define XFS_IS_UQUOTA_ENFORCED(mp)	((mp)->m_qflags & XFS_UQUOTA_ENFD)
-#define XFS_IS_OQUOTA_ENFORCED(mp)	((mp)->m_qflags & XFS_OQUOTA_ENFD)
+#define XFS_IS_GQUOTA_ENFORCED(mp)	((mp)->m_qflags & XFS_GQUOTA_ENFD)
+#define XFS_IS_PQUOTA_ENFORCED(mp)	((mp)->m_qflags & XFS_PQUOTA_ENFD)
 
 /*
  * Incore only flags for quotaoff - these bits get cleared when quota(s)
  * are in the process of getting turned off. These flags are in m_qflags but
  * never in sb_qflags.
  */
-#define XFS_UQUOTA_ACTIVE	0x0100  /* uquotas are being turned off */
-#define XFS_PQUOTA_ACTIVE	0x0200  /* pquotas are being turned off */
-#define XFS_GQUOTA_ACTIVE	0x0400  /* gquotas are being turned off */
+#define XFS_UQUOTA_ACTIVE	0x1000  /* uquotas are being turned off */
+#define XFS_GQUOTA_ACTIVE	0x2000  /* gquotas are being turned off */
+#define XFS_PQUOTA_ACTIVE	0x4000  /* pquotas are being turned off */
 #define XFS_ALL_QUOTA_ACTIVE	\
-	(XFS_UQUOTA_ACTIVE | XFS_PQUOTA_ACTIVE | XFS_GQUOTA_ACTIVE)
+	(XFS_UQUOTA_ACTIVE | XFS_GQUOTA_ACTIVE | XFS_PQUOTA_ACTIVE)
 
 /*
  * Checking XFS_IS_*QUOTA_ON() while holding any inode lock guarantees
@@ -268,24 +280,23 @@ typedef struct xfs_qoff_logformat {
 	((XFS_IS_UQUOTA_ON(mp) && \
 		(mp->m_sb.sb_qflags & XFS_UQUOTA_CHKD) == 0) || \
 	 (XFS_IS_GQUOTA_ON(mp) && \
-		((mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD) == 0 || \
-		 (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT))) || \
+		(mp->m_sb.sb_qflags & XFS_GQUOTA_CHKD) == 0) || \
 	 (XFS_IS_PQUOTA_ON(mp) && \
-		((mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD) == 0 || \
-		 (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT))))
+		(mp->m_sb.sb_qflags & XFS_PQUOTA_CHKD) == 0))
 
 #define XFS_MOUNT_QUOTA_SET1	(XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
-				 XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\
-				 XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD)
+				 XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT|\
+				 XFS_GQUOTA_ENFD|XFS_GQUOTA_CHKD)
 
 #define XFS_MOUNT_QUOTA_SET2	(XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
-				 XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT|\
-				 XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD)
+				 XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\
+				 XFS_PQUOTA_ENFD|XFS_PQUOTA_CHKD)
 
 #define XFS_MOUNT_QUOTA_ALL	(XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
-				 XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\
-				 XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD|\
-				 XFS_GQUOTA_ACCT)
+				 XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT|\
+				 XFS_GQUOTA_ENFD|XFS_GQUOTA_CHKD|\
+				 XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD|\
+				 XFS_PQUOTA_CHKD)
 
 
 /*
diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c
index 71926d6..20e30f9 100644
--- a/fs/xfs/xfs_quotaops.c
+++ b/fs/xfs/xfs_quotaops.c
@@ -75,8 +75,10 @@ xfs_fs_set_xstate(
 		flags |= XFS_GQUOTA_ACCT;
 	if (uflags & FS_QUOTA_UDQ_ENFD)
 		flags |= XFS_UQUOTA_ENFD;
-	if (uflags & (FS_QUOTA_PDQ_ENFD|FS_QUOTA_GDQ_ENFD))
-		flags |= XFS_OQUOTA_ENFD;
+	if (uflags & FS_QUOTA_GDQ_ENFD)
+		flags |= XFS_GQUOTA_ENFD;
+	if (uflags & FS_QUOTA_PDQ_ENFD)
+		flags |= XFS_PQUOTA_ENFD;
 
 	switch (op) {
 	case Q_XQUOTAON:
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 1492409..19663c7 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -359,17 +359,17 @@ xfs_parseargs(
 		} else if (!strcmp(this_char, MNTOPT_PQUOTA) ||
 			   !strcmp(this_char, MNTOPT_PRJQUOTA)) {
 			mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE |
-					 XFS_OQUOTA_ENFD);
+					 XFS_PQUOTA_ENFD);
 		} else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) {
 			mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
-			mp->m_qflags &= ~XFS_OQUOTA_ENFD;
+			mp->m_qflags &= ~XFS_PQUOTA_ENFD;
 		} else if (!strcmp(this_char, MNTOPT_GQUOTA) ||
 			   !strcmp(this_char, MNTOPT_GRPQUOTA)) {
 			mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE |
-					 XFS_OQUOTA_ENFD);
+					 XFS_GQUOTA_ENFD);
 		} else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) {
 			mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
-			mp->m_qflags &= ~XFS_OQUOTA_ENFD;
+			mp->m_qflags &= ~XFS_GQUOTA_ENFD;
 		} else if (!strcmp(this_char, MNTOPT_DELAYLOG)) {
 			xfs_warn(mp,
 	"delaylog is the default now, option is deprecated.");
@@ -558,12 +558,12 @@ xfs_showargs(
 	/* Either project or group quotas can be active, not both */
 
 	if (mp->m_qflags & XFS_PQUOTA_ACCT) {
-		if (mp->m_qflags & XFS_OQUOTA_ENFD)
+		if (mp->m_qflags & XFS_PQUOTA_ENFD)
 			seq_puts(m, "," MNTOPT_PRJQUOTA);
 		else
 			seq_puts(m, "," MNTOPT_PQUOTANOENF);
 	} else if (mp->m_qflags & XFS_GQUOTA_ACCT) {
-		if (mp->m_qflags & XFS_OQUOTA_ENFD)
+		if (mp->m_qflags & XFS_GQUOTA_ENFD)
 			seq_puts(m, "," MNTOPT_GRPQUOTA);
 		else
 			seq_puts(m, "," MNTOPT_GQUOTANOENF);
@@ -1131,8 +1131,8 @@ xfs_fs_statfs(
 	spin_unlock(&mp->m_sb_lock);
 
 	if ((ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) &&
-	    ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))) ==
-			      (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))
+	    ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD))) ==
+			      (XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD))
 		xfs_qm_statvfs(ip, statp);
 	return 0;
 }
diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
index 7ea7485..3ba64d5 100644
--- a/fs/xfs/xfs_trans_dquot.c
+++ b/fs/xfs/xfs_trans_dquot.c
@@ -632,8 +632,8 @@ xfs_trans_dqresv(
 	if ((flags & XFS_QMOPT_FORCE_RES) == 0 &&
 	    dqp->q_core.d_id &&
 	    ((XFS_IS_UQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISUDQ(dqp)) ||
-	     (XFS_IS_OQUOTA_ENFORCED(dqp->q_mount) &&
-	      (XFS_QM_ISPDQ(dqp) || XFS_QM_ISGDQ(dqp))))) {
+	     (XFS_IS_GQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISGDQ(dqp)) ||
+	     (XFS_IS_PQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISPDQ(dqp)))) {
 		if (nblks > 0) {
 			/*
 			 * dquot is locked already. See if we'd go over the
-- 
1.7.1

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v10 08/11] xfs: Add pquota fields where gquota is used.
  2013-06-27 22:25 [PATCH v10 00/11] Allow pquota and gquota to be used together Chandra Seetharaman
                   ` (6 preceding siblings ...)
  2013-06-27 22:25 ` [PATCH v10 07/11] xfs: Remove incore use of XFS_OQUOTA_ENFD and XFS_OQUOTA_CHKD Chandra Seetharaman
@ 2013-06-27 22:25 ` Chandra Seetharaman
  2013-07-10 21:39   ` Ben Myers
  2013-06-27 22:25 ` [PATCH v10 09/11] xfs: Start using pquotaino from the superblock Chandra Seetharaman
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 40+ messages in thread
From: Chandra Seetharaman @ 2013-06-27 22:25 UTC (permalink / raw)
  To: xfs; +Cc: Chandra Seetharaman

Add project quota changes to all the places where group quota field
is used:
   * add separate project quota members into various structures
   * split project quota and group quotas so that instead of overriding
     the group quota members incore, the new project quota members are
     used instead
   * get rid of usage of the OQUOTA flag incore, in favor of separate
   * group and project quota flags.
   * add a project dquot argument to various functions.

Not using the pquotino field from superblock yet.

Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
---
 fs/xfs/xfs_dquot.c       |   15 +++-
 fs/xfs/xfs_dquot.h       |    7 +-
 fs/xfs/xfs_icache.c      |    1 +
 fs/xfs/xfs_inode.h       |    1 +
 fs/xfs/xfs_ioctl.c       |   14 ++--
 fs/xfs/xfs_iops.c        |    4 +-
 fs/xfs/xfs_qm.c          |  241 +++++++++++++++++++++++++++++++++-------------
 fs/xfs/xfs_qm.h          |   16 ++-
 fs/xfs/xfs_qm_bhv.c      |    2 +-
 fs/xfs/xfs_qm_syscalls.c |   19 +++-
 fs/xfs/xfs_quota.h       |   32 ++++---
 fs/xfs/xfs_symlink.c     |   10 ++-
 fs/xfs/xfs_trans_dquot.c |   26 ++++-
 fs/xfs/xfs_vnodeops.c    |   13 ++-
 14 files changed, 283 insertions(+), 118 deletions(-)

diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index f01012d..0adf27e 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -936,6 +936,7 @@ xfs_qm_dqput_final(
 {
 	struct xfs_quotainfo	*qi = dqp->q_mount->m_quotainfo;
 	struct xfs_dquot	*gdqp;
+	struct xfs_dquot	*pdqp;
 
 	trace_xfs_dqput_free(dqp);
 
@@ -949,21 +950,29 @@ xfs_qm_dqput_final(
 
 	/*
 	 * If we just added a udquot to the freelist, then we want to release
-	 * the gdquot reference that it (probably) has. Otherwise it'll keep
-	 * the gdquot from getting reclaimed.
+	 * the gdquot/pdquot reference that it (probably) has. Otherwise it'll
+	 * keep the gdquot/pdquot from getting reclaimed.
 	 */
 	gdqp = dqp->q_gdquot;
 	if (gdqp) {
 		xfs_dqlock(gdqp);
 		dqp->q_gdquot = NULL;
 	}
+
+	pdqp = dqp->q_pdquot;
+	if (pdqp) {
+		xfs_dqlock(pdqp);
+		dqp->q_pdquot = NULL;
+	}
 	xfs_dqunlock(dqp);
 
 	/*
-	 * If we had a group quota hint, release it now.
+	 * If we had a group/project quota hint, release it now.
 	 */
 	if (gdqp)
 		xfs_qm_dqput(gdqp);
+	if (pdqp)
+		xfs_qm_dqput(pdqp);
 }
 
 /*
diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
index b596626..55abbca 100644
--- a/fs/xfs/xfs_dquot.h
+++ b/fs/xfs/xfs_dquot.h
@@ -53,6 +53,7 @@ typedef struct xfs_dquot {
 	xfs_fileoff_t	 q_fileoffset;	/* offset in quotas file */
 
 	struct xfs_dquot*q_gdquot;	/* group dquot, hint only */
+	struct xfs_dquot*q_pdquot;	/* project dquot, hint only */
 	xfs_disk_dquot_t q_core;	/* actual usage & quotas */
 	xfs_dq_logitem_t q_logitem;	/* dquot log item */
 	xfs_qcnt_t	 q_res_bcount;	/* total regular nblks used+reserved */
@@ -118,8 +119,9 @@ static inline int xfs_this_quota_on(struct xfs_mount *mp, int type)
 	case XFS_DQ_USER:
 		return XFS_IS_UQUOTA_ON(mp);
 	case XFS_DQ_GROUP:
+		return XFS_IS_GQUOTA_ON(mp);
 	case XFS_DQ_PROJ:
-		return XFS_IS_OQUOTA_ON(mp);
+		return XFS_IS_PQUOTA_ON(mp);
 	default:
 		return 0;
 	}
@@ -131,8 +133,9 @@ static inline xfs_dquot_t *xfs_inode_dquot(struct xfs_inode *ip, int type)
 	case XFS_DQ_USER:
 		return ip->i_udquot;
 	case XFS_DQ_GROUP:
-	case XFS_DQ_PROJ:
 		return ip->i_gdquot;
+	case XFS_DQ_PROJ:
+		return ip->i_pdquot;
 	default:
 		return NULL;
 	}
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index 9560dc1..3f90e1c 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -337,6 +337,7 @@ xfs_iget_cache_miss(
 		iflags |= XFS_IDONTCACHE;
 	ip->i_udquot = NULL;
 	ip->i_gdquot = NULL;
+	ip->i_pdquot = NULL;
 	xfs_iflags_set(ip, iflags);
 
 	/* insert the new inode */
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 9112979..b55fd34 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -250,6 +250,7 @@ typedef struct xfs_inode {
 	struct xfs_mount	*i_mount;	/* fs mount struct ptr */
 	struct xfs_dquot	*i_udquot;	/* user dquot */
 	struct xfs_dquot	*i_gdquot;	/* group dquot */
+	struct xfs_dquot	*i_pdquot;	/* project dquot */
 
 	/* Inode location stuff */
 	xfs_ino_t		i_ino;		/* inode number (agno/agino)*/
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 5e99968..71a8bc5 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -928,7 +928,7 @@ xfs_ioctl_setattr(
 	struct xfs_trans	*tp;
 	unsigned int		lock_flags = 0;
 	struct xfs_dquot	*udqp = NULL;
-	struct xfs_dquot	*gdqp = NULL;
+	struct xfs_dquot	*pdqp = NULL;
 	struct xfs_dquot	*olddquot = NULL;
 	int			code;
 
@@ -957,7 +957,7 @@ xfs_ioctl_setattr(
 	if (XFS_IS_QUOTA_ON(mp) && (mask & FSX_PROJID)) {
 		code = xfs_qm_vop_dqalloc(ip, ip->i_d.di_uid,
 					 ip->i_d.di_gid, fa->fsx_projid,
-					 XFS_QMOPT_PQUOTA, &udqp, &gdqp);
+					 XFS_QMOPT_PQUOTA, &udqp, NULL, &pdqp);
 		if (code)
 			return code;
 	}
@@ -994,8 +994,8 @@ xfs_ioctl_setattr(
 		    XFS_IS_PQUOTA_ON(mp) &&
 		    xfs_get_projid(ip) != fa->fsx_projid) {
 			ASSERT(tp);
-			code = xfs_qm_vop_chown_reserve(tp, ip, udqp, gdqp,
-						capable(CAP_FOWNER) ?
+			code = xfs_qm_vop_chown_reserve(tp, ip, udqp, NULL,
+						pdqp, capable(CAP_FOWNER) ?
 						XFS_QMOPT_FORCE_RES : 0);
 			if (code)	/* out of quota */
 				goto error_return;
@@ -1113,7 +1113,7 @@ xfs_ioctl_setattr(
 		if (xfs_get_projid(ip) != fa->fsx_projid) {
 			if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_PQUOTA_ON(mp)) {
 				olddquot = xfs_qm_vop_chown(tp, ip,
-							&ip->i_gdquot, gdqp);
+							&ip->i_pdquot, pdqp);
 			}
 			xfs_set_projid(ip, fa->fsx_projid);
 
@@ -1160,13 +1160,13 @@ xfs_ioctl_setattr(
 	 */
 	xfs_qm_dqrele(olddquot);
 	xfs_qm_dqrele(udqp);
-	xfs_qm_dqrele(gdqp);
+	xfs_qm_dqrele(pdqp);
 
 	return code;
 
  error_return:
 	xfs_qm_dqrele(udqp);
-	xfs_qm_dqrele(gdqp);
+	xfs_qm_dqrele(pdqp);
 	xfs_trans_cancel(tp, 0);
 	if (lock_flags)
 		xfs_iunlock(ip, lock_flags);
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index c69bbc4..2ae62d2 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -539,7 +539,7 @@ xfs_setattr_nonsize(
 		ASSERT(udqp == NULL);
 		ASSERT(gdqp == NULL);
 		error = xfs_qm_vop_dqalloc(ip, uid, gid, xfs_get_projid(ip),
-					 qflags, &udqp, &gdqp);
+					 qflags, &udqp, &gdqp, NULL);
 		if (error)
 			return error;
 	}
@@ -575,7 +575,7 @@ xfs_setattr_nonsize(
 		     (XFS_IS_GQUOTA_ON(mp) && igid != gid))) {
 			ASSERT(tp);
 			error = xfs_qm_vop_chown_reserve(tp, ip, udqp, gdqp,
-						capable(CAP_FOWNER) ?
+						NULL, capable(CAP_FOWNER) ?
 						XFS_QMOPT_FORCE_RES : 0);
 			if (error)	/* out of quota */
 				goto out_trans_cancel;
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 7a3e007..42055ca 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -137,6 +137,7 @@ xfs_qm_dqpurge(
 	struct xfs_mount	*mp = dqp->q_mount;
 	struct xfs_quotainfo	*qi = mp->m_quotainfo;
 	struct xfs_dquot	*gdqp = NULL;
+	struct xfs_dquot	*pdqp = NULL;
 
 	xfs_dqlock(dqp);
 	if ((dqp->dq_flags & XFS_DQ_FREEING) || dqp->q_nrefs != 0) {
@@ -145,8 +146,7 @@ xfs_qm_dqpurge(
 	}
 
 	/*
-	 * If this quota has a group hint attached, prepare for releasing it
-	 * now.
+	 * If this quota has a hint attached, prepare for releasing it now.
 	 */
 	gdqp = dqp->q_gdquot;
 	if (gdqp) {
@@ -154,6 +154,12 @@ xfs_qm_dqpurge(
 		dqp->q_gdquot = NULL;
 	}
 
+	pdqp = dqp->q_pdquot;
+	if (pdqp) {
+		xfs_dqlock(pdqp);
+		dqp->q_pdquot = NULL;
+	}
+
 	dqp->dq_flags |= XFS_DQ_FREEING;
 
 	xfs_dqflock(dqp);
@@ -208,6 +214,8 @@ xfs_qm_dqpurge(
 
 	if (gdqp)
 		xfs_qm_dqput(gdqp);
+	if (pdqp)
+		xfs_qm_dqput(pdqp);
 	return 0;
 }
 
@@ -364,6 +372,10 @@ xfs_qm_unmount_quotas(
 			IRELE(mp->m_quotainfo->qi_gquotaip);
 			mp->m_quotainfo->qi_gquotaip = NULL;
 		}
+		if (mp->m_quotainfo->qi_pquotaip) {
+			IRELE(mp->m_quotainfo->qi_pquotaip);
+			mp->m_quotainfo->qi_pquotaip = NULL;
+		}
 	}
 }
 
@@ -410,7 +422,10 @@ xfs_qm_dqattach_one(
 		 * be reclaimed as long as we have a ref from inode and we
 		 * hold the ilock.
 		 */
-		dqp = udqhint->q_gdquot;
+		if (type == XFS_DQ_GROUP)
+			dqp = udqhint->q_gdquot;
+		else
+			dqp = udqhint->q_pdquot;
 		if (dqp && be32_to_cpu(dqp->q_core.d_id) == id) {
 			ASSERT(*IO_idqpp == NULL);
 
@@ -453,28 +468,40 @@ xfs_qm_dqattach_one(
 
 
 /*
- * Given a udquot and gdquot, attach a ptr to the group dquot in the
- * udquot as a hint for future lookups.
+ * Given a udquot and group/project type, attach the group/project
+ * dquot pointer to the udquot as a hint for future lookups.
  */
 STATIC void
-xfs_qm_dqattach_grouphint(
-	xfs_dquot_t	*udq,
-	xfs_dquot_t	*gdq)
+xfs_qm_dqattach_hint(
+	struct xfs_inode	*ip,
+	int			type)
 {
-	xfs_dquot_t	*tmp;
+	struct xfs_dquot **dqhint;
+	struct xfs_dquot *dqp;
+	struct xfs_dquot *udq = ip->i_udquot;
 
 	xfs_dqlock(udq);
 
-	tmp = udq->q_gdquot;
-	if (tmp) {
-		if (tmp == gdq)
+	if (type == XFS_DQ_GROUP) {
+		dqp = ip->i_gdquot;
+		dqhint = &udq->q_gdquot;
+	} else {
+		dqp = ip->i_pdquot;
+		dqhint = &udq->q_pdquot;
+	}
+
+	if (*dqhint) {
+		struct xfs_dquot *tmp;
+
+		if (*dqhint == dqp)
 			goto done;
 
-		udq->q_gdquot = NULL;
+		tmp = *dqhint;
+		*dqhint = NULL;
 		xfs_qm_dqrele(tmp);
 	}
 
-	udq->q_gdquot = xfs_qm_dqhold(gdq);
+	*dqhint = xfs_qm_dqhold(dqp);
 done:
 	xfs_dqunlock(udq);
 }
@@ -527,12 +554,8 @@ xfs_qm_dqattach_locked(
 	}
 
 	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
-	if (XFS_IS_OQUOTA_ON(mp)) {
-		error = XFS_IS_GQUOTA_ON(mp) ?
-			xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP,
-						flags & XFS_QMOPT_DQALLOC,
-						ip->i_udquot, &ip->i_gdquot) :
-			xfs_qm_dqattach_one(ip, xfs_get_projid(ip), XFS_DQ_PROJ,
+	if (XFS_IS_GQUOTA_ON(mp)) {
+		error = xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP,
 						flags & XFS_QMOPT_DQALLOC,
 						ip->i_udquot, &ip->i_gdquot);
 		/*
@@ -544,14 +567,28 @@ xfs_qm_dqattach_locked(
 		nquotas++;
 	}
 
+	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
+	if (XFS_IS_PQUOTA_ON(mp)) {
+		error = xfs_qm_dqattach_one(ip, xfs_get_projid(ip), XFS_DQ_PROJ,
+						flags & XFS_QMOPT_DQALLOC,
+						ip->i_udquot, &ip->i_pdquot);
+		/*
+		 * Don't worry about the udquot that we may have
+		 * attached above. It'll get detached, if not already.
+		 */
+		if (error)
+			goto done;
+		nquotas++;
+	}
+
 	/*
-	 * Attach this group quota to the user quota as a hint.
+	 * Attach this group/project quota to the user quota as a hint.
 	 * This WON'T, in general, result in a thrash.
 	 */
-	if (nquotas == 2) {
+	if (nquotas > 1 && ip->i_udquot) {
 		ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
-		ASSERT(ip->i_udquot);
-		ASSERT(ip->i_gdquot);
+		ASSERT(ip->i_gdquot || !XFS_IS_GQUOTA_ON(mp));
+		ASSERT(ip->i_pdquot || !XFS_IS_PQUOTA_ON(mp));
 
 		/*
 		 * We do not have i_udquot locked at this point, but this check
@@ -560,7 +597,10 @@ xfs_qm_dqattach_locked(
 		 * succeed in general.
 		 */
 		if (ip->i_udquot->q_gdquot != ip->i_gdquot)
-			xfs_qm_dqattach_grouphint(ip->i_udquot, ip->i_gdquot);
+			xfs_qm_dqattach_hint(ip, XFS_DQ_GROUP);
+
+		if (ip->i_udquot->q_pdquot != ip->i_pdquot)
+			xfs_qm_dqattach_hint(ip, XFS_DQ_PROJ);
 	}
 
  done:
@@ -568,8 +608,10 @@ xfs_qm_dqattach_locked(
 	if (!error) {
 		if (XFS_IS_UQUOTA_ON(mp))
 			ASSERT(ip->i_udquot);
-		if (XFS_IS_OQUOTA_ON(mp))
+		if (XFS_IS_GQUOTA_ON(mp))
 			ASSERT(ip->i_gdquot);
+		if (XFS_IS_PQUOTA_ON(mp))
+			ASSERT(ip->i_pdquot);
 	}
 	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
 #endif
@@ -602,7 +644,7 @@ void
 xfs_qm_dqdetach(
 	xfs_inode_t	*ip)
 {
-	if (!(ip->i_udquot || ip->i_gdquot))
+	if (!(ip->i_udquot || ip->i_gdquot || ip->i_pdquot))
 		return;
 
 	trace_xfs_dquot_dqdetach(ip);
@@ -616,6 +658,10 @@ xfs_qm_dqdetach(
 		xfs_qm_dqrele(ip->i_gdquot);
 		ip->i_gdquot = NULL;
 	}
+	if (ip->i_pdquot) {
+		xfs_qm_dqrele(ip->i_pdquot);
+		ip->i_pdquot = NULL;
+	}
 }
 
 int
@@ -660,6 +706,7 @@ xfs_qm_init_quotainfo(
 
 	INIT_RADIX_TREE(&qinf->qi_uquota_tree, GFP_NOFS);
 	INIT_RADIX_TREE(&qinf->qi_gquota_tree, GFP_NOFS);
+	INIT_RADIX_TREE(&qinf->qi_pquota_tree, GFP_NOFS);
 	mutex_init(&qinf->qi_tree_lock);
 
 	INIT_LIST_HEAD(&qinf->qi_lru_list);
@@ -761,6 +808,10 @@ xfs_qm_destroy_quotainfo(
 		IRELE(qi->qi_gquotaip);
 		qi->qi_gquotaip = NULL;
 	}
+	if (qi->qi_pquotaip) {
+		IRELE(qi->qi_pquotaip);
+		qi->qi_pquotaip = NULL;
+	}
 	mutex_destroy(&qi->qi_quotaofflock);
 	kmem_free(qi);
 	mp->m_quotainfo = NULL;
@@ -1269,13 +1320,14 @@ xfs_qm_quotacheck(
 	LIST_HEAD		(buffer_list);
 	struct xfs_inode	*uip = mp->m_quotainfo->qi_uquotaip;
 	struct xfs_inode	*gip = mp->m_quotainfo->qi_gquotaip;
+	struct xfs_inode	*pip = mp->m_quotainfo->qi_pquotaip;
 
 	count = INT_MAX;
 	structsz = 1;
 	lastino = 0;
 	flags = 0;
 
-	ASSERT(uip || gip);
+	ASSERT(uip || gip || pip);
 	ASSERT(XFS_IS_QUOTA_RUNNING(mp));
 
 	xfs_notice(mp, "Quotacheck needed: Please wait.");
@@ -1294,13 +1346,19 @@ xfs_qm_quotacheck(
 	}
 
 	if (gip) {
-		error = xfs_qm_dqiterate(mp, gip, XFS_IS_GQUOTA_ON(mp) ?
-					 XFS_QMOPT_GQUOTA : XFS_QMOPT_PQUOTA,
+		error = xfs_qm_dqiterate(mp, gip, XFS_QMOPT_GQUOTA,
+					 &buffer_list);
+		if (error)
+			goto error_return;
+		flags |= XFS_GQUOTA_CHKD;
+	}
+
+	if (pip) {
+		error = xfs_qm_dqiterate(mp, pip, XFS_QMOPT_PQUOTA,
 					 &buffer_list);
 		if (error)
 			goto error_return;
-		flags |= XFS_IS_GQUOTA_ON(mp) ?
-					XFS_GQUOTA_CHKD : XFS_PQUOTA_CHKD;
+		flags |= XFS_PQUOTA_CHKD;
 	}
 
 	do {
@@ -1397,6 +1455,7 @@ xfs_qm_init_quotainos(
 {
 	struct xfs_inode	*uip = NULL;
 	struct xfs_inode	*gip = NULL;
+	struct xfs_inode	*pip = NULL;
 	int			error;
 	__int64_t		sbflags = 0;
 	uint			flags = 0;
@@ -1415,7 +1474,7 @@ xfs_qm_init_quotainos(
 			if (error)
 				return XFS_ERROR(error);
 		}
-		if (XFS_IS_OQUOTA_ON(mp) &&
+		if (XFS_IS_GQUOTA_ON(mp) &&
 		    mp->m_sb.sb_gquotino != NULLFSINO) {
 			ASSERT(mp->m_sb.sb_gquotino > 0);
 			error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
@@ -1423,6 +1482,15 @@ xfs_qm_init_quotainos(
 			if (error)
 				goto error_rele;
 		}
+		/* XXX: Use gquotino for now */
+		if (XFS_IS_PQUOTA_ON(mp) &&
+		    mp->m_sb.sb_gquotino != NULLFSINO) {
+			ASSERT(mp->m_sb.sb_gquotino > 0);
+			error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
+					     0, 0, &pip);
+			if (error)
+				goto error_rele;
+		}
 	} else {
 		flags |= XFS_QMOPT_SBVERSION;
 		sbflags |= (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO |
@@ -1430,7 +1498,7 @@ xfs_qm_init_quotainos(
 	}
 
 	/*
-	 * Create the two inodes, if they don't exist already. The changes
+	 * Create the three inodes, if they don't exist already. The changes
 	 * made above will get added to a transaction and logged in one of
 	 * the qino_alloc calls below.  If the device is readonly,
 	 * temporarily switch to read-write to do this.
@@ -1444,17 +1512,27 @@ xfs_qm_init_quotainos(
 
 		flags &= ~XFS_QMOPT_SBVERSION;
 	}
-	if (XFS_IS_OQUOTA_ON(mp) && gip == NULL) {
-		flags |= (XFS_IS_GQUOTA_ON(mp) ?
-				XFS_QMOPT_GQUOTA : XFS_QMOPT_PQUOTA);
+	if (XFS_IS_GQUOTA_ON(mp) && gip == NULL) {
 		error = xfs_qm_qino_alloc(mp, &gip,
-					  sbflags | XFS_SB_GQUOTINO, flags);
+					  sbflags | XFS_SB_GQUOTINO,
+					  flags | XFS_QMOPT_GQUOTA);
+		if (error)
+			goto error_rele;
+
+		flags &= ~XFS_QMOPT_SBVERSION;
+	}
+	if (XFS_IS_PQUOTA_ON(mp) && pip == NULL) {
+		/* XXX: Use XFS_SB_GQUOTINO for now */
+		error = xfs_qm_qino_alloc(mp, &pip,
+					  sbflags | XFS_SB_GQUOTINO,
+					  flags | XFS_QMOPT_PQUOTA);
 		if (error)
 			goto error_rele;
 	}
 
 	mp->m_quotainfo->qi_uquotaip = uip;
 	mp->m_quotainfo->qi_gquotaip = gip;
+	mp->m_quotainfo->qi_pquotaip = pip;
 
 	return 0;
 
@@ -1463,6 +1541,8 @@ error_rele:
 		IRELE(uip);
 	if (gip)
 		IRELE(gip);
+	if (pip)
+		IRELE(pip);
 	return XFS_ERROR(error);
 }
 
@@ -1657,11 +1737,13 @@ xfs_qm_vop_dqalloc(
 	prid_t			prid,
 	uint			flags,
 	struct xfs_dquot	**O_udqpp,
-	struct xfs_dquot	**O_gdqpp)
+	struct xfs_dquot	**O_gdqpp,
+	struct xfs_dquot	**O_pdqpp)
 {
 	struct xfs_mount	*mp = ip->i_mount;
 	struct xfs_dquot	*uq = NULL;
 	struct xfs_dquot	*gq = NULL;
+	struct xfs_dquot	*pq = NULL;
 	int			error;
 	uint			lockflags;
 
@@ -1741,24 +1823,25 @@ xfs_qm_vop_dqalloc(
 			ASSERT(ip->i_gdquot);
 			gq = xfs_qm_dqhold(ip->i_gdquot);
 		}
-	} else if ((flags & XFS_QMOPT_PQUOTA) && XFS_IS_PQUOTA_ON(mp)) {
+	}
+	if ((flags & XFS_QMOPT_PQUOTA) && XFS_IS_PQUOTA_ON(mp)) {
 		if (xfs_get_projid(ip) != prid) {
 			xfs_iunlock(ip, lockflags);
 			error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)prid,
 						 XFS_DQ_PROJ,
 						 XFS_QMOPT_DQALLOC |
 						 XFS_QMOPT_DOWARN,
-						 &gq);
+						 &pq);
 			if (error) {
 				ASSERT(error != ENOENT);
 				goto error_rele;
 			}
-			xfs_dqunlock(gq);
+			xfs_dqunlock(pq);
 			lockflags = XFS_ILOCK_SHARED;
 			xfs_ilock(ip, lockflags);
 		} else {
-			ASSERT(ip->i_gdquot);
-			gq = xfs_qm_dqhold(ip->i_gdquot);
+			ASSERT(ip->i_pdquot);
+			pq = xfs_qm_dqhold(ip->i_pdquot);
 		}
 	}
 	if (uq)
@@ -1773,9 +1856,15 @@ xfs_qm_vop_dqalloc(
 		*O_gdqpp = gq;
 	else if (gq)
 		xfs_qm_dqrele(gq);
+	if (O_pdqpp)
+		*O_pdqpp = pq;
+	else if (pq)
+		xfs_qm_dqrele(pq);
 	return 0;
 
 error_rele:
+	if (gq)
+		xfs_qm_dqrele(gq);
 	if (uq)
 		xfs_qm_dqrele(uq);
 	return error;
@@ -1830,14 +1919,17 @@ xfs_qm_vop_chown_reserve(
 	struct xfs_inode	*ip,
 	struct xfs_dquot	*udqp,
 	struct xfs_dquot	*gdqp,
+	struct xfs_dquot	*pdqp,
 	uint			flags)
 {
 	struct xfs_mount	*mp = ip->i_mount;
 	uint			delblks, blkflags, prjflags = 0;
 	struct xfs_dquot	*udq_unres = NULL;
 	struct xfs_dquot	*gdq_unres = NULL;
+	struct xfs_dquot	*pdq_unres = NULL;
 	struct xfs_dquot	*udq_delblks = NULL;
 	struct xfs_dquot	*gdq_delblks = NULL;
+	struct xfs_dquot	*pdq_delblks = NULL;
 	int			error;
 
 
@@ -1861,24 +1953,28 @@ xfs_qm_vop_chown_reserve(
 			udq_unres = ip->i_udquot;
 		}
 	}
-	if (XFS_IS_OQUOTA_ON(ip->i_mount) && gdqp) {
-		if (XFS_IS_PQUOTA_ON(ip->i_mount) &&
-		     xfs_get_projid(ip) != be32_to_cpu(gdqp->q_core.d_id))
-			prjflags = XFS_QMOPT_ENOSPC;
-
-		if (prjflags ||
-		    (XFS_IS_GQUOTA_ON(ip->i_mount) &&
-		     ip->i_d.di_gid != be32_to_cpu(gdqp->q_core.d_id))) {
-			gdq_delblks = gdqp;
-			if (delblks) {
-				ASSERT(ip->i_gdquot);
-				gdq_unres = ip->i_gdquot;
-			}
+	if (XFS_IS_GQUOTA_ON(ip->i_mount) && gdqp &&
+	    ip->i_d.di_gid != be32_to_cpu(gdqp->q_core.d_id)) {
+		gdq_delblks = gdqp;
+		if (delblks) {
+			ASSERT(ip->i_gdquot);
+			gdq_unres = ip->i_gdquot;
+		}
+	}
+
+	if (XFS_IS_PQUOTA_ON(ip->i_mount) && pdqp &&
+	    xfs_get_projid(ip) != be32_to_cpu(pdqp->q_core.d_id)) {
+		prjflags = XFS_QMOPT_ENOSPC;
+		pdq_delblks = pdqp;
+		if (delblks) {
+			ASSERT(ip->i_pdquot);
+			pdq_unres = ip->i_pdquot;
 		}
 	}
 
 	error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount,
-				udq_delblks, gdq_delblks, ip->i_d.di_nblocks, 1,
+				udq_delblks, gdq_delblks, pdq_delblks,
+				ip->i_d.di_nblocks, 1,
 				flags | blkflags | prjflags);
 	if (error)
 		return error;
@@ -1893,16 +1989,17 @@ xfs_qm_vop_chown_reserve(
 		/*
 		 * Do the reservations first. Unreservation can't fail.
 		 */
-		ASSERT(udq_delblks || gdq_delblks);
-		ASSERT(udq_unres || gdq_unres);
+		ASSERT(udq_delblks || gdq_delblks || pdq_delblks);
+		ASSERT(udq_unres || gdq_unres || pdq_unres);
 		error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
-			    udq_delblks, gdq_delblks, (xfs_qcnt_t)delblks, 0,
+			    udq_delblks, gdq_delblks, pdq_delblks,
+			    (xfs_qcnt_t)delblks, 0,
 			    flags | blkflags | prjflags);
 		if (error)
 			return error;
 		xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
-				udq_unres, gdq_unres, -((xfs_qcnt_t)delblks), 0,
-				blkflags);
+				udq_unres, gdq_unres, pdq_unres,
+				-((xfs_qcnt_t)delblks), 0, blkflags);
 	}
 
 	return (0);
@@ -1941,7 +2038,8 @@ xfs_qm_vop_create_dqattach(
 	struct xfs_trans	*tp,
 	struct xfs_inode	*ip,
 	struct xfs_dquot	*udqp,
-	struct xfs_dquot	*gdqp)
+	struct xfs_dquot	*gdqp,
+	struct xfs_dquot	*pdqp)
 {
 	struct xfs_mount	*mp = tp->t_mountp;
 
@@ -1961,13 +2059,18 @@ xfs_qm_vop_create_dqattach(
 	}
 	if (gdqp) {
 		ASSERT(ip->i_gdquot == NULL);
-		ASSERT(XFS_IS_OQUOTA_ON(mp));
-		ASSERT((XFS_IS_GQUOTA_ON(mp) ?
-			ip->i_d.di_gid : xfs_get_projid(ip)) ==
-				be32_to_cpu(gdqp->q_core.d_id));
-
+		ASSERT(XFS_IS_GQUOTA_ON(mp));
+		ASSERT(ip->i_d.di_gid == be32_to_cpu(gdqp->q_core.d_id));
 		ip->i_gdquot = xfs_qm_dqhold(gdqp);
 		xfs_trans_mod_dquot(tp, gdqp, XFS_TRANS_DQ_ICOUNT, 1);
 	}
+	if (pdqp) {
+		ASSERT(ip->i_pdquot == NULL);
+		ASSERT(XFS_IS_PQUOTA_ON(mp));
+		ASSERT(xfs_get_projid(ip) == be32_to_cpu(pdqp->q_core.d_id));
+
+		ip->i_pdquot = xfs_qm_dqhold(pdqp);
+		xfs_trans_mod_dquot(tp, pdqp, XFS_TRANS_DQ_ICOUNT, 1);
+	}
 }
 
diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
index 9efec02..dcf8063 100644
--- a/fs/xfs/xfs_qm.h
+++ b/fs/xfs/xfs_qm.h
@@ -44,9 +44,11 @@ extern struct kmem_zone	*xfs_qm_dqtrxzone;
 typedef struct xfs_quotainfo {
 	struct radix_tree_root	qi_uquota_tree;
 	struct radix_tree_root	qi_gquota_tree;
+	struct radix_tree_root	qi_pquota_tree;
 	struct mutex		qi_tree_lock;
 	struct xfs_inode	*qi_uquotaip;
 	struct xfs_inode	*qi_gquotaip;
+	struct xfs_inode	*qi_pquotaip;
 	struct list_head	qi_lru_list;
 	struct mutex		qi_lru_lock;
 	int			qi_lru_count;
@@ -78,8 +80,9 @@ xfs_dquot_tree(
 	case XFS_DQ_USER:
 		return &qi->qi_uquota_tree;
 	case XFS_DQ_GROUP:
-	case XFS_DQ_PROJ:
 		return &qi->qi_gquota_tree;
+	case XFS_DQ_PROJ:
+		return &qi->qi_pquota_tree;
 	default:
 		ASSERT(0);
 	}
@@ -93,8 +96,9 @@ xfs_dq_to_quota_inode(struct xfs_dquot *dqp)
 	case XFS_DQ_USER:
 		return dqp->q_mount->m_quotainfo->qi_uquotaip;
 	case XFS_DQ_GROUP:
-	case XFS_DQ_PROJ:
 		return dqp->q_mount->m_quotainfo->qi_gquotaip;
+	case XFS_DQ_PROJ:
+		return dqp->q_mount->m_quotainfo->qi_pquotaip;
 	default:
 		ASSERT(0);
 	}
@@ -107,18 +111,20 @@ extern void	xfs_trans_mod_dquot(struct xfs_trans *,
 					struct xfs_dquot *, uint, long);
 extern int	xfs_trans_reserve_quota_bydquots(struct xfs_trans *,
 			struct xfs_mount *, struct xfs_dquot *,
-			struct xfs_dquot *, long, long, uint);
+			struct xfs_dquot *, struct xfs_dquot *,
+			long, long, uint);
 extern void	xfs_trans_dqjoin(struct xfs_trans *, struct xfs_dquot *);
 extern void	xfs_trans_log_dquot(struct xfs_trans *, struct xfs_dquot *);
 
 /*
- * We keep the usr and grp dquots separately so that locking will be easier
- * to do at commit time. All transactions that we know of at this point
+ * We keep the usr, grp, and prj dquots separately so that locking will be
+ * easier to do at commit time. All transactions that we know of at this point
  * affect no more than two dquots of one type. Hence, the TRANS_MAXDQS value.
  */
 enum {
 	XFS_QM_TRANS_USR = 0,
 	XFS_QM_TRANS_GRP,
+	XFS_QM_TRANS_PRJ,
 	XFS_QM_TRANS_DQTYPES
 };
 #define XFS_QM_TRANS_MAXDQS		2
diff --git a/fs/xfs/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c
index 2d02eac..72a4fdd 100644
--- a/fs/xfs/xfs_qm_bhv.c
+++ b/fs/xfs/xfs_qm_bhv.c
@@ -115,7 +115,7 @@ xfs_qm_newmount(
 	     (pquotaondisk && !XFS_IS_PQUOTA_ON(mp)) ||
 	    (!pquotaondisk &&  XFS_IS_PQUOTA_ON(mp)) ||
 	     (gquotaondisk && !XFS_IS_GQUOTA_ON(mp)) ||
-	    (!gquotaondisk &&  XFS_IS_OQUOTA_ON(mp)))  &&
+	    (!gquotaondisk &&  XFS_IS_GQUOTA_ON(mp)))  &&
 	    xfs_dev_is_read_only(mp, "changing quota state")) {
 		xfs_warn(mp, "please mount with%s%s%s%s.",
 			(!quotaondisk ? "out quota" : ""),
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index a08801a..b936383 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -119,7 +119,8 @@ xfs_qm_scall_quotaoff(
 		dqtype |= XFS_QMOPT_GQUOTA;
 		flags |= (XFS_GQUOTA_CHKD | XFS_GQUOTA_ENFD);
 		inactivate_flags |= XFS_GQUOTA_ACTIVE;
-	} else if (flags & XFS_PQUOTA_ACCT) {
+	}
+	if (flags & XFS_PQUOTA_ACCT) {
 		dqtype |= XFS_QMOPT_PQUOTA;
 		flags |= (XFS_PQUOTA_CHKD | XFS_PQUOTA_ENFD);
 		inactivate_flags |= XFS_PQUOTA_ACTIVE;
@@ -214,10 +215,14 @@ xfs_qm_scall_quotaoff(
 		IRELE(q->qi_uquotaip);
 		q->qi_uquotaip = NULL;
 	}
-	if ((dqtype & (XFS_QMOPT_GQUOTA|XFS_QMOPT_PQUOTA)) && q->qi_gquotaip) {
+	if ((dqtype & XFS_QMOPT_GQUOTA) && q->qi_gquotaip) {
 		IRELE(q->qi_gquotaip);
 		q->qi_gquotaip = NULL;
 	}
+	if ((dqtype & XFS_QMOPT_PQUOTA) && q->qi_pquotaip) {
+		IRELE(q->qi_pquotaip);
+		q->qi_pquotaip = NULL;
+	}
 
 out_unlock:
 	mutex_unlock(&q->qi_quotaofflock);
@@ -859,9 +864,11 @@ xfs_dqrele_inode(
 {
 	/* skip quota inodes */
 	if (ip == ip->i_mount->m_quotainfo->qi_uquotaip ||
-	    ip == ip->i_mount->m_quotainfo->qi_gquotaip) {
+	    ip == ip->i_mount->m_quotainfo->qi_gquotaip ||
+	    ip == ip->i_mount->m_quotainfo->qi_pquotaip) {
 		ASSERT(ip->i_udquot == NULL);
 		ASSERT(ip->i_gdquot == NULL);
+		ASSERT(ip->i_pdquot == NULL);
 		return 0;
 	}
 
@@ -870,10 +877,14 @@ xfs_dqrele_inode(
 		xfs_qm_dqrele(ip->i_udquot);
 		ip->i_udquot = NULL;
 	}
-	if (flags & (XFS_PQUOTA_ACCT|XFS_GQUOTA_ACCT) && ip->i_gdquot) {
+	if ((flags & XFS_GQUOTA_ACCT) && ip->i_gdquot) {
 		xfs_qm_dqrele(ip->i_gdquot);
 		ip->i_gdquot = NULL;
 	}
+	if ((flags & XFS_PQUOTA_ACCT) && ip->i_pdquot) {
+		xfs_qm_dqrele(ip->i_pdquot);
+		ip->i_pdquot = NULL;
+	}
 	xfs_iunlock(ip, XFS_ILOCK_EXCL);
 	return 0;
 }
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h
index c3483ba..5faf654 100644
--- a/fs/xfs/xfs_quota.h
+++ b/fs/xfs/xfs_quota.h
@@ -271,10 +271,10 @@ typedef struct xfs_qoff_logformat {
  * we didn't have the inode locked, the appropriate dquot(s) will be
  * attached atomically.
  */
-#define XFS_NOT_DQATTACHED(mp, ip) ((XFS_IS_UQUOTA_ON(mp) &&\
-				     (ip)->i_udquot == NULL) || \
-				    (XFS_IS_OQUOTA_ON(mp) && \
-				     (ip)->i_gdquot == NULL))
+#define XFS_NOT_DQATTACHED(mp, ip) \
+	((XFS_IS_UQUOTA_ON(mp) && (ip)->i_udquot == NULL) || \
+	 (XFS_IS_GQUOTA_ON(mp) && (ip)->i_gdquot == NULL) || \
+	 (XFS_IS_PQUOTA_ON(mp) && (ip)->i_pdquot == NULL))
 
 #define XFS_QM_NEED_QUOTACHECK(mp) \
 	((XFS_IS_UQUOTA_ON(mp) && \
@@ -329,17 +329,18 @@ extern int xfs_trans_reserve_quota_nblks(struct xfs_trans *,
 		struct xfs_inode *, long, long, uint);
 extern int xfs_trans_reserve_quota_bydquots(struct xfs_trans *,
 		struct xfs_mount *, struct xfs_dquot *,
-		struct xfs_dquot *, long, long, uint);
+		struct xfs_dquot *, struct xfs_dquot *, long, long, uint);
 
 extern int xfs_qm_vop_dqalloc(struct xfs_inode *, uid_t, gid_t, prid_t, uint,
-		struct xfs_dquot **, struct xfs_dquot **);
+		struct xfs_dquot **, struct xfs_dquot **, struct xfs_dquot **);
 extern void xfs_qm_vop_create_dqattach(struct xfs_trans *, struct xfs_inode *,
-		struct xfs_dquot *, struct xfs_dquot *);
+		struct xfs_dquot *, struct xfs_dquot *, struct xfs_dquot *);
 extern int xfs_qm_vop_rename_dqattach(struct xfs_inode **);
 extern struct xfs_dquot *xfs_qm_vop_chown(struct xfs_trans *,
 		struct xfs_inode *, struct xfs_dquot **, struct xfs_dquot *);
 extern int xfs_qm_vop_chown_reserve(struct xfs_trans *, struct xfs_inode *,
-		struct xfs_dquot *, struct xfs_dquot *, uint);
+		struct xfs_dquot *, struct xfs_dquot *,
+		struct xfs_dquot *, uint);
 extern int xfs_qm_dqattach(struct xfs_inode *, uint);
 extern int xfs_qm_dqattach_locked(struct xfs_inode *, uint);
 extern void xfs_qm_dqdetach(struct xfs_inode *);
@@ -353,10 +354,12 @@ extern void xfs_qm_unmount_quotas(struct xfs_mount *);
 #else
 static inline int
 xfs_qm_vop_dqalloc(struct xfs_inode *ip, uid_t uid, gid_t gid, prid_t prid,
-		uint flags, struct xfs_dquot **udqp, struct xfs_dquot **gdqp)
+		uint flags, struct xfs_dquot **udqp, struct xfs_dquot **gdqp,
+		struct xfs_dquot **pdqp)
 {
 	*udqp = NULL;
 	*gdqp = NULL;
+	*pdqp = NULL;
 	return 0;
 }
 #define xfs_trans_dup_dqinfo(tp, tp2)
@@ -371,14 +374,15 @@ static inline int xfs_trans_reserve_quota_nblks(struct xfs_trans *tp,
 }
 static inline int xfs_trans_reserve_quota_bydquots(struct xfs_trans *tp,
 		struct xfs_mount *mp, struct xfs_dquot *udqp,
-		struct xfs_dquot *gdqp, long nblks, long nions, uint flags)
+		struct xfs_dquot *gdqp, struct xfs_dquot *pdqp,
+		long nblks, long nions, uint flags)
 {
 	return 0;
 }
-#define xfs_qm_vop_create_dqattach(tp, ip, u, g)
+#define xfs_qm_vop_create_dqattach(tp, ip, u, g, p)
 #define xfs_qm_vop_rename_dqattach(it)					(0)
 #define xfs_qm_vop_chown(tp, ip, old, new)				(NULL)
-#define xfs_qm_vop_chown_reserve(tp, ip, u, g, fl)			(0)
+#define xfs_qm_vop_chown_reserve(tp, ip, u, g, p, fl)			(0)
 #define xfs_qm_dqattach(ip, fl)						(0)
 #define xfs_qm_dqattach_locked(ip, fl)					(0)
 #define xfs_qm_dqdetach(ip)
@@ -392,8 +396,8 @@ static inline int xfs_trans_reserve_quota_bydquots(struct xfs_trans *tp,
 
 #define xfs_trans_unreserve_quota_nblks(tp, ip, nblks, ninos, flags) \
 	xfs_trans_reserve_quota_nblks(tp, ip, -(nblks), -(ninos), flags)
-#define xfs_trans_reserve_quota(tp, mp, ud, gd, nb, ni, f) \
-	xfs_trans_reserve_quota_bydquots(tp, mp, ud, gd, nb, ni, \
+#define xfs_trans_reserve_quota(tp, mp, ud, gd, pd, nb, ni, f) \
+	xfs_trans_reserve_quota_bydquots(tp, mp, ud, gd, pd, nb, ni, \
 				f | XFS_QMOPT_RES_REGBLKS)
 
 extern int xfs_qm_dqcheck(struct xfs_mount *, xfs_disk_dquot_t *,
diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c
index e830fb5..f4895b6 100644
--- a/fs/xfs/xfs_symlink.c
+++ b/fs/xfs/xfs_symlink.c
@@ -360,6 +360,7 @@ xfs_symlink(
 	prid_t			prid;
 	struct xfs_dquot	*udqp = NULL;
 	struct xfs_dquot	*gdqp = NULL;
+	struct xfs_dquot	*pdqp = NULL;
 	uint			resblks;
 
 	*ipp = NULL;
@@ -386,7 +387,7 @@ xfs_symlink(
 	 * Make sure that we have allocated dquot(s) on disk.
 	 */
 	error = xfs_qm_vop_dqalloc(dp, current_fsuid(), current_fsgid(), prid,
-			XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
+		XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp, &pdqp);
 	if (error)
 		goto std_return;
 
@@ -427,7 +428,8 @@ xfs_symlink(
 	/*
 	 * Reserve disk quota : blocks and inode.
 	 */
-	error = xfs_trans_reserve_quota(tp, mp, udqp, gdqp, resblks, 1, 0);
+	error = xfs_trans_reserve_quota(tp, mp, udqp, gdqp,
+						pdqp, resblks, 1, 0);
 	if (error)
 		goto error_return;
 
@@ -465,7 +467,7 @@ xfs_symlink(
 	/*
 	 * Also attach the dquot(s) to it, if applicable.
 	 */
-	xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp);
+	xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp);
 
 	if (resblks)
 		resblks -= XFS_IALLOC_SPACE_RES(mp);
@@ -563,6 +565,7 @@ xfs_symlink(
 	error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
 	xfs_qm_dqrele(udqp);
 	xfs_qm_dqrele(gdqp);
+	xfs_qm_dqrele(pdqp);
 
 	*ipp = ip;
 	return 0;
@@ -576,6 +579,7 @@ xfs_symlink(
 	xfs_trans_cancel(tp, cancel_flags);
 	xfs_qm_dqrele(udqp);
 	xfs_qm_dqrele(gdqp);
+	xfs_qm_dqrele(pdqp);
 
 	if (unlock_dp_on_error)
 		xfs_iunlock(dp, XFS_ILOCK_EXCL);
diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
index 3ba64d5..e3a8b25 100644
--- a/fs/xfs/xfs_trans_dquot.c
+++ b/fs/xfs/xfs_trans_dquot.c
@@ -163,8 +163,10 @@ xfs_trans_mod_dquot_byino(
 
 	if (XFS_IS_UQUOTA_ON(mp) && ip->i_udquot)
 		(void) xfs_trans_mod_dquot(tp, ip->i_udquot, field, delta);
-	if (XFS_IS_OQUOTA_ON(mp) && ip->i_gdquot)
+	if (XFS_IS_GQUOTA_ON(mp) && ip->i_gdquot)
 		(void) xfs_trans_mod_dquot(tp, ip->i_gdquot, field, delta);
+	if (XFS_IS_PQUOTA_ON(mp) && ip->i_pdquot)
+		(void) xfs_trans_mod_dquot(tp, ip->i_pdquot, field, delta);
 }
 
 STATIC struct xfs_dqtrx *
@@ -177,8 +179,12 @@ xfs_trans_get_dqtrx(
 
 	if (XFS_QM_ISUDQ(dqp))
 		qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_USR];
-	else
+	else if (XFS_QM_ISGDQ(dqp))
 		qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_GRP];
+	else if (XFS_QM_ISPDQ(dqp))
+		qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_PRJ];
+	else
+		return NULL;
 
 	for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
 		if (qa[i].qt_dquot == NULL ||
@@ -728,8 +734,8 @@ error_return:
 
 /*
  * Given dquot(s), make disk block and/or inode reservations against them.
- * The fact that this does the reservation against both the usr and
- * grp/prj quotas is important, because this follows a both-or-nothing
+ * The fact that this does the reservation against user, group and
+ * project quotas is important, because this follows a all-or-nothing
  * approach.
  *
  * flags = XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown.
@@ -744,6 +750,7 @@ xfs_trans_reserve_quota_bydquots(
 	struct xfs_mount	*mp,
 	struct xfs_dquot	*udqp,
 	struct xfs_dquot	*gdqp,
+	struct xfs_dquot	*pdqp,
 	long			nblks,
 	long			ninos,
 	uint			flags)
@@ -771,11 +778,21 @@ xfs_trans_reserve_quota_bydquots(
 			goto unwind_usr;
 	}
 
+	if (pdqp) {
+		error = xfs_trans_dqresv(tp, mp, pdqp, nblks, ninos, flags);
+		if (error)
+			goto unwind_grp;
+	}
+
 	/*
 	 * Didn't change anything critical, so, no need to log
 	 */
 	return 0;
 
+unwind_grp:
+	flags |= XFS_QMOPT_FORCE_RES;
+	if (gdqp)
+		xfs_trans_dqresv(tp, mp, gdqp, -nblks, -ninos, flags);
 unwind_usr:
 	flags |= XFS_QMOPT_FORCE_RES;
 	if (udqp)
@@ -817,6 +834,7 @@ xfs_trans_reserve_quota_nblks(
 	 */
 	return xfs_trans_reserve_quota_bydquots(tp, mp,
 						ip->i_udquot, ip->i_gdquot,
+						ip->i_pdquot,
 						nblks, ninos, flags);
 }
 
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 42c0ef2..dc730ac 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -489,6 +489,7 @@ xfs_create(
 	prid_t			prid;
 	struct xfs_dquot	*udqp = NULL;
 	struct xfs_dquot	*gdqp = NULL;
+	struct xfs_dquot	*pdqp = NULL;
 	uint			resblks;
 	uint			log_res;
 	uint			log_count;
@@ -507,7 +508,8 @@ xfs_create(
 	 * Make sure that we have allocated dquot(s) on disk.
 	 */
 	error = xfs_qm_vop_dqalloc(dp, current_fsuid(), current_fsgid(), prid,
-			XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
+					XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT,
+					&udqp, &gdqp, &pdqp);
 	if (error)
 		return error;
 
@@ -559,7 +561,8 @@ xfs_create(
 	/*
 	 * Reserve disk quota and the inode.
 	 */
-	error = xfs_trans_reserve_quota(tp, mp, udqp, gdqp, resblks, 1, 0);
+	error = xfs_trans_reserve_quota(tp, mp, udqp, gdqp,
+						pdqp, resblks, 1, 0);
 	if (error)
 		goto out_trans_cancel;
 
@@ -623,7 +626,7 @@ xfs_create(
 	 * These ids of the inode couldn't have changed since the new
 	 * inode has been locked ever since it was created.
 	 */
-	xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp);
+	xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp);
 
 	error = xfs_bmap_finish(&tp, &free_list, &committed);
 	if (error)
@@ -635,6 +638,7 @@ xfs_create(
 
 	xfs_qm_dqrele(udqp);
 	xfs_qm_dqrele(gdqp);
+	xfs_qm_dqrele(pdqp);
 
 	*ipp = ip;
 	return 0;
@@ -656,6 +660,7 @@ xfs_create(
 
 	xfs_qm_dqrele(udqp);
 	xfs_qm_dqrele(gdqp);
+	xfs_qm_dqrele(pdqp);
 
 	if (unlock_dp_on_error)
 		xfs_iunlock(dp, XFS_ILOCK_EXCL);
@@ -1568,7 +1573,7 @@ xfs_free_file_space(
 		}
 		xfs_ilock(ip, XFS_ILOCK_EXCL);
 		error = xfs_trans_reserve_quota(tp, mp,
-				ip->i_udquot, ip->i_gdquot,
+				ip->i_udquot, ip->i_gdquot, ip->i_pdquot,
 				resblks, 0, XFS_QMOPT_RES_REGBLKS);
 		if (error)
 			goto error1;
-- 
1.7.1

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v10 09/11] xfs: Start using pquotaino from the superblock.
  2013-06-27 22:25 [PATCH v10 00/11] Allow pquota and gquota to be used together Chandra Seetharaman
                   ` (7 preceding siblings ...)
  2013-06-27 22:25 ` [PATCH v10 08/11] xfs: Add pquota fields where gquota is used Chandra Seetharaman
@ 2013-06-27 22:25 ` Chandra Seetharaman
  2013-07-01  2:06   ` Dave Chinner
  2013-06-27 22:25 ` [PATCH v10 10/11] quota: Add proper versioning support to fs_quota_stat Chandra Seetharaman
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 40+ messages in thread
From: Chandra Seetharaman @ 2013-06-27 22:25 UTC (permalink / raw)
  To: xfs; +Cc: Chandra Seetharaman

Start using pquotino and define a macro to check if the
superblock has pquotino.

Keep backward compatibilty by alowing mount of older superblock
with no separate pquota inode.

Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
---
 fs/xfs/xfs_fsops.c             |    3 +-
 fs/xfs/xfs_mount.c             |   44 ++++++++++++++++++++++++++++++++++-----
 fs/xfs/xfs_qm.c                |   29 ++++++++++++++++----------
 fs/xfs/xfs_qm_syscalls.c       |   24 +++++++++++++++++++--
 fs/xfs/xfs_quota.h             |    8 -------
 fs/xfs/xfs_sb.h                |   16 +++++++++++++-
 fs/xfs/xfs_super.c             |   14 +++++++-----
 include/uapi/linux/dqblk_xfs.h |    1 +
 8 files changed, 103 insertions(+), 36 deletions(-)

diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 614eb0c..3bf05f4 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -501,7 +501,8 @@ xfs_growfs_data_private(
 				error, agno);
 			break;
 		}
-		xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, XFS_SB_ALL_BITS);
+		xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb,
+				xfs_sb_all_bits(&mp->m_sb));
 
 		/*
 		 * If we get an error writing out the alternate superblocks,
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 2b0ba35..27c5833 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -336,12 +336,17 @@ xfs_mount_validate_sb(
 		return XFS_ERROR(EWRONGFS);
 	}
 
-	if ((sbp->sb_qflags & (XFS_OQUOTA_ENFD | XFS_OQUOTA_CHKD)) &&
-			(sbp->sb_qflags & (XFS_PQUOTA_ENFD | XFS_GQUOTA_ENFD |
-				XFS_PQUOTA_CHKD | XFS_GQUOTA_CHKD))) {
-		xfs_notice(mp,
-"Super block has XFS_OQUOTA bits along with XFS_PQUOTA and/or XFS_GQUOTA bits.\n");
-		return XFS_ERROR(EFSCORRUPTED);
+	if (xfs_sb_version_has_pquota(sbp)) {
+		if (sbp->sb_qflags & (XFS_OQUOTA_ENFD | XFS_OQUOTA_CHKD)) {
+			xfs_notice(mp,
+			   "Version 5 of Super block has XFS_OQUOTA bits.\n");
+			return XFS_ERROR(EFSCORRUPTED);
+		}
+	} else if (sbp->sb_qflags & (XFS_PQUOTA_ENFD | XFS_GQUOTA_ENFD |
+				XFS_PQUOTA_CHKD | XFS_GQUOTA_CHKD)) {
+			xfs_notice(mp,
+"Superblock earlier than Version 5 has XFS_[PQ]UOTA_{ENFD|CHKD} bits.\n");
+			return XFS_ERROR(EFSCORRUPTED);
 	}
 
 	/*
@@ -572,6 +577,10 @@ out_unwind:
 static void
 xfs_sb_quota_from_disk(struct xfs_sb *sbp)
 {
+
+	if (xfs_sb_version_has_pquota(sbp))
+		return;
+
 	if (sbp->sb_qflags & XFS_OQUOTA_ENFD)
 		sbp->sb_qflags |= (sbp->sb_qflags & XFS_PQUOTA_ACCT) ?
 					XFS_PQUOTA_ENFD : XFS_GQUOTA_ENFD;
@@ -650,6 +659,13 @@ xfs_sb_quota_to_disk(
 {
 	__uint16_t	qflags = from->sb_qflags;
 
+	/*
+	 * We need to do these manipilations only if we are working
+	 * with an older version of on-disk superblock.
+	 */
+	if (xfs_sb_version_has_pquota(from))
+		return;
+
 	if (*fields & XFS_SB_QFLAGS) {
 		/*
 		 * The in-core version of sb_qflags do not have
@@ -669,6 +685,10 @@ xfs_sb_quota_to_disk(
 		to->sb_qflags = cpu_to_be16(qflags);
 		*fields &= ~XFS_SB_QFLAGS;
 	}
+	if (*fields & XFS_SB_PQUOTINO) {
+		to->sb_gquotino = cpu_to_be64(from->sb_pquotino);
+		*fields &= ~XFS_SB_PQUOTINO;
+	}
 }
 
 /*
@@ -885,6 +905,18 @@ reread:
 	 */
 	xfs_sb_from_disk(&mp->m_sb, XFS_BUF_TO_SBP(bp));
 
+	if (!xfs_sb_version_has_pquota(&mp->m_sb) && (XFS_IS_PQUOTA_ON(mp))) {
+		/*
+		 * On disk superblock only has sb_gquotino, and incore
+		 * superblock has both sb_gquotino and sb_pquotino.
+		 * But, only one them is supported at any point of time.
+		 * So, if PQUOTA is set in disk superblock, copy over
+		 * sb_gquotino to sb_pquotino.
+		 */
+		mp->m_sb.sb_pquotino = mp->m_sb.sb_gquotino;
+		mp->m_sb.sb_gquotino = NULLFSINO;
+	}
+
 	xfs_sb_quota_from_disk(&mp->m_sb);
 	/*
 	 * We must be able to do sector-sized and sector-aligned IO.
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 42055ca..473f4dd 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -857,22 +857,21 @@ xfs_qm_qino_alloc(
 	spin_lock(&mp->m_sb_lock);
 	if (flags & XFS_QMOPT_SBVERSION) {
 		ASSERT(!xfs_sb_version_hasquota(&mp->m_sb));
-		ASSERT((sbfields & (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO |
-				   XFS_SB_GQUOTINO | XFS_SB_QFLAGS)) ==
-		       (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO |
-			XFS_SB_GQUOTINO | XFS_SB_QFLAGS));
 
 		xfs_sb_version_addquota(&mp->m_sb);
 		mp->m_sb.sb_uquotino = NULLFSINO;
 		mp->m_sb.sb_gquotino = NULLFSINO;
+		mp->m_sb.sb_pquotino = NULLFSINO;
 
 		/* qflags will get updated _after_ quotacheck */
 		mp->m_sb.sb_qflags = 0;
 	}
 	if (flags & XFS_QMOPT_UQUOTA)
 		mp->m_sb.sb_uquotino = (*ip)->i_ino;
-	else
+	else if (flags & XFS_QMOPT_GQUOTA)
 		mp->m_sb.sb_gquotino = (*ip)->i_ino;
+	else
+		mp->m_sb.sb_pquotino = (*ip)->i_ino;
 	spin_unlock(&mp->m_sb_lock);
 	xfs_mod_sb(tp, sbfields);
 
@@ -1482,11 +1481,10 @@ xfs_qm_init_quotainos(
 			if (error)
 				goto error_rele;
 		}
-		/* XXX: Use gquotino for now */
 		if (XFS_IS_PQUOTA_ON(mp) &&
-		    mp->m_sb.sb_gquotino != NULLFSINO) {
-			ASSERT(mp->m_sb.sb_gquotino > 0);
-			error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
+		    mp->m_sb.sb_pquotino != NULLFSINO) {
+			ASSERT(mp->m_sb.sb_pquotino > 0);
+			error = xfs_iget(mp, NULL, mp->m_sb.sb_pquotino,
 					     0, 0, &pip);
 			if (error)
 				goto error_rele;
@@ -1495,6 +1493,8 @@ xfs_qm_init_quotainos(
 		flags |= XFS_QMOPT_SBVERSION;
 		sbflags |= (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO |
 			    XFS_SB_GQUOTINO | XFS_SB_QFLAGS);
+		if (xfs_sb_version_has_pquota(&mp->m_sb))
+			sbflags |= XFS_SB_PQUOTINO;
 	}
 
 	/*
@@ -1522,9 +1522,16 @@ xfs_qm_init_quotainos(
 		flags &= ~XFS_QMOPT_SBVERSION;
 	}
 	if (XFS_IS_PQUOTA_ON(mp) && pip == NULL) {
-		/* XXX: Use XFS_SB_GQUOTINO for now */
+		if (!xfs_sb_version_has_pquota(&mp->m_sb))
+			/*
+			 * If our superblock is an earlier version, we can
+			 * use either XFS_SB_GQUOTINO or XFS_SB_PQUOTINO
+			 * but not both. Clear XFS_SB_GQUOTINO as it might
+			 * be set above.
+			 */
+			sbflags &= ~XFS_SB_GQUOTINO;
 		error = xfs_qm_qino_alloc(mp, &pip,
-					  sbflags | XFS_SB_GQUOTINO,
+					  sbflags | XFS_SB_PQUOTINO,
 					  flags | XFS_QMOPT_PQUOTA);
 		if (error)
 			goto error_rele;
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index b936383..f42b585 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -201,8 +201,7 @@ xfs_qm_scall_quotaoff(
 	/*
 	 * If quotas is completely disabled, close shop.
 	 */
-	if (((flags & XFS_MOUNT_QUOTA_ALL) == XFS_MOUNT_QUOTA_SET1) ||
-	    ((flags & XFS_MOUNT_QUOTA_ALL) == XFS_MOUNT_QUOTA_SET2)) {
+	if ((flags & XFS_MOUNT_QUOTA_ALL) == XFS_MOUNT_QUOTA_ALL) {
 		mutex_unlock(&q->qi_quotaofflock);
 		xfs_qm_destroy_quotainfo(mp);
 		return (0);
@@ -297,8 +296,10 @@ xfs_qm_scall_trunc_qfiles(
 
 	if (flags & XFS_DQ_USER)
 		error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_uquotino);
-	if (flags & (XFS_DQ_GROUP|XFS_DQ_PROJ))
+	if (flags & XFS_DQ_GROUP)
 		error2 = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_gquotino);
+	if (flags & XFS_DQ_PROJ)
+		error2 = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_pquotino);
 
 	return error ? error : error2;
 }
@@ -414,8 +415,10 @@ xfs_qm_scall_getqstat(
 	struct xfs_quotainfo	*q = mp->m_quotainfo;
 	struct xfs_inode	*uip = NULL;
 	struct xfs_inode	*gip = NULL;
+	struct xfs_inode	*pip = NULL;
 	bool                    tempuqip = false;
 	bool                    tempgqip = false;
+	bool                    temppqip = false;
 
 	memset(out, 0, sizeof(fs_quota_stat_t));
 
@@ -423,6 +426,7 @@ xfs_qm_scall_getqstat(
 	if (!xfs_sb_version_hasquota(&mp->m_sb)) {
 		out->qs_uquota.qfs_ino = NULLFSINO;
 		out->qs_gquota.qfs_ino = NULLFSINO;
+		out->qs_pquota.qfs_ino = NULLFSINO;
 		return (0);
 	}
 	out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags &
@@ -431,10 +435,13 @@ xfs_qm_scall_getqstat(
 	out->qs_pad = 0;
 	out->qs_uquota.qfs_ino = mp->m_sb.sb_uquotino;
 	out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino;
+	if (&out->qs_gquota != &out->qs_pquota)
+		out->qs_pquota.qfs_ino = mp->m_sb.sb_pquotino;
 
 	if (q) {
 		uip = q->qi_uquotaip;
 		gip = q->qi_gquotaip;
+		pip = q->qi_pquotaip;
 	}
 	if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) {
 		if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino,
@@ -446,6 +453,11 @@ xfs_qm_scall_getqstat(
 					0, 0, &gip) == 0)
 			tempgqip = true;
 	}
+	if (!pip && mp->m_sb.sb_pquotino != NULLFSINO) {
+		if (xfs_iget(mp, NULL, mp->m_sb.sb_pquotino,
+					0, 0, &pip) == 0)
+			temppqip = true;
+	}
 	if (uip) {
 		out->qs_uquota.qfs_nblks = uip->i_d.di_nblocks;
 		out->qs_uquota.qfs_nextents = uip->i_d.di_nextents;
@@ -458,6 +470,12 @@ xfs_qm_scall_getqstat(
 		if (tempgqip)
 			IRELE(gip);
 	}
+	if (pip) {
+		out->qs_pquota.qfs_nblks = pip->i_d.di_nblocks;
+		out->qs_pquota.qfs_nextents = pip->i_d.di_nextents;
+		if (temppqip)
+			IRELE(pip);
+	}
 	if (q) {
 		out->qs_incoredqs = q->qi_dquots;
 		out->qs_btimelimit = q->qi_btimelimit;
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h
index 5faf654..eae93d1 100644
--- a/fs/xfs/xfs_quota.h
+++ b/fs/xfs/xfs_quota.h
@@ -284,14 +284,6 @@ typedef struct xfs_qoff_logformat {
 	 (XFS_IS_PQUOTA_ON(mp) && \
 		(mp->m_sb.sb_qflags & XFS_PQUOTA_CHKD) == 0))
 
-#define XFS_MOUNT_QUOTA_SET1	(XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
-				 XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT|\
-				 XFS_GQUOTA_ENFD|XFS_GQUOTA_CHKD)
-
-#define XFS_MOUNT_QUOTA_SET2	(XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
-				 XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\
-				 XFS_PQUOTA_ENFD|XFS_PQUOTA_CHKD)
-
 #define XFS_MOUNT_QUOTA_ALL	(XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
 				 XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT|\
 				 XFS_GQUOTA_ENFD|XFS_GQUOTA_CHKD|\
diff --git a/fs/xfs/xfs_sb.h b/fs/xfs/xfs_sb.h
index 78f9e70..d1d2407 100644
--- a/fs/xfs/xfs_sb.h
+++ b/fs/xfs/xfs_sb.h
@@ -621,7 +621,21 @@ xfs_sb_has_incompat_log_feature(
 static inline bool
 xfs_is_quota_inode(struct xfs_sb *sbp, xfs_ino_t ino)
 {
-	return (ino == sbp->sb_uquotino || ino == sbp->sb_gquotino);
+	return (ino == sbp->sb_uquotino ||
+		ino == sbp->sb_gquotino ||
+		ino == sbp->sb_pquotino);
+}
+
+static inline int xfs_sb_version_has_pquota(xfs_sb_t *sbp)
+{
+	return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5;
+}
+
+static inline __int64_t xfs_sb_all_bits(xfs_sb_t *sbp)
+{
+	if (xfs_sb_version_has_pquota(sbp))
+		return XFS_SB_ALL_BITS;
+	return XFS_SB_ALL_BITS & ~XFS_SB_PQUOTINO;
 }
 
 /*
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 19663c7..992044f 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -420,12 +420,6 @@ xfs_parseargs(
 	}
 #endif
 
-	if ((mp->m_qflags & (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE)) &&
-	    (mp->m_qflags & (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE))) {
-		xfs_warn(mp, "cannot mount with both project and group quota");
-		return EINVAL;
-	}
-
 	if ((dsunit && !dswidth) || (!dsunit && dswidth)) {
 		xfs_warn(mp, "sunit and swidth must be specified together");
 		return EINVAL;
@@ -1395,6 +1389,14 @@ xfs_finish_flags(
 		return XFS_ERROR(EROFS);
 	}
 
+	if ((mp->m_qflags & (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE)) &&
+	    (mp->m_qflags & (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE)) &&
+	    !xfs_sb_version_has_pquota(&mp->m_sb)) {
+		xfs_warn(mp,
+		  "Super block does not support project and group quota together");
+		return XFS_ERROR(EINVAL);
+	}
+
 	return 0;
 }
 
diff --git a/include/uapi/linux/dqblk_xfs.h b/include/uapi/linux/dqblk_xfs.h
index 8655280..f17e3bb 100644
--- a/include/uapi/linux/dqblk_xfs.h
+++ b/include/uapi/linux/dqblk_xfs.h
@@ -155,6 +155,7 @@ typedef struct fs_quota_stat {
 	__s8		qs_pad;		/* unused */
 	fs_qfilestat_t	qs_uquota;	/* user quota storage information */
 	fs_qfilestat_t	qs_gquota;	/* group quota storage information */
+#define qs_pquota	qs_gquota
 	__u32		qs_incoredqs;	/* number of dquots incore */
 	__s32		qs_btimelimit;  /* limit for blks timer */	
 	__s32		qs_itimelimit;  /* limit for inodes timer */	
-- 
1.7.1

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v10 10/11] quota: Add proper versioning support to fs_quota_stat
  2013-06-27 22:25 [PATCH v10 00/11] Allow pquota and gquota to be used together Chandra Seetharaman
                   ` (8 preceding siblings ...)
  2013-06-27 22:25 ` [PATCH v10 09/11] xfs: Start using pquotaino from the superblock Chandra Seetharaman
@ 2013-06-27 22:25 ` Chandra Seetharaman
  2013-07-10 15:55   ` Ben Myers
  2013-06-27 22:25 ` [PATCH v10 11/11] xfs: Use new qs_pquota field in fs_quota_stat for Q_XGETQSTAT Chandra Seetharaman
  2013-06-28 22:53 ` [PATCH v10 00/11] Allow pquota and gquota to be used together Ben Myers
  11 siblings, 1 reply; 40+ messages in thread
From: Chandra Seetharaman @ 2013-06-27 22:25 UTC (permalink / raw)
  To: xfs; +Cc: Chandra Seetharaman, swhiteho

Added appropriate pads and code for backward compatibility.

Copied over the old version as it is different from the newer padded
version.

New callers of the system call have to set the version of the data
structure being passed, and kernel will fill as much data as requested.

Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
---
 fs/gfs2/quota.c                |    3 --
 fs/quota/quota.c               |   49 ++++++++++++++++++++++++++++++++++-
 fs/xfs/xfs_qm_syscalls.c       |    4 ---
 fs/xfs/xfs_super.c             |    5 +--
 include/uapi/linux/dqblk_xfs.h |   55 ++++++++++++++++++++++++++++++++++-----
 5 files changed, 97 insertions(+), 19 deletions(-)

diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index c7c840e..ca0dccd 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -1443,9 +1443,6 @@ static int gfs2_quota_get_xstate(struct super_block *sb,
 {
 	struct gfs2_sbd *sdp = sb->s_fs_info;
 
-	memset(fqs, 0, sizeof(struct fs_quota_stat));
-	fqs->qs_version = FS_QSTAT_VERSION;
-
 	switch (sdp->sd_args.ar_quota) {
 	case GFS2_QUOTA_ON:
 		fqs->qs_flags |= (FS_QUOTA_UDQ_ENFD | FS_QUOTA_GDQ_ENFD);
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index c7314f1..ae6526e 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -207,12 +207,57 @@ static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr)
 static int quota_getxstate(struct super_block *sb, void __user *addr)
 {
 	struct fs_quota_stat fqs;
-	int ret;
+	struct fs_quota_stat_v1 fqs_v1;
+	int ret, size;
+	void *fqsp;
 
 	if (!sb->s_qcop->get_xstate)
 		return -ENOSYS;
+
+	memset(&fqs, 0, sizeof(struct fs_quota_stat));
+	if (copy_from_user(&fqs, addr, 1)) /* just get the version */
+		return -EFAULT;
+
+	switch (fqs.qs_version) {
+	case FS_QSTAT_VERSION_2:
+		size = FS_QSTAT_V2_SIZE;
+		break;
+	default:
+		fqs.qs_version = FS_QSTAT_VERSION;
+		/* fallthrough */
+	case FS_QSTAT_VERSION:
+		size = FS_QSTAT_V1_SIZE;
+		break;
+	}
+
 	ret = sb->s_qcop->get_xstate(sb, &fqs);
-	if (!ret && copy_to_user(addr, &fqs, sizeof(fqs)))
+	if (ret)
+		return ret;
+
+	if (fqs.qs_version == FS_QSTAT_VERSION) {
+		fqs_v1.qs_version = fqs.qs_version;
+		fqs_v1.qs_flags = fqs.qs_flags;
+		fqs_v1.qs_pad = 0;
+
+		fqs_v1.qs_uquota.qfs_ino = fqs.qs_uquota.qfs_ino;
+		fqs_v1.qs_uquota.qfs_nblks = fqs.qs_uquota.qfs_nblks;
+		fqs_v1.qs_uquota.qfs_nextents = fqs.qs_uquota.qfs_nextents;
+
+		fqs_v1.qs_gquota.qfs_ino = fqs.qs_gquota.qfs_ino;
+		fqs_v1.qs_gquota.qfs_nblks = fqs.qs_gquota.qfs_nblks;
+		fqs_v1.qs_gquota.qfs_nextents = fqs.qs_gquota.qfs_nextents;
+
+		fqs_v1.qs_incoredqs = fqs.qs_incoredqs;
+		fqs_v1.qs_btimelimit = fqs.qs_btimelimit;
+		fqs_v1.qs_itimelimit = fqs.qs_itimelimit;
+		fqs_v1.qs_rtbtimelimit = fqs.qs_rtbtimelimit;
+		fqs_v1.qs_bwarnlimit = fqs.qs_bwarnlimit;
+		fqs_v1.qs_iwarnlimit = fqs.qs_iwarnlimit;
+		fqsp = &fqs_v1;
+	} else
+		fqsp = &fqs;
+
+	if (copy_to_user(addr, fqsp, size))
 		return -EFAULT;
 	return ret;
 }
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index f42b585..1900022 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -420,9 +420,6 @@ xfs_qm_scall_getqstat(
 	bool                    tempgqip = false;
 	bool                    temppqip = false;
 
-	memset(out, 0, sizeof(fs_quota_stat_t));
-
-	out->qs_version = FS_QSTAT_VERSION;
 	if (!xfs_sb_version_hasquota(&mp->m_sb)) {
 		out->qs_uquota.qfs_ino = NULLFSINO;
 		out->qs_gquota.qfs_ino = NULLFSINO;
@@ -432,7 +429,6 @@ xfs_qm_scall_getqstat(
 	out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags &
 							(XFS_ALL_QUOTA_ACCT|
 							 XFS_ALL_QUOTA_ENFD));
-	out->qs_pad = 0;
 	out->qs_uquota.qfs_ino = mp->m_sb.sb_uquotino;
 	out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino;
 	if (&out->qs_gquota != &out->qs_pquota)
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 992044f..1fafec9 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -549,14 +549,13 @@ xfs_showargs(
 	else if (mp->m_qflags & XFS_UQUOTA_ACCT)
 		seq_puts(m, "," MNTOPT_UQUOTANOENF);
 
-	/* Either project or group quotas can be active, not both */
-
 	if (mp->m_qflags & XFS_PQUOTA_ACCT) {
 		if (mp->m_qflags & XFS_PQUOTA_ENFD)
 			seq_puts(m, "," MNTOPT_PRJQUOTA);
 		else
 			seq_puts(m, "," MNTOPT_PQUOTANOENF);
-	} else if (mp->m_qflags & XFS_GQUOTA_ACCT) {
+	}
+	if (mp->m_qflags & XFS_GQUOTA_ACCT) {
 		if (mp->m_qflags & XFS_GQUOTA_ENFD)
 			seq_puts(m, "," MNTOPT_GRPQUOTA);
 		else
diff --git a/include/uapi/linux/dqblk_xfs.h b/include/uapi/linux/dqblk_xfs.h
index f17e3bb..04c4806 100644
--- a/include/uapi/linux/dqblk_xfs.h
+++ b/include/uapi/linux/dqblk_xfs.h
@@ -47,6 +47,7 @@
  * 512 bytes.
  */
 #define FS_DQUOT_VERSION	1	/* fs_disk_quota.d_version */
+
 typedef struct fs_disk_quota {
 	__s8		d_version;	/* version of this structure */
 	__s8		d_flags;	/* FS_{USER,PROJ,GROUP}_QUOTA */
@@ -137,31 +138,71 @@ typedef struct fs_disk_quota {
  * Provides a centralized way to get meta information about the quota subsystem.
  * eg. space taken up for user and group quotas, number of dquots currently
  * incore.
+ * User space caller should set qs_version to the appropriate version
+ * of the fs_quota_stat data structure they are providing. Not providing
+ * a version will be treated as FS_QSTAT_VERSION.
  */
 #define FS_QSTAT_VERSION	1	/* fs_quota_stat.qs_version */
+#define FS_QSTAT_VERSION_2	2	/* new field qs_pquota; realignment */
 
 /*
  * Some basic information about 'quota files'.
  */
-typedef struct fs_qfilestat {
+struct fs_qfilestat_v1 {
 	__u64		qfs_ino;	/* inode number */
 	__u64		qfs_nblks;	/* number of BBs 512-byte-blks */
 	__u32		qfs_nextents;	/* number of extents */
-} fs_qfilestat_t;
+};
 
-typedef struct fs_quota_stat {
+struct fs_quota_stat_v1 {
 	__s8		qs_version;	/* version number for future changes */
 	__u16		qs_flags;	/* FS_QUOTA_{U,P,G}DQ_{ACCT,ENFD} */
 	__s8		qs_pad;		/* unused */
-	fs_qfilestat_t	qs_uquota;	/* user quota storage information */
-	fs_qfilestat_t	qs_gquota;	/* group quota storage information */
-#define qs_pquota	qs_gquota
+	struct fs_qfilestat_v1	qs_uquota;	/* user quota information */
+	struct fs_qfilestat_v1	qs_gquota;	/* group quota information */
 	__u32		qs_incoredqs;	/* number of dquots incore */
 	__s32		qs_btimelimit;  /* limit for blks timer */	
 	__s32		qs_itimelimit;  /* limit for inodes timer */	
 	__s32		qs_rtbtimelimit;/* limit for rt blks timer */	
 	__u16		qs_bwarnlimit;	/* limit for num warnings */
 	__u16		qs_iwarnlimit;	/* limit for num warnings */
-} fs_quota_stat_t;
+};
+
+/*
+ * Some basic information about 'quota files'. Version 2.
+ */
+struct fs_qfilestat {
+	__u64		qfs_ino;	/* inode number */
+	__u64		qfs_nblks;	/* number of BBs 512-byte-blks */
+	__u32		qfs_nextents;	/* number of extents */
+	__u32		qfs_pad;	/* pad for 8-byte alignment */
+};
+
+struct fs_quota_stat {
+	__s8			qs_version;	/* version for future changes */
+	__u8			qs_pad1;	/* pad for 16bit alignment */
+	__u16			qs_flags;	/* FS_QUOTA_.* flags */
+	__u32			qs_incoredqs;	/* number of dquots incore */
+	struct fs_qfilestat	qs_uquota;	/* user quota information */
+	struct fs_qfilestat	qs_gquota;	/* group quota information */
+	struct fs_qfilestat	qs_pquota;	/* project quota information */
+	__s32			qs_btimelimit;  /* limit for blks timer */
+	__s32			qs_itimelimit;  /* limit for inodes timer */
+	__s32			qs_rtbtimelimit;/* limit for rt blks timer */
+	__u16			qs_bwarnlimit;	/* limit for num warnings */
+	__u16			qs_iwarnlimit;	/* limit for num warnings */
+	__u64			qs_pad2[8];	/* for future proofing */
+};
+
+/*
+ * Since Version 1 did not have padding at appropriate places,
+ * a new data structure has been defined for the older version to
+ * provide backward compatibility.
+ * Future extentions of this data structure won't require new
+ * data structure definitions as the current one can be extended
+ * with the logic and padding in place now.
+ */
+#define FS_QSTAT_V1_SIZE	(sizeof(struct fs_quota_stat_v1))
+#define FS_QSTAT_V2_SIZE	(sizeof(struct fs_quota_stat))
 
 #endif	/* _LINUX_DQBLK_XFS_H */
-- 
1.7.1

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v10 11/11] xfs: Use new qs_pquota field in fs_quota_stat for Q_XGETQSTAT
  2013-06-27 22:25 [PATCH v10 00/11] Allow pquota and gquota to be used together Chandra Seetharaman
                   ` (9 preceding siblings ...)
  2013-06-27 22:25 ` [PATCH v10 10/11] quota: Add proper versioning support to fs_quota_stat Chandra Seetharaman
@ 2013-06-27 22:25 ` Chandra Seetharaman
  2013-06-28 22:53 ` [PATCH v10 00/11] Allow pquota and gquota to be used together Ben Myers
  11 siblings, 0 replies; 40+ messages in thread
From: Chandra Seetharaman @ 2013-06-27 22:25 UTC (permalink / raw)
  To: xfs; +Cc: Chandra Seetharaman

For the Q_XGETQSTAT quota command, if the new version of fs_quota_stat
data structure is used, fill the project quota information.

Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
---
 fs/xfs/xfs_qm_syscalls.c |   38 ++++++++++++++++++++++++++------------
 1 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index 1900022..844423a 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -406,6 +406,14 @@ xfs_qm_scall_quotaon(
 
 /*
  * Return quota status information, such as uquota-off, enforcements, etc.
+ *
+ * We support two different versions of the fs_quota_stat structure
+ * here. If the version is FS_QSTAT_VERSION, then there is no
+ * separate project quota fields, and so we write project quota
+ * information into the group quota fields. With FS_QSTAT_VERSION_2,
+ * there is a separate project quota field so we can use that
+ * instead to pass both group and project quota back to user space.
+ *
  */
 int
 xfs_qm_scall_getqstat(
@@ -420,19 +428,15 @@ xfs_qm_scall_getqstat(
 	bool                    tempgqip = false;
 	bool                    temppqip = false;
 
-	if (!xfs_sb_version_hasquota(&mp->m_sb)) {
-		out->qs_uquota.qfs_ino = NULLFSINO;
-		out->qs_gquota.qfs_ino = NULLFSINO;
-		out->qs_pquota.qfs_ino = NULLFSINO;
-		return (0);
-	}
+	out->qs_uquota.qfs_ino = NULLFSINO;
+	out->qs_gquota.qfs_ino = NULLFSINO;
+	out->qs_pquota.qfs_ino = NULLFSINO;
+	if (!xfs_sb_version_hasquota(&mp->m_sb))
+		return 0;
+
 	out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags &
 							(XFS_ALL_QUOTA_ACCT|
 							 XFS_ALL_QUOTA_ENFD));
-	out->qs_uquota.qfs_ino = mp->m_sb.sb_uquotino;
-	out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino;
-	if (&out->qs_gquota != &out->qs_pquota)
-		out->qs_pquota.qfs_ino = mp->m_sb.sb_pquotino;
 
 	if (q) {
 		uip = q->qi_uquotaip;
@@ -454,21 +458,31 @@ xfs_qm_scall_getqstat(
 					0, 0, &pip) == 0)
 			temppqip = true;
 	}
+
 	if (uip) {
+		out->qs_uquota.qfs_ino = mp->m_sb.sb_uquotino;
 		out->qs_uquota.qfs_nblks = uip->i_d.di_nblocks;
 		out->qs_uquota.qfs_nextents = uip->i_d.di_nextents;
 		if (tempuqip)
 			IRELE(uip);
 	}
 	if (gip) {
+		out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino;
 		out->qs_gquota.qfs_nblks = gip->i_d.di_nblocks;
 		out->qs_gquota.qfs_nextents = gip->i_d.di_nextents;
 		if (tempgqip)
 			IRELE(gip);
 	}
 	if (pip) {
-		out->qs_pquota.qfs_nblks = pip->i_d.di_nblocks;
-		out->qs_pquota.qfs_nextents = pip->i_d.di_nextents;
+		if (out->qs_version >= FS_QSTAT_VERSION_2) {
+			out->qs_pquota.qfs_ino = mp->m_sb.sb_pquotino;
+			out->qs_pquota.qfs_nblks = pip->i_d.di_nblocks;
+			out->qs_pquota.qfs_nextents = pip->i_d.di_nextents;
+		} else {
+			out->qs_gquota.qfs_ino = mp->m_sb.sb_pquotino;
+			out->qs_gquota.qfs_nblks = pip->i_d.di_nblocks;
+			out->qs_gquota.qfs_nextents = pip->i_d.di_nextents;
+		}
 		if (temppqip)
 			IRELE(pip);
 	}
-- 
1.7.1

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 01/11] xfs: Define a new function xfs_is_quota_inode()
  2013-06-27 22:25 ` [PATCH v10 01/11] xfs: Define a new function xfs_is_quota_inode() Chandra Seetharaman
@ 2013-06-27 22:43   ` Ben Myers
  0 siblings, 0 replies; 40+ messages in thread
From: Ben Myers @ 2013-06-27 22:43 UTC (permalink / raw)
  To: Chandra Seetharaman; +Cc: xfs

On Thu, Jun 27, 2013 at 05:25:04PM -0500, Chandra Seetharaman wrote:
> In preparation for combined pquota/gquota support, define
> a new function to check if the fiven inode is a quota inode.
> 
> Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>

Looks great.

Reviewed-by: Ben Myers <bpm@sgi.com>

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 02/11] xfs: Replace macro XFS_DQUOT_TREE with a function
  2013-06-27 22:25 ` [PATCH v10 02/11] xfs: Replace macro XFS_DQUOT_TREE with a function Chandra Seetharaman
@ 2013-06-27 23:19   ` Ben Myers
  0 siblings, 0 replies; 40+ messages in thread
From: Ben Myers @ 2013-06-27 23:19 UTC (permalink / raw)
  To: Chandra Seetharaman; +Cc: xfs

On Thu, Jun 27, 2013 at 05:25:05PM -0500, Chandra Seetharaman wrote:
> In preparation for combined pquota/gquota support, for the sake
> of readability, change the macro to an inline function.
> 
> Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>

Looks good.

Reviewed-by: Ben Myers <bpm@sgi.com>

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 03/11] xfs: Replace macro XFS_DQ_TO_QIP with a function
  2013-06-27 22:25 ` [PATCH v10 03/11] xfs: Replace macro XFS_DQ_TO_QIP " Chandra Seetharaman
@ 2013-06-27 23:23   ` Ben Myers
  0 siblings, 0 replies; 40+ messages in thread
From: Ben Myers @ 2013-06-27 23:23 UTC (permalink / raw)
  To: Chandra Seetharaman; +Cc: xfs

On Thu, Jun 27, 2013 at 05:25:06PM -0500, Chandra Seetharaman wrote:
> In preparation for combined pquota/gquota support, for the sake
> of readability, change the macro to an inline function.
> 
> Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>

Looks good.

Reviewed-by: Ben Myers <bpm@sgi.com>

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 04/11] xfs: Code cleanup and removal of some typedef usage
  2013-06-27 22:25 ` [PATCH v10 04/11] xfs: Code cleanup and removal of some typedef usage Chandra Seetharaman
@ 2013-06-27 23:50   ` Ben Myers
  0 siblings, 0 replies; 40+ messages in thread
From: Ben Myers @ 2013-06-27 23:50 UTC (permalink / raw)
  To: Chandra Seetharaman; +Cc: xfs

On Thu, Jun 27, 2013 at 05:25:07PM -0500, Chandra Seetharaman wrote:
> In preparation for combined pquota/gquota support, for the sake
> of readability, do some code cleanup surrounding the affected
> code.
> 
> Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>

Looks great.  Thanks for addressing my nit regarding the error asserts.

Reviewed-by: Ben Myers <bpm@sgi.com>

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 05/11] xfs: Do some whitespace cleanup in the data structure xfs_quotainfo
  2013-06-27 22:25 ` [PATCH v10 05/11] xfs: Do some whitespace cleanup in the data structure xfs_quotainfo Chandra Seetharaman
@ 2013-06-28 16:30   ` Ben Myers
  2013-06-28 18:14     ` Chandra Seetharaman
  0 siblings, 1 reply; 40+ messages in thread
From: Ben Myers @ 2013-06-28 16:30 UTC (permalink / raw)
  To: Chandra Seetharaman; +Cc: xfs

Hey Chandra,

On Thu, Jun 27, 2013 at 05:25:08PM -0500, Chandra Seetharaman wrote:
> In preparation for combined pquota/gquota support, do some
> whitespace cleanups.
> 
> Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>

Wow.  Putting this in a patch by itself really puts it into stark
relief.

If we pull this in we're representing that some tabs and the alignment
of the fields is more valuable than the comments?  I'm fairly certain I
don't agree that's the case...

I'm sorry for your trouble, but I think I should pass on this one.  Do
you agree?

Thanks,
	Ben

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 05/11] xfs: Do some whitespace cleanup in the data structure xfs_quotainfo
  2013-06-28 16:30   ` Ben Myers
@ 2013-06-28 18:14     ` Chandra Seetharaman
  2013-06-28 18:31       ` Ben Myers
  0 siblings, 1 reply; 40+ messages in thread
From: Chandra Seetharaman @ 2013-06-28 18:14 UTC (permalink / raw)
  To: Ben Myers; +Cc: xfs

On Fri, 2013-06-28 at 11:30 -0500, Ben Myers wrote:
> Hey Chandra,
> 
> On Thu, Jun 27, 2013 at 05:25:08PM -0500, Chandra Seetharaman wrote:
> > In preparation for combined pquota/gquota support, do some
> > whitespace cleanups.
> > 
> > Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
> 
> Wow.  Putting this in a patch by itself really puts it into stark
> relief.
> 
> If we pull this in we're representing that some tabs and the alignment
> of the fields is more valuable than the comments?  I'm fairly certain I


If you put it that way, it does sound not correct, and I would agree
with you too :). 

But, IMO, it has to be more subjective than that. The comments removed,
IMO, add no additional value (the field name conveys the same
information). You can see that I left alone the comments that provide
some value.

> don't agree that's the case...
> 
> I'm sorry for your trouble, but I think I should pass on this one.  Do
> you agree?
> 

In effect, the code does look better (than I found it :) at the cost of
removal of redundant comments.

If you still don't want to include, I would accept your decision.

> Thanks,
> 	Ben
> 
> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
> http://oss.sgi.com/mailman/listinfo/xfs
> 


_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 05/11] xfs: Do some whitespace cleanup in the data structure xfs_quotainfo
  2013-06-28 18:14     ` Chandra Seetharaman
@ 2013-06-28 18:31       ` Ben Myers
  0 siblings, 0 replies; 40+ messages in thread
From: Ben Myers @ 2013-06-28 18:31 UTC (permalink / raw)
  To: Chandra Seetharaman; +Cc: xfs

Hey Chandra,

On Fri, Jun 28, 2013 at 01:14:33PM -0500, Chandra Seetharaman wrote:
> On Fri, 2013-06-28 at 11:30 -0500, Ben Myers wrote:
> > Hey Chandra,
> > 
> > On Thu, Jun 27, 2013 at 05:25:08PM -0500, Chandra Seetharaman wrote:
> > > In preparation for combined pquota/gquota support, do some
> > > whitespace cleanups.
> > > 
> > > Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
> > 
> > Wow.  Putting this in a patch by itself really puts it into stark
> > relief.
> > 
> > If we pull this in we're representing that some tabs and the alignment
> > of the fields is more valuable than the comments?  I'm fairly certain I
> 
> 
> If you put it that way, it does sound not correct, and I would agree
> with you too :). 
> 
> But, IMO, it has to be more subjective than that. The comments removed,
> IMO, add no additional value (the field name conveys the same
> information). You can see that I left alone the comments that provide
> some value.

I did notice that you kept some of the comments.  However, I am finding some of
the removed ones to be useful too.  I think if you try to look at this
structure with the eyes of a newbie the comments do help you.  e.g.
di_btimelimit doesn't carry much meaning for me out of context, and the comment
is helping me, at least.  Not everyone is quite so moronic as me, though.  ;)

> > don't agree that's the case...
> > 
> > I'm sorry for your trouble, but I think I should pass on this one.  Do
> > you agree?
> > 
> 
> In effect, the code does look better (than I found it :) at the cost of
> removal of redundant comments.
> 
> If you still don't want to include, I would accept your decision.

Thanks.  I really would prefer to keep them.  FWIW, the rest of your patch set
doesn't appear to be adversely affected by doing so.

Regards,
	Ben

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 06/11] xfs: Change xfs_dquot_acct to be a 2-dimensional array
  2013-06-27 22:25 ` [PATCH v10 06/11] xfs: Change xfs_dquot_acct to be a 2-dimensional array Chandra Seetharaman
@ 2013-06-28 19:06   ` Ben Myers
  0 siblings, 0 replies; 40+ messages in thread
From: Ben Myers @ 2013-06-28 19:06 UTC (permalink / raw)
  To: Chandra Seetharaman; +Cc: xfs

On Thu, Jun 27, 2013 at 05:25:09PM -0500, Chandra Seetharaman wrote:
> In preparation for combined pquota/gquota support, for the sake
> of readability, change xfs_dquot_acct to be a 2-dimensional array.
> 
> Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>

Looks good.

Reviewed-by: Ben Myers <bpm@sgi.com>

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 07/11] xfs: Remove incore use of XFS_OQUOTA_ENFD and XFS_OQUOTA_CHKD
  2013-06-27 22:25 ` [PATCH v10 07/11] xfs: Remove incore use of XFS_OQUOTA_ENFD and XFS_OQUOTA_CHKD Chandra Seetharaman
@ 2013-06-28 22:36   ` Ben Myers
  0 siblings, 0 replies; 40+ messages in thread
From: Ben Myers @ 2013-06-28 22:36 UTC (permalink / raw)
  To: Chandra Seetharaman; +Cc: xfs

On Thu, Jun 27, 2013 at 05:25:10PM -0500, Chandra Seetharaman wrote:
> Remove all incore use of XFS_OQUOTA_ENFD and XFS_OQUOTA_CHKD. Instead,
> start using XFS_GQUOTA_.* XFS_PQUOTA_.* counterparts for GQUOTA and
> PQUOTA respectively.
> 
> On-disk copy still uses XFS_OQUOTA_ENFD and XFS_OQUOTA_CHKD.
> 
> Read and write of the superblock does the conversion from *OQUOTA*
> to *[PG]QUOTA*.
> 
> Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>

Looks good.

Reviewed-by: Ben Myers <bpm@sgi.com>

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 00/11] Allow pquota and gquota to be used together
  2013-06-27 22:25 [PATCH v10 00/11] Allow pquota and gquota to be used together Chandra Seetharaman
                   ` (10 preceding siblings ...)
  2013-06-27 22:25 ` [PATCH v10 11/11] xfs: Use new qs_pquota field in fs_quota_stat for Q_XGETQSTAT Chandra Seetharaman
@ 2013-06-28 22:53 ` Ben Myers
  11 siblings, 0 replies; 40+ messages in thread
From: Ben Myers @ 2013-06-28 22:53 UTC (permalink / raw)
  To: Chandra Seetharaman; +Cc: xfs

On Thu, Jun 27, 2013 at 05:25:03PM -0500, Chandra Seetharaman wrote:
> Hello All,
> 
> This is the version 10 of the changes to allow pquota and gquota to be used
> together.
> 
> Patchset applies cleanly on top of 80a4049813a2ae0977d8e5db78e711c7f21c420b
> in xfs git tree.
> 
> Ran xfstests against it with DEBUG and do not see any regressions.

Applied patches 1-4,6,7.

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 09/11] xfs: Start using pquotaino from the superblock.
  2013-06-27 22:25 ` [PATCH v10 09/11] xfs: Start using pquotaino from the superblock Chandra Seetharaman
@ 2013-07-01  2:06   ` Dave Chinner
  2013-07-01 17:59     ` Chandra Seetharaman
  0 siblings, 1 reply; 40+ messages in thread
From: Dave Chinner @ 2013-07-01  2:06 UTC (permalink / raw)
  To: Chandra Seetharaman; +Cc: xfs

On Thu, Jun 27, 2013 at 05:25:12PM -0500, Chandra Seetharaman wrote:
> Start using pquotino and define a macro to check if the
> superblock has pquotino.
> 
> Keep backward compatibilty by alowing mount of older superblock
> with no separate pquota inode.
> 
> Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>

This is unchanged from the previous version, so all of my review
comments from here:

http://oss.sgi.com/pipermail/xfs/2013-June/027637.html

are still unaddressed.

Also:

> @@ -885,6 +905,18 @@ reread:
>  	 */
>  	xfs_sb_from_disk(&mp->m_sb, XFS_BUF_TO_SBP(bp));
>  
> +	if (!xfs_sb_version_has_pquota(&mp->m_sb) && (XFS_IS_PQUOTA_ON(mp))) {
> +		/*
> +		 * On disk superblock only has sb_gquotino, and incore
> +		 * superblock has both sb_gquotino and sb_pquotino.
> +		 * But, only one them is supported at any point of time.
> +		 * So, if PQUOTA is set in disk superblock, copy over
> +		 * sb_gquotino to sb_pquotino.
> +		 */
> +		mp->m_sb.sb_pquotino = mp->m_sb.sb_gquotino;
> +		mp->m_sb.sb_gquotino = NULLFSINO;
> +	}
> +
>  	xfs_sb_quota_from_disk(&mp->m_sb);

This code should be inside xfs_sb_quota_from_disk()....

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 09/11] xfs: Start using pquotaino from the superblock.
  2013-07-01  2:06   ` Dave Chinner
@ 2013-07-01 17:59     ` Chandra Seetharaman
  2013-07-03 17:12       ` Chandra Seetharaman
  0 siblings, 1 reply; 40+ messages in thread
From: Chandra Seetharaman @ 2013-07-01 17:59 UTC (permalink / raw)
  To: Dave Chinner; +Cc: xfs

On Mon, 2013-07-01 at 12:06 +1000, Dave Chinner wrote:
> On Thu, Jun 27, 2013 at 05:25:12PM -0500, Chandra Seetharaman wrote:
> > Start using pquotino and define a macro to check if the
> > superblock has pquotino.
> > 
> > Keep backward compatibilty by alowing mount of older superblock
> > with no separate pquota inode.
> > 
> > Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
> 
> This is unchanged from the previous version, so all of my review
> comments from here:
> 
> http://oss.sgi.com/pipermail/xfs/2013-June/027637.html
> 
> are still unaddressed.

See the other email I sent on this context.
> 
> Also:
> 
> > @@ -885,6 +905,18 @@ reread:
> >  	 */
> >  	xfs_sb_from_disk(&mp->m_sb, XFS_BUF_TO_SBP(bp));
> >  
> > +	if (!xfs_sb_version_has_pquota(&mp->m_sb) && (XFS_IS_PQUOTA_ON(mp))) {
> > +		/*
> > +		 * On disk superblock only has sb_gquotino, and incore
> > +		 * superblock has both sb_gquotino and sb_pquotino.
> > +		 * But, only one them is supported at any point of time.
> > +		 * So, if PQUOTA is set in disk superblock, copy over
> > +		 * sb_gquotino to sb_pquotino.
> > +		 */
> > +		mp->m_sb.sb_pquotino = mp->m_sb.sb_gquotino;
> > +		mp->m_sb.sb_gquotino = NULLFSINO;
> > +	}
> > +
> >  	xfs_sb_quota_from_disk(&mp->m_sb);
> 
> This code should be inside xfs_sb_quota_from_disk()....

will move.
> 
> Cheers,
> 
> Dave.


_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 09/11] xfs: Start using pquotaino from the superblock.
  2013-07-01 17:59     ` Chandra Seetharaman
@ 2013-07-03 17:12       ` Chandra Seetharaman
  2013-07-04  1:35         ` Dave Chinner
  0 siblings, 1 reply; 40+ messages in thread
From: Chandra Seetharaman @ 2013-07-03 17:12 UTC (permalink / raw)
  To: Dave Chinner; +Cc: xfs

Hi Dave,

Any comments ?

Thanks

Chandra
On Mon, 2013-07-01 at 12:59 -0500, Chandra Seetharaman wrote:
> On Mon, 2013-07-01 at 12:06 +1000, Dave Chinner wrote:
> > On Thu, Jun 27, 2013 at 05:25:12PM -0500, Chandra Seetharaman wrote:
> > > Start using pquotino and define a macro to check if the
> > > superblock has pquotino.
> > > 
> > > Keep backward compatibilty by alowing mount of older superblock
> > > with no separate pquota inode.
> > > 
> > > Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
> > 
> > This is unchanged from the previous version, so all of my review
> > comments from here:
> > 
> > http://oss.sgi.com/pipermail/xfs/2013-June/027637.html
> > 
> > are still unaddressed.
> 
> See the other email I sent on this context.
> > 
> > Also:
> > 
> > > @@ -885,6 +905,18 @@ reread:
> > >  	 */
> > >  	xfs_sb_from_disk(&mp->m_sb, XFS_BUF_TO_SBP(bp));
> > >  
> > > +	if (!xfs_sb_version_has_pquota(&mp->m_sb) && (XFS_IS_PQUOTA_ON(mp))) {
> > > +		/*
> > > +		 * On disk superblock only has sb_gquotino, and incore
> > > +		 * superblock has both sb_gquotino and sb_pquotino.
> > > +		 * But, only one them is supported at any point of time.
> > > +		 * So, if PQUOTA is set in disk superblock, copy over
> > > +		 * sb_gquotino to sb_pquotino.
> > > +		 */
> > > +		mp->m_sb.sb_pquotino = mp->m_sb.sb_gquotino;
> > > +		mp->m_sb.sb_gquotino = NULLFSINO;
> > > +	}
> > > +
> > >  	xfs_sb_quota_from_disk(&mp->m_sb);
> > 
> > This code should be inside xfs_sb_quota_from_disk()....
> 
> will move.
> > 
> > Cheers,
> > 
> > Dave.
> 
> 
> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
> http://oss.sgi.com/mailman/listinfo/xfs
> 


_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 09/11] xfs: Start using pquotaino from the superblock.
  2013-07-03 17:12       ` Chandra Seetharaman
@ 2013-07-04  1:35         ` Dave Chinner
  0 siblings, 0 replies; 40+ messages in thread
From: Dave Chinner @ 2013-07-04  1:35 UTC (permalink / raw)
  To: Chandra Seetharaman; +Cc: xfs

On Wed, Jul 03, 2013 at 12:12:07PM -0500, Chandra Seetharaman wrote:
> Hi Dave,
> 
> Any comments ?

Patience, please. Some of us have more than one problem to solve at
a time. I've responded in the other thread.

FWIW, I just found out that SGI are on holidays this week(*), so it
will be next week before there's any chance of this being merged.
You've got plenty of time to revise and repost it... ;)

Cheers,

Dave.

(*) I'm a bit annoyed that maintainers didn't think to tell us that
they would be absent this week. I've been wondering why they'd been
silent since last Friday given the 3.11 merge window opened a few
days ago...
-- 
Dave Chinner
david@fromorbit.com

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 10/11] quota: Add proper versioning support to fs_quota_stat
  2013-06-27 22:25 ` [PATCH v10 10/11] quota: Add proper versioning support to fs_quota_stat Chandra Seetharaman
@ 2013-07-10 15:55   ` Ben Myers
  2013-07-10 16:26     ` Jan Kara
  0 siblings, 1 reply; 40+ messages in thread
From: Ben Myers @ 2013-07-10 15:55 UTC (permalink / raw)
  To: Chandra Seetharaman; +Cc: Jan Kara, swhiteho, xfs

Hey Chandra,

On Thu, Jun 27, 2013 at 05:25:13PM -0500, Chandra Seetharaman wrote:
> Added appropriate pads and code for backward compatibility.
> 
> Copied over the old version as it is different from the newer padded
> version.
> 
> New callers of the system call have to set the version of the data
> structure being passed, and kernel will fill as much data as requested.
> 
> Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>

I think we also need to

Cc: Jan Kara <jack@suse.cz>

on this one, since he maintains the quota subsystem.

Regards,
	Ben

> ---
>  fs/gfs2/quota.c                |    3 --
>  fs/quota/quota.c               |   49 ++++++++++++++++++++++++++++++++++-
>  fs/xfs/xfs_qm_syscalls.c       |    4 ---
>  fs/xfs/xfs_super.c             |    5 +--
>  include/uapi/linux/dqblk_xfs.h |   55 ++++++++++++++++++++++++++++++++++-----
>  5 files changed, 97 insertions(+), 19 deletions(-)
> 
> diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
> index c7c840e..ca0dccd 100644
> --- a/fs/gfs2/quota.c
> +++ b/fs/gfs2/quota.c
> @@ -1443,9 +1443,6 @@ static int gfs2_quota_get_xstate(struct super_block *sb,
>  {
>  	struct gfs2_sbd *sdp = sb->s_fs_info;
>  
> -	memset(fqs, 0, sizeof(struct fs_quota_stat));
> -	fqs->qs_version = FS_QSTAT_VERSION;
> -
>  	switch (sdp->sd_args.ar_quota) {
>  	case GFS2_QUOTA_ON:
>  		fqs->qs_flags |= (FS_QUOTA_UDQ_ENFD | FS_QUOTA_GDQ_ENFD);
> diff --git a/fs/quota/quota.c b/fs/quota/quota.c
> index c7314f1..ae6526e 100644
> --- a/fs/quota/quota.c
> +++ b/fs/quota/quota.c
> @@ -207,12 +207,57 @@ static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr)
>  static int quota_getxstate(struct super_block *sb, void __user *addr)
>  {
>  	struct fs_quota_stat fqs;
> -	int ret;
> +	struct fs_quota_stat_v1 fqs_v1;
> +	int ret, size;
> +	void *fqsp;
>  
>  	if (!sb->s_qcop->get_xstate)
>  		return -ENOSYS;
> +
> +	memset(&fqs, 0, sizeof(struct fs_quota_stat));
> +	if (copy_from_user(&fqs, addr, 1)) /* just get the version */
> +		return -EFAULT;
> +
> +	switch (fqs.qs_version) {
> +	case FS_QSTAT_VERSION_2:
> +		size = FS_QSTAT_V2_SIZE;
> +		break;
> +	default:
> +		fqs.qs_version = FS_QSTAT_VERSION;
> +		/* fallthrough */
> +	case FS_QSTAT_VERSION:
> +		size = FS_QSTAT_V1_SIZE;
> +		break;
> +	}
> +
>  	ret = sb->s_qcop->get_xstate(sb, &fqs);
> -	if (!ret && copy_to_user(addr, &fqs, sizeof(fqs)))
> +	if (ret)
> +		return ret;
> +
> +	if (fqs.qs_version == FS_QSTAT_VERSION) {
> +		fqs_v1.qs_version = fqs.qs_version;
> +		fqs_v1.qs_flags = fqs.qs_flags;
> +		fqs_v1.qs_pad = 0;
> +
> +		fqs_v1.qs_uquota.qfs_ino = fqs.qs_uquota.qfs_ino;
> +		fqs_v1.qs_uquota.qfs_nblks = fqs.qs_uquota.qfs_nblks;
> +		fqs_v1.qs_uquota.qfs_nextents = fqs.qs_uquota.qfs_nextents;
> +
> +		fqs_v1.qs_gquota.qfs_ino = fqs.qs_gquota.qfs_ino;
> +		fqs_v1.qs_gquota.qfs_nblks = fqs.qs_gquota.qfs_nblks;
> +		fqs_v1.qs_gquota.qfs_nextents = fqs.qs_gquota.qfs_nextents;
> +
> +		fqs_v1.qs_incoredqs = fqs.qs_incoredqs;
> +		fqs_v1.qs_btimelimit = fqs.qs_btimelimit;
> +		fqs_v1.qs_itimelimit = fqs.qs_itimelimit;
> +		fqs_v1.qs_rtbtimelimit = fqs.qs_rtbtimelimit;
> +		fqs_v1.qs_bwarnlimit = fqs.qs_bwarnlimit;
> +		fqs_v1.qs_iwarnlimit = fqs.qs_iwarnlimit;
> +		fqsp = &fqs_v1;
> +	} else
> +		fqsp = &fqs;
> +
> +	if (copy_to_user(addr, fqsp, size))
>  		return -EFAULT;
>  	return ret;
>  }
> diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
> index f42b585..1900022 100644
> --- a/fs/xfs/xfs_qm_syscalls.c
> +++ b/fs/xfs/xfs_qm_syscalls.c
> @@ -420,9 +420,6 @@ xfs_qm_scall_getqstat(
>  	bool                    tempgqip = false;
>  	bool                    temppqip = false;
>  
> -	memset(out, 0, sizeof(fs_quota_stat_t));
> -
> -	out->qs_version = FS_QSTAT_VERSION;
>  	if (!xfs_sb_version_hasquota(&mp->m_sb)) {
>  		out->qs_uquota.qfs_ino = NULLFSINO;
>  		out->qs_gquota.qfs_ino = NULLFSINO;
> @@ -432,7 +429,6 @@ xfs_qm_scall_getqstat(
>  	out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags &
>  							(XFS_ALL_QUOTA_ACCT|
>  							 XFS_ALL_QUOTA_ENFD));
> -	out->qs_pad = 0;
>  	out->qs_uquota.qfs_ino = mp->m_sb.sb_uquotino;
>  	out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino;
>  	if (&out->qs_gquota != &out->qs_pquota)
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index 992044f..1fafec9 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -549,14 +549,13 @@ xfs_showargs(
>  	else if (mp->m_qflags & XFS_UQUOTA_ACCT)
>  		seq_puts(m, "," MNTOPT_UQUOTANOENF);
>  
> -	/* Either project or group quotas can be active, not both */
> -
>  	if (mp->m_qflags & XFS_PQUOTA_ACCT) {
>  		if (mp->m_qflags & XFS_PQUOTA_ENFD)
>  			seq_puts(m, "," MNTOPT_PRJQUOTA);
>  		else
>  			seq_puts(m, "," MNTOPT_PQUOTANOENF);
> -	} else if (mp->m_qflags & XFS_GQUOTA_ACCT) {
> +	}
> +	if (mp->m_qflags & XFS_GQUOTA_ACCT) {
>  		if (mp->m_qflags & XFS_GQUOTA_ENFD)
>  			seq_puts(m, "," MNTOPT_GRPQUOTA);
>  		else
> diff --git a/include/uapi/linux/dqblk_xfs.h b/include/uapi/linux/dqblk_xfs.h
> index f17e3bb..04c4806 100644
> --- a/include/uapi/linux/dqblk_xfs.h
> +++ b/include/uapi/linux/dqblk_xfs.h
> @@ -47,6 +47,7 @@
>   * 512 bytes.
>   */
>  #define FS_DQUOT_VERSION	1	/* fs_disk_quota.d_version */
> +
>  typedef struct fs_disk_quota {
>  	__s8		d_version;	/* version of this structure */
>  	__s8		d_flags;	/* FS_{USER,PROJ,GROUP}_QUOTA */
> @@ -137,31 +138,71 @@ typedef struct fs_disk_quota {
>   * Provides a centralized way to get meta information about the quota subsystem.
>   * eg. space taken up for user and group quotas, number of dquots currently
>   * incore.
> + * User space caller should set qs_version to the appropriate version
> + * of the fs_quota_stat data structure they are providing. Not providing
> + * a version will be treated as FS_QSTAT_VERSION.
>   */
>  #define FS_QSTAT_VERSION	1	/* fs_quota_stat.qs_version */
> +#define FS_QSTAT_VERSION_2	2	/* new field qs_pquota; realignment */
>  
>  /*
>   * Some basic information about 'quota files'.
>   */
> -typedef struct fs_qfilestat {
> +struct fs_qfilestat_v1 {
>  	__u64		qfs_ino;	/* inode number */
>  	__u64		qfs_nblks;	/* number of BBs 512-byte-blks */
>  	__u32		qfs_nextents;	/* number of extents */
> -} fs_qfilestat_t;
> +};
>  
> -typedef struct fs_quota_stat {
> +struct fs_quota_stat_v1 {
>  	__s8		qs_version;	/* version number for future changes */
>  	__u16		qs_flags;	/* FS_QUOTA_{U,P,G}DQ_{ACCT,ENFD} */
>  	__s8		qs_pad;		/* unused */
> -	fs_qfilestat_t	qs_uquota;	/* user quota storage information */
> -	fs_qfilestat_t	qs_gquota;	/* group quota storage information */
> -#define qs_pquota	qs_gquota
> +	struct fs_qfilestat_v1	qs_uquota;	/* user quota information */
> +	struct fs_qfilestat_v1	qs_gquota;	/* group quota information */
>  	__u32		qs_incoredqs;	/* number of dquots incore */
>  	__s32		qs_btimelimit;  /* limit for blks timer */	
>  	__s32		qs_itimelimit;  /* limit for inodes timer */	
>  	__s32		qs_rtbtimelimit;/* limit for rt blks timer */	
>  	__u16		qs_bwarnlimit;	/* limit for num warnings */
>  	__u16		qs_iwarnlimit;	/* limit for num warnings */
> -} fs_quota_stat_t;
> +};
> +
> +/*
> + * Some basic information about 'quota files'. Version 2.
> + */
> +struct fs_qfilestat {
> +	__u64		qfs_ino;	/* inode number */
> +	__u64		qfs_nblks;	/* number of BBs 512-byte-blks */
> +	__u32		qfs_nextents;	/* number of extents */
> +	__u32		qfs_pad;	/* pad for 8-byte alignment */
> +};
> +
> +struct fs_quota_stat {
> +	__s8			qs_version;	/* version for future changes */
> +	__u8			qs_pad1;	/* pad for 16bit alignment */
> +	__u16			qs_flags;	/* FS_QUOTA_.* flags */
> +	__u32			qs_incoredqs;	/* number of dquots incore */
> +	struct fs_qfilestat	qs_uquota;	/* user quota information */
> +	struct fs_qfilestat	qs_gquota;	/* group quota information */
> +	struct fs_qfilestat	qs_pquota;	/* project quota information */
> +	__s32			qs_btimelimit;  /* limit for blks timer */
> +	__s32			qs_itimelimit;  /* limit for inodes timer */
> +	__s32			qs_rtbtimelimit;/* limit for rt blks timer */
> +	__u16			qs_bwarnlimit;	/* limit for num warnings */
> +	__u16			qs_iwarnlimit;	/* limit for num warnings */
> +	__u64			qs_pad2[8];	/* for future proofing */
> +};
> +
> +/*
> + * Since Version 1 did not have padding at appropriate places,
> + * a new data structure has been defined for the older version to
> + * provide backward compatibility.
> + * Future extentions of this data structure won't require new
> + * data structure definitions as the current one can be extended
> + * with the logic and padding in place now.
> + */
> +#define FS_QSTAT_V1_SIZE	(sizeof(struct fs_quota_stat_v1))
> +#define FS_QSTAT_V2_SIZE	(sizeof(struct fs_quota_stat))
>  
>  #endif	/* _LINUX_DQBLK_XFS_H */
> -- 
> 1.7.1
> 
> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
> http://oss.sgi.com/mailman/listinfo/xfs

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 10/11] quota: Add proper versioning support to fs_quota_stat
  2013-07-10 15:55   ` Ben Myers
@ 2013-07-10 16:26     ` Jan Kara
  2013-07-10 18:47       ` Ben Myers
  2013-07-10 20:49       ` Chandra Seetharaman
  0 siblings, 2 replies; 40+ messages in thread
From: Jan Kara @ 2013-07-10 16:26 UTC (permalink / raw)
  To: Ben Myers; +Cc: swhiteho, Jan Kara, Chandra Seetharaman, xfs

On Wed 10-07-13 10:55:38, Ben Myers wrote:
> Hey Chandra,
> 
> On Thu, Jun 27, 2013 at 05:25:13PM -0500, Chandra Seetharaman wrote:
> > Added appropriate pads and code for backward compatibility.
> > 
> > Copied over the old version as it is different from the newer padded
> > version.
> > 
> > New callers of the system call have to set the version of the data
> > structure being passed, and kernel will fill as much data as requested.
> > 
> > Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
> 
> I think we also need to
> 
> Cc: Jan Kara <jack@suse.cz>
  Thanks for CC.

> > diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
> > index c7c840e..ca0dccd 100644
> > --- a/fs/gfs2/quota.c
> > +++ b/fs/gfs2/quota.c
> > @@ -1443,9 +1443,6 @@ static int gfs2_quota_get_xstate(struct super_block *sb,
> >  {
> >  	struct gfs2_sbd *sdp = sb->s_fs_info;
> >  
> > -	memset(fqs, 0, sizeof(struct fs_quota_stat));
> > -	fqs->qs_version = FS_QSTAT_VERSION;
> > -
> >  	switch (sdp->sd_args.ar_quota) {
> >  	case GFS2_QUOTA_ON:
> >  		fqs->qs_flags |= (FS_QUOTA_UDQ_ENFD | FS_QUOTA_GDQ_ENFD);
> > diff --git a/fs/quota/quota.c b/fs/quota/quota.c
> > index c7314f1..ae6526e 100644
> > --- a/fs/quota/quota.c
> > +++ b/fs/quota/quota.c
> > @@ -207,12 +207,57 @@ static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr)
> >  static int quota_getxstate(struct super_block *sb, void __user *addr)
> >  {
> >  	struct fs_quota_stat fqs;
> > -	int ret;
> > +	struct fs_quota_stat_v1 fqs_v1;
> > +	int ret, size;
> > +	void *fqsp;
> >  
> >  	if (!sb->s_qcop->get_xstate)
> >  		return -ENOSYS;
> > +
> > +	memset(&fqs, 0, sizeof(struct fs_quota_stat));
> > +	if (copy_from_user(&fqs, addr, 1)) /* just get the version */
> > +		return -EFAULT;
> > +
> > +	switch (fqs.qs_version) {
> > +	case FS_QSTAT_VERSION_2:
> > +		size = FS_QSTAT_V2_SIZE;
> > +		break;
> > +	default:
> > +		fqs.qs_version = FS_QSTAT_VERSION;
> > +		/* fallthrough */
> > +	case FS_QSTAT_VERSION:
> > +		size = FS_QSTAT_V1_SIZE;
> > +		break;
> > +	}
  Guys, you cannot really do this. If anyone is using getxstate() with
uninitialized buffer (which is fine so far), you cannot suddently start to
rely on the contents of qs_version field. That's ABI (and even API)
breakage.

Unless I'm missing something, the only clean way is to use new quotactl
value for the interface with version field used for input as well.

								Honza

> > +
> >  	ret = sb->s_qcop->get_xstate(sb, &fqs);
> > -	if (!ret && copy_to_user(addr, &fqs, sizeof(fqs)))
> > +	if (ret)
> > +		return ret;
> > +
> > +	if (fqs.qs_version == FS_QSTAT_VERSION) {
> > +		fqs_v1.qs_version = fqs.qs_version;
> > +		fqs_v1.qs_flags = fqs.qs_flags;
> > +		fqs_v1.qs_pad = 0;
> > +
> > +		fqs_v1.qs_uquota.qfs_ino = fqs.qs_uquota.qfs_ino;
> > +		fqs_v1.qs_uquota.qfs_nblks = fqs.qs_uquota.qfs_nblks;
> > +		fqs_v1.qs_uquota.qfs_nextents = fqs.qs_uquota.qfs_nextents;
> > +
> > +		fqs_v1.qs_gquota.qfs_ino = fqs.qs_gquota.qfs_ino;
> > +		fqs_v1.qs_gquota.qfs_nblks = fqs.qs_gquota.qfs_nblks;
> > +		fqs_v1.qs_gquota.qfs_nextents = fqs.qs_gquota.qfs_nextents;
> > +
> > +		fqs_v1.qs_incoredqs = fqs.qs_incoredqs;
> > +		fqs_v1.qs_btimelimit = fqs.qs_btimelimit;
> > +		fqs_v1.qs_itimelimit = fqs.qs_itimelimit;
> > +		fqs_v1.qs_rtbtimelimit = fqs.qs_rtbtimelimit;
> > +		fqs_v1.qs_bwarnlimit = fqs.qs_bwarnlimit;
> > +		fqs_v1.qs_iwarnlimit = fqs.qs_iwarnlimit;
> > +		fqsp = &fqs_v1;
> > +	} else
> > +		fqsp = &fqs;
> > +
> > +	if (copy_to_user(addr, fqsp, size))
> >  		return -EFAULT;
> >  	return ret;
> >  }
> > diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
> > index f42b585..1900022 100644
> > --- a/fs/xfs/xfs_qm_syscalls.c
> > +++ b/fs/xfs/xfs_qm_syscalls.c
> > @@ -420,9 +420,6 @@ xfs_qm_scall_getqstat(
> >  	bool                    tempgqip = false;
> >  	bool                    temppqip = false;
> >  
> > -	memset(out, 0, sizeof(fs_quota_stat_t));
> > -
> > -	out->qs_version = FS_QSTAT_VERSION;
> >  	if (!xfs_sb_version_hasquota(&mp->m_sb)) {
> >  		out->qs_uquota.qfs_ino = NULLFSINO;
> >  		out->qs_gquota.qfs_ino = NULLFSINO;
> > @@ -432,7 +429,6 @@ xfs_qm_scall_getqstat(
> >  	out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags &
> >  							(XFS_ALL_QUOTA_ACCT|
> >  							 XFS_ALL_QUOTA_ENFD));
> > -	out->qs_pad = 0;
> >  	out->qs_uquota.qfs_ino = mp->m_sb.sb_uquotino;
> >  	out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino;
> >  	if (&out->qs_gquota != &out->qs_pquota)
> > diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> > index 992044f..1fafec9 100644
> > --- a/fs/xfs/xfs_super.c
> > +++ b/fs/xfs/xfs_super.c
> > @@ -549,14 +549,13 @@ xfs_showargs(
> >  	else if (mp->m_qflags & XFS_UQUOTA_ACCT)
> >  		seq_puts(m, "," MNTOPT_UQUOTANOENF);
> >  
> > -	/* Either project or group quotas can be active, not both */
> > -
> >  	if (mp->m_qflags & XFS_PQUOTA_ACCT) {
> >  		if (mp->m_qflags & XFS_PQUOTA_ENFD)
> >  			seq_puts(m, "," MNTOPT_PRJQUOTA);
> >  		else
> >  			seq_puts(m, "," MNTOPT_PQUOTANOENF);
> > -	} else if (mp->m_qflags & XFS_GQUOTA_ACCT) {
> > +	}
> > +	if (mp->m_qflags & XFS_GQUOTA_ACCT) {
> >  		if (mp->m_qflags & XFS_GQUOTA_ENFD)
> >  			seq_puts(m, "," MNTOPT_GRPQUOTA);
> >  		else
> > diff --git a/include/uapi/linux/dqblk_xfs.h b/include/uapi/linux/dqblk_xfs.h
> > index f17e3bb..04c4806 100644
> > --- a/include/uapi/linux/dqblk_xfs.h
> > +++ b/include/uapi/linux/dqblk_xfs.h
> > @@ -47,6 +47,7 @@
> >   * 512 bytes.
> >   */
> >  #define FS_DQUOT_VERSION	1	/* fs_disk_quota.d_version */
> > +
> >  typedef struct fs_disk_quota {
> >  	__s8		d_version;	/* version of this structure */
> >  	__s8		d_flags;	/* FS_{USER,PROJ,GROUP}_QUOTA */
> > @@ -137,31 +138,71 @@ typedef struct fs_disk_quota {
> >   * Provides a centralized way to get meta information about the quota subsystem.
> >   * eg. space taken up for user and group quotas, number of dquots currently
> >   * incore.
> > + * User space caller should set qs_version to the appropriate version
> > + * of the fs_quota_stat data structure they are providing. Not providing
> > + * a version will be treated as FS_QSTAT_VERSION.
> >   */
> >  #define FS_QSTAT_VERSION	1	/* fs_quota_stat.qs_version */
> > +#define FS_QSTAT_VERSION_2	2	/* new field qs_pquota; realignment */
> >  
> >  /*
> >   * Some basic information about 'quota files'.
> >   */
> > -typedef struct fs_qfilestat {
> > +struct fs_qfilestat_v1 {
> >  	__u64		qfs_ino;	/* inode number */
> >  	__u64		qfs_nblks;	/* number of BBs 512-byte-blks */
> >  	__u32		qfs_nextents;	/* number of extents */
> > -} fs_qfilestat_t;
> > +};
> >  
> > -typedef struct fs_quota_stat {
> > +struct fs_quota_stat_v1 {
> >  	__s8		qs_version;	/* version number for future changes */
> >  	__u16		qs_flags;	/* FS_QUOTA_{U,P,G}DQ_{ACCT,ENFD} */
> >  	__s8		qs_pad;		/* unused */
> > -	fs_qfilestat_t	qs_uquota;	/* user quota storage information */
> > -	fs_qfilestat_t	qs_gquota;	/* group quota storage information */
> > -#define qs_pquota	qs_gquota
> > +	struct fs_qfilestat_v1	qs_uquota;	/* user quota information */
> > +	struct fs_qfilestat_v1	qs_gquota;	/* group quota information */
> >  	__u32		qs_incoredqs;	/* number of dquots incore */
> >  	__s32		qs_btimelimit;  /* limit for blks timer */	
> >  	__s32		qs_itimelimit;  /* limit for inodes timer */	
> >  	__s32		qs_rtbtimelimit;/* limit for rt blks timer */	
> >  	__u16		qs_bwarnlimit;	/* limit for num warnings */
> >  	__u16		qs_iwarnlimit;	/* limit for num warnings */
> > -} fs_quota_stat_t;
> > +};
> > +
> > +/*
> > + * Some basic information about 'quota files'. Version 2.
> > + */
> > +struct fs_qfilestat {
> > +	__u64		qfs_ino;	/* inode number */
> > +	__u64		qfs_nblks;	/* number of BBs 512-byte-blks */
> > +	__u32		qfs_nextents;	/* number of extents */
> > +	__u32		qfs_pad;	/* pad for 8-byte alignment */
> > +};
> > +
> > +struct fs_quota_stat {
> > +	__s8			qs_version;	/* version for future changes */
> > +	__u8			qs_pad1;	/* pad for 16bit alignment */
> > +	__u16			qs_flags;	/* FS_QUOTA_.* flags */
> > +	__u32			qs_incoredqs;	/* number of dquots incore */
> > +	struct fs_qfilestat	qs_uquota;	/* user quota information */
> > +	struct fs_qfilestat	qs_gquota;	/* group quota information */
> > +	struct fs_qfilestat	qs_pquota;	/* project quota information */
> > +	__s32			qs_btimelimit;  /* limit for blks timer */
> > +	__s32			qs_itimelimit;  /* limit for inodes timer */
> > +	__s32			qs_rtbtimelimit;/* limit for rt blks timer */
> > +	__u16			qs_bwarnlimit;	/* limit for num warnings */
> > +	__u16			qs_iwarnlimit;	/* limit for num warnings */
> > +	__u64			qs_pad2[8];	/* for future proofing */
> > +};
> > +
> > +/*
> > + * Since Version 1 did not have padding at appropriate places,
> > + * a new data structure has been defined for the older version to
> > + * provide backward compatibility.
> > + * Future extentions of this data structure won't require new
> > + * data structure definitions as the current one can be extended
> > + * with the logic and padding in place now.
> > + */
> > +#define FS_QSTAT_V1_SIZE	(sizeof(struct fs_quota_stat_v1))
> > +#define FS_QSTAT_V2_SIZE	(sizeof(struct fs_quota_stat))
> >  
> >  #endif	/* _LINUX_DQBLK_XFS_H */
> > -- 
> > 1.7.1
> > 
> > _______________________________________________
> > xfs mailing list
> > xfs@oss.sgi.com
> > http://oss.sgi.com/mailman/listinfo/xfs
-- 
Jan Kara <jack@suse.cz>
SUSE Labs, CR

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 10/11] quota: Add proper versioning support to fs_quota_stat
  2013-07-10 16:26     ` Jan Kara
@ 2013-07-10 18:47       ` Ben Myers
  2013-07-10 21:52         ` Jan Kara
  2013-07-10 20:49       ` Chandra Seetharaman
  1 sibling, 1 reply; 40+ messages in thread
From: Ben Myers @ 2013-07-10 18:47 UTC (permalink / raw)
  To: Jan Kara; +Cc: swhiteho, Chandra Seetharaman, xfs

Hey Jan,

On Wed, Jul 10, 2013 at 06:26:02PM +0200, Jan Kara wrote:
> On Wed 10-07-13 10:55:38, Ben Myers wrote:
> > Hey Chandra,
> > 
> > On Thu, Jun 27, 2013 at 05:25:13PM -0500, Chandra Seetharaman wrote:
> > > Added appropriate pads and code for backward compatibility.
> > > 
> > > Copied over the old version as it is different from the newer padded
> > > version.
> > > 
> > > New callers of the system call have to set the version of the data
> > > structure being passed, and kernel will fill as much data as requested.
> > > 
> > > Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
> > 
> > I think we also need to
> > 
> > Cc: Jan Kara <jack@suse.cz>
>   Thanks for CC.
> 
> > > diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
> > > index c7c840e..ca0dccd 100644
> > > --- a/fs/gfs2/quota.c
> > > +++ b/fs/gfs2/quota.c
> > > @@ -1443,9 +1443,6 @@ static int gfs2_quota_get_xstate(struct super_block *sb,
> > >  {
> > >  	struct gfs2_sbd *sdp = sb->s_fs_info;
> > >  
> > > -	memset(fqs, 0, sizeof(struct fs_quota_stat));
> > > -	fqs->qs_version = FS_QSTAT_VERSION;
> > > -
> > >  	switch (sdp->sd_args.ar_quota) {
> > >  	case GFS2_QUOTA_ON:
> > >  		fqs->qs_flags |= (FS_QUOTA_UDQ_ENFD | FS_QUOTA_GDQ_ENFD);
> > > diff --git a/fs/quota/quota.c b/fs/quota/quota.c
> > > index c7314f1..ae6526e 100644
> > > --- a/fs/quota/quota.c
> > > +++ b/fs/quota/quota.c
> > > @@ -207,12 +207,57 @@ static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr)
> > >  static int quota_getxstate(struct super_block *sb, void __user *addr)
> > >  {
> > >  	struct fs_quota_stat fqs;
> > > -	int ret;
> > > +	struct fs_quota_stat_v1 fqs_v1;
> > > +	int ret, size;
> > > +	void *fqsp;
> > >  
> > >  	if (!sb->s_qcop->get_xstate)
> > >  		return -ENOSYS;
> > > +
> > > +	memset(&fqs, 0, sizeof(struct fs_quota_stat));
> > > +	if (copy_from_user(&fqs, addr, 1)) /* just get the version */
> > > +		return -EFAULT;
> > > +
> > > +	switch (fqs.qs_version) {
> > > +	case FS_QSTAT_VERSION_2:
> > > +		size = FS_QSTAT_V2_SIZE;
> > > +		break;
> > > +	default:
> > > +		fqs.qs_version = FS_QSTAT_VERSION;
> > > +		/* fallthrough */
> > > +	case FS_QSTAT_VERSION:
> > > +		size = FS_QSTAT_V1_SIZE;
> > > +		break;
> > > +	}
>   Guys, you cannot really do this. If anyone is using getxstate() with
> uninitialized buffer (which is fine so far), you cannot suddently start to
> rely on the contents of qs_version field. That's ABI (and even API)
> breakage.

Looks like you are correct to me.  Seems that qs_version number was never
checked until this patch.

> Unless I'm missing something, the only clean way is to use new quotactl
> value for the interface with version field used for input as well.

If I understand... it would be something like this?

#define Q_XGETQSTATV     XQM_CMD(8)

Or Q_XGETQSTAT2?

Thanks,
	Ben

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 10/11] quota: Add proper versioning support to fs_quota_stat
  2013-07-10 16:26     ` Jan Kara
  2013-07-10 18:47       ` Ben Myers
@ 2013-07-10 20:49       ` Chandra Seetharaman
  2013-07-10 21:54         ` Jan Kara
  2013-07-11  1:45         ` Dave Chinner
  1 sibling, 2 replies; 40+ messages in thread
From: Chandra Seetharaman @ 2013-07-10 20:49 UTC (permalink / raw)
  To: Jan Kara; +Cc: Ben Myers, swhiteho, xfs

On Wed, 2013-07-10 at 18:26 +0200, Jan Kara wrote:
> On Wed 10-07-13 10:55:38, Ben Myers wrote:
> > Hey Chandra,

<snip>

> > > diff --git a/fs/quota/quota.c b/fs/quota/quota.c
> > > index c7314f1..ae6526e 100644
> > > --- a/fs/quota/quota.c
> > > +++ b/fs/quota/quota.c
> > > @@ -207,12 +207,57 @@ static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr)
> > >  static int quota_getxstate(struct super_block *sb, void __user *addr)
> > >  {
> > >  	struct fs_quota_stat fqs;
> > > -	int ret;
> > > +	struct fs_quota_stat_v1 fqs_v1;
> > > +	int ret, size;
> > > +	void *fqsp;
> > >  
> > >  	if (!sb->s_qcop->get_xstate)
> > >  		return -ENOSYS;
> > > +
> > > +	memset(&fqs, 0, sizeof(struct fs_quota_stat));
> > > +	if (copy_from_user(&fqs, addr, 1)) /* just get the version */
> > > +		return -EFAULT;
> > > +
> > > +	switch (fqs.qs_version) {
> > > +	case FS_QSTAT_VERSION_2:
> > > +		size = FS_QSTAT_V2_SIZE;
> > > +		break;
> > > +	default:
> > > +		fqs.qs_version = FS_QSTAT_VERSION;
> > > +		/* fallthrough */
> > > +	case FS_QSTAT_VERSION:
> > > +		size = FS_QSTAT_V1_SIZE;
> > > +		break;
> > > +	}
>   Guys, you cannot really do this. If anyone is using getxstate() with
> uninitialized buffer (which is fine so far), you cannot suddently start to
> rely on the contents of qs_version field. That's ABI (and even API)
> breakage.

Agree, it is a API breakage.

Will fix it by adding a new quotactl value as you suggest. 
Does 

#define Q_XGETQSTAT2     XQM_CMD(8)

sound good ?
> 
> Unless I'm missing something, the only clean way is to use new quotactl
> value for the interface with version field used for input as well.
> 
> 								Honza
> 


_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 08/11] xfs: Add pquota fields where gquota is used.
  2013-06-27 22:25 ` [PATCH v10 08/11] xfs: Add pquota fields where gquota is used Chandra Seetharaman
@ 2013-07-10 21:39   ` Ben Myers
  2013-07-10 21:46     ` Chandra Seetharaman
  0 siblings, 1 reply; 40+ messages in thread
From: Ben Myers @ 2013-07-10 21:39 UTC (permalink / raw)
  To: Chandra Seetharaman; +Cc: xfs

Hi Chandra,

On Thu, Jun 27, 2013 at 05:25:11PM -0500, Chandra Seetharaman wrote:
> Add project quota changes to all the places where group quota field
> is used:
>    * add separate project quota members into various structures
>    * split project quota and group quotas so that instead of overriding
>      the group quota members incore, the new project quota members are
>      used instead
>    * get rid of usage of the OQUOTA flag incore, in favor of separate
>    * group and project quota flags.

     ^ * is extra?

>    * add a project dquot argument to various functions.
> 
> Not using the pquotino field from superblock yet.
> 
> Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>

Patch looks good to me.

Reviewed-by: Ben Myers <bpm@sgi.com>

I had just a few tiny nits and questions I found in review.  If you were not
already planning to repost I suggest you ignore them.  ;)

Regards,
	Ben

> diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
> index 5e99968..71a8bc5 100644
> --- a/fs/xfs/xfs_ioctl.c
> +++ b/fs/xfs/xfs_ioctl.c
> @@ -928,7 +928,7 @@ xfs_ioctl_setattr(
>  	struct xfs_trans	*tp;
>  	unsigned int		lock_flags = 0;
>  	struct xfs_dquot	*udqp = NULL;
> -	struct xfs_dquot	*gdqp = NULL;
> +	struct xfs_dquot	*pdqp = NULL;
>  	struct xfs_dquot	*olddquot = NULL;
>  	int			code;
>  
> @@ -957,7 +957,7 @@ xfs_ioctl_setattr(
>  	if (XFS_IS_QUOTA_ON(mp) && (mask & FSX_PROJID)) {
>  		code = xfs_qm_vop_dqalloc(ip, ip->i_d.di_uid,
>  					 ip->i_d.di_gid, fa->fsx_projid,
> -					 XFS_QMOPT_PQUOTA, &udqp, &gdqp);
> +					 XFS_QMOPT_PQUOTA, &udqp, NULL, &pdqp);
>  		if (code)
>  			return code;
>  	}
> @@ -994,8 +994,8 @@ xfs_ioctl_setattr(
>  		    XFS_IS_PQUOTA_ON(mp) &&
>  		    xfs_get_projid(ip) != fa->fsx_projid) {
>  			ASSERT(tp);
> -			code = xfs_qm_vop_chown_reserve(tp, ip, udqp, gdqp,
> -						capable(CAP_FOWNER) ?
> +			code = xfs_qm_vop_chown_reserve(tp, ip, udqp, NULL,
> +						pdqp, capable(CAP_FOWNER) ?
>  						XFS_QMOPT_FORCE_RES : 0);
>  			if (code)	/* out of quota */
>  				goto error_return;
> @@ -1113,7 +1113,7 @@ xfs_ioctl_setattr(
>  		if (xfs_get_projid(ip) != fa->fsx_projid) {
>  			if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_PQUOTA_ON(mp)) {
>  				olddquot = xfs_qm_vop_chown(tp, ip,
> -							&ip->i_gdquot, gdqp);
> +							&ip->i_pdquot, pdqp);
>  			}
>  			xfs_set_projid(ip, fa->fsx_projid);
>  
> @@ -1160,13 +1160,13 @@ xfs_ioctl_setattr(
>  	 */
>  	xfs_qm_dqrele(olddquot);
>  	xfs_qm_dqrele(udqp);
> -	xfs_qm_dqrele(gdqp);
> +	xfs_qm_dqrele(pdqp);
>  
>  	return code;
>  
>   error_return:
>  	xfs_qm_dqrele(udqp);
> -	xfs_qm_dqrele(gdqp);
> +	xfs_qm_dqrele(pdqp);
>  	xfs_trans_cancel(tp, 0);
>  	if (lock_flags)
>  		xfs_iunlock(ip, lock_flags);

Here in xfs_ioctl_setattr, I'm not clear on why we're messing with the user
dquot at all.  Could it be removed entirely?  A change in project id doesn't
effect user quota, right?

Maybe that's an idea for a separate patch.

>  STATIC void
> -xfs_qm_dqattach_grouphint(
> -	xfs_dquot_t	*udq,
> -	xfs_dquot_t	*gdq)
> +xfs_qm_dqattach_hint(
> +	struct xfs_inode	*ip,
> +	int			type)
>  {
> -	xfs_dquot_t	*tmp;
> +	struct xfs_dquot **dqhint;

Maybe clearer as dqhintp.

> +	struct xfs_dquot *dqp;
> +	struct xfs_dquot *udq = ip->i_udquot;
>  
>  	xfs_dqlock(udq);
>  
> -	tmp = udq->q_gdquot;
> -	if (tmp) {
> -		if (tmp == gdq)

If I understand this xfs_qm_dqattach_hint correctly, this might be nice:

	ASSERT(type == XFS_DQ_GROUP || type == XFS_DQ_PROJ);

> diff --git a/fs/xfs/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c
> index 2d02eac..72a4fdd 100644
> --- a/fs/xfs/xfs_qm_bhv.c
> +++ b/fs/xfs/xfs_qm_bhv.c
> @@ -115,7 +115,7 @@ xfs_qm_newmount(
>  	     (pquotaondisk && !XFS_IS_PQUOTA_ON(mp)) ||
>  	    (!pquotaondisk &&  XFS_IS_PQUOTA_ON(mp)) ||
>  	     (gquotaondisk && !XFS_IS_GQUOTA_ON(mp)) ||
> -	    (!gquotaondisk &&  XFS_IS_OQUOTA_ON(mp)))  &&
> +	    (!gquotaondisk &&  XFS_IS_GQUOTA_ON(mp)))  &&

These are not in the usual user/group/project order, and so are some other
checks in this function.  Could be cleaned up.  Maybe a different patch too.

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 08/11] xfs: Add pquota fields where gquota is used.
  2013-07-10 21:39   ` Ben Myers
@ 2013-07-10 21:46     ` Chandra Seetharaman
  2013-07-11  1:23       ` Dave Chinner
  0 siblings, 1 reply; 40+ messages in thread
From: Chandra Seetharaman @ 2013-07-10 21:46 UTC (permalink / raw)
  To: Ben Myers; +Cc: xfs

I am rolling up a new set with changes based on David's comments and
Jan's comments.

Will address your comments too.
On Wed, 2013-07-10 at 16:39 -0500, Ben Myers wrote:
> Hi Chandra,
> 
> On Thu, Jun 27, 2013 at 05:25:11PM -0500, Chandra Seetharaman wrote:
> > Add project quota changes to all the places where group quota field
> > is used:
> >    * add separate project quota members into various structures
> >    * split project quota and group quotas so that instead of overriding
> >      the group quota members incore, the new project quota members are
> >      used instead
> >    * get rid of usage of the OQUOTA flag incore, in favor of separate
> >    * group and project quota flags.
> 
>      ^ * is extra?

will fix
> 
> >    * add a project dquot argument to various functions.
> > 
> > Not using the pquotino field from superblock yet.
> > 
> > Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
> 
> Patch looks good to me.
> 
> Reviewed-by: Ben Myers <bpm@sgi.com>
> 
> I had just a few tiny nits and questions I found in review.  If you were not
> already planning to repost I suggest you ignore them.  ;)
> 
> Regards,
> 	Ben
> 
> > diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
> > index 5e99968..71a8bc5 100644
> > --- a/fs/xfs/xfs_ioctl.c
> > +++ b/fs/xfs/xfs_ioctl.c
> > @@ -928,7 +928,7 @@ xfs_ioctl_setattr(
> >  	struct xfs_trans	*tp;
> >  	unsigned int		lock_flags = 0;
> >  	struct xfs_dquot	*udqp = NULL;
> > -	struct xfs_dquot	*gdqp = NULL;
> > +	struct xfs_dquot	*pdqp = NULL;
> >  	struct xfs_dquot	*olddquot = NULL;
> >  	int			code;
> >  
> > @@ -957,7 +957,7 @@ xfs_ioctl_setattr(
> >  	if (XFS_IS_QUOTA_ON(mp) && (mask & FSX_PROJID)) {
> >  		code = xfs_qm_vop_dqalloc(ip, ip->i_d.di_uid,
> >  					 ip->i_d.di_gid, fa->fsx_projid,
> > -					 XFS_QMOPT_PQUOTA, &udqp, &gdqp);
> > +					 XFS_QMOPT_PQUOTA, &udqp, NULL, &pdqp);
> >  		if (code)
> >  			return code;
> >  	}
> > @@ -994,8 +994,8 @@ xfs_ioctl_setattr(
> >  		    XFS_IS_PQUOTA_ON(mp) &&
> >  		    xfs_get_projid(ip) != fa->fsx_projid) {
> >  			ASSERT(tp);
> > -			code = xfs_qm_vop_chown_reserve(tp, ip, udqp, gdqp,
> > -						capable(CAP_FOWNER) ?
> > +			code = xfs_qm_vop_chown_reserve(tp, ip, udqp, NULL,
> > +						pdqp, capable(CAP_FOWNER) ?
> >  						XFS_QMOPT_FORCE_RES : 0);
> >  			if (code)	/* out of quota */
> >  				goto error_return;
> > @@ -1113,7 +1113,7 @@ xfs_ioctl_setattr(
> >  		if (xfs_get_projid(ip) != fa->fsx_projid) {
> >  			if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_PQUOTA_ON(mp)) {
> >  				olddquot = xfs_qm_vop_chown(tp, ip,
> > -							&ip->i_gdquot, gdqp);
> > +							&ip->i_pdquot, pdqp);
> >  			}
> >  			xfs_set_projid(ip, fa->fsx_projid);
> >  
> > @@ -1160,13 +1160,13 @@ xfs_ioctl_setattr(
> >  	 */
> >  	xfs_qm_dqrele(olddquot);
> >  	xfs_qm_dqrele(udqp);
> > -	xfs_qm_dqrele(gdqp);
> > +	xfs_qm_dqrele(pdqp);
> >  
> >  	return code;
> >  
> >   error_return:
> >  	xfs_qm_dqrele(udqp);
> > -	xfs_qm_dqrele(gdqp);
> > +	xfs_qm_dqrele(pdqp);
> >  	xfs_trans_cancel(tp, 0);
> >  	if (lock_flags)
> >  		xfs_iunlock(ip, lock_flags);
> 
> Here in xfs_ioctl_setattr, I'm not clear on why we're messing with the user
> dquot at all.  Could it be removed entirely?  A change in project id doesn't
> effect user quota, right?
> 
> Maybe that's an idea for a separate patch.

I will look into that after these get in :)
> 
> >  STATIC void
> > -xfs_qm_dqattach_grouphint(
> > -	xfs_dquot_t	*udq,
> > -	xfs_dquot_t	*gdq)
> > +xfs_qm_dqattach_hint(
> > +	struct xfs_inode	*ip,
> > +	int			type)
> >  {
> > -	xfs_dquot_t	*tmp;
> > +	struct xfs_dquot **dqhint;
> 
> Maybe clearer as dqhintp.
> 
sure.
> > +	struct xfs_dquot *dqp;
> > +	struct xfs_dquot *udq = ip->i_udquot;
> >  
> >  	xfs_dqlock(udq);
> >  
> > -	tmp = udq->q_gdquot;
> > -	if (tmp) {
> > -		if (tmp == gdq)
> 
> If I understand this xfs_qm_dqattach_hint correctly, this might be nice:
> 
> 	ASSERT(type == XFS_DQ_GROUP || type == XFS_DQ_PROJ);

will do.

> 
> > diff --git a/fs/xfs/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c
> > index 2d02eac..72a4fdd 100644
> > --- a/fs/xfs/xfs_qm_bhv.c
> > +++ b/fs/xfs/xfs_qm_bhv.c
> > @@ -115,7 +115,7 @@ xfs_qm_newmount(
> >  	     (pquotaondisk && !XFS_IS_PQUOTA_ON(mp)) ||
> >  	    (!pquotaondisk &&  XFS_IS_PQUOTA_ON(mp)) ||
> >  	     (gquotaondisk && !XFS_IS_GQUOTA_ON(mp)) ||
> > -	    (!gquotaondisk &&  XFS_IS_OQUOTA_ON(mp)))  &&
> > +	    (!gquotaondisk &&  XFS_IS_GQUOTA_ON(mp)))  &&
> 
> These are not in the usual user/group/project order, and so are some other
> checks in this function.  Could be cleaned up.  Maybe a different patch too.
> 
I thought I fixed all of them around. Will fix this too.
> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
> http://oss.sgi.com/mailman/listinfo/xfs
> 


_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 10/11] quota: Add proper versioning support to fs_quota_stat
  2013-07-10 18:47       ` Ben Myers
@ 2013-07-10 21:52         ` Jan Kara
  0 siblings, 0 replies; 40+ messages in thread
From: Jan Kara @ 2013-07-10 21:52 UTC (permalink / raw)
  To: Ben Myers; +Cc: swhiteho, Jan Kara, Chandra Seetharaman, xfs

On Wed 10-07-13 13:47:04, Ben Myers wrote:
> Hey Jan,
> 
> On Wed, Jul 10, 2013 at 06:26:02PM +0200, Jan Kara wrote:
> > On Wed 10-07-13 10:55:38, Ben Myers wrote:
> > > Hey Chandra,
> > > 
> > > On Thu, Jun 27, 2013 at 05:25:13PM -0500, Chandra Seetharaman wrote:
> > > > Added appropriate pads and code for backward compatibility.
> > > > 
> > > > Copied over the old version as it is different from the newer padded
> > > > version.
> > > > 
> > > > New callers of the system call have to set the version of the data
> > > > structure being passed, and kernel will fill as much data as requested.
> > > > 
> > > > Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
> > > 
> > > I think we also need to
> > > 
> > > Cc: Jan Kara <jack@suse.cz>
> >   Thanks for CC.
> > 
> > > > diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
> > > > index c7c840e..ca0dccd 100644
> > > > --- a/fs/gfs2/quota.c
> > > > +++ b/fs/gfs2/quota.c
> > > > @@ -1443,9 +1443,6 @@ static int gfs2_quota_get_xstate(struct super_block *sb,
> > > >  {
> > > >  	struct gfs2_sbd *sdp = sb->s_fs_info;
> > > >  
> > > > -	memset(fqs, 0, sizeof(struct fs_quota_stat));
> > > > -	fqs->qs_version = FS_QSTAT_VERSION;
> > > > -
> > > >  	switch (sdp->sd_args.ar_quota) {
> > > >  	case GFS2_QUOTA_ON:
> > > >  		fqs->qs_flags |= (FS_QUOTA_UDQ_ENFD | FS_QUOTA_GDQ_ENFD);
> > > > diff --git a/fs/quota/quota.c b/fs/quota/quota.c
> > > > index c7314f1..ae6526e 100644
> > > > --- a/fs/quota/quota.c
> > > > +++ b/fs/quota/quota.c
> > > > @@ -207,12 +207,57 @@ static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr)
> > > >  static int quota_getxstate(struct super_block *sb, void __user *addr)
> > > >  {
> > > >  	struct fs_quota_stat fqs;
> > > > -	int ret;
> > > > +	struct fs_quota_stat_v1 fqs_v1;
> > > > +	int ret, size;
> > > > +	void *fqsp;
> > > >  
> > > >  	if (!sb->s_qcop->get_xstate)
> > > >  		return -ENOSYS;
> > > > +
> > > > +	memset(&fqs, 0, sizeof(struct fs_quota_stat));
> > > > +	if (copy_from_user(&fqs, addr, 1)) /* just get the version */
> > > > +		return -EFAULT;
> > > > +
> > > > +	switch (fqs.qs_version) {
> > > > +	case FS_QSTAT_VERSION_2:
> > > > +		size = FS_QSTAT_V2_SIZE;
> > > > +		break;
> > > > +	default:
> > > > +		fqs.qs_version = FS_QSTAT_VERSION;
> > > > +		/* fallthrough */
> > > > +	case FS_QSTAT_VERSION:
> > > > +		size = FS_QSTAT_V1_SIZE;
> > > > +		break;
> > > > +	}
> >   Guys, you cannot really do this. If anyone is using getxstate() with
> > uninitialized buffer (which is fine so far), you cannot suddently start to
> > rely on the contents of qs_version field. That's ABI (and even API)
> > breakage.
> 
> Looks like you are correct to me.  Seems that qs_version number was never
> checked until this patch.
> 
> > Unless I'm missing something, the only clean way is to use new quotactl
> > value for the interface with version field used for input as well.
> 
> If I understand... it would be something like this?
> 
> #define Q_XGETQSTATV     XQM_CMD(8)
   Yes.

> Or Q_XGETQSTAT2?
  I don't really care but the first name looks a bit better.

								Honza
-- 
Jan Kara <jack@suse.cz>
SUSE Labs, CR

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 10/11] quota: Add proper versioning support to fs_quota_stat
  2013-07-10 20:49       ` Chandra Seetharaman
@ 2013-07-10 21:54         ` Jan Kara
  2013-07-11  1:45         ` Dave Chinner
  1 sibling, 0 replies; 40+ messages in thread
From: Jan Kara @ 2013-07-10 21:54 UTC (permalink / raw)
  To: Chandra Seetharaman; +Cc: Ben Myers, Jan Kara, swhiteho, xfs

On Wed 10-07-13 15:49:50, Chandra Seetharaman wrote:
> On Wed, 2013-07-10 at 18:26 +0200, Jan Kara wrote:
> > On Wed 10-07-13 10:55:38, Ben Myers wrote:
> > > Hey Chandra,
> 
> <snip>
> 
> > > > diff --git a/fs/quota/quota.c b/fs/quota/quota.c
> > > > index c7314f1..ae6526e 100644
> > > > --- a/fs/quota/quota.c
> > > > +++ b/fs/quota/quota.c
> > > > @@ -207,12 +207,57 @@ static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr)
> > > >  static int quota_getxstate(struct super_block *sb, void __user *addr)
> > > >  {
> > > >  	struct fs_quota_stat fqs;
> > > > -	int ret;
> > > > +	struct fs_quota_stat_v1 fqs_v1;
> > > > +	int ret, size;
> > > > +	void *fqsp;
> > > >  
> > > >  	if (!sb->s_qcop->get_xstate)
> > > >  		return -ENOSYS;
> > > > +
> > > > +	memset(&fqs, 0, sizeof(struct fs_quota_stat));
> > > > +	if (copy_from_user(&fqs, addr, 1)) /* just get the version */
> > > > +		return -EFAULT;
> > > > +
> > > > +	switch (fqs.qs_version) {
> > > > +	case FS_QSTAT_VERSION_2:
> > > > +		size = FS_QSTAT_V2_SIZE;
> > > > +		break;
> > > > +	default:
> > > > +		fqs.qs_version = FS_QSTAT_VERSION;
> > > > +		/* fallthrough */
> > > > +	case FS_QSTAT_VERSION:
> > > > +		size = FS_QSTAT_V1_SIZE;
> > > > +		break;
> > > > +	}
> >   Guys, you cannot really do this. If anyone is using getxstate() with
> > uninitialized buffer (which is fine so far), you cannot suddently start to
> > rely on the contents of qs_version field. That's ABI (and even API)
> > breakage.
> 
> Agree, it is a API breakage.
> 
> Will fix it by adding a new quotactl value as you suggest. 
> Does 
> 
> #define Q_XGETQSTAT2     XQM_CMD(8)
> 
> sound good ?
  Ben's Q_XGETQSTATV name looked a bit better to me but I don't really
care. Whatever works for you...

								Honza

-- 
Jan Kara <jack@suse.cz>
SUSE Labs, CR

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 08/11] xfs: Add pquota fields where gquota is used.
  2013-07-10 21:46     ` Chandra Seetharaman
@ 2013-07-11  1:23       ` Dave Chinner
  2013-07-11  4:05         ` Chandra Seetharaman
  0 siblings, 1 reply; 40+ messages in thread
From: Dave Chinner @ 2013-07-11  1:23 UTC (permalink / raw)
  To: Chandra Seetharaman; +Cc: Ben Myers, xfs

On Wed, Jul 10, 2013 at 04:46:38PM -0500, Chandra Seetharaman wrote:
> > > @@ -1160,13 +1160,13 @@ xfs_ioctl_setattr(
> > >  	 */
> > >  	xfs_qm_dqrele(olddquot);
> > >  	xfs_qm_dqrele(udqp);
> > > -	xfs_qm_dqrele(gdqp);
> > > +	xfs_qm_dqrele(pdqp);
> > >  
> > >  	return code;
> > >  
> > >   error_return:
> > >  	xfs_qm_dqrele(udqp);
> > > -	xfs_qm_dqrele(gdqp);
> > > +	xfs_qm_dqrele(pdqp);
> > >  	xfs_trans_cancel(tp, 0);
> > >  	if (lock_flags)
> > >  		xfs_iunlock(ip, lock_flags);
> > 
> > Here in xfs_ioctl_setattr, I'm not clear on why we're messing with the user
> > dquot at all.  Could it be removed entirely?  A change in project id doesn't
> > effect user quota, right?
> > 
> > Maybe that's an idea for a separate patch.
> 
> I will look into that after these get in :)

The user dquot may have group and/or project dquot hints attached to
it. Therefore if we are changing project quota and user quotas are
enabled, then we may have to remove the hint from the user dquot
that points to the old project dquot....

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 10/11] quota: Add proper versioning support to fs_quota_stat
  2013-07-10 20:49       ` Chandra Seetharaman
  2013-07-10 21:54         ` Jan Kara
@ 2013-07-11  1:45         ` Dave Chinner
  2013-07-11  4:16           ` Chandra Seetharaman
  1 sibling, 1 reply; 40+ messages in thread
From: Dave Chinner @ 2013-07-11  1:45 UTC (permalink / raw)
  To: Chandra Seetharaman; +Cc: Ben Myers, Jan Kara, swhiteho, xfs

On Wed, Jul 10, 2013 at 03:49:50PM -0500, Chandra Seetharaman wrote:
> On Wed, 2013-07-10 at 18:26 +0200, Jan Kara wrote:
> > On Wed 10-07-13 10:55:38, Ben Myers wrote:
> > > Hey Chandra,
> 
> <snip>
> 
> > > > diff --git a/fs/quota/quota.c b/fs/quota/quota.c
> > > > index c7314f1..ae6526e 100644
> > > > --- a/fs/quota/quota.c
> > > > +++ b/fs/quota/quota.c
> > > > @@ -207,12 +207,57 @@ static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr)
> > > >  static int quota_getxstate(struct super_block *sb, void __user *addr)
> > > >  {
> > > >  	struct fs_quota_stat fqs;
> > > > -	int ret;
> > > > +	struct fs_quota_stat_v1 fqs_v1;
> > > > +	int ret, size;
> > > > +	void *fqsp;
> > > >  
> > > >  	if (!sb->s_qcop->get_xstate)
> > > >  		return -ENOSYS;
> > > > +
> > > > +	memset(&fqs, 0, sizeof(struct fs_quota_stat));
> > > > +	if (copy_from_user(&fqs, addr, 1)) /* just get the version */
> > > > +		return -EFAULT;
> > > > +
> > > > +	switch (fqs.qs_version) {
> > > > +	case FS_QSTAT_VERSION_2:
> > > > +		size = FS_QSTAT_V2_SIZE;
> > > > +		break;
> > > > +	default:
> > > > +		fqs.qs_version = FS_QSTAT_VERSION;
> > > > +		/* fallthrough */
> > > > +	case FS_QSTAT_VERSION:
> > > > +		size = FS_QSTAT_V1_SIZE;
> > > > +		break;
> > > > +	}
> >   Guys, you cannot really do this. If anyone is using getxstate() with
> > uninitialized buffer (which is fine so far), you cannot suddently start to
> > rely on the contents of qs_version field. That's ABI (and even API)
> > breakage.
> 
> Agree, it is a API breakage.
> 
> Will fix it by adding a new quotactl value as you suggest. 

Please enforce the version number as being valid so we don't
need to add another new interface if we need to change this
structure again. :)

FWIW, we're now going to need a new xfs_quota changes to go along
with this - it will need to use the new interface by default, and
fall back to the existing interface if it gets an error saying the
command does not exist.  We can't actually test the new interface
until we have xfs_quota patches that use it.

And to play Devil's advocate: it is way too late in the merge cycle
to make these sorts of ABI changes to a patch and test/review them
adequately.

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 08/11] xfs: Add pquota fields where gquota is used.
  2013-07-11  1:23       ` Dave Chinner
@ 2013-07-11  4:05         ` Chandra Seetharaman
  0 siblings, 0 replies; 40+ messages in thread
From: Chandra Seetharaman @ 2013-07-11  4:05 UTC (permalink / raw)
  To: Dave Chinner; +Cc: Ben Myers, xfs

On Thu, 2013-07-11 at 11:23 +1000, Dave Chinner wrote:
> On Wed, Jul 10, 2013 at 04:46:38PM -0500, Chandra Seetharaman wrote:
> > > > @@ -1160,13 +1160,13 @@ xfs_ioctl_setattr(
> > > >  	 */
> > > >  	xfs_qm_dqrele(olddquot);
> > > >  	xfs_qm_dqrele(udqp);
> > > > -	xfs_qm_dqrele(gdqp);
> > > > +	xfs_qm_dqrele(pdqp);
> > > >  
> > > >  	return code;
> > > >  
> > > >   error_return:
> > > >  	xfs_qm_dqrele(udqp);
> > > > -	xfs_qm_dqrele(gdqp);
> > > > +	xfs_qm_dqrele(pdqp);
> > > >  	xfs_trans_cancel(tp, 0);
> > > >  	if (lock_flags)
> > > >  		xfs_iunlock(ip, lock_flags);
> > > 
> > > Here in xfs_ioctl_setattr, I'm not clear on why we're messing with the user
> > > dquot at all.  Could it be removed entirely?  A change in project id doesn't
> > > effect user quota, right?
> > > 
> > > Maybe that's an idea for a separate patch.
> > 
> > I will look into that after these get in :)
> 
> The user dquot may have group and/or project dquot hints attached to
> it. Therefore if we are changing project quota and user quotas are
> enabled, then we may have to remove the hint from the user dquot
> that points to the old project dquot....

Thanks for the explanation Dave.
> 
> Cheers,
> 
> Dave.


_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 10/11] quota: Add proper versioning support to fs_quota_stat
  2013-07-11  1:45         ` Dave Chinner
@ 2013-07-11  4:16           ` Chandra Seetharaman
  2013-07-11  7:18             ` Dave Chinner
  2013-07-11  7:51             ` Steven Whitehouse
  0 siblings, 2 replies; 40+ messages in thread
From: Chandra Seetharaman @ 2013-07-11  4:16 UTC (permalink / raw)
  To: Dave Chinner; +Cc: Ben Myers, Jan Kara, swhiteho, xfs

On Thu, 2013-07-11 at 11:45 +1000, Dave Chinner wrote:
> On Wed, Jul 10, 2013 at 03:49:50PM -0500, Chandra Seetharaman wrote:
> > On Wed, 2013-07-10 at 18:26 +0200, Jan Kara wrote:
> > > On Wed 10-07-13 10:55:38, Ben Myers wrote:
> > > > Hey Chandra,
> > 
> > <snip>
> > 
> > > > > diff --git a/fs/quota/quota.c b/fs/quota/quota.c
> > > > > index c7314f1..ae6526e 100644
> > > > > --- a/fs/quota/quota.c
> > > > > +++ b/fs/quota/quota.c
> > > > > @@ -207,12 +207,57 @@ static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr)
> > > > >  static int quota_getxstate(struct super_block *sb, void __user *addr)
> > > > >  {
> > > > >  	struct fs_quota_stat fqs;
> > > > > -	int ret;
> > > > > +	struct fs_quota_stat_v1 fqs_v1;
> > > > > +	int ret, size;
> > > > > +	void *fqsp;
> > > > >  
> > > > >  	if (!sb->s_qcop->get_xstate)
> > > > >  		return -ENOSYS;
> > > > > +
> > > > > +	memset(&fqs, 0, sizeof(struct fs_quota_stat));
> > > > > +	if (copy_from_user(&fqs, addr, 1)) /* just get the version */
> > > > > +		return -EFAULT;
> > > > > +
> > > > > +	switch (fqs.qs_version) {
> > > > > +	case FS_QSTAT_VERSION_2:
> > > > > +		size = FS_QSTAT_V2_SIZE;
> > > > > +		break;
> > > > > +	default:
> > > > > +		fqs.qs_version = FS_QSTAT_VERSION;
> > > > > +		/* fallthrough */
> > > > > +	case FS_QSTAT_VERSION:
> > > > > +		size = FS_QSTAT_V1_SIZE;
> > > > > +		break;
> > > > > +	}
> > >   Guys, you cannot really do this. If anyone is using getxstate() with
> > > uninitialized buffer (which is fine so far), you cannot suddently start to
> > > rely on the contents of qs_version field. That's ABI (and even API)
> > > breakage.
> > 
> > Agree, it is a API breakage.
> > 
> > Will fix it by adding a new quotactl value as you suggest. 
> 
> Please enforce the version number as being valid so we don't
> need to add another new interface if we need to change this
> structure again. :)

Yes, I am keeping the lower level interface same as before.

> 
> FWIW, we're now going to need a new xfs_quota changes to go along
> with this - it will need to use the new interface by default, and
> fall back to the existing interface if it gets an error saying the
> command does not exist.  We can't actually test the new interface
> until we have xfs_quota patches that use it.

The lower level interface doesn't change. It will remain the same. I
will send the code soon.

> 
> And to play Devil's advocate: it is way too late in the merge cycle
> to make these sorts of ABI changes to a patch and test/review them
> adequately.

There is no ABI issues even in the earlier version, it was an API
breakage. And with Jan's suggestion even that API breakage is being
fixed. There is no change in API or ABI. We are just adding a new
interface.

Old code and old binary will work as before.

> 
> Cheers,
> 
> Dave.


_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 10/11] quota: Add proper versioning support to fs_quota_stat
  2013-07-11  4:16           ` Chandra Seetharaman
@ 2013-07-11  7:18             ` Dave Chinner
  2013-07-11  7:51             ` Steven Whitehouse
  1 sibling, 0 replies; 40+ messages in thread
From: Dave Chinner @ 2013-07-11  7:18 UTC (permalink / raw)
  To: Chandra Seetharaman; +Cc: Ben Myers, Jan Kara, swhiteho, xfs

On Wed, Jul 10, 2013 at 11:16:01PM -0500, Chandra Seetharaman wrote:
> On Thu, 2013-07-11 at 11:45 +1000, Dave Chinner wrote:
> > And to play Devil's advocate: it is way too late in the merge cycle
> > to make these sorts of ABI changes to a patch and test/review them
> > adequately.
> 
> There is no ABI issues even in the earlier version, it was an API
> breakage.

Old binaries would have done the wrong thing - that's an ABI
issue. I'm sorry I didn't realise this earlier.

> And with Jan's suggestion even that API breakage is being
> fixed. There is no change in API or ABI. We are just adding a new
> interface.

Yes, we are adding a new API to avoid ABI problems with
re-interpreting the old API. 

But whether it's API or ABI, it doesn't matter - my point is that
it's almost 2 weeks after the merge window was opened and adding new
userspace APIs at the last moment before the merge window closes
tends to be frowned upon....

> Old code and old binary will work as before.

Yes, but we have no new code or binaries to test the new interface,
do we?

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 10/11] quota: Add proper versioning support to fs_quota_stat
  2013-07-11  4:16           ` Chandra Seetharaman
  2013-07-11  7:18             ` Dave Chinner
@ 2013-07-11  7:51             ` Steven Whitehouse
  1 sibling, 0 replies; 40+ messages in thread
From: Steven Whitehouse @ 2013-07-11  7:51 UTC (permalink / raw)
  To: sekharan; +Cc: Jan Kara, Ben Myers, adas, xfs

Hi,

Copying in Abhi, since he is the quota expert on the GFS2 side,

Steve.

On Wed, 2013-07-10 at 23:16 -0500, Chandra Seetharaman wrote:
> On Thu, 2013-07-11 at 11:45 +1000, Dave Chinner wrote:
> > On Wed, Jul 10, 2013 at 03:49:50PM -0500, Chandra Seetharaman wrote:
> > > On Wed, 2013-07-10 at 18:26 +0200, Jan Kara wrote:
> > > > On Wed 10-07-13 10:55:38, Ben Myers wrote:
> > > > > Hey Chandra,
> > > 
> > > <snip>
> > > 
> > > > > > diff --git a/fs/quota/quota.c b/fs/quota/quota.c
> > > > > > index c7314f1..ae6526e 100644
> > > > > > --- a/fs/quota/quota.c
> > > > > > +++ b/fs/quota/quota.c
> > > > > > @@ -207,12 +207,57 @@ static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr)
> > > > > >  static int quota_getxstate(struct super_block *sb, void __user *addr)
> > > > > >  {
> > > > > >  	struct fs_quota_stat fqs;
> > > > > > -	int ret;
> > > > > > +	struct fs_quota_stat_v1 fqs_v1;
> > > > > > +	int ret, size;
> > > > > > +	void *fqsp;
> > > > > >  
> > > > > >  	if (!sb->s_qcop->get_xstate)
> > > > > >  		return -ENOSYS;
> > > > > > +
> > > > > > +	memset(&fqs, 0, sizeof(struct fs_quota_stat));
> > > > > > +	if (copy_from_user(&fqs, addr, 1)) /* just get the version */
> > > > > > +		return -EFAULT;
> > > > > > +
> > > > > > +	switch (fqs.qs_version) {
> > > > > > +	case FS_QSTAT_VERSION_2:
> > > > > > +		size = FS_QSTAT_V2_SIZE;
> > > > > > +		break;
> > > > > > +	default:
> > > > > > +		fqs.qs_version = FS_QSTAT_VERSION;
> > > > > > +		/* fallthrough */
> > > > > > +	case FS_QSTAT_VERSION:
> > > > > > +		size = FS_QSTAT_V1_SIZE;
> > > > > > +		break;
> > > > > > +	}
> > > >   Guys, you cannot really do this. If anyone is using getxstate() with
> > > > uninitialized buffer (which is fine so far), you cannot suddently start to
> > > > rely on the contents of qs_version field. That's ABI (and even API)
> > > > breakage.
> > > 
> > > Agree, it is a API breakage.
> > > 
> > > Will fix it by adding a new quotactl value as you suggest. 
> > 
> > Please enforce the version number as being valid so we don't
> > need to add another new interface if we need to change this
> > structure again. :)
> 
> Yes, I am keeping the lower level interface same as before.
> 
> > 
> > FWIW, we're now going to need a new xfs_quota changes to go along
> > with this - it will need to use the new interface by default, and
> > fall back to the existing interface if it gets an error saying the
> > command does not exist.  We can't actually test the new interface
> > until we have xfs_quota patches that use it.
> 
> The lower level interface doesn't change. It will remain the same. I
> will send the code soon.
> 
> > 
> > And to play Devil's advocate: it is way too late in the merge cycle
> > to make these sorts of ABI changes to a patch and test/review them
> > adequately.
> 
> There is no ABI issues even in the earlier version, it was an API
> breakage. And with Jan's suggestion even that API breakage is being
> fixed. There is no change in API or ABI. We are just adding a new
> interface.
> 
> Old code and old binary will work as before.
> 
> > 
> > Cheers,
> > 
> > Dave.
> 
> 


_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2013-07-11  7:55 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-06-27 22:25 [PATCH v10 00/11] Allow pquota and gquota to be used together Chandra Seetharaman
2013-06-27 22:25 ` [PATCH v10 01/11] xfs: Define a new function xfs_is_quota_inode() Chandra Seetharaman
2013-06-27 22:43   ` Ben Myers
2013-06-27 22:25 ` [PATCH v10 02/11] xfs: Replace macro XFS_DQUOT_TREE with a function Chandra Seetharaman
2013-06-27 23:19   ` Ben Myers
2013-06-27 22:25 ` [PATCH v10 03/11] xfs: Replace macro XFS_DQ_TO_QIP " Chandra Seetharaman
2013-06-27 23:23   ` Ben Myers
2013-06-27 22:25 ` [PATCH v10 04/11] xfs: Code cleanup and removal of some typedef usage Chandra Seetharaman
2013-06-27 23:50   ` Ben Myers
2013-06-27 22:25 ` [PATCH v10 05/11] xfs: Do some whitespace cleanup in the data structure xfs_quotainfo Chandra Seetharaman
2013-06-28 16:30   ` Ben Myers
2013-06-28 18:14     ` Chandra Seetharaman
2013-06-28 18:31       ` Ben Myers
2013-06-27 22:25 ` [PATCH v10 06/11] xfs: Change xfs_dquot_acct to be a 2-dimensional array Chandra Seetharaman
2013-06-28 19:06   ` Ben Myers
2013-06-27 22:25 ` [PATCH v10 07/11] xfs: Remove incore use of XFS_OQUOTA_ENFD and XFS_OQUOTA_CHKD Chandra Seetharaman
2013-06-28 22:36   ` Ben Myers
2013-06-27 22:25 ` [PATCH v10 08/11] xfs: Add pquota fields where gquota is used Chandra Seetharaman
2013-07-10 21:39   ` Ben Myers
2013-07-10 21:46     ` Chandra Seetharaman
2013-07-11  1:23       ` Dave Chinner
2013-07-11  4:05         ` Chandra Seetharaman
2013-06-27 22:25 ` [PATCH v10 09/11] xfs: Start using pquotaino from the superblock Chandra Seetharaman
2013-07-01  2:06   ` Dave Chinner
2013-07-01 17:59     ` Chandra Seetharaman
2013-07-03 17:12       ` Chandra Seetharaman
2013-07-04  1:35         ` Dave Chinner
2013-06-27 22:25 ` [PATCH v10 10/11] quota: Add proper versioning support to fs_quota_stat Chandra Seetharaman
2013-07-10 15:55   ` Ben Myers
2013-07-10 16:26     ` Jan Kara
2013-07-10 18:47       ` Ben Myers
2013-07-10 21:52         ` Jan Kara
2013-07-10 20:49       ` Chandra Seetharaman
2013-07-10 21:54         ` Jan Kara
2013-07-11  1:45         ` Dave Chinner
2013-07-11  4:16           ` Chandra Seetharaman
2013-07-11  7:18             ` Dave Chinner
2013-07-11  7:51             ` Steven Whitehouse
2013-06-27 22:25 ` [PATCH v10 11/11] xfs: Use new qs_pquota field in fs_quota_stat for Q_XGETQSTAT Chandra Seetharaman
2013-06-28 22:53 ` [PATCH v10 00/11] Allow pquota and gquota to be used together Ben Myers

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.