<!-- 
RSS generated by JIRA (9.4.14#940014-sha1:734e6822bbf0d45eff9af51f82432957f73aa32c) at Sat Feb 10 03:28:51 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-16651] hold invalidate_lock when invalidating page cache under kernel 5.15+</title>
                <link>https://jira.whamcloud.com/browse/LU-16651</link>
                <project id="10000" key="LU">Lustre</project>
                    <description>&lt;p&gt;When three processes are keeping doing I/O on a same file on a client:&lt;/p&gt;
&lt;ul class=&quot;alternate&quot; type=&quot;square&quot;&gt;
	&lt;li&gt;A: buffered write&lt;/li&gt;
	&lt;li&gt;B: buffered read&lt;/li&gt;
	&lt;li&gt;C: direct I/O read&lt;br/&gt;
Process B will return -EIO on the newer kernel such as Ubuntu 2204.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;After investigate the bug, the problem should be that:&lt;br/&gt;
The client has two overlapped PR DLM extent locks:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;L1 = &amp;lt;PR, &lt;span class=&quot;error&quot;&gt;&amp;#91;1M, 4M - 1&amp;#93;&lt;/span&gt;&amp;gt;&lt;/li&gt;
	&lt;li&gt;L2 = &amp;lt;PR, &lt;span class=&quot;error&quot;&gt;&amp;#91;3M, 5M - 1&amp;#93;&lt;/span&gt;&amp;gt;&lt;br/&gt;
A reader process holds L1 and read data in range &lt;span class=&quot;error&quot;&gt;&amp;#91;3M, 4M -1&amp;#93;&lt;/span&gt;.&lt;br/&gt;
L2 is being revoking due to the conflict access.&lt;br/&gt;
Then in the -&amp;gt;readpage() call:&lt;br/&gt;
It will unlock the page after the page is in Uptodate state.&lt;br/&gt;
And lock blocking callback for L2 will clear the Uptodate state and delete the page from cache.&lt;br/&gt;
Then in the old kernel, it will:&lt;/li&gt;
&lt;/ul&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-comment&quot;&gt;/* Start the actual read. The read will unlock the page. */&lt;/span&gt;
		error = mapping-&amp;gt;a_ops-&amp;gt;readpage(filp, page);

		&lt;span class=&quot;code-keyword&quot;&gt;if&lt;/span&gt; (unlikely(error)) {
			&lt;span class=&quot;code-keyword&quot;&gt;if&lt;/span&gt; (error == AOP_TRUNCATED_PAGE) {
				put_page(page);
				error = 0;
				&lt;span class=&quot;code-keyword&quot;&gt;goto&lt;/span&gt; find_page;
			}
			&lt;span class=&quot;code-keyword&quot;&gt;goto&lt;/span&gt; readpage_error;
		}

		&lt;span class=&quot;code-keyword&quot;&gt;if&lt;/span&gt; (!PageUptodate(page)) {
			error = lock_page_killable(page);
			&lt;span class=&quot;code-keyword&quot;&gt;if&lt;/span&gt; (unlikely(error))
				&lt;span class=&quot;code-keyword&quot;&gt;goto&lt;/span&gt; readpage_error;
			&lt;span class=&quot;code-keyword&quot;&gt;if&lt;/span&gt; (!PageUptodate(page)) {
				&lt;span class=&quot;code-keyword&quot;&gt;if&lt;/span&gt; (page-&amp;gt;mapping == NULL) { =====&amp;gt;
					/*
					 * invalidate_mapping_pages got it
					 */
					unlock_page(page);
					put_page(page);
					&lt;span class=&quot;code-keyword&quot;&gt;goto&lt;/span&gt; find_page;
				}
				unlock_page(page);
				shrink_readahead_size_eio(filp, ra);
				error = -EIO;
				&lt;span class=&quot;code-keyword&quot;&gt;goto&lt;/span&gt; readpage_error;
			}
			unlock_page(page);
		}

		&lt;span class=&quot;code-keyword&quot;&gt;goto&lt;/span&gt; page_ok;
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It will check whether the page was truncated and deleted from page cache via page-&amp;gt;mapping, if so, it will retry the page read.&lt;/p&gt;

&lt;p&gt;But in the newer kernel, it deletes this check and retry.&lt;br/&gt;
It seems there is no any simple solution for this bug.&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; filemap_read_page(struct file *file, struct address_space *mapping,
		struct page *page)
{
	&lt;span class=&quot;code-object&quot;&gt;int&lt;/span&gt; error;

	/*
	 * A previous I/O error may have been due to temporary failures,
	 * eg. multipath errors.  PG_error will be set again &lt;span class=&quot;code-keyword&quot;&gt;if&lt;/span&gt; readpage
	 * fails.
	 */
	ClearPageError(page);
	&lt;span class=&quot;code-comment&quot;&gt;/* Start the actual read. The read will unlock the page. */&lt;/span&gt;
	error = mapping-&amp;gt;a_ops-&amp;gt;readpage(file, page);
	&lt;span class=&quot;code-keyword&quot;&gt;if&lt;/span&gt; (error)
		&lt;span class=&quot;code-keyword&quot;&gt;return&lt;/span&gt; error;

	error = wait_on_page_locked_killable(page);
	&lt;span class=&quot;code-keyword&quot;&gt;if&lt;/span&gt; (error)
		&lt;span class=&quot;code-keyword&quot;&gt;return&lt;/span&gt; error;
	&lt;span class=&quot;code-keyword&quot;&gt;if&lt;/span&gt; (PageUptodate(page))
		&lt;span class=&quot;code-keyword&quot;&gt;return&lt;/span&gt; 0;

	shrink_readahead_size_eio(&amp;amp;file-&amp;gt;f_ra);
	&lt;span class=&quot;code-keyword&quot;&gt;return&lt;/span&gt; -EIO;
}
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;


&lt;p&gt; According to the Linux Documents: Documentations/filkesystems/locking.rst:&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;
Locking rules:
	All except set_page_dirty and freepage may block

======================	======================== =========	===============
ops			PageLocked(page)	 i_rwsem	invalidate_lock
======================	======================== =========	===============
writepage:		yes, unlocks (see below)
readpage:		yes, unlocks				shared
writepages:
set_page_dirty		no
readahead:		yes, unlocks				shared
readpages:		no					shared
write_begin:		locks the page		 exclusive
write_end:		yes, unlocks		 exclusive
bmap:
invalidatepage:		yes					exclusive
releasepage:		yes
freepage:		yes
direct_IO:
isolate_page:		yes
migratepage:		yes (both)
putback_page:		yes
launder_page:		yes
is_partially_uptodate:	yes
error_remove_page:	yes
swap_activate:		no
swap_deactivate:	no
======================	======================== =========	===============
The filesystem must exclusively acquire invalidate_lock before invalidating page cache in truncate / hole punch path (and thus calling into -&amp;gt;invalidatepage) to block races between page cache invalidation and page cache filling functions (fault, read, ...).
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;



&lt;p&gt;The solution  should be that:&lt;br/&gt;
we must hold exclusive invalidate_lock (mapping-&amp;gt;invalidate_lock) (in the newer kernel) when remove pages from page cache caused by the revoking of the DLM extent lock protecting them.&lt;/p&gt;
</description>
                <environment></environment>
        <key id="75131">LU-16651</key>
            <summary>hold invalidate_lock when invalidating page cache under kernel 5.15+</summary>
                <type id="1" iconUrl="https://jira.whamcloud.com/secure/viewavatar?size=xsmall&amp;avatarId=11303&amp;avatarType=issuetype">Bug</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="qian_wc">Qian Yingjin</assignee>
                                    <reporter username="qian_wc">Qian Yingjin</reporter>
                        <labels>
                    </labels>
                <created>Tue, 21 Mar 2023 08:42:08 +0000</created>
                <updated>Mon, 28 Aug 2023 16:11:52 +0000</updated>
                            <resolved>Sun, 9 Jul 2023 14:22:12 +0000</resolved>
                                                    <fixVersion>Lustre 2.16.0</fixVersion>
                                        <due></due>
                            <votes>0</votes>
                                    <watches>5</watches>
                                                                            <comments>
                            <comment id="366652" author="qian_wc" created="Tue, 21 Mar 2023 12:42:07 +0000"  >&lt;p&gt;We may still need to patch Lustre to hold invalidate_lock for truncate and punch hole operations.&lt;/p&gt;</comment>
                            <comment id="366847" author="gerrit" created="Wed, 22 Mar 2023 08:42:17 +0000"  >&lt;p&gt;&quot;Qian Yingjin &amp;lt;qian@ddn.com&amp;gt;&quot; uploaded a new patch: &lt;a href=&quot;https://review.whamcloud.com/c/fs/lustre-release/+/50371&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://review.whamcloud.com/c/fs/lustre-release/+/50371&lt;/a&gt;&lt;br/&gt;
Subject: &lt;a href=&quot;https://jira.whamcloud.com/browse/LU-16651&quot; title=&quot;hold invalidate_lock when invalidating page cache under kernel 5.15+&quot; class=&quot;issue-link&quot; data-issue-key=&quot;LU-16651&quot;&gt;&lt;del&gt;LU-16651&lt;/del&gt;&lt;/a&gt; llite: hold invalidate_lock when invalidate cache pages&lt;br/&gt;
Project: fs/lustre-release&lt;br/&gt;
Branch: master&lt;br/&gt;
Current Patch Set: 1&lt;br/&gt;
Commit: 504cb9b2db177a695f05b95c79797516b99098c1&lt;/p&gt;</comment>
                            <comment id="366850" author="qian_wc" created="Wed, 22 Mar 2023 08:59:11 +0000"  >&lt;p&gt;There are four place that will delete a page from Lustre:&lt;/p&gt;
&lt;ul class=&quot;alternate&quot; type=&quot;square&quot;&gt;
	&lt;li&gt;truncate&lt;/li&gt;
	&lt;li&gt;punch hole&lt;/li&gt;
	&lt;li&gt;extent lock blocking AST callback&lt;/li&gt;
	&lt;li&gt;layout change will prune the pages&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;All these places we need to hold invalidate_lock.&lt;/p&gt;</comment>
                            <comment id="378035" author="gerrit" created="Sat, 8 Jul 2023 22:34:46 +0000"  >&lt;p&gt;&quot;Oleg Drokin &amp;lt;green@whamcloud.com&amp;gt;&quot; merged in patch &lt;a href=&quot;https://review.whamcloud.com/c/fs/lustre-release/+/50371/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://review.whamcloud.com/c/fs/lustre-release/+/50371/&lt;/a&gt;&lt;br/&gt;
Subject: &lt;a href=&quot;https://jira.whamcloud.com/browse/LU-16651&quot; title=&quot;hold invalidate_lock when invalidating page cache under kernel 5.15+&quot; class=&quot;issue-link&quot; data-issue-key=&quot;LU-16651&quot;&gt;&lt;del&gt;LU-16651&lt;/del&gt;&lt;/a&gt; llite: hold invalidate_lock when invalidate cache pages&lt;br/&gt;
Project: fs/lustre-release&lt;br/&gt;
Branch: master&lt;br/&gt;
Current Patch Set: &lt;br/&gt;
Commit: bba59b1287c9cd8c30a85fafb4fd5788452bd05c&lt;/p&gt;</comment>
                            <comment id="378066" author="pjones" created="Sun, 9 Jul 2023 14:22:13 +0000"  >&lt;p&gt;Landed for 2.16&lt;/p&gt;</comment>
                    </comments>
                <issuelinks>
                            <issuelinktype id="10011">
                    <name>Related</name>
                                            <outwardlinks description="is related to ">
                                        <issuelink>
            <issuekey id="71288">LU-16030</issuekey>
        </issuelink>
                            </outwardlinks>
                                                        </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|i03gqv:</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>
                                                                                            <customfield id="customfield_10060" key="com.atlassian.jira.plugin.system.customfieldtypes:select">
                        <customfieldname>Severity</customfieldname>
                        <customfieldvalues>
                                <customfieldvalue key="10022"><![CDATA[3]]></customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                        </customfields>
    </item>
</channel>
</rss>