From patchwork Fri Jan 8 18:36:27 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Sandeen X-Patchwork-Id: 7989121 Return-Path: X-Original-To: patchwork-linux-fsdevel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 83AFABEEE5 for ; Fri, 8 Jan 2016 18:36:36 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6FA5D201C0 for ; Fri, 8 Jan 2016 18:36:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3BAD52014A for ; Fri, 8 Jan 2016 18:36:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932698AbcAHSgb (ORCPT ); Fri, 8 Jan 2016 13:36:31 -0500 Received: from sandeen.net ([63.231.237.45]:55943 "EHLO sandeen.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932634AbcAHSg3 (ORCPT ); Fri, 8 Jan 2016 13:36:29 -0500 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 6C4E361AC509; Fri, 8 Jan 2016 12:36:28 -0600 (CST) Subject: [PATCH] linux-quota: wire Q_XGETQUOTA2 into generic repquota To: fsdevel , xfs@oss.sgi.com References: <568FEA2C.6080708@redhat.com> Cc: Jan Kara From: Eric Sandeen Message-ID: <569001AB.5040604@sandeen.net> Date: Fri, 8 Jan 2016 12:36:27 -0600 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.5.0 MIME-Version: 1.0 In-Reply-To: <568FEA2C.6080708@redhat.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Here's a patch to hook Q_XGETQUOTA2 into the generic quota tools repquota command. Rather than looping over getpwent(), it increments the id sent into the quotactl until it gets back ESRCH. If Q_XGETQUOTA2 doesn't exist it falls back to the old method. Signed-off-by: Eric Sandeen --- -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/dqblk_xfs.h b/dqblk_xfs.h index 415e646..6c7693d 100644 --- a/dqblk_xfs.h +++ b/dqblk_xfs.h @@ -10,6 +10,7 @@ #define Q_XFS_QUOTAON Q_XQUOTAON #define Q_XFS_QUOTAOFF Q_XQUOTAOFF #define Q_XFS_GETQUOTA Q_XGETQUOTA +#define Q_XFS_GETQUOTA2 Q_XGETQUOTA2 #define Q_XFS_SETQLIM Q_XSETQLIM #define Q_XFS_GETQSTAT Q_XGETQSTAT #define Q_XFS_QUOTARM Q_XQUOTARM diff --git a/quotaio_generic.c b/quotaio_generic.c index 5001a56..ad84cc0 100644 --- a/quotaio_generic.c +++ b/quotaio_generic.c @@ -161,3 +161,52 @@ int generic_scan_dquots(struct quota_handle *h, free(dquot); return ret; } + +/* Generic quota scanning using Q_XGETQUOTA2... */ +int generic_scan_dquots2(struct quota_handle *h, + int (*process_dquot)(struct dquot *dquot, char *dqname), + int (*get_dquot)(struct dquot *dquot)) +{ + struct dquot *dquot = get_empty_dquot(); + char namebuf[MAXNAMELEN]; + int ret = 0; + + dquot->dq_id = 0; + dquot->dq_h = h; + if (h->qh_type == USRQUOTA) { + while (1) { + ret = scan_one_dquot(dquot, get_dquot); + if (ret < 0) { + if (errno == ESRCH) + ret =0; + break; + } + if (ret > 0) + continue; + id2name(dquot->dq_id, dquot->dq_h->qh_type, namebuf); + ret = process_dquot(dquot, namebuf); + if (ret < 0) + break; + dquot->dq_id++; + } + } else if (h->qh_type == GRPQUOTA) { + while (1) { + ret = scan_one_dquot(dquot, get_dquot); + if (ret < 0) { + if (errno == ESRCH) + ret =0; + break; + } + if (ret > 0) + continue; + id2name(dquot->dq_id, dquot->dq_h->qh_type, namebuf); + ret = process_dquot(dquot, namebuf); + if (ret < 0) + break; + dquot->dq_id++; + } + } + free(dquot); + return ret; +} + diff --git a/quotaio_generic.h b/quotaio_generic.h index 5edc11c..099a6b1 100644 --- a/quotaio_generic.h +++ b/quotaio_generic.h @@ -26,5 +26,9 @@ int vfs_set_dquot(struct dquot *dquot, int flags); int generic_scan_dquots(struct quota_handle *h, int (*process_dquot)(struct dquot *dquot, char *dqname), int (*get_dquot)(struct dquot *dquot)); +/* Generic routine for scanning dquots when kernel can do the scanning */ +int generic_scan_dquots2(struct quota_handle *h, + int (*process_dquot)(struct dquot *dquot, char *dqname), + int (*get_dquot)(struct dquot *dquot)); #endif diff --git a/quotaio_xfs.c b/quotaio_xfs.c index 903c03e..a3f516b 100644 --- a/quotaio_xfs.c +++ b/quotaio_xfs.c @@ -192,14 +192,42 @@ static int xfs_get_dquot(struct dquot *dq) } /* + * xfs_scan_dquots helper - processes a single dquot with Q_XGETQUOTA2 + */ +static int xfs_get_dquot2(struct dquot *dq) +{ + struct xfs_kern_dqblk d; + int qcmd = QCMD(Q_XFS_GETQUOTA2, dq->dq_h->qh_type); + int ret; + + memset(&d, 0, sizeof(d)); + ret = quotactl(qcmd, dq->dq_h->qh_quotadev, dq->dq_id, (void *)&d); + if (ret < 0) { + if (errno == ENOENT) + return 0; + return -1; + } + dq->dq_id = d.d_id; + xfs_kern2utildqblk(&dq->dq_dqb, &d); + return 0; +} + +/* * Scan all known dquots and call callback on each */ static int xfs_scan_dquots(struct quota_handle *h, int (*process_dquot) (struct dquot *dquot, char *dqname)) { + int ret; + if (!XFS_USRQUOTA(h) && !XFS_GRPQUOTA(h)) return 0; - return generic_scan_dquots(h, process_dquot, xfs_get_dquot); + ret = generic_scan_dquots2(h, process_dquot, xfs_get_dquot2); + + if (ret) + ret = generic_scan_dquots(h, process_dquot, xfs_get_dquot); + + return ret; } /* diff --git a/quotaio_xfs.h b/quotaio_xfs.h index 54725b0..eabee3e 100644 --- a/quotaio_xfs.h +++ b/quotaio_xfs.h @@ -46,6 +46,7 @@ #define Q_XSETQLIM XQM_CMD(0x4) /* set disk limits only */ #define Q_XGETQSTAT XQM_CMD(0x5) /* returns fs_quota_stat_t struct */ #define Q_XQUOTARM XQM_CMD(0x6) /* free quota files' space */ +#define Q_XGETQUOTA2 XQM_CMD(0x9) /* get disk limits and usage >= ID */ /* * fs_disk_quota structure: