<!-- 
RSS generated by JIRA (9.4.14#940014-sha1:734e6822bbf0d45eff9af51f82432957f73aa32c) at Sat Feb 10 02:27:13 UTC 2024

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary append 'field=key&field=summary' to the URL of your request.
-->
<rss version="0.92" >
<channel>
    <title>Whamcloud Community JIRA</title>
    <link>https://jira.whamcloud.com</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>9.4.14</version>
        <build-number>940014</build-number>
        <build-date>05-12-2023</build-date>
    </build-info>


<item>
            <title>[LU-9555] &quot;df /path/to/project&quot; should return projid-specific values</title>
                <link>https://jira.whamcloud.com/browse/LU-9555</link>
                <project id="10000" key="LU">Lustre</project>
                    <description>&lt;p&gt;With local ext4 and XFS filesystems, it is possible to use &quot;df /path/to/directory&quot; to return the current quota usage for the projid associated with that directory as &quot;used&quot;, and min(projid quota limit, free space) as &quot;total&quot;. This is a natural interface for users/applications, since it represents the used/maximum space for that subdirectory.  Otherwise, the user will get &lt;tt&gt;EDQUOT&lt;/tt&gt; back when the project quota runs out for that directory and applications will not be able to figure out how much data they could write into that directory.&lt;/p&gt;

&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;&lt;span class=&quot;code-keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;code-object&quot;&gt;int&lt;/span&gt; ext4_statfs(struct dentry *dentry, struct kstatfs *buf)
{
        buf-&amp;gt;f_type = EXT4_SUPER_MAGIC;
        buf-&amp;gt;f_bsize = sb-&amp;gt;s_blocksize;
        buf-&amp;gt;f_blocks = ext4_blocks_count(es) - EXT4_C2B(sbi, overhead);
        buf-&amp;gt;f_bfree = EXT4_C2B(sbi,
                percpu_counter_sum_positive(&amp;amp;sbi-&amp;gt;s_freeclusters_counter) -
                percpu_counter_sum_positive(&amp;amp;sbi-&amp;gt;s_dirtyclusters_counter));
        buf-&amp;gt;f_bavail = buf-&amp;gt;f_bfree -
                        (ext4_r_blocks_count(es) + resv_blocks);
        &lt;span class=&quot;code-keyword&quot;&gt;if&lt;/span&gt; (buf-&amp;gt;f_bfree &amp;lt; (ext4_r_blocks_count(es) + resv_blocks))
                buf-&amp;gt;f_bavail = 0;
        buf-&amp;gt;f_files = le32_to_cpu(es-&amp;gt;s_inodes_count);
        buf-&amp;gt;f_ffree = percpu_counter_sum_positive(&amp;amp;sbi-&amp;gt;s_freeinodes_counter);

#ifdef CONFIG_QUOTA
        &lt;span class=&quot;code-keyword&quot;&gt;if&lt;/span&gt; (ext4_test_inode_flag(dentry-&amp;gt;d_inode, EXT4_INODE_PROJINHERIT) &amp;amp;&amp;amp;
            sb_has_quota_limits_enabled(sb, PRJQUOTA))
                ext4_statfs_project(sb, EXT4_I(dentry-&amp;gt;d_inode)-&amp;gt;i_projid, buf);
#endif
}
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;/*
 * Directory tree accounting is implemented using project quotas, where
 * the project identifier is inherited from parent directories.
 * A statvfs (df, etc.) of a directory that is using project quota should
 * &lt;span class=&quot;code-keyword&quot;&gt;return&lt;/span&gt; a statvfs of the project, not the entire filesystem.
 * This makes such trees appear as &lt;span class=&quot;code-keyword&quot;&gt;if&lt;/span&gt; they are filesystems in themselves.
 */
void xfs_fill_statvfs_from_dquot(struct kstatfs *statp, struct xfs_dquot *dqp)
{
        uint64_t                limit;

        limit = dqp-&amp;gt;q_core.d_blk_softlimit ?
                be64_to_cpu(dqp-&amp;gt;q_core.d_blk_softlimit) :
                be64_to_cpu(dqp-&amp;gt;q_core.d_blk_hardlimit);
        &lt;span class=&quot;code-keyword&quot;&gt;if&lt;/span&gt; (limit &amp;amp;&amp;amp; statp-&amp;gt;f_blocks &amp;gt; limit) {
                statp-&amp;gt;f_blocks = limit;
                statp-&amp;gt;f_bfree = statp-&amp;gt;f_bavail =
                        (statp-&amp;gt;f_blocks &amp;gt; dqp-&amp;gt;q_res_bcount) ?
                         (statp-&amp;gt;f_blocks - dqp-&amp;gt;q_res_bcount) : 0;
        }

        limit = dqp-&amp;gt;q_core.d_ino_softlimit ?
                be64_to_cpu(dqp-&amp;gt;q_core.d_ino_softlimit) :
                be64_to_cpu(dqp-&amp;gt;q_core.d_ino_hardlimit);
        &lt;span class=&quot;code-keyword&quot;&gt;if&lt;/span&gt; (limit &amp;amp;&amp;amp; statp-&amp;gt;f_files &amp;gt; limit) {
                statp-&amp;gt;f_files = limit;
                statp-&amp;gt;f_ffree = (statp-&amp;gt;f_files &amp;gt; dqp-&amp;gt;q_res_icount) ?
                         (statp-&amp;gt;f_ffree - dqp-&amp;gt;q_res_icount) : 0;
        }
}

void xfs_qm_statvfs(xfs_inode_t *ip, struct kstatfs *statp)
{
        &lt;span class=&quot;code-keyword&quot;&gt;if&lt;/span&gt; (!xfs_qm_dqget(mp, NULL, xfs_get_projid(ip), XFS_DQ_PROJ, 0, &amp;amp;dqp)) {
                xfs_fill_statvfs_from_dquot(statp, dqp);
                xfs_qm_dqput(dqp);
        }
}
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It be useful to be able to do the same with Lustre. One option would be to transfer the projid to the MDS and OSS in the &lt;tt&gt;OBD_STATFS&lt;/tt&gt; request order to get the space usage for that projid directly.  Currently the client RPC request body is empty, so there is no place to put the projid, but a new body could be added. The other option would be to check for a projid on the inode in &lt;tt&gt;ll_statfs()&lt;/tt&gt; and &lt;tt&gt;ll_obd_statfs()&lt;/tt&gt;, and if projid != 0 send the equivalent of &quot;&lt;tt&gt;lfs quota -p&lt;/tt&gt;&quot; for that projid, and use it for the statfs &quot;used&quot; and &quot;total&quot; values.&lt;/p&gt;</description>
                <environment></environment>
        <key id="46293">LU-9555</key>
            <summary>&quot;df /path/to/project&quot; should return projid-specific values</summary>
                <type id="4" iconUrl="https://jira.whamcloud.com/secure/viewavatar?size=xsmall&amp;avatarId=11310&amp;avatarType=issuetype">Improvement</type>
                                            <priority id="4" iconUrl="https://jira.whamcloud.com/images/icons/priorities/minor.svg">Minor</priority>
                        <status id="5" iconUrl="https://jira.whamcloud.com/images/icons/statuses/resolved.png" description="A resolution has been taken, and it is awaiting verification by reporter. From here issues are either reopened, or are closed.">Resolved</status>
                    <statusCategory id="3" key="done" colorName="success"/>
                                    <resolution id="1">Fixed</resolution>
                                        <assignee username="wshilong">Wang Shilong</assignee>
                                    <reporter username="adilger">Andreas Dilger</reporter>
                        <labels>
                    </labels>
                <created>Wed, 24 May 2017 18:17:14 +0000</created>
                <updated>Sat, 6 Jan 2024 09:35:35 +0000</updated>
                            <resolved>Thu, 3 Dec 2020 18:29:28 +0000</resolved>
                                    <version>Lustre 2.10.0</version>
                                    <fixVersion>Lustre 2.14.0</fixVersion>
                                        <due></due>
                            <votes>0</votes>
                                    <watches>7</watches>
                                                                            <comments>
                            <comment id="208554" author="adilger" created="Sat, 16 Sep 2017 01:31:40 +0000"  >&lt;p&gt;Another option that is being discussed in the context of &lt;a href=&quot;https://jira.whamcloud.com/browse/LU-7236&quot; title=&quot;connections on demand&quot; class=&quot;issue-link&quot; data-issue-key=&quot;LU-7236&quot;&gt;&lt;del&gt;LU-7236&lt;/del&gt;&lt;/a&gt; (idle clients disconnect from servers) is to have the client send the STATFS RPCs only to MDT0000, and the MDS can aggregate the statfs data to send back to the client (not for &lt;tt&gt;lfs df&lt;/tt&gt;, however).&lt;/p&gt;

&lt;p&gt;The MDS already sends STATFS RPCs to the OSTs every few seconds for space balancing allocations, so it isn&apos;t much extra work to aggregate this for the client.  The quota master is also on the MDS with MDT0000 so getting the projid usage at the same time would be relatively easy.&lt;/p&gt;</comment>
                            <comment id="216454" author="adilger" created="Sat, 16 Dec 2017 08:38:50 +0000"  >&lt;p&gt;Sebastien, I think this would be useful for your virtualization work. If a projid is used for each container (subdir mount and nodemap) then df in that container can be controlled by the project quota directly, and the container will only see as much space as it is assigned.&lt;/p&gt;

&lt;p&gt;It would also benefit from &lt;a href=&quot;https://jira.whamcloud.com/browse/LU-9982&quot; title=&quot;Clients striping from mapped FID in nodemap&quot; class=&quot;issue-link&quot; data-issue-key=&quot;LU-9982&quot;&gt;LU-9982&lt;/a&gt;, to be able to control the layout within a container. &lt;/p&gt;</comment>
                            <comment id="227940" author="adilger" created="Wed, 16 May 2018 02:41:58 +0000"  >&lt;p&gt;Shilong, is there any plan for DDN to work on this?&lt;/p&gt;

&lt;p&gt;I think it would be good for Lustre project quota to be consistent with ext4/XFS project quota, and it also could help virtualization so that &quot;&lt;tt&gt;df&lt;/tt&gt;&quot; with a nodemap+project quota only shows space usage for that project.&lt;/p&gt;</comment>
                            <comment id="227946" author="wangshilong" created="Wed, 16 May 2018 03:57:13 +0000"  >&lt;p&gt;Hi Andreas,&lt;/p&gt;

&lt;p&gt; I will try to work on this.&lt;/p&gt;

&lt;p&gt;Thanks,&lt;br/&gt;
Shilong&lt;/p&gt;</comment>
                            <comment id="257539" author="adilger" created="Sat, 2 Nov 2019 04:18:49 +0000"  >&lt;p&gt;Hi Shilong, is there any chance you could look into this?  We are close to finishing 2.13 and will soon open master for 2.14 feature landings.  I don&apos;t think it will be a huge amount of work, just doing quota lookups in the statfs() call on the client to limit the maximum used/free for that quota ID.  This would have to be done at the llite level before the results are returned to userspace, since it can&apos;t be cached at lower layers due to other project IDs having different quota limits, unless we wanted to save one projid statfs result in cache for a second to avoid repeated quota lookups for the same user.&lt;/p&gt;</comment>
                            <comment id="257605" author="wshilong" created="Mon, 4 Nov 2019 13:11:39 +0000"  >&lt;p&gt;We might need pass project ID in struct obd_statfs, for example use os_spare3, and then&lt;br/&gt;
send quotactl in LMV/LOV layer with os_projid and limit space there.&lt;/p&gt;

&lt;p&gt;This might be a little tricky, as obd_statfs is expected to get data, but we use it as arg input.&lt;/p&gt;

&lt;p&gt;What do you think?&lt;/p&gt;</comment>
                            <comment id="257679" author="wshilong" created="Tue, 5 Nov 2019 02:32:12 +0000"  >&lt;p&gt;Maybe we don&apos;t need pass project ID down, just extra RPC might be simple and direct, let me try that.&lt;/p&gt;</comment>
                            <comment id="257695" author="adilger" created="Tue, 5 Nov 2019 04:55:10 +0000"  >&lt;p&gt;I don&apos;t think we need to get the project quota info from the lower layers of &lt;tt&gt;osc_statfs()&lt;/tt&gt; and &lt;tt&gt;mdc_statfs()&lt;/tt&gt;.  Instead, it should get the normal quota information in &lt;tt&gt;ll_statfs()&lt;/tt&gt; via &lt;tt&gt;quotactl_ioctl()&lt;/tt&gt; and then apply limits to &lt;tt&gt;osfs&lt;/tt&gt; returned from &lt;tt&gt;ll_statfs_internal()&lt;/tt&gt; in a similar manner to how &lt;tt&gt;ext4_statfs()&lt;/tt&gt; calls &lt;tt&gt;ext4_statfs_project()&lt;/tt&gt;.&lt;/p&gt;</comment>
                            <comment id="257710" author="wshilong" created="Tue, 5 Nov 2019 06:39:31 +0000"  >&lt;p&gt;Andreas, you missed &apos;lfs df&apos; case.&lt;/p&gt;</comment>
                            <comment id="257714" author="adilger" created="Tue, 5 Nov 2019 08:58:37 +0000"  >&lt;p&gt;&lt;del&gt;It should be possible for &quot;&lt;tt&gt;lfs df&lt;/tt&gt;&quot; to pass a new flag like &quot;&lt;tt&gt;LL_STATFS_PROJECT&quot;&lt;/tt&gt; (all the &quot;&lt;tt&gt;LL_STATFS_*&quot;&lt;/tt&gt; flags should be moved into e.g. &quot;&lt;tt&gt;enum ll_statfs_flags&lt;/tt&gt;&quot; to make it easier to find them), which asks the kernel to get the project ID for the inode in &lt;tt&gt;ll_obd_statfs()&lt;/tt&gt;, and then do the quota call from the kernel for each user+OST (which I &lt;em&gt;think&lt;/em&gt; is possible).&#160; The user doesn&apos;t have to send an explicit project ID from userspace, this can be found in the kernel from the inode.&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;No projid-specific handling for &quot;&lt;tt&gt;lfs df&lt;/tt&gt;&quot;.&lt;/p&gt;</comment>
                            <comment id="257718" author="wshilong" created="Tue, 5 Nov 2019 10:46:15 +0000"  >&lt;p&gt;I got a further questions for &apos;lfs df&apos; case:&lt;/p&gt;

&lt;p&gt;&lt;span class=&quot;error&quot;&gt;&amp;#91;root@server_el7_vm1 lustre&amp;#93;&lt;/span&gt;# lfs df /mnt/lustre&lt;br/&gt;
UUID                   1K-blocks        Used   Available Use% Mounted on&lt;br/&gt;
lustre-MDT0000_UUID      5825660       47240     5255588   1% /mnt/lustre&lt;span class=&quot;error&quot;&gt;&amp;#91;MDT:0&amp;#93;&lt;/span&gt;&lt;br/&gt;
lustre-OST0000_UUID      9662472       38040     9083760   1% /mnt/lustre&lt;span class=&quot;error&quot;&gt;&amp;#91;OST:0&amp;#93;&lt;/span&gt;&lt;br/&gt;
lustre-OST0001_UUID      9662472       38044     9083756   1% /mnt/lustre&lt;span class=&quot;error&quot;&gt;&amp;#91;OST:1&amp;#93;&lt;/span&gt;&lt;br/&gt;
lustre-OST0002_UUID      9662472       38044     9083756   1% /mnt/lustre&lt;span class=&quot;error&quot;&gt;&amp;#91;OST:2&amp;#93;&lt;/span&gt;&lt;br/&gt;
lustre-OST0003_UUID      9662472       38044     9083756   1% /mnt/lustre&lt;span class=&quot;error&quot;&gt;&amp;#91;OST:3&amp;#93;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;filesystem_summary:     38649888      152172    36335028   1% /mnt/lustre&lt;/p&gt;

&lt;p&gt;What exactly &apos;avail&apos; space and total space we should report for each OST/MDT?&lt;br/&gt;
I supposed we might need get each slave&apos;s granted space as total space and calculate&lt;br/&gt;
avail space based on that?&lt;/p&gt;

&lt;p&gt;And existed quotactl doesn&apos;t report that information back, we might need extend to support that?&lt;/p&gt;</comment>
                            <comment id="257797" author="adilger" created="Wed, 6 Nov 2019 00:27:07 +0000"  >&lt;p&gt;I think to be consistent with ext4 and ZFS the total space would be the quota limit for that projid, the free space is the remaining quota space for that projid, and the available space is based on the quota softlimit, and the same for inodes, something like:&lt;/p&gt;
&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;
        &lt;span class=&quot;code-keyword&quot;&gt;if&lt;/span&gt; (inode has project limit) {
                f_blocks = dqb_bhardlimit;
                f_bfree = min(dqb_bhardlimit - dqb_curspace, f_bfree);
                f_bavail = min(dqb_bsoftlimit - dqb_curspace, f_bavail);
                f_files = dqb_ihardlimit;
                f_ffree = min(dqb_ihardlimit - dqb_curinodes, f_ifree);
        }
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I thought that there is already a way for the &quot;&lt;tt&gt;lfs quota&lt;/tt&gt;&quot; command to print per-OST usage amounts?  If there isn&apos;t a &quot;granted&quot; field, then it would be possible to just take the unused quota space and divide it evenly across all of the OSTs, so that it adds up to the total unused quota space again at the end.&lt;/p&gt;</comment>
                            <comment id="257823" author="gerrit" created="Wed, 6 Nov 2019 14:00:38 +0000"  >&lt;p&gt;Wang Shilong (wshilong@ddn.com) uploaded a new patch: &lt;a href=&quot;https://review.whamcloud.com/36685&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://review.whamcloud.com/36685&lt;/a&gt;&lt;br/&gt;
Subject: &lt;a href=&quot;https://jira.whamcloud.com/browse/LU-9555&quot; title=&quot;&amp;quot;df /path/to/project&amp;quot; should return projid-specific values&quot; class=&quot;issue-link&quot; data-issue-key=&quot;LU-9555&quot;&gt;&lt;del&gt;LU-9555&lt;/del&gt;&lt;/a&gt; quota: df should return projid-specific values&lt;br/&gt;
Project: fs/lustre-release&lt;br/&gt;
Branch: master&lt;br/&gt;
Current Patch Set: 1&lt;br/&gt;
Commit: 844d2d2f519c9cffdf10ad637a194bdef1efd3e3&lt;/p&gt;</comment>
                            <comment id="258273" author="adilger" created="Thu, 14 Nov 2019 00:35:54 +0000"  >&lt;p&gt;It would also be good to submit a patch to the upstream kernel to include projid into the &lt;tt&gt;statx()&lt;/tt&gt; output. That is tracked under &lt;a href=&quot;https://jira.whamcloud.com/browse/LU-12480&quot; title=&quot;add STATX_PROJID to upstream kernel&quot; class=&quot;issue-link&quot; data-issue-key=&quot;LU-12480&quot;&gt;LU-12480&lt;/a&gt;.&lt;/p&gt;</comment>
                            <comment id="286640" author="gerrit" created="Thu, 3 Dec 2020 17:58:17 +0000"  >&lt;p&gt;Oleg Drokin (green@whamcloud.com) merged in patch &lt;a href=&quot;https://review.whamcloud.com/36685/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://review.whamcloud.com/36685/&lt;/a&gt;&lt;br/&gt;
Subject: &lt;a href=&quot;https://jira.whamcloud.com/browse/LU-9555&quot; title=&quot;&amp;quot;df /path/to/project&amp;quot; should return projid-specific values&quot; class=&quot;issue-link&quot; data-issue-key=&quot;LU-9555&quot;&gt;&lt;del&gt;LU-9555&lt;/del&gt;&lt;/a&gt; quota: df should return projid-specific values&lt;br/&gt;
Project: fs/lustre-release&lt;br/&gt;
Branch: master&lt;br/&gt;
Current Patch Set: &lt;br/&gt;
Commit: e5c8f6670fbeea9ec8c6092dfa4369508da54485&lt;/p&gt;</comment>
                            <comment id="286645" author="pjones" created="Thu, 3 Dec 2020 18:29:28 +0000"  >&lt;p&gt;Landed for 2.14&lt;/p&gt;</comment>
                            <comment id="327439" author="sthiell" created="Fri, 25 Feb 2022 18:19:03 +0000"  >&lt;p&gt;Hello,&lt;br/&gt;
I tried to apply the patch on top of b2_12 but as some prototypes have changed, I&apos;m a bit unsure on how to do it in a good way(tm). Would Whamcloud consider a backport to 2.12? We would LOVE to have this feature on our systems. Thanks for considering it!&lt;/p&gt;</comment>
                    </comments>
                <issuelinks>
                            <issuelinktype id="10011">
                    <name>Related</name>
                                            <outwardlinks description="is related to ">
                                        <issuelink>
            <issuekey id="69584">LU-15721</issuekey>
        </issuelink>
            <issuelink>
            <issuekey id="21158">LU-4017</issuekey>
        </issuelink>
            <issuelink>
            <issuekey id="56210">LU-12480</issuekey>
        </issuelink>
            <issuelink>
            <issuekey id="32398">LU-7236</issuekey>
        </issuelink>
            <issuelink>
            <issuekey id="48425">LU-10018</issuekey>
        </issuelink>
                            </outwardlinks>
                                                                <inwardlinks description="is related to">
                                        <issuelink>
            <issuekey id="79825">LU-17395</issuekey>
        </issuelink>
            <issuelink>
            <issuekey id="57327">LUDOC-460</issuekey>
        </issuelink>
                            </inwardlinks>
                                    </issuelinktype>
                    </issuelinks>
                <attachments>
                    </attachments>
                <subtasks>
                    </subtasks>
                <customfields>
                                                                                                                                                                                            <customfield id="customfield_10890" key="com.atlassian.jira.plugins.jira-development-integration-plugin:devsummary">
                        <customfieldname>Development</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                        <customfield id="customfield_10390" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>1|hzzdjz:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10090" key="com.pyxis.greenhopper.jira:gh-global-rank">
                        <customfieldname>Rank (Obsolete)</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>9223372036854775807</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                </customfields>
    </item>
</channel>
</rss>