All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] start the quota unification
@ 2010-05-05 10:39 Christoph Hellwig
  2010-05-05 10:39 ` [PATCH 1/3] cifs: drop quota operation stubs Christoph Hellwig
                   ` (3 more replies)
  0 siblings, 4 replies; 17+ messages in thread
From: Christoph Hellwig @ 2010-05-05 10:39 UTC (permalink / raw)
  To: jack; +Cc: linux-fsdevel

Start converging the "VFS" and "XFS" style quotas into more common
operations.  More to follow, but let's get some comments on these
simple ones first.

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

* [PATCH 1/3] cifs: drop quota operation stubs
  2010-05-05 10:39 [PATCH 0/3] start the quota unification Christoph Hellwig
@ 2010-05-05 10:39 ` Christoph Hellwig
  2010-05-05 15:34   ` Jan Kara
  2010-05-06 11:47   ` Jeff Layton
  2010-05-05 10:39 ` [PATCH 2/3] quota: unify ->get_dqblk Christoph Hellwig
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 17+ messages in thread
From: Christoph Hellwig @ 2010-05-05 10:39 UTC (permalink / raw)
  To: jack; +Cc: linux-fsdevel

[-- Attachment #1: cifs-drop-quota-support --]
[-- Type: text/plain, Size: 3309 bytes --]

CIFS has stubs for XFS-style quotas without an actual implementation backing
them, hidden behind a config option not visible in Kconfig.  Remove these
stubs for now as the quota operations will see some major changes and this
code simply gets in the way.


Signed-off-by: Christoph Hellwig <hch@lst.de>

Index: linux-2.6/fs/cifs/cifsfs.c
===================================================================
--- linux-2.6.orig/fs/cifs/cifsfs.c	2010-04-28 13:48:24.783253716 +0200
+++ linux-2.6/fs/cifs/cifsfs.c	2010-04-28 13:49:23.706253646 +0200
@@ -49,10 +49,6 @@
 #include "cifs_spnego.h"
 #define CIFS_MAGIC_NUMBER 0xFF534D42	/* the first four bytes of SMB PDUs */
 
-#ifdef CONFIG_CIFS_QUOTA
-static const struct quotactl_ops cifs_quotactl_ops;
-#endif /* QUOTA */
-
 int cifsFYI = 0;
 int cifsERROR = 1;
 int traceSMB = 0;
@@ -138,9 +134,6 @@ cifs_read_super(struct super_block *sb,
 /*	if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512)
 	    sb->s_blocksize =
 		cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */
-#ifdef CONFIG_CIFS_QUOTA
-	sb->s_qcop = &cifs_quotactl_ops;
-#endif
 	sb->s_blocksize = CIFS_MAX_MSGSIZE;
 	sb->s_blocksize_bits = 14;	/* default 2**14 = CIFS_MAX_MSGSIZE */
 	inode = cifs_root_iget(sb, ROOT_I);
@@ -422,106 +415,6 @@ cifs_show_options(struct seq_file *s, st
 	return 0;
 }
 
-#ifdef CONFIG_CIFS_QUOTA
-int cifs_xquota_set(struct super_block *sb, int quota_type, qid_t qid,
-		struct fs_disk_quota *pdquota)
-{
-	int xid;
-	int rc = 0;
-	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
-	struct cifsTconInfo *pTcon;
-
-	if (cifs_sb)
-		pTcon = cifs_sb->tcon;
-	else
-		return -EIO;
-
-
-	xid = GetXid();
-	if (pTcon) {
-		cFYI(1, ("set type: 0x%x id: %d", quota_type, qid));
-	} else
-		rc = -EIO;
-
-	FreeXid(xid);
-	return rc;
-}
-
-int cifs_xquota_get(struct super_block *sb, int quota_type, qid_t qid,
-		    struct fs_disk_quota *pdquota)
-{
-	int xid;
-	int rc = 0;
-	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
-	struct cifsTconInfo *pTcon;
-
-	if (cifs_sb)
-		pTcon = cifs_sb->tcon;
-	else
-		return -EIO;
-
-	xid = GetXid();
-	if (pTcon) {
-		cFYI(1, ("set type: 0x%x id: %d", quota_type, qid));
-	} else
-		rc = -EIO;
-
-	FreeXid(xid);
-	return rc;
-}
-
-int cifs_xstate_set(struct super_block *sb, unsigned int flags, int operation)
-{
-	int xid;
-	int rc = 0;
-	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
-	struct cifsTconInfo *pTcon;
-
-	if (cifs_sb)
-		pTcon = cifs_sb->tcon;
-	else
-		return -EIO;
-
-	xid = GetXid();
-	if (pTcon) {
-		cFYI(1, ("flags: 0x%x operation: 0x%x", flags, operation));
-	} else
-		rc = -EIO;
-
-	FreeXid(xid);
-	return rc;
-}
-
-int cifs_xstate_get(struct super_block *sb, struct fs_quota_stat *qstats)
-{
-	int xid;
-	int rc = 0;
-	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
-	struct cifsTconInfo *pTcon;
-
-	if (cifs_sb)
-		pTcon = cifs_sb->tcon;
-	else
-		return -EIO;
-
-	xid = GetXid();
-	if (pTcon) {
-		cFYI(1, ("pqstats %p", qstats));
-	} else
-		rc = -EIO;
-
-	FreeXid(xid);
-	return rc;
-}
-
-static const struct quotactl_ops cifs_quotactl_ops = {
-	.set_xquota	= cifs_xquota_set,
-	.get_xquota	= cifs_xquota_get,
-	.set_xstate	= cifs_xstate_set,
-	.get_xstate	= cifs_xstate_get,
-};
-#endif
-
 static void cifs_umount_begin(struct super_block *sb)
 {
 	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);


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

* [PATCH 2/3] quota: unify ->get_dqblk
  2010-05-05 10:39 [PATCH 0/3] start the quota unification Christoph Hellwig
  2010-05-05 10:39 ` [PATCH 1/3] cifs: drop quota operation stubs Christoph Hellwig
@ 2010-05-05 10:39 ` Christoph Hellwig
  2010-05-05 13:52   ` Steven Whitehouse
                     ` (2 more replies)
  2010-05-05 10:39 ` [PATCH 3/3] quota: unify ->set_dqblk Christoph Hellwig
  2010-05-07 16:35 ` [PATCH 4/3] quota: remove sb_has_quota_active in get/set_info Christoph Hellwig
  3 siblings, 3 replies; 17+ messages in thread
From: Christoph Hellwig @ 2010-05-05 10:39 UTC (permalink / raw)
  To: jack; +Cc: linux-fsdevel

[-- Attachment #1: quota-common-get_dqblk --]
[-- Type: text/plain, Size: 7299 bytes --]

Pass the larger struct fs_disk_quota to the ->get_dqblk operation so
that the Q_GETQUOTA and Q_XGETQUOTA operations can be implemented
with a single filesystem operation and we can retire the ->get_xquota
operation.  The additional information (RT-subvolume accounting and
warn counts) are left zero for the VFS quota implementation.

Signed-off-by: Christoph Hellwig <hch@lst.de>

Index: linux-2.6/fs/quota/quota.c
===================================================================
--- linux-2.6.orig/fs/quota/quota.c	2010-05-05 11:57:38.000000000 +0200
+++ linux-2.6/fs/quota/quota.c	2010-05-05 11:58:46.681263382 +0200
@@ -136,19 +136,32 @@ static int quota_setinfo(struct super_bl
 	return sb->s_qcop->set_info(sb, type, &info);
 }
 
+static void copy_to_if_dqblk(struct if_dqblk *dst, struct fs_disk_quota *src)
+{
+	dst->dqb_bhardlimit = src->d_blk_hardlimit;
+	dst->dqb_bsoftlimit = src->d_blk_softlimit;
+	dst->dqb_curspace = src->d_bcount;
+	dst->dqb_ihardlimit = src->d_ino_hardlimit;
+	dst->dqb_isoftlimit = src->d_ino_softlimit;
+	dst->dqb_curinodes = src->d_icount;
+	dst->dqb_btime = src->d_btimer;
+	dst->dqb_itime = src->d_itimer;
+	dst->dqb_valid = QIF_ALL;
+}
+
 static int quota_getquota(struct super_block *sb, int type, qid_t id,
 			  void __user *addr)
 {
+	struct fs_disk_quota fdq;
 	struct if_dqblk idq;
 	int ret;
 
-	if (!sb_has_quota_active(sb, type))
-		return -ESRCH;
 	if (!sb->s_qcop->get_dqblk)
 		return -ENOSYS;
-	ret = sb->s_qcop->get_dqblk(sb, type, id, &idq);
+	ret = sb->s_qcop->get_dqblk(sb, type, id, &fdq);
 	if (ret)
 		return ret;
+	copy_to_if_dqblk(&idq, &fdq);
 	if (copy_to_user(addr, &idq, sizeof(idq)))
 		return -EFAULT;
 	return 0;
@@ -210,9 +223,9 @@ static int quota_getxquota(struct super_
 	struct fs_disk_quota fdq;
 	int ret;
 
-	if (!sb->s_qcop->get_xquota)
+	if (!sb->s_qcop->get_dqblk)
 		return -ENOSYS;
-	ret = sb->s_qcop->get_xquota(sb, type, id, &fdq);
+	ret = sb->s_qcop->get_dqblk(sb, type, id, &fdq);
 	if (!ret && copy_to_user(addr, &fdq, sizeof(fdq)))
 		return -EFAULT;
 	return ret;
Index: linux-2.6/fs/gfs2/quota.c
===================================================================
--- linux-2.6.orig/fs/gfs2/quota.c	2010-05-05 11:57:38.000000000 +0200
+++ linux-2.6/fs/gfs2/quota.c	2010-05-05 11:58:46.682274207 +0200
@@ -1432,8 +1432,8 @@ static int gfs2_quota_get_xstate(struct
 	return 0;
 }
 
-static int gfs2_xquota_get(struct super_block *sb, int type, qid_t id,
-			   struct fs_disk_quota *fdq)
+static int gfs2_get_dqblk(struct super_block *sb, int type, qid_t id,
+			  struct fs_disk_quota *fdq)
 {
 	struct gfs2_sbd *sdp = sb->s_fs_info;
 	struct gfs2_quota_lvb *qlvb;
@@ -1585,7 +1585,7 @@ out_put:
 const struct quotactl_ops gfs2_quotactl_ops = {
 	.quota_sync     = gfs2_quota_sync,
 	.get_xstate     = gfs2_quota_get_xstate,
-	.get_xquota	= gfs2_xquota_get,
+	.get_dqblk	= gfs2_get_dqblk,
 	.set_xquota	= gfs2_xquota_set,
 };
 
Index: linux-2.6/fs/xfs/linux-2.6/xfs_quotaops.c
===================================================================
--- linux-2.6.orig/fs/xfs/linux-2.6/xfs_quotaops.c	2010-05-05 11:57:38.000000000 +0200
+++ linux-2.6/fs/xfs/linux-2.6/xfs_quotaops.c	2010-05-05 11:58:46.688014813 +0200
@@ -97,7 +97,7 @@ xfs_fs_set_xstate(
 }
 
 STATIC int
-xfs_fs_get_xquota(
+xfs_fs_get_dqblk(
 	struct super_block	*sb,
 	int			type,
 	qid_t			id,
@@ -135,6 +135,6 @@ xfs_fs_set_xquota(
 const struct quotactl_ops xfs_quotactl_operations = {
 	.get_xstate		= xfs_fs_get_xstate,
 	.set_xstate		= xfs_fs_set_xstate,
-	.get_xquota		= xfs_fs_get_xquota,
+	.get_dqblk		= xfs_fs_get_dqblk,
 	.set_xquota		= xfs_fs_set_xquota,
 };
Index: linux-2.6/include/linux/quotaops.h
===================================================================
--- linux-2.6.orig/include/linux/quotaops.h	2010-05-05 11:57:38.000000000 +0200
+++ linux-2.6/include/linux/quotaops.h	2010-05-05 11:58:46.694004686 +0200
@@ -63,7 +63,8 @@ int vfs_quota_disable(struct super_block
 int vfs_quota_sync(struct super_block *sb, int type, int wait);
 int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
 int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
-int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di);
+int vfs_get_dqblk(struct super_block *sb, int type, qid_t id,
+		struct fs_disk_quota *di);
 int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di);
 
 int dquot_transfer(struct inode *inode, struct iattr *iattr);
Index: linux-2.6/include/linux/quota.h
===================================================================
--- linux-2.6.orig/include/linux/quota.h	2010-05-05 11:57:38.000000000 +0200
+++ linux-2.6/include/linux/quota.h	2010-05-05 11:58:46.699066287 +0200
@@ -311,11 +311,10 @@ struct quotactl_ops {
 	int (*quota_sync)(struct super_block *, int, int);
 	int (*get_info)(struct super_block *, int, struct if_dqinfo *);
 	int (*set_info)(struct super_block *, int, struct if_dqinfo *);
-	int (*get_dqblk)(struct super_block *, int, qid_t, struct if_dqblk *);
+	int (*get_dqblk)(struct super_block *, int, qid_t, struct fs_disk_quota *);
 	int (*set_dqblk)(struct super_block *, int, qid_t, struct if_dqblk *);
 	int (*get_xstate)(struct super_block *, struct fs_quota_stat *);
 	int (*set_xstate)(struct super_block *, unsigned int, int);
-	int (*get_xquota)(struct super_block *, int, qid_t, struct fs_disk_quota *);
 	int (*set_xquota)(struct super_block *, int, qid_t, struct fs_disk_quota *);
 };
 
Index: linux-2.6/fs/quota/dquot.c
===================================================================
--- linux-2.6.orig/fs/quota/dquot.c	2010-05-05 11:57:47.000000000 +0200
+++ linux-2.6/fs/quota/dquot.c	2010-05-05 11:59:07.614022286 +0200
@@ -2286,28 +2286,36 @@ static inline qsize_t stoqb(qsize_t spac
 }
 
 /* Generic routine for getting common part of quota structure */
-static void do_get_dqblk(struct dquot *dquot, struct if_dqblk *di)
+static void do_get_dqblk(struct dquot *dquot, struct fs_disk_quota *di)
 {
 	struct mem_dqblk *dm = &dquot->dq_dqb;
 
+	memset(di, 0, sizeof(*di));
+	di->d_version = FS_DQUOT_VERSION;
+	di->d_flags = dquot->dq_type == USRQUOTA ?
+			XFS_USER_QUOTA : XFS_GROUP_QUOTA;
+	di->d_id = dquot->dq_id;
+
 	spin_lock(&dq_data_lock);
-	di->dqb_bhardlimit = stoqb(dm->dqb_bhardlimit);
-	di->dqb_bsoftlimit = stoqb(dm->dqb_bsoftlimit);
-	di->dqb_curspace = dm->dqb_curspace + dm->dqb_rsvspace;
-	di->dqb_ihardlimit = dm->dqb_ihardlimit;
-	di->dqb_isoftlimit = dm->dqb_isoftlimit;
-	di->dqb_curinodes = dm->dqb_curinodes;
-	di->dqb_btime = dm->dqb_btime;
-	di->dqb_itime = dm->dqb_itime;
-	di->dqb_valid = QIF_ALL;
+	di->d_blk_hardlimit = stoqb(dm->dqb_bhardlimit);
+	di->d_blk_softlimit = stoqb(dm->dqb_bsoftlimit);
+	di->d_ino_hardlimit = dm->dqb_ihardlimit;
+	di->d_ino_softlimit = dm->dqb_isoftlimit;
+	di->d_bcount = dm->dqb_curspace + dm->dqb_rsvspace;
+	di->d_icount = dm->dqb_curinodes;
+	di->d_btimer = dm->dqb_btime;
+	di->d_itimer = dm->dqb_itime;
 	spin_unlock(&dq_data_lock);
 }
 
 int vfs_get_dqblk(struct super_block *sb, int type, qid_t id,
-		  struct if_dqblk *di)
+		  struct fs_disk_quota *di)
 {
 	struct dquot *dquot;
 
+	if (!sb_has_quota_active(sb, type))
+		return -ESRCH;
+
 	dquot = dqget(sb, id, type);
 	if (!dquot)
 		return -ESRCH;


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

* [PATCH 3/3] quota: unify ->set_dqblk
  2010-05-05 10:39 [PATCH 0/3] start the quota unification Christoph Hellwig
  2010-05-05 10:39 ` [PATCH 1/3] cifs: drop quota operation stubs Christoph Hellwig
  2010-05-05 10:39 ` [PATCH 2/3] quota: unify ->get_dqblk Christoph Hellwig
@ 2010-05-05 10:39 ` Christoph Hellwig
  2010-05-05 16:09   ` Jan Kara
  2010-05-06 21:05   ` [PATCH 3/3 v2] " Christoph Hellwig
  2010-05-07 16:35 ` [PATCH 4/3] quota: remove sb_has_quota_active in get/set_info Christoph Hellwig
  3 siblings, 2 replies; 17+ messages in thread
From: Christoph Hellwig @ 2010-05-05 10:39 UTC (permalink / raw)
  To: jack; +Cc: linux-fsdevel

[-- Attachment #1: quota-common-set_dqblk --]
[-- Type: text/plain, Size: 12373 bytes --]

Pass the larger struct fs_disk_quota to the ->set_dqblk operation so
that the Q_SETQUOTA and Q_XSETQUOTA operations can be implemented
with a single filesystem operation and we can retire the ->set_xquota
operation.  The additional information (RT-subvolume accounting and
warn counts) are left zero for the VFS quota implementation.

Add new fieldmask values for setting the numer of blocks and inodes
values which is required for the VFS quota, but wasn't for XFS.

Signed-off-by: Christoph Hellwig <hch@lst.de>


Index: linux-2.6/fs/gfs2/quota.c
===================================================================
--- linux-2.6.orig/fs/gfs2/quota.c	2010-05-05 11:59:36.453004197 +0200
+++ linux-2.6/fs/gfs2/quota.c	2010-05-05 11:59:51.775254163 +0200
@@ -1477,8 +1477,8 @@ out:
 /* GFS2 only supports a subset of the XFS fields */
 #define GFS2_FIELDMASK (FS_DQ_BSOFT|FS_DQ_BHARD)
 
-static int gfs2_xquota_set(struct super_block *sb, int type, qid_t id,
-			   struct fs_disk_quota *fdq)
+static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id,
+			  struct fs_disk_quota *fdq)
 {
 	struct gfs2_sbd *sdp = sb->s_fs_info;
 	struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode);
@@ -1586,6 +1586,6 @@ const struct quotactl_ops gfs2_quotactl_
 	.quota_sync     = gfs2_quota_sync,
 	.get_xstate     = gfs2_quota_get_xstate,
 	.get_dqblk	= gfs2_get_dqblk,
-	.set_xquota	= gfs2_xquota_set,
+	.set_dqblk	= gfs2_set_dqblk,
 };
 
Index: linux-2.6/fs/quota/quota.c
===================================================================
--- linux-2.6.orig/fs/quota/quota.c	2010-05-05 11:59:36.459003429 +0200
+++ linux-2.6/fs/quota/quota.c	2010-05-05 12:20:07.307257027 +0200
@@ -167,18 +167,44 @@ static int quota_getquota(struct super_b
 	return 0;
 }
 
+static void copy_from_if_dqblk(struct fs_disk_quota *dst, struct if_dqblk *src)
+{
+	dst->d_blk_hardlimit = src->dqb_bhardlimit;
+	dst->d_blk_softlimit  = src->dqb_bsoftlimit;
+	dst->d_bcount = src->dqb_curspace;
+	dst->d_ino_hardlimit = src->dqb_ihardlimit;
+	dst->d_ino_softlimit = src->dqb_isoftlimit;
+	dst->d_icount = src->dqb_curinodes;
+	dst->d_btimer = src->dqb_btime;
+	dst->d_itimer = src->dqb_itime;
+
+	dst->d_fieldmask = 0;
+	if (src->dqb_valid & QIF_BLIMITS)
+		dst->d_fieldmask |= FS_DQ_BSOFT | FS_DQ_BHARD;
+	if (src->dqb_valid & QIF_SPACE)
+		dst->d_fieldmask |= FS_DQ_BCOUNT;
+	if (src->dqb_valid & QIF_ILIMITS)
+		dst->d_fieldmask |= FS_DQ_ISOFT | FS_DQ_IHARD;
+	if (src->dqb_valid & QIF_INODES)
+		dst->d_fieldmask |= FS_DQ_ICOUNT;
+	if (src->dqb_valid & QIF_BTIME)
+		dst->d_fieldmask |= FS_DQ_BTIMER;
+	if (src->dqb_valid & QIF_ITIME)
+		dst->d_fieldmask |= FS_DQ_ITIMER;
+}
+
 static int quota_setquota(struct super_block *sb, int type, qid_t id,
 			  void __user *addr)
 {
+	struct fs_disk_quota fdq;
 	struct if_dqblk idq;
 
 	if (copy_from_user(&idq, addr, sizeof(idq)))
 		return -EFAULT;
-	if (!sb_has_quota_active(sb, type))
-		return -ESRCH;
 	if (!sb->s_qcop->set_dqblk)
 		return -ENOSYS;
-	return sb->s_qcop->set_dqblk(sb, type, id, &idq);
+	copy_from_if_dqblk(&fdq, &idq);
+	return sb->s_qcop->set_dqblk(sb, type, id, &fdq);
 }
 
 static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr)
@@ -212,9 +238,9 @@ static int quota_setxquota(struct super_
 
 	if (copy_from_user(&fdq, addr, sizeof(fdq)))
 		return -EFAULT;
-	if (!sb->s_qcop->set_xquota)
+	if (!sb->s_qcop->set_dqblk)
 		return -ENOSYS;
-	return sb->s_qcop->set_xquota(sb, type, id, &fdq);
+	return sb->s_qcop->set_dqblk(sb, type, id, &fdq);
 }
 
 static int quota_getxquota(struct super_block *sb, int type, qid_t id,
Index: linux-2.6/fs/xfs/linux-2.6/xfs_quotaops.c
===================================================================
--- linux-2.6.orig/fs/xfs/linux-2.6/xfs_quotaops.c	2010-05-05 11:59:36.475003848 +0200
+++ linux-2.6/fs/xfs/linux-2.6/xfs_quotaops.c	2010-05-05 11:59:51.779294113 +0200
@@ -114,7 +114,7 @@ xfs_fs_get_dqblk(
 }
 
 STATIC int
-xfs_fs_set_xquota(
+xfs_fs_set_dqblk(
 	struct super_block	*sb,
 	int			type,
 	qid_t			id,
@@ -136,5 +136,5 @@ const struct quotactl_ops xfs_quotactl_o
 	.get_xstate		= xfs_fs_get_xstate,
 	.set_xstate		= xfs_fs_set_xstate,
 	.get_dqblk		= xfs_fs_get_dqblk,
-	.set_xquota		= xfs_fs_set_xquota,
+	.set_dqblk		= xfs_fs_set_dqblk,
 };
Index: linux-2.6/include/linux/quota.h
===================================================================
--- linux-2.6.orig/include/linux/quota.h	2010-05-05 11:59:36.492004197 +0200
+++ linux-2.6/include/linux/quota.h	2010-05-05 11:59:51.783025430 +0200
@@ -312,10 +312,9 @@ struct quotactl_ops {
 	int (*get_info)(struct super_block *, int, struct if_dqinfo *);
 	int (*set_info)(struct super_block *, int, struct if_dqinfo *);
 	int (*get_dqblk)(struct super_block *, int, qid_t, struct fs_disk_quota *);
-	int (*set_dqblk)(struct super_block *, int, qid_t, struct if_dqblk *);
+	int (*set_dqblk)(struct super_block *, int, qid_t, struct fs_disk_quota *);
 	int (*get_xstate)(struct super_block *, struct fs_quota_stat *);
 	int (*set_xstate)(struct super_block *, unsigned int, int);
-	int (*set_xquota)(struct super_block *, int, qid_t, struct fs_disk_quota *);
 };
 
 struct quota_format_type {
Index: linux-2.6/include/linux/quotaops.h
===================================================================
--- linux-2.6.orig/include/linux/quotaops.h	2010-05-05 11:59:36.500004197 +0200
+++ linux-2.6/include/linux/quotaops.h	2010-05-05 11:59:51.788255630 +0200
@@ -65,7 +65,8 @@ int vfs_get_dqinfo(struct super_block *s
 int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
 int vfs_get_dqblk(struct super_block *sb, int type, qid_t id,
 		struct fs_disk_quota *di);
-int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di);
+int vfs_set_dqblk(struct super_block *sb, int type, qid_t id,
+		struct fs_disk_quota *di);
 
 int dquot_transfer(struct inode *inode, struct iattr *iattr);
 int vfs_dq_quota_on_remount(struct super_block *sb);
Index: linux-2.6/fs/xfs/quota/xfs_qm_syscalls.c
===================================================================
--- linux-2.6.orig/fs/xfs/quota/xfs_qm_syscalls.c	2010-05-05 11:59:36.483003709 +0200
+++ linux-2.6/fs/xfs/quota/xfs_qm_syscalls.c	2010-05-05 11:59:51.792284824 +0200
@@ -452,6 +452,9 @@ xfs_qm_scall_getqstat(
 	return (0);
 }
 
+#define XFS_DQ_MASK \
+	(FS_DQ_LIMIT_MASK | FS_DQ_TIMER_MASK | FS_DQ_WARNS_MASK)
+
 /*
  * Adjust quota limits, and start/stop timers accordingly.
  */
@@ -468,9 +471,10 @@ xfs_qm_scall_setqlim(
 	int			error;
 	xfs_qcnt_t		hard, soft;
 
-	if ((newlim->d_fieldmask &
-	    (FS_DQ_LIMIT_MASK|FS_DQ_TIMER_MASK|FS_DQ_WARNS_MASK)) == 0)
-		return (0);
+	if (newlim->d_fieldmask & ~XFS_DQ_MASK)
+		return EINVAL;
+	if ((newlim->d_fieldmask & XFS_DQ_MASK) == 0)
+		return 0;
 
 	tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SETQLIM);
 	if ((error = xfs_trans_reserve(tp, 0, sizeof(xfs_disk_dquot_t) + 128,
Index: linux-2.6/include/linux/dqblk_xfs.h
===================================================================
--- linux-2.6.orig/include/linux/dqblk_xfs.h	2010-05-05 11:59:36.511004337 +0200
+++ linux-2.6/include/linux/dqblk_xfs.h	2010-05-05 11:59:51.797255211 +0200
@@ -110,6 +110,15 @@ typedef struct fs_disk_quota {
 #define FS_DQ_WARNS_MASK	(FS_DQ_BWARNS | FS_DQ_IWARNS | FS_DQ_RTBWARNS)
 
 /*
+ * Accounting values.  These can only be set for filesystem with
+ * non-transactional quotas that require quotacheck(8) in userspace.
+ */
+#define FS_DQ_BCOUNT		(1<<12)
+#define FS_DQ_ICOUNT		(1<<13)
+#define FS_DQ_RTBCOUNT		(1<<14)
+#define FS_DQ_ACCT_MASK		(FS_DQ_BCOUNT | FS_DQ_ICOUNT | FS_DQ_RTBCOUNT)
+
+/*
  * Various flags related to quotactl(2).  Only relevant to XFS filesystems.
  */
 #define XFS_QUOTA_UDQ_ACCT	(1<<0)  /* user quota accounting */
Index: linux-2.6/fs/quota/dquot.c
===================================================================
--- linux-2.6.orig/fs/quota/dquot.c	2010-05-05 11:59:36.468003639 +0200
+++ linux-2.6/fs/quota/dquot.c	2010-05-05 11:59:51.803283357 +0200
@@ -2326,51 +2326,70 @@ int vfs_get_dqblk(struct super_block *sb
 }
 EXPORT_SYMBOL(vfs_get_dqblk);
 
+#define VFS_FS_DQ_MASK \
+	(FS_DQ_BCOUNT | FS_DQ_BSOFT | FS_DQ_BHARD | \
+	 FS_DQ_ICOUNT | FS_DQ_ISOFT | FS_DQ_IHARD | \
+	 FS_DQ_BTIMER | FS_DQ_ITIMER)
+
 /* Generic routine for setting common part of quota structure */
-static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di)
+static int do_set_dqblk(struct dquot *dquot, struct fs_disk_quota *di)
 {
 	struct mem_dqblk *dm = &dquot->dq_dqb;
 	int check_blim = 0, check_ilim = 0;
 	struct mem_dqinfo *dqi = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type];
 
-	if ((di->dqb_valid & QIF_BLIMITS &&
-	     (di->dqb_bhardlimit > dqi->dqi_maxblimit ||
-	      di->dqb_bsoftlimit > dqi->dqi_maxblimit)) ||
-	    (di->dqb_valid & QIF_ILIMITS &&
-	     (di->dqb_ihardlimit > dqi->dqi_maxilimit ||
-	      di->dqb_isoftlimit > dqi->dqi_maxilimit)))
+	if (di->d_fieldmask & ~VFS_FS_DQ_MASK)
+		return -EINVAL;
+
+	if (((di->d_fieldmask & FS_DQ_BSOFT) &&
+	     (di->d_blk_softlimit > dqi->dqi_maxblimit)) ||
+	    ((di->d_fieldmask & FS_DQ_BHARD) &&
+	     (di->d_blk_hardlimit > dqi->dqi_maxblimit)) ||
+	    ((di->d_fieldmask & FS_DQ_ISOFT) &&
+	     (di->d_ino_softlimit > dqi->dqi_maxilimit)) ||
+	    ((di->d_fieldmask & FS_DQ_IHARD) &&
+	     (di->d_ino_hardlimit > dqi->dqi_maxilimit)))
 		return -ERANGE;
 
 	spin_lock(&dq_data_lock);
-	if (di->dqb_valid & QIF_SPACE) {
-		dm->dqb_curspace = di->dqb_curspace - dm->dqb_rsvspace;
+	if (di->d_fieldmask & FS_DQ_BCOUNT) {
+		dm->dqb_curspace = di->d_bcount - dm->dqb_rsvspace;
 		check_blim = 1;
 		set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags);
 	}
-	if (di->dqb_valid & QIF_BLIMITS) {
-		dm->dqb_bsoftlimit = qbtos(di->dqb_bsoftlimit);
-		dm->dqb_bhardlimit = qbtos(di->dqb_bhardlimit);
+
+	if (di->d_fieldmask & FS_DQ_BSOFT)
+		dm->dqb_bsoftlimit = qbtos(di->d_blk_softlimit);
+	if (di->d_fieldmask & FS_DQ_BHARD)
+		dm->dqb_bhardlimit = qbtos(di->d_blk_hardlimit);
+	if (di->d_fieldmask & (FS_DQ_BSOFT | FS_DQ_BHARD)) {
 		check_blim = 1;
 		set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags);
 	}
-	if (di->dqb_valid & QIF_INODES) {
-		dm->dqb_curinodes = di->dqb_curinodes;
+
+	if (di->d_fieldmask & FS_DQ_ICOUNT) {
+		dm->dqb_curinodes = di->d_icount;
 		check_ilim = 1;
 		set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags);
 	}
-	if (di->dqb_valid & QIF_ILIMITS) {
-		dm->dqb_isoftlimit = di->dqb_isoftlimit;
-		dm->dqb_ihardlimit = di->dqb_ihardlimit;
+
+	if (di->d_fieldmask & FS_DQ_ISOFT)
+		dm->dqb_isoftlimit = di->d_ino_softlimit;
+	if (di->d_fieldmask & FS_DQ_IHARD)
+		dm->dqb_ihardlimit = di->d_ino_hardlimit;
+	if (di->d_fieldmask & (FS_DQ_ISOFT | FS_DQ_IHARD)) {
 		check_ilim = 1;
 		set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags);
 	}
-	if (di->dqb_valid & QIF_BTIME) {
-		dm->dqb_btime = di->dqb_btime;
+
+	if (di->d_fieldmask & FS_DQ_BTIMER) {
+		dm->dqb_btime = di->d_btimer;
 		check_blim = 1;
 		set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags);
 	}
-	if (di->dqb_valid & QIF_ITIME) {
-		dm->dqb_itime = di->dqb_itime;
+
+	if (di->d_fieldmask & FS_DQ_ITIMER) {
+		dm->dqb_itime = di->d_itimer;
 		check_ilim = 1;
 		set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags);
 	}
@@ -2380,7 +2399,7 @@ static int do_set_dqblk(struct dquot *dq
 		    dm->dqb_curspace < dm->dqb_bsoftlimit) {
 			dm->dqb_btime = 0;
 			clear_bit(DQ_BLKS_B, &dquot->dq_flags);
-		} else if (!(di->dqb_valid & QIF_BTIME))
+		} else if (!(di->d_fieldmask & FS_DQ_BTIMER))
 			/* Set grace only if user hasn't provided his own... */
 			dm->dqb_btime = get_seconds() + dqi->dqi_bgrace;
 	}
@@ -2389,7 +2408,7 @@ static int do_set_dqblk(struct dquot *dq
 		    dm->dqb_curinodes < dm->dqb_isoftlimit) {
 			dm->dqb_itime = 0;
 			clear_bit(DQ_INODES_B, &dquot->dq_flags);
-		} else if (!(di->dqb_valid & QIF_ITIME))
+		} else if (!(di->d_fieldmask & FS_DQ_ITIMER))
 			/* Set grace only if user hasn't provided his own... */
 			dm->dqb_itime = get_seconds() + dqi->dqi_igrace;
 	}
@@ -2405,11 +2424,14 @@ static int do_set_dqblk(struct dquot *dq
 }
 
 int vfs_set_dqblk(struct super_block *sb, int type, qid_t id,
-		  struct if_dqblk *di)
+		  struct fs_disk_quota *di)
 {
 	struct dquot *dquot;
 	int rc;
 
+	if (!sb_has_quota_active(sb, type))
+		return -ESRCH;
+
 	dquot = dqget(sb, id, type);
 	if (!dquot) {
 		rc = -ESRCH;


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

* Re: [PATCH 2/3] quota: unify ->get_dqblk
  2010-05-05 10:39 ` [PATCH 2/3] quota: unify ->get_dqblk Christoph Hellwig
@ 2010-05-05 13:52   ` Steven Whitehouse
  2010-05-05 16:18     ` Christoph Hellwig
  2010-05-05 16:00   ` Jan Kara
  2010-05-06 21:04   ` [PATCH 2/3 v2] " Christoph Hellwig
  2 siblings, 1 reply; 17+ messages in thread
From: Steven Whitehouse @ 2010-05-05 13:52 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: jack, linux-fsdevel

Hi,

On Wed, 2010-05-05 at 06:39 -0400, Christoph Hellwig wrote:
> plain text document attachment (quota-common-get_dqblk)
> Pass the larger struct fs_disk_quota to the ->get_dqblk operation so
> that the Q_GETQUOTA and Q_XGETQUOTA operations can be implemented
> with a single filesystem operation and we can retire the ->get_xquota
> operation.  The additional information (RT-subvolume accounting and
> warn counts) are left zero for the VFS quota implementation.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> 
> Index: linux-2.6/fs/quota/quota.c
> ===================================================================
> --- linux-2.6.orig/fs/quota/quota.c	2010-05-05 11:57:38.000000000 +0200
> +++ linux-2.6/fs/quota/quota.c	2010-05-05 11:58:46.681263382 +0200
> @@ -136,19 +136,32 @@ static int quota_setinfo(struct super_bl
>  	return sb->s_qcop->set_info(sb, type, &info);
>  }
>  
> +static void copy_to_if_dqblk(struct if_dqblk *dst, struct fs_disk_quota *src)
> +{
> +	dst->dqb_bhardlimit = src->d_blk_hardlimit;
> +	dst->dqb_bsoftlimit = src->d_blk_softlimit;
> +	dst->dqb_curspace = src->d_bcount;
> +	dst->dqb_ihardlimit = src->d_ino_hardlimit;
> +	dst->dqb_isoftlimit = src->d_ino_softlimit;
> +	dst->dqb_curinodes = src->d_icount;
> +	dst->dqb_btime = src->d_btimer;
> +	dst->dqb_itime = src->d_itimer;
> +	dst->dqb_valid = QIF_ALL;
Do the fields needs to be individually marked as valid according to what
is supported by a filesystem or can we always assume that a zero value
means unknown/unsupported?

Otherwise it looks good to me,

Steve.



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

* Re: [PATCH 1/3] cifs: drop quota operation stubs
  2010-05-05 10:39 ` [PATCH 1/3] cifs: drop quota operation stubs Christoph Hellwig
@ 2010-05-05 15:34   ` Jan Kara
  2010-05-05 18:57     ` Steve French
  2010-05-06 11:47   ` Jeff Layton
  1 sibling, 1 reply; 17+ messages in thread
From: Jan Kara @ 2010-05-05 15:34 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: jack, linux-fsdevel, Steve French, linux-cifs-client

On Wed 05-05-10 06:39:38, Christoph Hellwig wrote:
> CIFS has stubs for XFS-style quotas without an actual implementation backing
> them, hidden behind a config option not visible in Kconfig.  Remove these
> stubs for now as the quota operations will see some major changes and this
> code simply gets in the way.
  I have no problem with this but maybe a word from CIFS guys would be
nice? Added to CC...

								Honza
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> 
> Index: linux-2.6/fs/cifs/cifsfs.c
> ===================================================================
> --- linux-2.6.orig/fs/cifs/cifsfs.c	2010-04-28 13:48:24.783253716 +0200
> +++ linux-2.6/fs/cifs/cifsfs.c	2010-04-28 13:49:23.706253646 +0200
> @@ -49,10 +49,6 @@
>  #include "cifs_spnego.h"
>  #define CIFS_MAGIC_NUMBER 0xFF534D42	/* the first four bytes of SMB PDUs */
>  
> -#ifdef CONFIG_CIFS_QUOTA
> -static const struct quotactl_ops cifs_quotactl_ops;
> -#endif /* QUOTA */
> -
>  int cifsFYI = 0;
>  int cifsERROR = 1;
>  int traceSMB = 0;
> @@ -138,9 +134,6 @@ cifs_read_super(struct super_block *sb,
>  /*	if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512)
>  	    sb->s_blocksize =
>  		cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */
> -#ifdef CONFIG_CIFS_QUOTA
> -	sb->s_qcop = &cifs_quotactl_ops;
> -#endif
>  	sb->s_blocksize = CIFS_MAX_MSGSIZE;
>  	sb->s_blocksize_bits = 14;	/* default 2**14 = CIFS_MAX_MSGSIZE */
>  	inode = cifs_root_iget(sb, ROOT_I);
> @@ -422,106 +415,6 @@ cifs_show_options(struct seq_file *s, st
>  	return 0;
>  }
>  
> -#ifdef CONFIG_CIFS_QUOTA
> -int cifs_xquota_set(struct super_block *sb, int quota_type, qid_t qid,
> -		struct fs_disk_quota *pdquota)
> -{
> -	int xid;
> -	int rc = 0;
> -	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
> -	struct cifsTconInfo *pTcon;
> -
> -	if (cifs_sb)
> -		pTcon = cifs_sb->tcon;
> -	else
> -		return -EIO;
> -
> -
> -	xid = GetXid();
> -	if (pTcon) {
> -		cFYI(1, ("set type: 0x%x id: %d", quota_type, qid));
> -	} else
> -		rc = -EIO;
> -
> -	FreeXid(xid);
> -	return rc;
> -}
> -
> -int cifs_xquota_get(struct super_block *sb, int quota_type, qid_t qid,
> -		    struct fs_disk_quota *pdquota)
> -{
> -	int xid;
> -	int rc = 0;
> -	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
> -	struct cifsTconInfo *pTcon;
> -
> -	if (cifs_sb)
> -		pTcon = cifs_sb->tcon;
> -	else
> -		return -EIO;
> -
> -	xid = GetXid();
> -	if (pTcon) {
> -		cFYI(1, ("set type: 0x%x id: %d", quota_type, qid));
> -	} else
> -		rc = -EIO;
> -
> -	FreeXid(xid);
> -	return rc;
> -}
> -
> -int cifs_xstate_set(struct super_block *sb, unsigned int flags, int operation)
> -{
> -	int xid;
> -	int rc = 0;
> -	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
> -	struct cifsTconInfo *pTcon;
> -
> -	if (cifs_sb)
> -		pTcon = cifs_sb->tcon;
> -	else
> -		return -EIO;
> -
> -	xid = GetXid();
> -	if (pTcon) {
> -		cFYI(1, ("flags: 0x%x operation: 0x%x", flags, operation));
> -	} else
> -		rc = -EIO;
> -
> -	FreeXid(xid);
> -	return rc;
> -}
> -
> -int cifs_xstate_get(struct super_block *sb, struct fs_quota_stat *qstats)
> -{
> -	int xid;
> -	int rc = 0;
> -	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
> -	struct cifsTconInfo *pTcon;
> -
> -	if (cifs_sb)
> -		pTcon = cifs_sb->tcon;
> -	else
> -		return -EIO;
> -
> -	xid = GetXid();
> -	if (pTcon) {
> -		cFYI(1, ("pqstats %p", qstats));
> -	} else
> -		rc = -EIO;
> -
> -	FreeXid(xid);
> -	return rc;
> -}
> -
> -static const struct quotactl_ops cifs_quotactl_ops = {
> -	.set_xquota	= cifs_xquota_set,
> -	.get_xquota	= cifs_xquota_get,
> -	.set_xstate	= cifs_xstate_set,
> -	.get_xstate	= cifs_xstate_get,
> -};
> -#endif
> -
>  static void cifs_umount_begin(struct super_block *sb)
>  {
>  	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
> 
-- 
Jan Kara <jack@suse.cz>
SUSE Labs, CR

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

* Re: [PATCH 2/3] quota: unify ->get_dqblk
  2010-05-05 10:39 ` [PATCH 2/3] quota: unify ->get_dqblk Christoph Hellwig
  2010-05-05 13:52   ` Steven Whitehouse
@ 2010-05-05 16:00   ` Jan Kara
  2010-05-05 16:20     ` Christoph Hellwig
  2010-05-06 21:04   ` [PATCH 2/3 v2] " Christoph Hellwig
  2 siblings, 1 reply; 17+ messages in thread
From: Jan Kara @ 2010-05-05 16:00 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: jack, linux-fsdevel

On Wed 05-05-10 06:39:39, Christoph Hellwig wrote:
> Pass the larger struct fs_disk_quota to the ->get_dqblk operation so
> that the Q_GETQUOTA and Q_XGETQUOTA operations can be implemented
> with a single filesystem operation and we can retire the ->get_xquota
> operation.  The additional information (RT-subvolume accounting and
> warn counts) are left zero for the VFS quota implementation.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> 
> Index: linux-2.6/fs/quota/quota.c
> ===================================================================
> --- linux-2.6.orig/fs/quota/quota.c	2010-05-05 11:57:38.000000000 +0200
> +++ linux-2.6/fs/quota/quota.c	2010-05-05 11:58:46.681263382 +0200
> @@ -136,19 +136,32 @@ static int quota_setinfo(struct super_bl
>  	return sb->s_qcop->set_info(sb, type, &info);
>  }
>
> +static void copy_to_if_dqblk(struct if_dqblk *dst, struct fs_disk_quota *src)
  Could you move fs_disk_quota declaration from an XFS-specific header to
a generic one?

> Index: linux-2.6/fs/quota/dquot.c
> ===================================================================
> --- linux-2.6.orig/fs/quota/dquot.c	2010-05-05 11:57:47.000000000 +0200
> +++ linux-2.6/fs/quota/dquot.c	2010-05-05 11:59:07.614022286 +0200
> @@ -2286,28 +2286,36 @@ static inline qsize_t stoqb(qsize_t spac
>  }
>  
>  /* Generic routine for getting common part of quota structure */
> -static void do_get_dqblk(struct dquot *dquot, struct if_dqblk *di)
> +static void do_get_dqblk(struct dquot *dquot, struct fs_disk_quota *di)
>  {
>  	struct mem_dqblk *dm = &dquot->dq_dqb;
>  
> +	memset(di, 0, sizeof(*di));
> +	di->d_version = FS_DQUOT_VERSION;
> +	di->d_flags = dquot->dq_type == USRQUOTA ?
> +			XFS_USER_QUOTA : XFS_GROUP_QUOTA;
> +	di->d_id = dquot->dq_id;
  XFS_USER_QUOTA and XFS_GROUP_QUOTA looks awkward in the generic code...

...
>  int vfs_get_dqblk(struct super_block *sb, int type, qid_t id,
> -		  struct if_dqblk *di)
> +		  struct fs_disk_quota *di)
>  {
>  	struct dquot *dquot;
>  
> +	if (!sb_has_quota_active(sb, type))
> +		return -ESRCH;
> +
  dqget() already does this check so you can just remove it....

>  	dquot = dqget(sb, id, type);
>  	if (!dquot)
>  		return -ESRCH;
> 
-- 
Jan Kara <jack@suse.cz>
SUSE Labs, CR

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

* Re: [PATCH 3/3] quota: unify ->set_dqblk
  2010-05-05 10:39 ` [PATCH 3/3] quota: unify ->set_dqblk Christoph Hellwig
@ 2010-05-05 16:09   ` Jan Kara
  2010-05-05 16:21     ` Christoph Hellwig
  2010-05-06 21:05   ` [PATCH 3/3 v2] " Christoph Hellwig
  1 sibling, 1 reply; 17+ messages in thread
From: Jan Kara @ 2010-05-05 16:09 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: jack, linux-fsdevel

On Wed 05-05-10 06:39:40, Christoph Hellwig wrote:
> Pass the larger struct fs_disk_quota to the ->set_dqblk operation so
> that the Q_SETQUOTA and Q_XSETQUOTA operations can be implemented
> with a single filesystem operation and we can retire the ->set_xquota
> operation.  The additional information (RT-subvolume accounting and
> warn counts) are left zero for the VFS quota implementation.
> 
> Add new fieldmask values for setting the numer of blocks and inodes
> values which is required for the VFS quota, but wasn't for XFS.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> 
  Just one minor nit below...

...
> @@ -2405,11 +2424,14 @@ static int do_set_dqblk(struct dquot *dq
>  }
>  
>  int vfs_set_dqblk(struct super_block *sb, int type, qid_t id,
> -		  struct if_dqblk *di)
> +		  struct fs_disk_quota *di)
>  {
>  	struct dquot *dquot;
>  	int rc;
>  
> +	if (!sb_has_quota_active(sb, type))
> +		return -ESRCH;
> +
  This is unnecessary...

>  	dquot = dqget(sb, id, type);
>  	if (!dquot) {
>  		rc = -ESRCH;
> 
								Honza
-- 
Jan Kara <jack@suse.cz>
SUSE Labs, CR

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

* Re: [PATCH 2/3] quota: unify ->get_dqblk
  2010-05-05 13:52   ` Steven Whitehouse
@ 2010-05-05 16:18     ` Christoph Hellwig
  0 siblings, 0 replies; 17+ messages in thread
From: Christoph Hellwig @ 2010-05-05 16:18 UTC (permalink / raw)
  To: Steven Whitehouse; +Cc: jack, linux-fsdevel

On Wed, May 05, 2010 at 02:52:54PM +0100, Steven Whitehouse wrote:
> Do the fields needs to be individually marked as valid according to what
> is supported by a filesystem or can we always assume that a zero value
> means unknown/unsupported?

The quota-tools code assumes all fields to be valid and doesn't even
check dqb_valid.  It's only used for the set side.


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

* Re: [PATCH 2/3] quota: unify ->get_dqblk
  2010-05-05 16:00   ` Jan Kara
@ 2010-05-05 16:20     ` Christoph Hellwig
  0 siblings, 0 replies; 17+ messages in thread
From: Christoph Hellwig @ 2010-05-05 16:20 UTC (permalink / raw)
  To: Jan Kara; +Cc: Christoph Hellwig, linux-fsdevel

On Wed, May 05, 2010 at 06:00:53PM +0200, Jan Kara wrote:
> > +static void copy_to_if_dqblk(struct if_dqblk *dst, struct fs_disk_quota *src)
>   Could you move fs_disk_quota declaration from an XFS-specific header to
> a generic one?

The only XFS-specific thing in dqblk_xfs.h is the name.  Feel free to
rename it to whatever better name suits you.

> >  /* Generic routine for getting common part of quota structure */
> > -static void do_get_dqblk(struct dquot *dquot, struct if_dqblk *di)
> > +static void do_get_dqblk(struct dquot *dquot, struct fs_disk_quota *di)
> >  {
> >  	struct mem_dqblk *dm = &dquot->dq_dqb;
> >  
> > +	memset(di, 0, sizeof(*di));
> > +	di->d_version = FS_DQUOT_VERSION;
> > +	di->d_flags = dquot->dq_type == USRQUOTA ?
> > +			XFS_USER_QUOTA : XFS_GROUP_QUOTA;
> > +	di->d_id = dquot->dq_id;
>   XFS_USER_QUOTA and XFS_GROUP_QUOTA looks awkward in the generic code...

I have a patch renaming the last remaining XFS_ identifiers in
dqblk_xfs.h to FS_ like the rest, but as I've just sent a gfs2 patch
that touches code with these identifiers I'll hold it back until the
gfs2 tree is merged.

> >  int vfs_get_dqblk(struct super_block *sb, int type, qid_t id,
> > -		  struct if_dqblk *di)
> > +		  struct fs_disk_quota *di)
> >  {
> >  	struct dquot *dquot;
> >  
> > +	if (!sb_has_quota_active(sb, type))
> > +		return -ESRCH;
> > +
>   dqget() already does this check so you can just remove it....

Ok, fixed for the next version.


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

* Re: [PATCH 3/3] quota: unify ->set_dqblk
  2010-05-05 16:09   ` Jan Kara
@ 2010-05-05 16:21     ` Christoph Hellwig
  0 siblings, 0 replies; 17+ messages in thread
From: Christoph Hellwig @ 2010-05-05 16:21 UTC (permalink / raw)
  To: Jan Kara; +Cc: Christoph Hellwig, linux-fsdevel

On Wed, May 05, 2010 at 06:09:56PM +0200, Jan Kara wrote:
> > +	if (!sb_has_quota_active(sb, type))
> > +		return -ESRCH;
> > +
>   This is unnecessary...

Thanks, fixed for the next iteration.


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

* Re: [PATCH 1/3] cifs: drop quota operation stubs
  2010-05-05 15:34   ` Jan Kara
@ 2010-05-05 18:57     ` Steve French
  0 siblings, 0 replies; 17+ messages in thread
From: Steve French @ 2010-05-05 18:57 UTC (permalink / raw)
  To: Jan Kara; +Cc: linux-fsdevel, Steve French, linux-cifs-client


[-- Attachment #1.1: Type: text/plain, Size: 733 bytes --]

On Wed, May 5, 2010 at 10:34 AM, Jan Kara <jack@suse.cz> wrote:

> On Wed 05-05-10 06:39:38, Christoph Hellwig wrote:
> > CIFS has stubs for XFS-style quotas without an actual implementation
> backing
> > them, hidden behind a config option not visible in Kconfig.  Remove these
> > stubs for now as the quota operations will see some major changes and
> this
> > code simply gets in the way.
>


If the quota operations are changing, should be fine to remove the sutbs.  I
don't remember seeing a recent patch on this but will look.  I was thinking
of revisiting these in the smb2 module, since how to send these over the
wire are better documented now,  by not as high a priority as some of the
other function.

-- 
Thanks,

Steve

[-- Attachment #1.2: Type: text/html, Size: 1044 bytes --]

[-- Attachment #2: Type: text/plain, Size: 172 bytes --]

_______________________________________________
linux-cifs-client mailing list
linux-cifs-client@lists.samba.org
https://lists.samba.org/mailman/listinfo/linux-cifs-client

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

* Re: [PATCH 1/3] cifs: drop quota operation stubs
  2010-05-05 10:39 ` [PATCH 1/3] cifs: drop quota operation stubs Christoph Hellwig
  2010-05-05 15:34   ` Jan Kara
@ 2010-05-06 11:47   ` Jeff Layton
  1 sibling, 0 replies; 17+ messages in thread
From: Jeff Layton @ 2010-05-06 11:47 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: jack, linux-fsdevel

On Wed, 05 May 2010 06:39:38 -0400
Christoph Hellwig <hch@infradead.org> wrote:

> CIFS has stubs for XFS-style quotas without an actual implementation backing
> them, hidden behind a config option not visible in Kconfig.  Remove these
> stubs for now as the quota operations will see some major changes and this
> code simply gets in the way.
> 
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> 

Looks good to me.

Reviewed-by: Jeff Layton <jlayton@samba.org>

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

* [PATCH 2/3 v2] quota: unify ->get_dqblk
  2010-05-05 10:39 ` [PATCH 2/3] quota: unify ->get_dqblk Christoph Hellwig
  2010-05-05 13:52   ` Steven Whitehouse
  2010-05-05 16:00   ` Jan Kara
@ 2010-05-06 21:04   ` Christoph Hellwig
  2 siblings, 0 replies; 17+ messages in thread
From: Christoph Hellwig @ 2010-05-06 21:04 UTC (permalink / raw)
  To: jack; +Cc: linux-fsdevel

Pass the larger struct fs_disk_quota to the ->get_dqblk operation so
that the Q_GETQUOTA and Q_XGETQUOTA operations can be implemented
with a single filesystem operation and we can retire the ->get_xquota
operation.  The additional information (RT-subvolume accounting and
warn counts) are left zero for the VFS quota implementation.

Signed-off-by: Christoph Hellwig <hch@lst.de>

Index: linux-2.6/fs/quota/quota.c
===================================================================
--- linux-2.6.orig/fs/quota/quota.c	2010-05-05 18:17:42.442255839 +0200
+++ linux-2.6/fs/quota/quota.c	2010-05-05 18:17:44.577003220 +0200
@@ -136,19 +136,32 @@ static int quota_setinfo(struct super_bl
 	return sb->s_qcop->set_info(sb, type, &info);
 }
 
+static void copy_to_if_dqblk(struct if_dqblk *dst, struct fs_disk_quota *src)
+{
+	dst->dqb_bhardlimit = src->d_blk_hardlimit;
+	dst->dqb_bsoftlimit = src->d_blk_softlimit;
+	dst->dqb_curspace = src->d_bcount;
+	dst->dqb_ihardlimit = src->d_ino_hardlimit;
+	dst->dqb_isoftlimit = src->d_ino_softlimit;
+	dst->dqb_curinodes = src->d_icount;
+	dst->dqb_btime = src->d_btimer;
+	dst->dqb_itime = src->d_itimer;
+	dst->dqb_valid = QIF_ALL;
+}
+
 static int quota_getquota(struct super_block *sb, int type, qid_t id,
 			  void __user *addr)
 {
+	struct fs_disk_quota fdq;
 	struct if_dqblk idq;
 	int ret;
 
-	if (!sb_has_quota_active(sb, type))
-		return -ESRCH;
 	if (!sb->s_qcop->get_dqblk)
 		return -ENOSYS;
-	ret = sb->s_qcop->get_dqblk(sb, type, id, &idq);
+	ret = sb->s_qcop->get_dqblk(sb, type, id, &fdq);
 	if (ret)
 		return ret;
+	copy_to_if_dqblk(&idq, &fdq);
 	if (copy_to_user(addr, &idq, sizeof(idq)))
 		return -EFAULT;
 	return 0;
@@ -210,9 +223,9 @@ static int quota_getxquota(struct super_
 	struct fs_disk_quota fdq;
 	int ret;
 
-	if (!sb->s_qcop->get_xquota)
+	if (!sb->s_qcop->get_dqblk)
 		return -ENOSYS;
-	ret = sb->s_qcop->get_xquota(sb, type, id, &fdq);
+	ret = sb->s_qcop->get_dqblk(sb, type, id, &fdq);
 	if (!ret && copy_to_user(addr, &fdq, sizeof(fdq)))
 		return -EFAULT;
 	return ret;
Index: linux-2.6/fs/gfs2/quota.c
===================================================================
--- linux-2.6.orig/fs/gfs2/quota.c	2010-05-05 18:17:42.457254162 +0200
+++ linux-2.6/fs/gfs2/quota.c	2010-05-05 18:17:44.578004058 +0200
@@ -1432,8 +1432,8 @@ static int gfs2_quota_get_xstate(struct
 	return 0;
 }
 
-static int gfs2_xquota_get(struct super_block *sb, int type, qid_t id,
-			   struct fs_disk_quota *fdq)
+static int gfs2_get_dqblk(struct super_block *sb, int type, qid_t id,
+			  struct fs_disk_quota *fdq)
 {
 	struct gfs2_sbd *sdp = sb->s_fs_info;
 	struct gfs2_quota_lvb *qlvb;
@@ -1585,7 +1585,7 @@ out_put:
 const struct quotactl_ops gfs2_quotactl_ops = {
 	.quota_sync     = gfs2_quota_sync,
 	.get_xstate     = gfs2_quota_get_xstate,
-	.get_xquota	= gfs2_xquota_get,
+	.get_dqblk	= gfs2_get_dqblk,
 	.set_xquota	= gfs2_xquota_set,
 };
 
Index: linux-2.6/fs/xfs/linux-2.6/xfs_quotaops.c
===================================================================
--- linux-2.6.orig/fs/xfs/linux-2.6/xfs_quotaops.c	2010-05-05 18:17:42.466273718 +0200
+++ linux-2.6/fs/xfs/linux-2.6/xfs_quotaops.c	2010-05-05 18:17:44.580043938 +0200
@@ -97,7 +97,7 @@ xfs_fs_set_xstate(
 }
 
 STATIC int
-xfs_fs_get_xquota(
+xfs_fs_get_dqblk(
 	struct super_block	*sb,
 	int			type,
 	qid_t			id,
@@ -135,6 +135,6 @@ xfs_fs_set_xquota(
 const struct quotactl_ops xfs_quotactl_operations = {
 	.get_xstate		= xfs_fs_get_xstate,
 	.set_xstate		= xfs_fs_set_xstate,
-	.get_xquota		= xfs_fs_get_xquota,
+	.get_dqblk		= xfs_fs_get_dqblk,
 	.set_xquota		= xfs_fs_set_xquota,
 };
Index: linux-2.6/include/linux/quotaops.h
===================================================================
--- linux-2.6.orig/include/linux/quotaops.h	2010-05-05 18:17:42.473272461 +0200
+++ linux-2.6/include/linux/quotaops.h	2010-05-05 18:17:44.584043309 +0200
@@ -63,7 +63,8 @@ int vfs_quota_disable(struct super_block
 int vfs_quota_sync(struct super_block *sb, int type, int wait);
 int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
 int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
-int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di);
+int vfs_get_dqblk(struct super_block *sb, int type, qid_t id,
+		struct fs_disk_quota *di);
 int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di);
 
 int dquot_transfer(struct inode *inode, struct iattr *iattr);
Index: linux-2.6/include/linux/quota.h
===================================================================
--- linux-2.6.orig/include/linux/quota.h	2010-05-05 18:17:42.482253534 +0200
+++ linux-2.6/include/linux/quota.h	2010-05-05 18:17:44.587033671 +0200
@@ -311,11 +311,10 @@ struct quotactl_ops {
 	int (*quota_sync)(struct super_block *, int, int);
 	int (*get_info)(struct super_block *, int, struct if_dqinfo *);
 	int (*set_info)(struct super_block *, int, struct if_dqinfo *);
-	int (*get_dqblk)(struct super_block *, int, qid_t, struct if_dqblk *);
+	int (*get_dqblk)(struct super_block *, int, qid_t, struct fs_disk_quota *);
 	int (*set_dqblk)(struct super_block *, int, qid_t, struct if_dqblk *);
 	int (*get_xstate)(struct super_block *, struct fs_quota_stat *);
 	int (*set_xstate)(struct super_block *, unsigned int, int);
-	int (*get_xquota)(struct super_block *, int, qid_t, struct fs_disk_quota *);
 	int (*set_xquota)(struct super_block *, int, qid_t, struct fs_disk_quota *);
 };
 
Index: linux-2.6/fs/quota/dquot.c
===================================================================
--- linux-2.6.orig/fs/quota/dquot.c	2010-05-05 18:17:42.450254093 +0200
+++ linux-2.6/fs/quota/dquot.c	2010-05-05 18:18:24.635255699 +0200
@@ -2286,25 +2286,30 @@ static inline qsize_t stoqb(qsize_t spac
 }
 
 /* Generic routine for getting common part of quota structure */
-static void do_get_dqblk(struct dquot *dquot, struct if_dqblk *di)
+static void do_get_dqblk(struct dquot *dquot, struct fs_disk_quota *di)
 {
 	struct mem_dqblk *dm = &dquot->dq_dqb;
 
+	memset(di, 0, sizeof(*di));
+	di->d_version = FS_DQUOT_VERSION;
+	di->d_flags = dquot->dq_type == USRQUOTA ?
+			XFS_USER_QUOTA : XFS_GROUP_QUOTA;
+	di->d_id = dquot->dq_id;
+
 	spin_lock(&dq_data_lock);
-	di->dqb_bhardlimit = stoqb(dm->dqb_bhardlimit);
-	di->dqb_bsoftlimit = stoqb(dm->dqb_bsoftlimit);
-	di->dqb_curspace = dm->dqb_curspace + dm->dqb_rsvspace;
-	di->dqb_ihardlimit = dm->dqb_ihardlimit;
-	di->dqb_isoftlimit = dm->dqb_isoftlimit;
-	di->dqb_curinodes = dm->dqb_curinodes;
-	di->dqb_btime = dm->dqb_btime;
-	di->dqb_itime = dm->dqb_itime;
-	di->dqb_valid = QIF_ALL;
+	di->d_blk_hardlimit = stoqb(dm->dqb_bhardlimit);
+	di->d_blk_softlimit = stoqb(dm->dqb_bsoftlimit);
+	di->d_ino_hardlimit = dm->dqb_ihardlimit;
+	di->d_ino_softlimit = dm->dqb_isoftlimit;
+	di->d_bcount = dm->dqb_curspace + dm->dqb_rsvspace;
+	di->d_icount = dm->dqb_curinodes;
+	di->d_btimer = dm->dqb_btime;
+	di->d_itimer = dm->dqb_itime;
 	spin_unlock(&dq_data_lock);
 }
 
 int vfs_get_dqblk(struct super_block *sb, int type, qid_t id,
-		  struct if_dqblk *di)
+		  struct fs_disk_quota *di)
 {
 	struct dquot *dquot;
 

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

* [PATCH 3/3 v2] quota: unify ->set_dqblk
  2010-05-05 10:39 ` [PATCH 3/3] quota: unify ->set_dqblk Christoph Hellwig
  2010-05-05 16:09   ` Jan Kara
@ 2010-05-06 21:05   ` Christoph Hellwig
  1 sibling, 0 replies; 17+ messages in thread
From: Christoph Hellwig @ 2010-05-06 21:05 UTC (permalink / raw)
  To: jack; +Cc: linux-fsdevel

Pass the larger struct fs_disk_quota to the ->set_dqblk operation so
that the Q_SETQUOTA and Q_XSETQUOTA operations can be implemented
with a single filesystem operation and we can retire the ->set_xquota
operation.  The additional information (RT-subvolume accounting and
warn counts) are left zero for the VFS quota implementation.

Add new fieldmask values for setting the numer of blocks and inodes
values which is required for the VFS quota, but wasn't for XFS.

Signed-off-by: Christoph Hellwig <hch@lst.de>


Index: linux-2.6/fs/gfs2/quota.c
===================================================================
--- linux-2.6.orig/fs/gfs2/quota.c	2010-05-05 18:17:44.578004058 +0200
+++ linux-2.6/fs/gfs2/quota.c	2010-05-05 18:18:27.745003988 +0200
@@ -1477,8 +1477,8 @@ out:
 /* GFS2 only supports a subset of the XFS fields */
 #define GFS2_FIELDMASK (FS_DQ_BSOFT|FS_DQ_BHARD)
 
-static int gfs2_xquota_set(struct super_block *sb, int type, qid_t id,
-			   struct fs_disk_quota *fdq)
+static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id,
+			  struct fs_disk_quota *fdq)
 {
 	struct gfs2_sbd *sdp = sb->s_fs_info;
 	struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode);
@@ -1586,6 +1586,6 @@ const struct quotactl_ops gfs2_quotactl_
 	.quota_sync     = gfs2_quota_sync,
 	.get_xstate     = gfs2_quota_get_xstate,
 	.get_dqblk	= gfs2_get_dqblk,
-	.set_xquota	= gfs2_xquota_set,
+	.set_dqblk	= gfs2_set_dqblk,
 };
 
Index: linux-2.6/fs/quota/quota.c
===================================================================
--- linux-2.6.orig/fs/quota/quota.c	2010-05-05 18:17:44.577003220 +0200
+++ linux-2.6/fs/quota/quota.c	2010-05-05 18:18:27.745003988 +0200
@@ -167,18 +167,44 @@ static int quota_getquota(struct super_b
 	return 0;
 }
 
+static void copy_from_if_dqblk(struct fs_disk_quota *dst, struct if_dqblk *src)
+{
+	dst->d_blk_hardlimit = src->dqb_bhardlimit;
+	dst->d_blk_softlimit  = src->dqb_bsoftlimit;
+	dst->d_bcount = src->dqb_curspace;
+	dst->d_ino_hardlimit = src->dqb_ihardlimit;
+	dst->d_ino_softlimit = src->dqb_isoftlimit;
+	dst->d_icount = src->dqb_curinodes;
+	dst->d_btimer = src->dqb_btime;
+	dst->d_itimer = src->dqb_itime;
+
+	dst->d_fieldmask = 0;
+	if (src->dqb_valid & QIF_BLIMITS)
+		dst->d_fieldmask |= FS_DQ_BSOFT | FS_DQ_BHARD;
+	if (src->dqb_valid & QIF_SPACE)
+		dst->d_fieldmask |= FS_DQ_BCOUNT;
+	if (src->dqb_valid & QIF_ILIMITS)
+		dst->d_fieldmask |= FS_DQ_ISOFT | FS_DQ_IHARD;
+	if (src->dqb_valid & QIF_INODES)
+		dst->d_fieldmask |= FS_DQ_ICOUNT;
+	if (src->dqb_valid & QIF_BTIME)
+		dst->d_fieldmask |= FS_DQ_BTIMER;
+	if (src->dqb_valid & QIF_ITIME)
+		dst->d_fieldmask |= FS_DQ_ITIMER;
+}
+
 static int quota_setquota(struct super_block *sb, int type, qid_t id,
 			  void __user *addr)
 {
+	struct fs_disk_quota fdq;
 	struct if_dqblk idq;
 
 	if (copy_from_user(&idq, addr, sizeof(idq)))
 		return -EFAULT;
-	if (!sb_has_quota_active(sb, type))
-		return -ESRCH;
 	if (!sb->s_qcop->set_dqblk)
 		return -ENOSYS;
-	return sb->s_qcop->set_dqblk(sb, type, id, &idq);
+	copy_from_if_dqblk(&fdq, &idq);
+	return sb->s_qcop->set_dqblk(sb, type, id, &fdq);
 }
 
 static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr)
@@ -212,9 +238,9 @@ static int quota_setxquota(struct super_
 
 	if (copy_from_user(&fdq, addr, sizeof(fdq)))
 		return -EFAULT;
-	if (!sb->s_qcop->set_xquota)
+	if (!sb->s_qcop->set_dqblk)
 		return -ENOSYS;
-	return sb->s_qcop->set_xquota(sb, type, id, &fdq);
+	return sb->s_qcop->set_dqblk(sb, type, id, &fdq);
 }
 
 static int quota_getxquota(struct super_block *sb, int type, qid_t id,
Index: linux-2.6/fs/xfs/linux-2.6/xfs_quotaops.c
===================================================================
--- linux-2.6.orig/fs/xfs/linux-2.6/xfs_quotaops.c	2010-05-05 18:17:44.580043938 +0200
+++ linux-2.6/fs/xfs/linux-2.6/xfs_quotaops.c	2010-05-05 18:18:27.751024102 +0200
@@ -114,7 +114,7 @@ xfs_fs_get_dqblk(
 }
 
 STATIC int
-xfs_fs_set_xquota(
+xfs_fs_set_dqblk(
 	struct super_block	*sb,
 	int			type,
 	qid_t			id,
@@ -136,5 +136,5 @@ const struct quotactl_ops xfs_quotactl_o
 	.get_xstate		= xfs_fs_get_xstate,
 	.set_xstate		= xfs_fs_set_xstate,
 	.get_dqblk		= xfs_fs_get_dqblk,
-	.set_xquota		= xfs_fs_set_xquota,
+	.set_dqblk		= xfs_fs_set_dqblk,
 };
Index: linux-2.6/include/linux/quota.h
===================================================================
--- linux-2.6.orig/include/linux/quota.h	2010-05-05 18:17:44.587033671 +0200
+++ linux-2.6/include/linux/quota.h	2010-05-05 18:18:27.758006223 +0200
@@ -312,10 +312,9 @@ struct quotactl_ops {
 	int (*get_info)(struct super_block *, int, struct if_dqinfo *);
 	int (*set_info)(struct super_block *, int, struct if_dqinfo *);
 	int (*get_dqblk)(struct super_block *, int, qid_t, struct fs_disk_quota *);
-	int (*set_dqblk)(struct super_block *, int, qid_t, struct if_dqblk *);
+	int (*set_dqblk)(struct super_block *, int, qid_t, struct fs_disk_quota *);
 	int (*get_xstate)(struct super_block *, struct fs_quota_stat *);
 	int (*set_xstate)(struct super_block *, unsigned int, int);
-	int (*set_xquota)(struct super_block *, int, qid_t, struct fs_disk_quota *);
 };
 
 struct quota_format_type {
Index: linux-2.6/include/linux/quotaops.h
===================================================================
--- linux-2.6.orig/include/linux/quotaops.h	2010-05-05 18:17:44.584043309 +0200
+++ linux-2.6/include/linux/quotaops.h	2010-05-05 18:18:27.765005664 +0200
@@ -65,7 +65,8 @@ int vfs_get_dqinfo(struct super_block *s
 int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
 int vfs_get_dqblk(struct super_block *sb, int type, qid_t id,
 		struct fs_disk_quota *di);
-int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di);
+int vfs_set_dqblk(struct super_block *sb, int type, qid_t id,
+		struct fs_disk_quota *di);
 
 int dquot_transfer(struct inode *inode, struct iattr *iattr);
 int vfs_dq_quota_on_remount(struct super_block *sb);
Index: linux-2.6/fs/xfs/quota/xfs_qm_syscalls.c
===================================================================
--- linux-2.6.orig/fs/xfs/quota/xfs_qm_syscalls.c	2010-05-05 18:17:41.832011251 +0200
+++ linux-2.6/fs/xfs/quota/xfs_qm_syscalls.c	2010-05-05 18:18:27.772005315 +0200
@@ -452,6 +452,9 @@ xfs_qm_scall_getqstat(
 	return (0);
 }
 
+#define XFS_DQ_MASK \
+	(FS_DQ_LIMIT_MASK | FS_DQ_TIMER_MASK | FS_DQ_WARNS_MASK)
+
 /*
  * Adjust quota limits, and start/stop timers accordingly.
  */
@@ -468,9 +471,10 @@ xfs_qm_scall_setqlim(
 	int			error;
 	xfs_qcnt_t		hard, soft;
 
-	if ((newlim->d_fieldmask &
-	    (FS_DQ_LIMIT_MASK|FS_DQ_TIMER_MASK|FS_DQ_WARNS_MASK)) == 0)
-		return (0);
+	if (newlim->d_fieldmask & ~XFS_DQ_MASK)
+		return EINVAL;
+	if ((newlim->d_fieldmask & XFS_DQ_MASK) == 0)
+		return 0;
 
 	tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SETQLIM);
 	if ((error = xfs_trans_reserve(tp, 0, sizeof(xfs_disk_dquot_t) + 128,
Index: linux-2.6/include/linux/dqblk_xfs.h
===================================================================
--- linux-2.6.orig/include/linux/dqblk_xfs.h	2010-05-05 18:17:41.858004546 +0200
+++ linux-2.6/include/linux/dqblk_xfs.h	2010-05-05 18:18:27.777068033 +0200
@@ -110,6 +110,15 @@ typedef struct fs_disk_quota {
 #define FS_DQ_WARNS_MASK	(FS_DQ_BWARNS | FS_DQ_IWARNS | FS_DQ_RTBWARNS)
 
 /*
+ * Accounting values.  These can only be set for filesystem with
+ * non-transactional quotas that require quotacheck(8) in userspace.
+ */
+#define FS_DQ_BCOUNT		(1<<12)
+#define FS_DQ_ICOUNT		(1<<13)
+#define FS_DQ_RTBCOUNT		(1<<14)
+#define FS_DQ_ACCT_MASK		(FS_DQ_BCOUNT | FS_DQ_ICOUNT | FS_DQ_RTBCOUNT)
+
+/*
  * Various flags related to quotactl(2).  Only relevant to XFS filesystems.
  */
 #define XFS_QUOTA_UDQ_ACCT	(1<<0)  /* user quota accounting */
Index: linux-2.6/fs/quota/dquot.c
===================================================================
--- linux-2.6.orig/fs/quota/dquot.c	2010-05-05 18:18:24.635255699 +0200
+++ linux-2.6/fs/quota/dquot.c	2010-05-05 18:18:41.365005456 +0200
@@ -2323,51 +2323,70 @@ int vfs_get_dqblk(struct super_block *sb
 }
 EXPORT_SYMBOL(vfs_get_dqblk);
 
+#define VFS_FS_DQ_MASK \
+	(FS_DQ_BCOUNT | FS_DQ_BSOFT | FS_DQ_BHARD | \
+	 FS_DQ_ICOUNT | FS_DQ_ISOFT | FS_DQ_IHARD | \
+	 FS_DQ_BTIMER | FS_DQ_ITIMER)
+
 /* Generic routine for setting common part of quota structure */
-static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di)
+static int do_set_dqblk(struct dquot *dquot, struct fs_disk_quota *di)
 {
 	struct mem_dqblk *dm = &dquot->dq_dqb;
 	int check_blim = 0, check_ilim = 0;
 	struct mem_dqinfo *dqi = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type];
 
-	if ((di->dqb_valid & QIF_BLIMITS &&
-	     (di->dqb_bhardlimit > dqi->dqi_maxblimit ||
-	      di->dqb_bsoftlimit > dqi->dqi_maxblimit)) ||
-	    (di->dqb_valid & QIF_ILIMITS &&
-	     (di->dqb_ihardlimit > dqi->dqi_maxilimit ||
-	      di->dqb_isoftlimit > dqi->dqi_maxilimit)))
+	if (di->d_fieldmask & ~VFS_FS_DQ_MASK)
+		return -EINVAL;
+
+	if (((di->d_fieldmask & FS_DQ_BSOFT) &&
+	     (di->d_blk_softlimit > dqi->dqi_maxblimit)) ||
+	    ((di->d_fieldmask & FS_DQ_BHARD) &&
+	     (di->d_blk_hardlimit > dqi->dqi_maxblimit)) ||
+	    ((di->d_fieldmask & FS_DQ_ISOFT) &&
+	     (di->d_ino_softlimit > dqi->dqi_maxilimit)) ||
+	    ((di->d_fieldmask & FS_DQ_IHARD) &&
+	     (di->d_ino_hardlimit > dqi->dqi_maxilimit)))
 		return -ERANGE;
 
 	spin_lock(&dq_data_lock);
-	if (di->dqb_valid & QIF_SPACE) {
-		dm->dqb_curspace = di->dqb_curspace - dm->dqb_rsvspace;
+	if (di->d_fieldmask & FS_DQ_BCOUNT) {
+		dm->dqb_curspace = di->d_bcount - dm->dqb_rsvspace;
 		check_blim = 1;
 		set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags);
 	}
-	if (di->dqb_valid & QIF_BLIMITS) {
-		dm->dqb_bsoftlimit = qbtos(di->dqb_bsoftlimit);
-		dm->dqb_bhardlimit = qbtos(di->dqb_bhardlimit);
+
+	if (di->d_fieldmask & FS_DQ_BSOFT)
+		dm->dqb_bsoftlimit = qbtos(di->d_blk_softlimit);
+	if (di->d_fieldmask & FS_DQ_BHARD)
+		dm->dqb_bhardlimit = qbtos(di->d_blk_hardlimit);
+	if (di->d_fieldmask & (FS_DQ_BSOFT | FS_DQ_BHARD)) {
 		check_blim = 1;
 		set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags);
 	}
-	if (di->dqb_valid & QIF_INODES) {
-		dm->dqb_curinodes = di->dqb_curinodes;
+
+	if (di->d_fieldmask & FS_DQ_ICOUNT) {
+		dm->dqb_curinodes = di->d_icount;
 		check_ilim = 1;
 		set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags);
 	}
-	if (di->dqb_valid & QIF_ILIMITS) {
-		dm->dqb_isoftlimit = di->dqb_isoftlimit;
-		dm->dqb_ihardlimit = di->dqb_ihardlimit;
+
+	if (di->d_fieldmask & FS_DQ_ISOFT)
+		dm->dqb_isoftlimit = di->d_ino_softlimit;
+	if (di->d_fieldmask & FS_DQ_IHARD)
+		dm->dqb_ihardlimit = di->d_ino_hardlimit;
+	if (di->d_fieldmask & (FS_DQ_ISOFT | FS_DQ_IHARD)) {
 		check_ilim = 1;
 		set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags);
 	}
-	if (di->dqb_valid & QIF_BTIME) {
-		dm->dqb_btime = di->dqb_btime;
+
+	if (di->d_fieldmask & FS_DQ_BTIMER) {
+		dm->dqb_btime = di->d_btimer;
 		check_blim = 1;
 		set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags);
 	}
-	if (di->dqb_valid & QIF_ITIME) {
-		dm->dqb_itime = di->dqb_itime;
+
+	if (di->d_fieldmask & FS_DQ_ITIMER) {
+		dm->dqb_itime = di->d_itimer;
 		check_ilim = 1;
 		set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags);
 	}
@@ -2377,7 +2396,7 @@ static int do_set_dqblk(struct dquot *dq
 		    dm->dqb_curspace < dm->dqb_bsoftlimit) {
 			dm->dqb_btime = 0;
 			clear_bit(DQ_BLKS_B, &dquot->dq_flags);
-		} else if (!(di->dqb_valid & QIF_BTIME))
+		} else if (!(di->d_fieldmask & FS_DQ_BTIMER))
 			/* Set grace only if user hasn't provided his own... */
 			dm->dqb_btime = get_seconds() + dqi->dqi_bgrace;
 	}
@@ -2386,7 +2405,7 @@ static int do_set_dqblk(struct dquot *dq
 		    dm->dqb_curinodes < dm->dqb_isoftlimit) {
 			dm->dqb_itime = 0;
 			clear_bit(DQ_INODES_B, &dquot->dq_flags);
-		} else if (!(di->dqb_valid & QIF_ITIME))
+		} else if (!(di->d_fieldmask & FS_DQ_ITIMER))
 			/* Set grace only if user hasn't provided his own... */
 			dm->dqb_itime = get_seconds() + dqi->dqi_igrace;
 	}
@@ -2402,7 +2421,7 @@ static int do_set_dqblk(struct dquot *dq
 }
 
 int vfs_set_dqblk(struct super_block *sb, int type, qid_t id,
-		  struct if_dqblk *di)
+		  struct fs_disk_quota *di)
 {
 	struct dquot *dquot;
 	int rc;

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

* [PATCH 4/3] quota: remove sb_has_quota_active in get/set_info
  2010-05-05 10:39 [PATCH 0/3] start the quota unification Christoph Hellwig
                   ` (2 preceding siblings ...)
  2010-05-05 10:39 ` [PATCH 3/3] quota: unify ->set_dqblk Christoph Hellwig
@ 2010-05-07 16:35 ` Christoph Hellwig
  2010-05-11  8:33   ` Jan Kara
  3 siblings, 1 reply; 17+ messages in thread
From: Christoph Hellwig @ 2010-05-07 16:35 UTC (permalink / raw)
  To: jack; +Cc: linux-fsdevel

The methods already do these checks, so remove them in the quotactl
implementation to allow non-VFS quota implementations to also support
these calls.

Signed-off-by: Christoph Hellwig <hch@lst.de>

Index: linux-2.6/fs/quota/quota.c
===================================================================
--- linux-2.6.orig/fs/quota/quota.c	2010-05-07 18:28:26.438025430 +0200
+++ linux-2.6/fs/quota/quota.c	2010-05-07 18:30:30.919283361 +0200
@@ -113,8 +113,6 @@ static int quota_getinfo(struct super_bl
 	struct if_dqinfo info;
 	int ret;
 
-	if (!sb_has_quota_active(sb, type))
-		return -ESRCH;
 	if (!sb->s_qcop->get_info)
 		return -ENOSYS;
 	ret = sb->s_qcop->get_info(sb, type, &info);
@@ -129,8 +127,6 @@ static int quota_setinfo(struct super_bl
 
 	if (copy_from_user(&info, addr, sizeof(info)))
 		return -EFAULT;
-	if (!sb_has_quota_active(sb, type))
-		return -ESRCH;
 	if (!sb->s_qcop->set_info)
 		return -ENOSYS;
 	return sb->s_qcop->set_info(sb, type, &info);

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

* Re: [PATCH 4/3] quota: remove sb_has_quota_active in get/set_info
  2010-05-07 16:35 ` [PATCH 4/3] quota: remove sb_has_quota_active in get/set_info Christoph Hellwig
@ 2010-05-11  8:33   ` Jan Kara
  0 siblings, 0 replies; 17+ messages in thread
From: Jan Kara @ 2010-05-11  8:33 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: jack, linux-fsdevel

On Fri 07-05-10 12:35:40, Christoph Hellwig wrote:
> The methods already do these checks, so remove them in the quotactl
> implementation to allow non-VFS quota implementations to also support
> these calls.
  I've merged all four patches into my tree.

								Honza
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> 
> Index: linux-2.6/fs/quota/quota.c
> ===================================================================
> --- linux-2.6.orig/fs/quota/quota.c	2010-05-07 18:28:26.438025430 +0200
> +++ linux-2.6/fs/quota/quota.c	2010-05-07 18:30:30.919283361 +0200
> @@ -113,8 +113,6 @@ static int quota_getinfo(struct super_bl
>  	struct if_dqinfo info;
>  	int ret;
>  
> -	if (!sb_has_quota_active(sb, type))
> -		return -ESRCH;
>  	if (!sb->s_qcop->get_info)
>  		return -ENOSYS;
>  	ret = sb->s_qcop->get_info(sb, type, &info);
> @@ -129,8 +127,6 @@ static int quota_setinfo(struct super_bl
>  
>  	if (copy_from_user(&info, addr, sizeof(info)))
>  		return -EFAULT;
> -	if (!sb_has_quota_active(sb, type))
> -		return -ESRCH;
>  	if (!sb->s_qcop->set_info)
>  		return -ENOSYS;
>  	return sb->s_qcop->set_info(sb, type, &info);
-- 
Jan Kara <jack@suse.cz>
SUSE Labs, CR

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

end of thread, other threads:[~2010-05-11  8:33 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-05-05 10:39 [PATCH 0/3] start the quota unification Christoph Hellwig
2010-05-05 10:39 ` [PATCH 1/3] cifs: drop quota operation stubs Christoph Hellwig
2010-05-05 15:34   ` Jan Kara
2010-05-05 18:57     ` Steve French
2010-05-06 11:47   ` Jeff Layton
2010-05-05 10:39 ` [PATCH 2/3] quota: unify ->get_dqblk Christoph Hellwig
2010-05-05 13:52   ` Steven Whitehouse
2010-05-05 16:18     ` Christoph Hellwig
2010-05-05 16:00   ` Jan Kara
2010-05-05 16:20     ` Christoph Hellwig
2010-05-06 21:04   ` [PATCH 2/3 v2] " Christoph Hellwig
2010-05-05 10:39 ` [PATCH 3/3] quota: unify ->set_dqblk Christoph Hellwig
2010-05-05 16:09   ` Jan Kara
2010-05-05 16:21     ` Christoph Hellwig
2010-05-06 21:05   ` [PATCH 3/3 v2] " Christoph Hellwig
2010-05-07 16:35 ` [PATCH 4/3] quota: remove sb_has_quota_active in get/set_info Christoph Hellwig
2010-05-11  8:33   ` Jan Kara

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.