Re: [Cluster-devel] [PATCH] fs: record task name which froze superblock

2015-02-18 Thread Jan Kara
On Wed 18-02-15 10:34:55, Alexey Dobriyan wrote:
 On Mon, Feb 16, 2015 at 10:38:52AM +0100, Jan Kara wrote:
  On Sat 14-02-15 21:55:24, Alexey Dobriyan wrote:
   Freezing and thawing are separate system calls, task which is supposed
   to thaw filesystem/superblock can disappear due to crash or not thaw
   due to a bug. Record at least task name (we can't take task_struct
   reference) to make support engineer's life easier.
   
   Hopefully 16 bytes per superblock isn't much.
   
   P.S.: Cc'ing GFS2 people just in case they want to correct
   my understanding of GFS2 having async freeze code.
   
   Signed-off-by: Alexey Dobriyan adobri...@gmail.com
Hum, and when do you show the task name? Or do you expect that customer
  takes a crashdump and support just finds it in memory?
 
 Yeah, having at least something in crashdump is fine.
  OK, then comment about this at freeze_comm[] definition so that it's
clear it isn't just set-but-never-read field.
 
   --- a/fs/ioctl.c
   +++ b/fs/ioctl.c
   @@ -518,6 +518,7 @@ static int ioctl_fioasync(unsigned int fd, struct 
   file *filp,
static int ioctl_fsfreeze(struct file *filp)
{
 struct super_block *sb = file_inode(filp)-i_sb;
   + int rv;

 if (!capable(CAP_SYS_ADMIN))
 return -EPERM;
   @@ -527,22 +528,31 @@ static int ioctl_fsfreeze(struct file *filp)
 return -EOPNOTSUPP;

 /* Freeze */
   - if (sb-s_op-freeze_super)
   - return sb-s_op-freeze_super(sb);
   - return freeze_super(sb);
   + if (sb-s_op-freeze_super) {
   + rv = sb-s_op-freeze_super(sb);
   + if (rv == 0)
   + get_task_comm(sb-s_writers.freeze_comm, current);
   + } else
   + rv = freeze_super(sb);
   + return rv;
Why don't you just set the name in ioctl_fsfreeze() in both cases?
 
 There are users of freeze_super() in GFS2 unless I'm misreading code.
  Yes, there are. The call in fs/gfs2/glops.c is in a call path from
-freeze_super() handler for GFS2 so that one is handled in
ioctl_fsfreeze() anyway. The call in fs/gfs2/sys.c is a way to freeze
filesystem via sysfs (dunno why GFS2 has to invent its own thing and ioctl
isn't enough). Steven? So having the logic in ioctl_fsfreeze(),
freeze_bdev() and freeze_store() in gfs2 seems to be enough.

  Also you seem to be missing freezing / thawing in freeze/thaw_bdev()
  functions.
 
 You are correct. Resending patch (blockdev freezing tested with XFS).
 
   --- a/include/linux/fs.h
   +++ b/include/linux/fs.h
   @@ -1221,6 +1221,8 @@ struct sb_writers {
 int frozen; /* Is sb frozen? */
 wait_queue_head_t   wait_unfrozen;  /* queue for waiting for
sb to be thawed */
   + /* who froze superblock */
   + charfreeze_comm[16];
Here should be TASK_COMM_LEN, shouldn't it?
 
 It will pull sched.h, dunno if we care about headers anymore.
  That's not ideal but IMHO better than having the value hardcoded here.
That is pretty fragile - i.e. think what happens when someone decides to
increase TASK_COMM_LEN...

Honza
-- 
Jan Kara j...@suse.cz
SUSE Labs, CR



Re: [Cluster-devel] [PATCH] fs: record task name which froze superblock

2015-02-18 Thread Steven Whitehouse

Hi,

On 18/02/15 09:13, Jan Kara wrote:

On Wed 18-02-15 10:34:55, Alexey Dobriyan wrote:

On Mon, Feb 16, 2015 at 10:38:52AM +0100, Jan Kara wrote:

On Sat 14-02-15 21:55:24, Alexey Dobriyan wrote:

Freezing and thawing are separate system calls, task which is supposed
to thaw filesystem/superblock can disappear due to crash or not thaw
due to a bug. Record at least task name (we can't take task_struct
reference) to make support engineer's life easier.

Hopefully 16 bytes per superblock isn't much.

P.S.: Cc'ing GFS2 people just in case they want to correct
my understanding of GFS2 having async freeze code.

Signed-off-by: Alexey Dobriyan adobri...@gmail.com

   Hum, and when do you show the task name? Or do you expect that customer
takes a crashdump and support just finds it in memory?

Yeah, having at least something in crashdump is fine.

   OK, then comment about this at freeze_comm[] definition so that it's
clear it isn't just set-but-never-read field.
  

--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -518,6 +518,7 @@ static int ioctl_fioasync(unsigned int fd, struct file 
*filp,
  static int ioctl_fsfreeze(struct file *filp)
  {
struct super_block *sb = file_inode(filp)-i_sb;
+   int rv;
  
  	if (!capable(CAP_SYS_ADMIN))

return -EPERM;
@@ -527,22 +528,31 @@ static int ioctl_fsfreeze(struct file *filp)
return -EOPNOTSUPP;
  
  	/* Freeze */

-   if (sb-s_op-freeze_super)
-   return sb-s_op-freeze_super(sb);
-   return freeze_super(sb);
+   if (sb-s_op-freeze_super) {
+   rv = sb-s_op-freeze_super(sb);
+   if (rv == 0)
+   get_task_comm(sb-s_writers.freeze_comm, current);
+   } else
+   rv = freeze_super(sb);
+   return rv;

   Why don't you just set the name in ioctl_fsfreeze() in both cases?

There are users of freeze_super() in GFS2 unless I'm misreading code.

   Yes, there are. The call in fs/gfs2/glops.c is in a call path from
-freeze_super() handler for GFS2 so that one is handled in
ioctl_fsfreeze() anyway. The call in fs/gfs2/sys.c is a way to freeze
filesystem via sysfs (dunno why GFS2 has to invent its own thing and ioctl
isn't enough). Steven? So having the logic in ioctl_fsfreeze(),
freeze_bdev() and freeze_store() in gfs2 seems to be enough.

The sysfs freeze thing is historical and strongly deprecated - I hope 
that we may be able to remove it one day,


Steve.



Re: [Cluster-devel] [PATCH 7/8] xfs: Add support for Q_SETINFO

2015-02-18 Thread Jan Kara
On Wed 18-02-15 08:54:12, Christoph Hellwig wrote:
 Looks fine except for the cosmetical argument alignment style issue.
  OK, fixed.
 
 Reviewed-by: Christoph Hellwig h...@lst.de
Honza
-- 
Jan Kara j...@suse.cz
SUSE Labs, CR



Re: [Cluster-devel] [PATCH 8/8] quota: Hook up Q_XSETQLIM for id 0 to -set_info

2015-02-18 Thread Christoph Hellwig
Looks good,

Reviewed-by: Christoph Hellwig h...@lst.de



Re: [Cluster-devel] [PATCH 7/8] xfs: Add support for Q_SETINFO

2015-02-18 Thread Christoph Hellwig
Looks fine except for the cosmetical argument alignment style issue.

Reviewed-by: Christoph Hellwig h...@lst.de



Re: [Cluster-devel] [PATCH 3/8] xfs: Convert to using -get_state callback

2015-02-18 Thread Christoph Hellwig
 +static void
 +xfs_qm_fill_state(
 + struct qc_type_state *tstate,
 + struct xfs_mount *mp,
 + struct xfs_inode *ip,
 + xfs_ino_t ino)

 +/*
 + * Return quota status information, such as enforcements, quota file inode
 + * numbers etc.
 + */
 +static int
 +xfs_fs_get_quota_state(
 + struct super_block *sb,
 + struct qc_state *state)

We usually tab-align the arguments in XFS prototypes.


Otherwise this patch looks good,

Reviewed-by: Christoph Hellwig h...@lst.de



Re: [Cluster-devel] [PATCH 3/8] xfs: Convert to using -get_state callback

2015-02-18 Thread Jan Kara
On Wed 18-02-15 08:51:54, Christoph Hellwig wrote:
  +static void
  +xfs_qm_fill_state(
  +   struct qc_type_state *tstate,
  +   struct xfs_mount *mp,
  +   struct xfs_inode *ip,
  +   xfs_ino_t ino)
 
  +/*
  + * Return quota status information, such as enforcements, quota file inode
  + * numbers etc.
  + */
  +static int
  +xfs_fs_get_quota_state(
  +   struct super_block *sb,
  +   struct qc_state *state)
 
 We usually tab-align the arguments in XFS prototypes.
  OK, fixed.

 Otherwise this patch looks good,
 
 Reviewed-by: Christoph Hellwig h...@lst.de
  Thanks.

Honza
-- 
Jan Kara j...@suse.cz
SUSE Labs, CR



Re: [Cluster-devel] [PATCH 6/8] quota: Make -set_info use structure with neccesary info to VFS and XFS

2015-02-18 Thread Jan Kara
On Wed 18-02-15 08:53:34, Christoph Hellwig wrote:
 On Wed, Feb 18, 2015 at 02:47:52PM +0100, Jan Kara wrote:
  Change -set_info to take new qc_info structure which contains all the
  necessary information both for XFS and VFS. Convert Q_SETINFO handler
  to use this structure.
...
  +/* Structure for communicating via -set_info */
  +struct qc_info {
  +   int i_fieldmask;/* mask of fields to change in -set_info() */
  +   unsigned int i_flags;   /* Flags QCI_* */
  +   unsigned int i_spc_timelimit;   /* Time after which space softlimit is
  +* enforced */
  +   unsigned int i_ino_timelimit;   /* Ditto for inode softlimit */
  +   unsigned int i_rt_spc_timelimit;/* Ditto for real-time space */
  +   unsigned int i_spc_warnlimit;   /* Limit for number of space warnings */
  +   unsigned int i_ino_warnlimit;   /* Limit for number of inode warnings */
  +   unsigned int i_rt_spc_warnlimit;/* Ditto for real-time space */
  +};
 
 What does the i_ prefix stand for?
  It stands for info. I can change it e.g. to qci_ for quotactl info if you
think that would be better...

Honza
-- 
Jan Kara j...@suse.cz
SUSE Labs, CR



[Cluster-devel] [PATCH 0/8 v5] quota: Unify VFS and XFS quota interfaces

2015-02-18 Thread Jan Kara
  Hello,

  these are outstanding patches in my series unifying VFS and XFS quota
interfaces so that XFS quotactls work for filesystems with VFS quotas and vice
versa.  This is useful so that userspace doesn't have to care that much about
which filesystem it is using at least when using basic quota functionality. In
particular we should be able to reuse project quota tests in xfstests for ext4.

The patches are based on top of Linus' tree from few days ago which already
contains initial part of the original series.  The patch series can also be
pulled from 'quota_interface' branch of my tree [1].

I'm sending the series as there are two XFS and one GFS2 patches which still
need review before I can add them to my tree for the next merge window.

Honza

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



[Cluster-devel] [PATCH 3/8] xfs: Convert to using -get_state callback

2015-02-18 Thread Jan Kara
Convert xfs to use -get_state callback instead of -get_xstate and
-get_xstatev.

Signed-off-by: Jan Kara j...@suse.cz
---
 fs/xfs/xfs_qm.h  |   4 --
 fs/xfs/xfs_qm_syscalls.c | 176 ---
 fs/xfs/xfs_quotaops.c|  98 +++---
 3 files changed, 72 insertions(+), 206 deletions(-)

diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
index 0d4d3590cf85..996a04064894 100644
--- a/fs/xfs/xfs_qm.h
+++ b/fs/xfs/xfs_qm.h
@@ -168,10 +168,6 @@ extern int xfs_qm_scall_getquota(struct xfs_mount 
*, xfs_dqid_t,
uint, struct qc_dqblk *);
 extern int xfs_qm_scall_setqlim(struct xfs_mount *, xfs_dqid_t, 
uint,
struct qc_dqblk *);
-extern int xfs_qm_scall_getqstat(struct xfs_mount *,
-   struct fs_quota_stat *);
-extern int xfs_qm_scall_getqstatv(struct xfs_mount *,
-   struct fs_quota_statv *);
 extern int xfs_qm_scall_quotaon(struct xfs_mount *, uint);
 extern int xfs_qm_scall_quotaoff(struct xfs_mount *, uint);
 
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index 9b965db45800..9a25c9275fb3 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -38,7 +38,6 @@
 STATIC int xfs_qm_log_quotaoff(xfs_mount_t *, xfs_qoff_logitem_t **, uint);
 STATIC int xfs_qm_log_quotaoff_end(xfs_mount_t *, xfs_qoff_logitem_t *,
uint);
-STATIC uintxfs_qm_export_flags(uint);
 
 /*
  * Turn off quota accounting and/or enforcement for all udquots and/or
@@ -389,159 +388,6 @@ xfs_qm_scall_quotaon(
return 0;
 }
 
-
-/*
- * Return quota status information, such as uquota-off, enforcements, etc.
- * for Q_XGETQSTAT command.
- */
-int
-xfs_qm_scall_getqstat(
-   struct xfs_mount*mp,
-   struct fs_quota_stat*out)
-{
-   struct xfs_quotainfo*q = mp-m_quotainfo;
-   struct xfs_inode*uip = NULL;
-   struct xfs_inode*gip = NULL;
-   struct xfs_inode*pip = NULL;
-   booltempuqip = false;
-   booltempgqip = false;
-   booltemppqip = false;
-
-   memset(out, 0, sizeof(fs_quota_stat_t));
-
-   out-qs_version = FS_QSTAT_VERSION;
-   out-qs_flags = (__uint16_t) xfs_qm_export_flags(mp-m_qflags 
-   (XFS_ALL_QUOTA_ACCT|
-XFS_ALL_QUOTA_ENFD));
-   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,
-   0, 0, uip) == 0)
-   tempuqip = true;
-   }
-   if (!gip  mp-m_sb.sb_gquotino != NULLFSINO) {
-   if (xfs_iget(mp, NULL, mp-m_sb.sb_gquotino,
-   0, 0, gip) == 0)
-   tempgqip = true;
-   }
-   /*
-* Q_XGETQSTAT doesn't have room for both group and project quotas.
-* So, allow the project quota values to be copied out only if
-* there is no group quota information available.
-*/
-   if (!gip) {
-   if (!pip  mp-m_sb.sb_pquotino != NULLFSINO) {
-   if (xfs_iget(mp, NULL, mp-m_sb.sb_pquotino,
-   0, 0, pip) == 0)
-   temppqip = true;
-   }
-   } else
-   pip = NULL;
-   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_gquota.qfs_ino = mp-m_sb.sb_gquotino;
-   out-qs_gquota.qfs_nblks = pip-i_d.di_nblocks;
-   out-qs_gquota.qfs_nextents = pip-i_d.di_nextents;
-   if (temppqip)
-   IRELE(pip);
-   }
-   out-qs_incoredqs = q-qi_dquots;
-   out-qs_btimelimit = q-qi_btimelimit;
-   out-qs_itimelimit = q-qi_itimelimit;
-   out-qs_rtbtimelimit = q-qi_rtbtimelimit;
-   out-qs_bwarnlimit = q-qi_bwarnlimit;
-   out-qs_iwarnlimit = q-qi_iwarnlimit;
-
-   return 0;
-}
-
-/*
- * Return quota status information, such as uquota-off, enforcements, etc.
- * for Q_XGETQSTATV command, 

[Cluster-devel] [PATCH 7/8] xfs: Add support for Q_SETINFO

2015-02-18 Thread Jan Kara
Add support to XFS so that time limits can be set through Q_SETINFO
quotactl.

Signed-off-by: Jan Kara j...@suse.cz
---
 fs/xfs/xfs_quotaops.c | 37 +
 1 file changed, 37 insertions(+)

diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c
index df9835396c4f..bbe8ddf1f700 100644
--- a/fs/xfs/xfs_quotaops.c
+++ b/fs/xfs/xfs_quotaops.c
@@ -111,6 +111,42 @@ xfs_quota_type(int type)
}
 }
 
+#define XFS_QC_SETINFO_MASK (QC_TIMER_MASK | QC_WARNS_MASK)
+
+/*
+ * Adjust quota timers  warnings
+ */
+static int
+xfs_fs_set_info(
+   struct super_block *sb,
+   int type,
+   struct qc_info *info)
+{
+   struct xfs_mount *mp = XFS_M(sb);
+   struct qc_dqblk newlim;
+
+   if (sb-s_flags  MS_RDONLY)
+   return -EROFS;
+   if (!XFS_IS_QUOTA_RUNNING(mp))
+   return -ENOSYS;
+   if (!XFS_IS_QUOTA_ON(mp))
+   return -ESRCH;
+   if (info-i_fieldmask  ~XFS_QC_SETINFO_MASK)
+   return -EINVAL;
+   if ((info-i_fieldmask  XFS_QC_SETINFO_MASK) == 0)
+   return 0;
+
+   newlim.d_fieldmask = info-i_fieldmask;
+   newlim.d_spc_timer = info-i_spc_timelimit;
+   newlim.d_ino_timer = info-i_ino_timelimit;
+   newlim.d_rt_spc_timer = info-i_rt_spc_timelimit;
+   newlim.d_ino_warns = info-i_ino_warnlimit;
+   newlim.d_spc_warns = info-i_spc_warnlimit;
+   newlim.d_rt_spc_warns = info-i_rt_spc_warnlimit;
+
+   return xfs_qm_scall_setqlim(mp, 0, xfs_quota_type(type), newlim);
+}
+
 static unsigned int
 xfs_quota_flags(unsigned int uflags)
 {
@@ -226,6 +262,7 @@ xfs_fs_set_dqblk(
 
 const struct quotactl_ops xfs_quotactl_operations = {
.get_state  = xfs_fs_get_quota_state,
+   .set_info   = xfs_fs_set_info,
.quota_enable   = xfs_quota_enable,
.quota_disable  = xfs_quota_disable,
.rm_xquota  = xfs_fs_rm_xquota,
-- 
2.1.4



[Cluster-devel] [PATCH 1/8] quota: Make VFS quotas use new interface for getting quota info

2015-02-18 Thread Jan Kara
Create new internal interface for getting information about quota which
contains everything needed for both VFS quotas and XFS quotas. Make VFS
use this and hook it up to Q_GETINFO.

Reviewed-by: Christoph Hellwig h...@lst.de
Signed-off-by: Jan Kara j...@suse.cz
---
 fs/ext3/super.c  |  2 +-
 fs/ext4/super.c  |  2 +-
 fs/quota/dquot.c | 41 +++--
 fs/quota/quota.c | 25 +
 fs/reiserfs/super.c  |  2 +-
 include/linux/quota.h| 33 -
 include/linux/quotaops.h |  2 +-
 7 files changed, 84 insertions(+), 23 deletions(-)

diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index d4dbf3c259b3..f037b4b27300 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -789,7 +789,7 @@ static const struct quotactl_ops ext3_qctl_operations = {
.quota_on   = ext3_quota_on,
.quota_off  = dquot_quota_off,
.quota_sync = dquot_quota_sync,
-   .get_info   = dquot_get_dqinfo,
+   .get_state  = dquot_get_state,
.set_info   = dquot_set_dqinfo,
.get_dqblk  = dquot_get_dqblk,
.set_dqblk  = dquot_set_dqblk
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index ac64edbe501d..c6e70831e135 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1076,7 +1076,7 @@ static const struct quotactl_ops ext4_qctl_operations = {
.quota_on   = ext4_quota_on,
.quota_off  = ext4_quota_off,
.quota_sync = dquot_quota_sync,
-   .get_info   = dquot_get_dqinfo,
+   .get_state  = dquot_get_state,
.set_info   = dquot_set_dqinfo,
.get_dqblk  = dquot_get_dqblk,
.set_dqblk  = dquot_set_dqblk
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 0ccd4ba3a246..cf4edd87e854 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -2614,26 +2614,39 @@ out:
 EXPORT_SYMBOL(dquot_set_dqblk);
 
 /* Generic routine for getting common part of quota file information */
-int dquot_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
+int dquot_get_state(struct super_block *sb, struct qc_state *state)
 {
struct mem_dqinfo *mi;
+   struct qc_type_state *tstate;
+   struct quota_info *dqopt = sb_dqopt(sb);
+   int type;
   
mutex_lock(sb_dqopt(sb)-dqonoff_mutex);
-   if (!sb_has_quota_active(sb, type)) {
-   mutex_unlock(sb_dqopt(sb)-dqonoff_mutex);
-   return -ESRCH;
+   memset(state, 0, sizeof(*state));
+   for (type = 0; type  MAXQUOTAS; type++) {
+   if (!sb_has_quota_active(sb, type))
+   continue;
+   tstate = state-s_state + type;
+   mi = sb_dqopt(sb)-info + type;
+   tstate-flags = QCI_ACCT_ENABLED;
+   spin_lock(dq_data_lock);
+   if (mi-dqi_flags  DQF_SYS_FILE)
+   tstate-flags |= QCI_SYSFILE;
+   if (mi-dqi_flags  DQF_ROOT_SQUASH)
+   tstate-flags |= QCI_ROOT_SQUASH;
+   if (sb_has_quota_limits_enabled(sb, type))
+   tstate-flags |= QCI_LIMITS_ENFORCED;
+   tstate-spc_timelimit = mi-dqi_bgrace;
+   tstate-ino_timelimit = mi-dqi_igrace;
+   tstate-ino = dqopt-files[type]-i_ino;
+   tstate-blocks = dqopt-files[type]-i_blocks;
+   tstate-nextents = 1;   /* We don't know... */
+   spin_unlock(dq_data_lock);
}
-   mi = sb_dqopt(sb)-info + type;
-   spin_lock(dq_data_lock);
-   ii-dqi_bgrace = mi-dqi_bgrace;
-   ii-dqi_igrace = mi-dqi_igrace;
-   ii-dqi_flags = mi-dqi_flags  DQF_GETINFO_MASK;
-   ii-dqi_valid = IIF_ALL;
-   spin_unlock(dq_data_lock);
mutex_unlock(sb_dqopt(sb)-dqonoff_mutex);
return 0;
 }
-EXPORT_SYMBOL(dquot_get_dqinfo);
+EXPORT_SYMBOL(dquot_get_state);
 
 /* Generic routine for setting common part of quota file information */
 int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
@@ -2677,7 +2690,7 @@ const struct quotactl_ops dquot_quotactl_ops = {
.quota_on   = dquot_quota_on,
.quota_off  = dquot_quota_off,
.quota_sync = dquot_quota_sync,
-   .get_info   = dquot_get_dqinfo,
+   .get_state  = dquot_get_state,
.set_info   = dquot_set_dqinfo,
.get_dqblk  = dquot_get_dqblk,
.set_dqblk  = dquot_set_dqblk
@@ -2688,7 +2701,7 @@ const struct quotactl_ops dquot_quotactl_sysfile_ops = {
.quota_enable   = dquot_quota_enable,
.quota_disable  = dquot_quota_disable,
.quota_sync = dquot_quota_sync,
-   .get_info   = dquot_get_dqinfo,
+   .get_state  = dquot_get_state,
.set_info   = dquot_set_dqinfo,
.get_dqblk  = dquot_get_dqblk,
.set_dqblk  = dquot_set_dqblk
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index 

[Cluster-devel] [PATCH 8/8] quota: Hook up Q_XSETQLIM for id 0 to -set_info

2015-02-18 Thread Jan Kara
Setting timers or warning counts for id 0 via Q_XSETQLIM is used to
actually set time limits and warning limits for all users. Hook up
-set_info to this so that VFS quota time limits get set the same
way as XFS ones.

When doing this Q_XSETQLIM for XFS is effectively split into two
independent transactions - one for setting timers and warning limits and
one for setting space and inode limits. Although this is inefficient, it
is rare enough that it does not matter.

Signed-off-by: Jan Kara j...@suse.cz
---
 fs/quota/quota.c | 39 +++
 1 file changed, 39 insertions(+)

diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index 741d5a178268..86ded7375c21 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -517,6 +517,30 @@ static void copy_from_xfs_dqblk(struct qc_dqblk *dst, 
struct fs_disk_quota *src)
dst-d_fieldmask |= QC_RT_SPACE;
 }
 
+static void copy_qcinfo_from_xfs_dqblk(struct qc_info *dst,
+  struct fs_disk_quota *src)
+{
+   memset(dst, 0, sizeof(*dst));
+   dst-i_spc_timelimit = src-d_btimer;
+   dst-i_ino_timelimit = src-d_itimer;
+   dst-i_rt_spc_timelimit = src-d_rtbtimer;
+   dst-i_ino_warnlimit = src-d_iwarns;
+   dst-i_spc_warnlimit = src-d_bwarns;
+   dst-i_rt_spc_warnlimit = src-d_rtbwarns;
+   if (src-d_fieldmask  FS_DQ_BWARNS)
+   dst-i_fieldmask |= QC_SPC_WARNS;
+   if (src-d_fieldmask  FS_DQ_IWARNS)
+   dst-i_fieldmask |= QC_INO_WARNS;
+   if (src-d_fieldmask  FS_DQ_RTBWARNS)
+   dst-i_fieldmask |= QC_RT_SPC_WARNS;
+   if (src-d_fieldmask  FS_DQ_BTIMER)
+   dst-i_fieldmask |= QC_SPC_TIMER;
+   if (src-d_fieldmask  FS_DQ_ITIMER)
+   dst-i_fieldmask |= QC_INO_TIMER;
+   if (src-d_fieldmask  FS_DQ_RTBTIMER)
+   dst-i_fieldmask |= QC_RT_SPC_TIMER;
+}
+
 static int quota_setxquota(struct super_block *sb, int type, qid_t id,
   void __user *addr)
 {
@@ -531,6 +555,21 @@ static int quota_setxquota(struct super_block *sb, int 
type, qid_t id,
qid = make_kqid(current_user_ns(), type, id);
if (!qid_valid(qid))
return -EINVAL;
+   /* Are we actually setting timer / warning limits for all users? */
+   if (from_kqid(init_user_ns, qid) == 0 
+   fdq.d_fieldmask  (FS_DQ_WARNS_MASK | FS_DQ_TIMER_MASK)) {
+   struct qc_info qinfo;
+   int ret;
+
+   if (!sb-s_qcop-set_info)
+   return -EINVAL;
+   copy_qcinfo_from_xfs_dqblk(qinfo, fdq);
+   ret = sb-s_qcop-set_info(sb, type, qinfo);
+   if (ret)
+   return ret;
+   /* These are already done */
+   fdq.d_fieldmask = ~(FS_DQ_WARNS_MASK | FS_DQ_TIMER_MASK);
+   }
copy_from_xfs_dqblk(qdq, fdq);
return sb-s_qcop-set_dqblk(sb, qid, qdq);
 }
-- 
2.1.4



[Cluster-devel] [PATCH 6/8] quota: Make -set_info use structure with neccesary info to VFS and XFS

2015-02-18 Thread Jan Kara
Change -set_info to take new qc_info structure which contains all the
necessary information both for XFS and VFS. Convert Q_SETINFO handler
to use this structure.

Signed-off-by: Jan Kara j...@suse.cz
---
 fs/quota/dquot.c | 27 ---
 fs/quota/quota.c | 21 -
 include/linux/quota.h| 21 +++--
 include/linux/quotaops.h |  2 +-
 4 files changed, 56 insertions(+), 15 deletions(-)

diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index cf4edd87e854..f37b74eab807 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -2649,33 +2649,38 @@ int dquot_get_state(struct super_block *sb, struct 
qc_state *state)
 EXPORT_SYMBOL(dquot_get_state);
 
 /* Generic routine for setting common part of quota file information */
-int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
+int dquot_set_dqinfo(struct super_block *sb, int type, struct qc_info *ii)
 {
struct mem_dqinfo *mi;
int err = 0;
 
+   if ((ii-i_fieldmask  QC_WARNS_MASK) ||
+   (ii-i_fieldmask  QC_RT_SPC_TIMER))
+   return -EINVAL;
mutex_lock(sb_dqopt(sb)-dqonoff_mutex);
if (!sb_has_quota_active(sb, type)) {
err = -ESRCH;
goto out;
}
mi = sb_dqopt(sb)-info + type;
-   if (ii-dqi_valid  IIF_FLAGS) {
-   if (ii-dqi_flags  ~DQF_SETINFO_MASK ||
-   (ii-dqi_flags  DQF_ROOT_SQUASH 
+   if (ii-i_fieldmask  QC_FLAGS) {
+   if ((ii-i_flags  QCI_ROOT_SQUASH 
 mi-dqi_format-qf_fmt_id != QFMT_VFS_OLD)) {
err = -EINVAL;
goto out;
}
}
spin_lock(dq_data_lock);
-   if (ii-dqi_valid  IIF_BGRACE)
-   mi-dqi_bgrace = ii-dqi_bgrace;
-   if (ii-dqi_valid  IIF_IGRACE)
-   mi-dqi_igrace = ii-dqi_igrace;
-   if (ii-dqi_valid  IIF_FLAGS)
-   mi-dqi_flags = (mi-dqi_flags  ~DQF_SETINFO_MASK) |
-   (ii-dqi_flags  DQF_SETINFO_MASK);
+   if (ii-i_fieldmask  QC_SPC_TIMER)
+   mi-dqi_bgrace = ii-i_spc_timelimit;
+   if (ii-i_fieldmask  QC_INO_TIMER)
+   mi-dqi_igrace = ii-i_ino_timelimit;
+   if (ii-i_fieldmask  QC_FLAGS) {
+   if (ii-i_flags  QCI_ROOT_SQUASH)
+   mi-dqi_flags |= DQF_ROOT_SQUASH;
+   else
+   mi-dqi_flags = ~DQF_ROOT_SQUASH;
+   }
spin_unlock(dq_data_lock);
mark_info_dirty(sb, type);
/* Force write to disk */
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index 20d11cd21247..741d5a178268 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -149,12 +149,31 @@ static int quota_getinfo(struct super_block *sb, int 
type, void __user *addr)
 static int quota_setinfo(struct super_block *sb, int type, void __user *addr)
 {
struct if_dqinfo info;
+   struct qc_info qinfo;
 
if (copy_from_user(info, addr, sizeof(info)))
return -EFAULT;
if (!sb-s_qcop-set_info)
return -ENOSYS;
-   return sb-s_qcop-set_info(sb, type, info);
+   if (info.dqi_valid  ~(IIF_FLAGS | IIF_BGRACE | IIF_IGRACE))
+   return -EINVAL;
+   memset(qinfo, 0, sizeof(qinfo));
+   if (info.dqi_valid  IIF_FLAGS) {
+   if (info.dqi_flags  ~DQF_SETINFO_MASK)
+   return -EINVAL;
+   if (info.dqi_flags  DQF_ROOT_SQUASH)
+   qinfo.i_flags |= QCI_ROOT_SQUASH;
+   qinfo.i_fieldmask |= QC_FLAGS;
+   }
+   if (info.dqi_valid  IIF_BGRACE) {
+   qinfo.i_spc_timelimit = info.dqi_bgrace;
+   qinfo.i_fieldmask |= QC_SPC_TIMER;
+   }
+   if (info.dqi_valid  IIF_IGRACE) {
+   qinfo.i_ino_timelimit = info.dqi_igrace;
+   qinfo.i_fieldmask |= QC_INO_TIMER;
+   }
+   return sb-s_qcop-set_info(sb, type, qinfo);
 }
 
 static inline qsize_t qbtos(qsize_t blocks)
diff --git a/include/linux/quota.h b/include/linux/quota.h
index a07f2ed25284..3d521199a0bd 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -344,7 +344,10 @@ struct qc_dqblk {
int d_rt_spc_warns; /* # warnings issued wrt RT space */
 };
 
-/* Field specifiers for -set_dqblk() in struct qc_dqblk */
+/*
+ * Field specifiers for -set_dqblk() in struct qc_dqblk and also for
+ * -set_info() in struct qc_info
+ */
 #defineQC_INO_SOFT (10)
 #defineQC_INO_HARD (11)
 #defineQC_SPC_SOFT (12)
@@ -365,6 +368,7 @@ struct qc_dqblk {
 #defineQC_INO_COUNT(113)
 #defineQC_RT_SPACE (114)
 #define QC_ACCT_MASK (QC_SPACE | QC_INO_COUNT | QC_RT_SPACE)
+#define QC_FLAGS   (115)
 
 #define QCI_SYSFILE(1  0)/* Quota file is hidden from 
userspace */
 #define QCI_ROOT_SQUASH(1  1)/* Root squash 

[Cluster-devel] [PATCH 4/8] gfs2: Convert to using -get_state callback

2015-02-18 Thread Jan Kara
Convert gfs2 to use -get_state callback instead of -get_xstate.

Signed-off-by: Jan Kara j...@suse.cz
---
 fs/gfs2/quota.c | 28 +++-
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 3e193cb36996..c76e031ccbb4 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -1467,32 +1467,34 @@ int gfs2_quotad(void *data)
return 0;
 }
 
-static int gfs2_quota_get_xstate(struct super_block *sb,
-struct fs_quota_stat *fqs)
+static int gfs2_quota_get_state(struct super_block *sb, struct qc_state *state)
 {
struct gfs2_sbd *sdp = sb-s_fs_info;
 
-   memset(fqs, 0, sizeof(struct fs_quota_stat));
-   fqs-qs_version = FS_QSTAT_VERSION;
+   memset(state, 0, sizeof(*state));
 
switch (sdp-sd_args.ar_quota) {
case GFS2_QUOTA_ON:
-   fqs-qs_flags |= (FS_QUOTA_UDQ_ENFD | FS_QUOTA_GDQ_ENFD);
+   state-s_state[USRQUOTA].flags |= QCI_LIMITS_ENFORCED;
+   state-s_state[GRPQUOTA].flags |= QCI_LIMITS_ENFORCED;
/*FALLTHRU*/
case GFS2_QUOTA_ACCOUNT:
-   fqs-qs_flags |= (FS_QUOTA_UDQ_ACCT | FS_QUOTA_GDQ_ACCT);
+   state-s_state[USRQUOTA].flags |= QCI_ACCT_ENABLED |
+ QCI_SYSFILE;
+   state-s_state[GRPQUOTA].flags |= QCI_ACCT_ENABLED |
+ QCI_SYSFILE;
break;
case GFS2_QUOTA_OFF:
break;
}
-
if (sdp-sd_quota_inode) {
-   fqs-qs_uquota.qfs_ino = GFS2_I(sdp-sd_quota_inode)-i_no_addr;
-   fqs-qs_uquota.qfs_nblks = sdp-sd_quota_inode-i_blocks;
+   state-s_state[USRQUOTA].ino =
+   GFS2_I(sdp-sd_quota_inode)-i_no_addr;
+   state-s_state[USRQUOTA].blocks = sdp-sd_quota_inode-i_blocks;
}
-   fqs-qs_uquota.qfs_nextents = 1; /* unsupported */
-   fqs-qs_gquota = fqs-qs_uquota; /* its the same inode in both cases */
-   fqs-qs_incoredqs = list_lru_count(gfs2_qd_lru);
+   state-s_state[USRQUOTA].nextents = 1;  /* unsupported */
+   state-s_state[GRPQUOTA] = state-s_state[USRQUOTA];
+   state-s_incoredqs = list_lru_count(gfs2_qd_lru);
return 0;
 }
 
@@ -1637,7 +1639,7 @@ out_put:
 
 const struct quotactl_ops gfs2_quotactl_ops = {
.quota_sync = gfs2_quota_sync,
-   .get_xstate = gfs2_quota_get_xstate,
+   .get_state  = gfs2_quota_get_state,
.get_dqblk  = gfs2_get_dqblk,
.set_dqblk  = gfs2_set_dqblk,
 };
-- 
2.1.4



[Cluster-devel] [PATCH 5/8] quota: Remove -get_xstate and -get_xstatev callbacks

2015-02-18 Thread Jan Kara
These callbacks are now unused. Remove them.

Reviewed-by: Christoph Hellwig h...@lst.de
Signed-off-by: Jan Kara j...@suse.cz
---
 fs/quota/quota.c  | 14 --
 include/linux/quota.h |  2 --
 2 files changed, 4 insertions(+), 12 deletions(-)

diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index 83939ff4c444..20d11cd21247 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -350,12 +350,9 @@ static int quota_getxstate(struct super_block *sb, void 
__user *addr)
struct fs_quota_stat fqs;
int ret;
 
-   if (!sb-s_qcop-get_xstate  !sb-s_qcop-get_state)
+   if (!sb-s_qcop-get_state)
return -ENOSYS;
-   if (sb-s_qcop-get_state)
-   ret = quota_getstate(sb, fqs);
-   else
-   ret = sb-s_qcop-get_xstate(sb, fqs);
+   ret = quota_getstate(sb, fqs);
if (!ret  copy_to_user(addr, fqs, sizeof(fqs)))
return -EFAULT;
return ret;
@@ -414,7 +411,7 @@ static int quota_getxstatev(struct super_block *sb, void 
__user *addr)
struct fs_quota_statv fqs;
int ret;
 
-   if (!sb-s_qcop-get_xstatev  !sb-s_qcop-get_state)
+   if (!sb-s_qcop-get_state)
return -ENOSYS;
 
memset(fqs, 0, sizeof(fqs));
@@ -428,10 +425,7 @@ static int quota_getxstatev(struct super_block *sb, void 
__user *addr)
default:
return -EINVAL;
}
-   if (sb-s_qcop-get_state)
-   ret = quota_getstatev(sb, fqs);
-   else
-   ret = sb-s_qcop-get_xstatev(sb, fqs);
+   ret = quota_getstatev(sb, fqs);
if (!ret  copy_to_user(addr, fqs, sizeof(fqs)))
return -EFAULT;
return ret;
diff --git a/include/linux/quota.h b/include/linux/quota.h
index 6ecac0f3b2ca..a07f2ed25284 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -408,8 +408,6 @@ struct quotactl_ops {
int (*get_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *);
int (*set_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *);
int (*get_state)(struct super_block *, struct qc_state *);
-   int (*get_xstate)(struct super_block *, struct fs_quota_stat *);
-   int (*get_xstatev)(struct super_block *, struct fs_quota_statv *);
int (*rm_xquota)(struct super_block *, unsigned int);
 };
 
-- 
2.1.4



[Cluster-devel] [PATCH 2/8] quota: Wire up Q_GETXSTATE and Q_GETXSTATV calls to work with -get_state

2015-02-18 Thread Jan Kara
Add appropriate conversion functions so that filesystems supporting
-get_state() method can be queried using Q_GETXSTATE and Q_GETXSTATV
calls.

Reviewed-by: Christoph Hellwig h...@lst.de
Signed-off-by: Jan Kara j...@suse.cz
---
 fs/quota/quota.c | 138 +--
 1 file changed, 134 insertions(+), 4 deletions(-)

diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index 00d50fca1005..83939ff4c444 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -269,25 +269,152 @@ static int quota_disable(struct super_block *sb, void 
__user *addr)
return sb-s_qcop-quota_disable(sb, flags);
 }
 
+static int quota_state_to_flags(struct qc_state *state)
+{
+   int flags = 0;
+
+   if (state-s_state[USRQUOTA].flags  QCI_ACCT_ENABLED)
+   flags |= FS_QUOTA_UDQ_ACCT;
+   if (state-s_state[USRQUOTA].flags  QCI_LIMITS_ENFORCED)
+   flags |= FS_QUOTA_UDQ_ENFD;
+   if (state-s_state[GRPQUOTA].flags  QCI_ACCT_ENABLED)
+   flags |= FS_QUOTA_GDQ_ACCT;
+   if (state-s_state[GRPQUOTA].flags  QCI_LIMITS_ENFORCED)
+   flags |= FS_QUOTA_GDQ_ENFD;
+   if (state-s_state[PRJQUOTA].flags  QCI_ACCT_ENABLED)
+   flags |= FS_QUOTA_PDQ_ACCT;
+   if (state-s_state[PRJQUOTA].flags  QCI_LIMITS_ENFORCED)
+   flags |= FS_QUOTA_PDQ_ENFD;
+   return flags;
+}
+
+static int quota_getstate(struct super_block *sb, struct fs_quota_stat *fqs)
+{
+   int type;
+   struct qc_state state;
+   int ret;
+
+   ret = sb-s_qcop-get_state(sb, state);
+   if (ret  0)
+   return ret;
+
+   memset(fqs, 0, sizeof(*fqs));
+   fqs-qs_version = FS_QSTAT_VERSION;
+   fqs-qs_flags = quota_state_to_flags(state);
+   /* No quota enabled? */
+   if (!fqs-qs_flags)
+   return -ENOSYS;
+   fqs-qs_incoredqs = state.s_incoredqs;
+   /*
+* GETXSTATE quotactl has space for just one set of time limits so
+* report them for the first enabled quota type
+*/
+   for (type = 0; type  XQM_MAXQUOTAS; type++)
+   if (state.s_state[type].flags  QCI_ACCT_ENABLED)
+   break;
+   BUG_ON(type == XQM_MAXQUOTAS);
+   fqs-qs_btimelimit = state.s_state[type].spc_timelimit;
+   fqs-qs_itimelimit = state.s_state[type].ino_timelimit;
+   fqs-qs_rtbtimelimit = state.s_state[type].rt_spc_timelimit;
+   fqs-qs_bwarnlimit = state.s_state[type].spc_warnlimit;
+   fqs-qs_iwarnlimit = state.s_state[type].ino_warnlimit;
+   if (state.s_state[USRQUOTA].flags  QCI_ACCT_ENABLED) {
+   fqs-qs_uquota.qfs_ino = state.s_state[USRQUOTA].ino;
+   fqs-qs_uquota.qfs_nblks = state.s_state[USRQUOTA].blocks;
+   fqs-qs_uquota.qfs_nextents = state.s_state[USRQUOTA].nextents;
+   }
+   if (state.s_state[GRPQUOTA].flags  QCI_ACCT_ENABLED) {
+   fqs-qs_gquota.qfs_ino = state.s_state[GRPQUOTA].ino;
+   fqs-qs_gquota.qfs_nblks = state.s_state[GRPQUOTA].blocks;
+   fqs-qs_gquota.qfs_nextents = state.s_state[GRPQUOTA].nextents;
+   }
+   if (state.s_state[PRJQUOTA].flags  QCI_ACCT_ENABLED) {
+   /*
+* Q_XGETQSTAT doesn't have room for both group and project
+* quotas.  So, allow the project quota values to be copied out
+* only if there is no group quota information available.
+*/
+   if (!(state.s_state[GRPQUOTA].flags  QCI_ACCT_ENABLED)) {
+   fqs-qs_gquota.qfs_ino = state.s_state[PRJQUOTA].ino;
+   fqs-qs_gquota.qfs_nblks =
+   state.s_state[PRJQUOTA].blocks;
+   fqs-qs_gquota.qfs_nextents =
+   state.s_state[PRJQUOTA].nextents;
+   }
+   }
+   return 0;
+}
+
 static int quota_getxstate(struct super_block *sb, void __user *addr)
 {
struct fs_quota_stat fqs;
int ret;
 
-   if (!sb-s_qcop-get_xstate)
+   if (!sb-s_qcop-get_xstate  !sb-s_qcop-get_state)
return -ENOSYS;
-   ret = sb-s_qcop-get_xstate(sb, fqs);
+   if (sb-s_qcop-get_state)
+   ret = quota_getstate(sb, fqs);
+   else
+   ret = sb-s_qcop-get_xstate(sb, fqs);
if (!ret  copy_to_user(addr, fqs, sizeof(fqs)))
return -EFAULT;
return ret;
 }
 
+static int quota_getstatev(struct super_block *sb, struct fs_quota_statv *fqs)
+{
+   int type;
+   struct qc_state state;
+   int ret;
+
+   ret = sb-s_qcop-get_state(sb, state);
+   if (ret  0)
+   return ret;
+
+   memset(fqs, 0, sizeof(*fqs));
+   fqs-qs_version = FS_QSTAT_VERSION;
+   fqs-qs_flags = quota_state_to_flags(state);
+   /* No quota enabled? */
+   if (!fqs-qs_flags)
+   return -ENOSYS;
+   fqs-qs_incoredqs = 

Re: [Cluster-devel] [PATCH 4/8] gfs2: Convert to using -get_state callback

2015-02-18 Thread Bob Peterson
- Original Message -
 Convert gfs2 to use -get_state callback instead of -get_xstate.
 
 Signed-off-by: Jan Kara j...@suse.cz
 ---
  fs/gfs2/quota.c | 28 +++-
  1 file changed, 15 insertions(+), 13 deletions(-)
 
 diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
 index 3e193cb36996..c76e031ccbb4 100644
 --- a/fs/gfs2/quota.c
 +++ b/fs/gfs2/quota.c
 @@ -1467,32 +1467,34 @@ int gfs2_quotad(void *data)
   return 0;
  }
  
 -static int gfs2_quota_get_xstate(struct super_block *sb,
 -  struct fs_quota_stat *fqs)
 +static int gfs2_quota_get_state(struct super_block *sb, struct qc_state
 *state)
  {
   struct gfs2_sbd *sdp = sb-s_fs_info;
  
 - memset(fqs, 0, sizeof(struct fs_quota_stat));
 - fqs-qs_version = FS_QSTAT_VERSION;
 + memset(state, 0, sizeof(*state));
  
   switch (sdp-sd_args.ar_quota) {
   case GFS2_QUOTA_ON:
 - fqs-qs_flags |= (FS_QUOTA_UDQ_ENFD | FS_QUOTA_GDQ_ENFD);
 + state-s_state[USRQUOTA].flags |= QCI_LIMITS_ENFORCED;
 + state-s_state[GRPQUOTA].flags |= QCI_LIMITS_ENFORCED;
   /*FALLTHRU*/
   case GFS2_QUOTA_ACCOUNT:
 - fqs-qs_flags |= (FS_QUOTA_UDQ_ACCT | FS_QUOTA_GDQ_ACCT);
 + state-s_state[USRQUOTA].flags |= QCI_ACCT_ENABLED |
 +   QCI_SYSFILE;
 + state-s_state[GRPQUOTA].flags |= QCI_ACCT_ENABLED |
 +   QCI_SYSFILE;
   break;
   case GFS2_QUOTA_OFF:
   break;
   }
 -
   if (sdp-sd_quota_inode) {
 - fqs-qs_uquota.qfs_ino = GFS2_I(sdp-sd_quota_inode)-i_no_addr;
 - fqs-qs_uquota.qfs_nblks = sdp-sd_quota_inode-i_blocks;
 + state-s_state[USRQUOTA].ino =
 + GFS2_I(sdp-sd_quota_inode)-i_no_addr;
 + state-s_state[USRQUOTA].blocks = sdp-sd_quota_inode-i_blocks;
   }
 - fqs-qs_uquota.qfs_nextents = 1; /* unsupported */
 - fqs-qs_gquota = fqs-qs_uquota; /* its the same inode in both cases */
 - fqs-qs_incoredqs = list_lru_count(gfs2_qd_lru);
 + state-s_state[USRQUOTA].nextents = 1;  /* unsupported */
 + state-s_state[GRPQUOTA] = state-s_state[USRQUOTA];
 + state-s_incoredqs = list_lru_count(gfs2_qd_lru);
   return 0;
  }
  
 @@ -1637,7 +1639,7 @@ out_put:
  
  const struct quotactl_ops gfs2_quotactl_ops = {
   .quota_sync = gfs2_quota_sync,
 - .get_xstate = gfs2_quota_get_xstate,
 + .get_state  = gfs2_quota_get_state,
   .get_dqblk  = gfs2_get_dqblk,
   .set_dqblk  = gfs2_set_dqblk,
  };
 --
 2.1.4
 
 

ACK

Looks right.

Bob Peterson
Red Hat File Systems