Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp1210619ybi; Fri, 21 Jun 2019 16:28:39 -0700 (PDT) X-Google-Smtp-Source: APXvYqyLw80njF1OtSLhRp1uT1qn7iqyH4iJ9OgfaPO5CLS7n5rIK6+YlsYHs3LQjOqruM7N0udq X-Received: by 2002:a65:534b:: with SMTP id w11mr21270416pgr.210.1561159718729; Fri, 21 Jun 2019 16:28:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1561159718; cv=none; d=google.com; s=arc-20160816; b=gDjTpJOnlPcL9tZpO8zBSqoZZBZFvVVL3pN38ozIvl76vn/M+zT9E2LktO2zqDFtX3 DNJfLWB9tISSQVZbagrhA8CWRlNrL3+wPz0HF2wapHGjYIAOgIcgx8P7gUugF9JXh6nJ 7pzhCiD138zR94w/gCliv/GNtxXjgsfsdSoBM1JTWs2jzKuRrwTSKiHB4eAC9VEaQIPn VKFdj/EFjoYZbcBxH9RCKZadb1XIidh4GWXDiLZ3gJz92jaTA3VI5XpCjDSOK446XGaX C+Vnfp8iOR1OUdFOjHTOmSN3v5dVBuQWF2g2ud9xzGV0Fk+pIKALGzc5bHhudUZex54/ 5onw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:mime-version:user-agent:date:message-id:cc:to :subject:from; bh=411nD8Syxd3Q5yW6cmvsfAFLac6LGgONSBGrcOrhJ2c=; b=HXbCHYStJ2H4Z7LNWsMc+RGvj9IAGSHTYf5lVt6/Ugijdyfy462w7OMcEYWxk99bDa dvUFfP21jyMpv7m9Rc+IsSam08yt6DU6kNAeW7v9/V9kL1+O4NYMVqx780XZWKR3YL9z pcw3jv8x8sbtAwCCab76+ou+X/ftNqyy1GpSDl+hSSIzQmODpQxB35Bim1dlYybUWlKv ZNz9tWhpF/7SEU36KCtSXHa9toTfOd92dBGcH2Wmz/y73xPsRg0SBUmi2w4CVnl8xUQN tkR7N1q7ZEMr2TpqPWVlxrFSdXBrRjA8kQeeSfcujgikXi9qdMNNqsZxUxxXjOpJnA22 iS1Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-ext4-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-ext4-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s187si3727730pgb.49.2019.06.21.16.28.17; Fri, 21 Jun 2019 16:28:38 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-ext4-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-ext4-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-ext4-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726067AbfFUX1P (ORCPT + 99 others); Fri, 21 Jun 2019 19:27:15 -0400 Received: from mx1.redhat.com ([209.132.183.28]:58784 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726049AbfFUX1P (ORCPT ); Fri, 21 Jun 2019 19:27:15 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7A2B8309174E; Fri, 21 Jun 2019 23:27:14 +0000 (UTC) Received: from [IPv6:::1] (ovpn04.gateway.prod.ext.phx2.redhat.com [10.5.9.4]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 0C8885C21A; Fri, 21 Jun 2019 23:27:13 +0000 (UTC) From: Eric Sandeen Subject: [PATCH] quota: honor quote type in Q_XGETQSTAT[V] calls To: fsdevel Cc: Jan Kara , linux-xfs , "linux-ext4@vger.kernel.org" , Bob Peterson Message-ID: <0b96d49c-3c0b-eb71-dd87-750a6a48f1ef@redhat.com> Date: Fri, 21 Jun 2019 18:27:13 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:60.0) Gecko/20100101 Thunderbird/60.7.1 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.41]); Fri, 21 Jun 2019 23:27:14 +0000 (UTC) Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org The code in quota_getstate and quota_getstatev is strange; it says the returned fs_quota_stat[v] structure has room for only one type of time limits, so fills it in with the first enabled quota, even though every quotactl command must have a type sent in by the user. Instead of just picking the first enabled quota, fill in the reply with the timers for the quota type that was actually requested. Signed-off-by: Eric Sandeen --- I guess this is a change in behavior, but it goes from a rather unexpected and unpredictable behavior to something more expected, so I hope it's ok. I'm working on breaking out xfs quota timers by type as well (they are separate on disk, but not in memory) so I'll work up an xfstest to go with this... diff --git a/fs/quota/quota.c b/fs/quota/quota.c index fd5dd806f1b9..cb13fb76dbee 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c @@ -331,9 +331,9 @@ static int quota_state_to_flags(struct qc_state *state) return flags; } -static int quota_getstate(struct super_block *sb, struct fs_quota_stat *fqs) +static int quota_getstate(struct super_block *sb, int type, + struct fs_quota_stat *fqs) { - int type; struct qc_state state; int ret; @@ -349,14 +349,7 @@ static int quota_getstate(struct super_block *sb, struct fs_quota_stat *fqs) 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 < MAXQUOTAS; type++) - if (state.s_state[type].flags & QCI_ACCT_ENABLED) - break; - BUG_ON(type == 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; @@ -391,22 +384,22 @@ static int quota_getstate(struct super_block *sb, struct fs_quota_stat *fqs) return 0; } -static int quota_getxstate(struct super_block *sb, void __user *addr) +static int quota_getxstate(struct super_block *sb, int type, void __user *addr) { struct fs_quota_stat fqs; int ret; if (!sb->s_qcop->get_state) return -ENOSYS; - ret = quota_getstate(sb, &fqs); + ret = quota_getstate(sb, type, &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) +static int quota_getstatev(struct super_block *sb, int type, + struct fs_quota_statv *fqs) { - int type; struct qc_state state; int ret; @@ -422,14 +415,7 @@ static int quota_getstatev(struct super_block *sb, struct fs_quota_statv *fqs) if (!fqs->qs_flags) return -ENOSYS; fqs->qs_incoredqs = state.s_incoredqs; - /* - * GETXSTATV quotactl has space for just one set of time limits so - * report them for the first enabled quota type - */ - for (type = 0; type < MAXQUOTAS; type++) - if (state.s_state[type].flags & QCI_ACCT_ENABLED) - break; - BUG_ON(type == 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; @@ -455,7 +441,7 @@ static int quota_getstatev(struct super_block *sb, struct fs_quota_statv *fqs) return 0; } -static int quota_getxstatev(struct super_block *sb, void __user *addr) +static int quota_getxstatev(struct super_block *sb, int type, void __user *addr) { struct fs_quota_statv fqs; int ret; @@ -474,7 +460,7 @@ static int quota_getxstatev(struct super_block *sb, void __user *addr) default: return -EINVAL; } - ret = quota_getstatev(sb, &fqs); + ret = quota_getstatev(sb, type, &fqs); if (!ret && copy_to_user(addr, &fqs, sizeof(fqs))) return -EFAULT; return ret; @@ -744,9 +730,9 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, case Q_XQUOTARM: return quota_rmxquota(sb, addr); case Q_XGETQSTAT: - return quota_getxstate(sb, addr); + return quota_getxstate(sb, type, addr); case Q_XGETQSTATV: - return quota_getxstatev(sb, addr); + return quota_getxstatev(sb, type, addr); case Q_XSETQLIM: return quota_setxquota(sb, type, id, addr); case Q_XGETQUOTA: