<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<id>tag:old.nabble.com,2006:forum-30424</id>
	<title>Nabble - linux-ext4</title>
	<updated>2009-12-17T09:32:32Z</updated>
	<link rel="self" type="application/atom+xml" href="http://old.nabble.com/linux-ext4-f30424.xml" />
	<link rel="alternate" type="text/html" href="http://old.nabble.com/linux-ext4-f30424.html" />
	<subtitle type="html"></subtitle>
	
<entry>
	<id>tag:old.nabble.com,2006:post-26831856</id>
	<title>Re: [PATCH] ext4: return correct wbc.nr_to_write in ext4_da_writepages</title>
	<published>2009-12-17T09:32:32Z</published>
	<updated>2009-12-17T09:32:32Z</updated>
	<author>
		<name>Aneesh Kumar K.V-3</name>
	</author>
	<content type="html">On Thu, Dec 17, 2009 at 09:40:25AM -0600, Eric Sandeen wrote:
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; Richard Kennedy wrote:
&lt;br&gt;&amp;gt; &amp;gt; ext4: always re-base nr_to_write in ext4_da_writepages
&lt;br&gt;&amp;gt; &amp;gt; 
&lt;br&gt;&amp;gt; &amp;gt; When ext4_da_writepages increases the nr_to_write in writeback_control
&lt;br&gt;&amp;gt; &amp;gt; then it must always re-base the return value.
&lt;br&gt;&amp;gt; &amp;gt; 
&lt;br&gt;&amp;gt; &amp;gt; Without this change, when wb_writeback calculates how many pages were
&lt;br&gt;&amp;gt; &amp;gt; actually written it can get a negative value and loop more times than
&lt;br&gt;&amp;gt; &amp;gt; necessary. In tests I have seen nearly all the dirty pages pushed out to
&lt;br&gt;&amp;gt; &amp;gt; writeback due to this issue.
&lt;br&gt;&amp;gt; &amp;gt; 
&lt;br&gt;&amp;gt; &amp;gt; Signed-off-by: Richard Kennedy &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26831856&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;richard@...&lt;/a&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; 
&lt;br&gt;&amp;gt; &amp;gt; ----
&lt;br&gt;&amp;gt; &amp;gt; 
&lt;br&gt;&amp;gt; &amp;gt; patch against 2.6.32
&lt;br&gt;&amp;gt; &amp;gt; tested on x86_64
&lt;br&gt;&amp;gt; &amp;gt; 
&lt;br&gt;&amp;gt; &amp;gt; wb_writeback calculates (MAX_WRITE_PAGES - nr_to_write) &amp; cannot know
&lt;br&gt;&amp;gt; &amp;gt; that the value got changed.
&lt;br&gt;&amp;gt; &amp;gt; 
&lt;br&gt;&amp;gt; &amp;gt; I'm not sure what the test I removed was for.
&lt;br&gt;&amp;gt; &amp;gt; Perhaps 
&lt;br&gt;&amp;gt; &amp;gt; 	if (nr_to_writebump)
&lt;br&gt;&amp;gt; &amp;gt; 		wbc-&amp;gt;nr_to_write -= nr_to_writebump;
&lt;br&gt;&amp;gt; &amp;gt; was intended?
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; Ted's commit 55138e0b added it (just part of the commit):
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; @@ -2914,7 +2994,8 @@ retry:
&lt;br&gt;&amp;gt; &amp;nbsp;out_writepages:
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!no_nrwrite_index_update)
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;no_nrwrite_index_update = 0;
&lt;br&gt;&amp;gt; - &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;nr_to_write -= nr_to_writebump;
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp; &amp;nbsp; if (wbc-&amp;gt;nr_to_write &amp;gt; nr_to_writebump)
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;nr_to_write -= nr_to_writebump;
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;range_start = range_start;
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; trace_ext4_da_writepages_result(inode, wbc, ret, pages_written);
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return ret;
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; so it looks like the intent there was to stop -&amp;gt;nr_to_write from
&lt;br&gt;&amp;gt; going negative ...
&lt;/div&gt;&lt;br&gt;I guess writeback code can handle nr_to_write going negative. If we are
&lt;br&gt;not updating wbc-&amp;gt;nr_to_write then i guess writeback code will get a 
&lt;br&gt;wrong value for number of pages written and can end up doing wrong things
&lt;br&gt;We had it that way as a part of 22208dedbd7626e5fc4339c417f8d24cc21f79d7
&lt;br&gt;and i guess we didn't had any problems with that
&lt;br&gt;&lt;br&gt;So for the patch
&lt;br&gt;&lt;br&gt;Acked-by: Aneesh Kumar K.V &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26831856&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;aneesh.kumar@...&lt;/a&gt;&amp;gt;
&lt;br&gt;&lt;br&gt;-aneesh
&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26831856&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH--ext4%3A-return-correct-wbc.nr_to_write-in-ext4_da_writepages-tp26829580p26831856.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26830569</id>
	<title>Re: [PATCH] quota: manage reserved space when quota is not active [v2]</title>
	<published>2009-12-17T08:14:37Z</published>
	<updated>2009-12-17T08:14:37Z</updated>
	<author>
		<name>Jan Kara</name>
	</author>
	<content type="html">On Thu 17-12-09 18:25:55, Dmitry Monakhov wrote:
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; Since we implemented generic reserved space management interface,
&lt;br&gt;&amp;gt; then it is possible to account reserved space even when quota
&lt;br&gt;&amp;gt; is not active (similar to i_blocks/i_bytes).
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; Without this patch following testcase result in massive comlain from
&lt;br&gt;&amp;gt; WARN_ON in dquot_claim_space()
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; TEST_CASE:
&lt;br&gt;&amp;gt; mount /dev/sdb /mnt -oquota
&lt;br&gt;&amp;gt; dd if=/dev/zero of=/mnt/test bs=1M count=1
&lt;br&gt;&amp;gt; quotaon /mnt
&lt;br&gt;&amp;gt; # fs_reserved_spave == 1Mb
&lt;br&gt;&amp;gt; # quota_reserved_space == 0, because quota was disabled
&lt;br&gt;&amp;gt; dd if=/dev/zero of=/mnt/test seek=1 bs=1M count=1
&lt;br&gt;&amp;gt; # fs_reserved_spave == 2Mb
&lt;br&gt;&amp;gt; # quota_reserved_space == 1Mb
&lt;br&gt;&amp;gt; sync &amp;nbsp;# -&amp;gt;dquot_claim_space() -&amp;gt; WARN_ON
&lt;/div&gt;&amp;nbsp; Thanks. Folded into &amp;quot;quota: decouple fs reserved space from quota
&lt;br&gt;reservation&amp;quot;
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Honza
&lt;br&gt;&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; Signed-off-by: Dmitry Monakhov &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26830569&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;dmonakhov@...&lt;/a&gt;&amp;gt;
&lt;br&gt;&amp;gt; ---
&lt;br&gt;&amp;gt; &amp;nbsp;fs/quota/dquot.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; 10 ++++++----
&lt;br&gt;&amp;gt; &amp;nbsp;include/linux/quotaops.h | &amp;nbsp; 11 +++++++++--
&lt;br&gt;&amp;gt; &amp;nbsp;2 files changed, 15 insertions(+), 6 deletions(-)
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
&lt;br&gt;&amp;gt; index dea86ab..a532d44 100644
&lt;br&gt;&amp;gt; --- a/fs/quota/dquot.c
&lt;br&gt;&amp;gt; +++ b/fs/quota/dquot.c
&lt;br&gt;&amp;gt; @@ -1351,28 +1351,30 @@ static qsize_t *inode_reserved_space(struct inode * inode)
&lt;br&gt;&amp;gt; &amp;nbsp;	return inode-&amp;gt;i_sb-&amp;gt;dq_op-&amp;gt;get_reserved_space(inode);
&lt;br&gt;&amp;gt; &amp;nbsp;}
&lt;br&gt;&amp;gt; &amp;nbsp;
&lt;br&gt;&amp;gt; -static void inode_add_rsv_space(struct inode *inode, qsize_t number)
&lt;br&gt;&amp;gt; +void inode_add_rsv_space(struct inode *inode, qsize_t number)
&lt;br&gt;&amp;gt; &amp;nbsp;{
&lt;br&gt;&amp;gt; &amp;nbsp;	spin_lock(&amp;inode-&amp;gt;i_lock);
&lt;br&gt;&amp;gt; &amp;nbsp;	*inode_reserved_space(inode) += number;
&lt;br&gt;&amp;gt; &amp;nbsp;	spin_unlock(&amp;inode-&amp;gt;i_lock);
&lt;br&gt;&amp;gt; &amp;nbsp;}
&lt;br&gt;&amp;gt; +EXPORT_SYMBOL(inode_add_rsv_space);
&lt;br&gt;&amp;gt; &amp;nbsp;
&lt;br&gt;&amp;gt; -
&lt;br&gt;&amp;gt; -static void inode_claim_rsv_space(struct inode *inode, qsize_t number)
&lt;br&gt;&amp;gt; +void inode_claim_rsv_space(struct inode *inode, qsize_t number)
&lt;br&gt;&amp;gt; &amp;nbsp;{
&lt;br&gt;&amp;gt; &amp;nbsp;	spin_lock(&amp;inode-&amp;gt;i_lock);
&lt;br&gt;&amp;gt; &amp;nbsp;	*inode_reserved_space(inode) -= number;
&lt;br&gt;&amp;gt; &amp;nbsp;	__inode_add_bytes(inode, number);
&lt;br&gt;&amp;gt; &amp;nbsp;	spin_unlock(&amp;inode-&amp;gt;i_lock);
&lt;br&gt;&amp;gt; &amp;nbsp;}
&lt;br&gt;&amp;gt; +EXPORT_SYMBOL(inode_claim_rsv_space);
&lt;br&gt;&amp;gt; &amp;nbsp;
&lt;br&gt;&amp;gt; -static void inode_sub_rsv_space(struct inode *inode, qsize_t number)
&lt;br&gt;&amp;gt; +void inode_sub_rsv_space(struct inode *inode, qsize_t number)
&lt;br&gt;&amp;gt; &amp;nbsp;{
&lt;br&gt;&amp;gt; &amp;nbsp;	spin_lock(&amp;inode-&amp;gt;i_lock);
&lt;br&gt;&amp;gt; &amp;nbsp;	*inode_reserved_space(inode) -= number;
&lt;br&gt;&amp;gt; &amp;nbsp;	spin_unlock(&amp;inode-&amp;gt;i_lock);
&lt;br&gt;&amp;gt; &amp;nbsp;}
&lt;br&gt;&amp;gt; +EXPORT_SYMBOL(inode_sub_rsv_space);
&lt;br&gt;&amp;gt; &amp;nbsp;
&lt;br&gt;&amp;gt; &amp;nbsp;static qsize_t inode_get_rsv_space(struct inode *inode)
&lt;br&gt;&amp;gt; &amp;nbsp;{
&lt;br&gt;&amp;gt; diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
&lt;br&gt;&amp;gt; index 3ebb231..a529d86 100644
&lt;br&gt;&amp;gt; --- a/include/linux/quotaops.h
&lt;br&gt;&amp;gt; +++ b/include/linux/quotaops.h
&lt;br&gt;&amp;gt; @@ -26,6 +26,10 @@ static inline void writeout_quota_sb(struct super_block *sb, int type)
&lt;br&gt;&amp;gt; &amp;nbsp;		sb-&amp;gt;s_qcop-&amp;gt;quota_sync(sb, type);
&lt;br&gt;&amp;gt; &amp;nbsp;}
&lt;br&gt;&amp;gt; &amp;nbsp;
&lt;br&gt;&amp;gt; +void inode_add_rsv_space(struct inode *inode, qsize_t number);
&lt;br&gt;&amp;gt; +void inode_claim_rsv_space(struct inode *inode, qsize_t number);
&lt;br&gt;&amp;gt; +void inode_sub_rsv_space(struct inode *inode, qsize_t number);
&lt;br&gt;&amp;gt; +
&lt;br&gt;&amp;gt; &amp;nbsp;int dquot_initialize(struct inode *inode, int type);
&lt;br&gt;&amp;gt; &amp;nbsp;int dquot_drop(struct inode *inode);
&lt;br&gt;&amp;gt; &amp;nbsp;struct dquot *dqget(struct super_block *sb, unsigned int id, int type);
&lt;br&gt;&amp;gt; @@ -42,7 +46,6 @@ int dquot_alloc_inode(const struct inode *inode, qsize_t number);
&lt;br&gt;&amp;gt; &amp;nbsp;int dquot_reserve_space(struct inode *inode, qsize_t number, int prealloc);
&lt;br&gt;&amp;gt; &amp;nbsp;int dquot_claim_space(struct inode *inode, qsize_t number);
&lt;br&gt;&amp;gt; &amp;nbsp;void dquot_release_reserved_space(struct inode *inode, qsize_t number);
&lt;br&gt;&amp;gt; -qsize_t dquot_get_reserved_space(struct inode *inode);
&lt;br&gt;&amp;gt; &amp;nbsp;
&lt;br&gt;&amp;gt; &amp;nbsp;int dquot_free_space(struct inode *inode, qsize_t number);
&lt;br&gt;&amp;gt; &amp;nbsp;int dquot_free_inode(const struct inode *inode, qsize_t number);
&lt;br&gt;&amp;gt; @@ -199,6 +202,8 @@ static inline int vfs_dq_reserve_space(struct inode *inode, qsize_t nr)
&lt;br&gt;&amp;gt; &amp;nbsp;		if (inode-&amp;gt;i_sb-&amp;gt;dq_op-&amp;gt;reserve_space(inode, nr, 0) == NO_QUOTA)
&lt;br&gt;&amp;gt; &amp;nbsp;			return 1;
&lt;br&gt;&amp;gt; &amp;nbsp;	}
&lt;br&gt;&amp;gt; +	else
&lt;br&gt;&amp;gt; +		inode_add_rsv_space(inode, nr);
&lt;br&gt;&amp;gt; &amp;nbsp;	return 0;
&lt;br&gt;&amp;gt; &amp;nbsp;}
&lt;br&gt;&amp;gt; &amp;nbsp;
&lt;br&gt;&amp;gt; @@ -221,7 +226,7 @@ static inline int vfs_dq_claim_space(struct inode *inode, qsize_t nr)
&lt;br&gt;&amp;gt; &amp;nbsp;		if (inode-&amp;gt;i_sb-&amp;gt;dq_op-&amp;gt;claim_space(inode, nr) == NO_QUOTA)
&lt;br&gt;&amp;gt; &amp;nbsp;			return 1;
&lt;br&gt;&amp;gt; &amp;nbsp;	} else
&lt;br&gt;&amp;gt; -		inode_add_bytes(inode, nr);
&lt;br&gt;&amp;gt; +		inode_claim_rsv_space(inode, nr);
&lt;br&gt;&amp;gt; &amp;nbsp;
&lt;br&gt;&amp;gt; &amp;nbsp;	mark_inode_dirty(inode);
&lt;br&gt;&amp;gt; &amp;nbsp;	return 0;
&lt;br&gt;&amp;gt; @@ -235,6 +240,8 @@ void vfs_dq_release_reservation_space(struct inode *inode, qsize_t nr)
&lt;br&gt;&amp;gt; &amp;nbsp;{
&lt;br&gt;&amp;gt; &amp;nbsp;	if (sb_any_quota_active(inode-&amp;gt;i_sb))
&lt;br&gt;&amp;gt; &amp;nbsp;		inode-&amp;gt;i_sb-&amp;gt;dq_op-&amp;gt;release_rsv(inode, nr);
&lt;br&gt;&amp;gt; +	else
&lt;br&gt;&amp;gt; +		inode_sub_rsv_space(inode, nr);
&lt;br&gt;&amp;gt; &amp;nbsp;}
&lt;br&gt;&amp;gt; &amp;nbsp;
&lt;br&gt;&amp;gt; &amp;nbsp;static inline void vfs_dq_free_space_nodirty(struct inode *inode, qsize_t nr)
&lt;br&gt;&amp;gt; -- 
&lt;br&gt;&amp;gt; 1.6.0.4
&lt;br&gt;&amp;gt; 
&lt;/div&gt;-- 
&lt;br&gt;Jan Kara &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26830569&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;jack@...&lt;/a&gt;&amp;gt;
&lt;br&gt;SUSE Labs, CR
&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26830569&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Re%3A--PATCH--quota%3A-manage-reserved-space-even-when-quota-is-not-active-tp26828793p26830569.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26830271</id>
	<title>Re: [PATCH] ext4: return correct wbc.nr_to_write in ext4_da_writepages</title>
	<published>2009-12-17T07:58:26Z</published>
	<updated>2009-12-17T07:58:26Z</updated>
	<author>
		<name>Richard Kennedy</name>
	</author>
	<content type="html">On Thu, 2009-12-17 at 09:40 -0600, Eric Sandeen wrote:
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; Richard Kennedy wrote:
&lt;br&gt;&amp;gt; &amp;gt; ext4: always re-base nr_to_write in ext4_da_writepages
&lt;br&gt;&amp;gt; &amp;gt; 
&lt;br&gt;&amp;gt; &amp;gt; When ext4_da_writepages increases the nr_to_write in writeback_control
&lt;br&gt;&amp;gt; &amp;gt; then it must always re-base the return value.
&lt;br&gt;&amp;gt; &amp;gt; 
&lt;br&gt;&amp;gt; &amp;gt; Without this change, when wb_writeback calculates how many pages were
&lt;br&gt;&amp;gt; &amp;gt; actually written it can get a negative value and loop more times than
&lt;br&gt;&amp;gt; &amp;gt; necessary. In tests I have seen nearly all the dirty pages pushed out to
&lt;br&gt;&amp;gt; &amp;gt; writeback due to this issue.
&lt;br&gt;&amp;gt; &amp;gt; 
&lt;br&gt;&amp;gt; &amp;gt; Signed-off-by: Richard Kennedy &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26830271&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;richard@...&lt;/a&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; 
&lt;br&gt;&amp;gt; &amp;gt; ----
&lt;br&gt;&amp;gt; &amp;gt; 
&lt;br&gt;&amp;gt; &amp;gt; patch against 2.6.32
&lt;br&gt;&amp;gt; &amp;gt; tested on x86_64
&lt;br&gt;&amp;gt; &amp;gt; 
&lt;br&gt;&amp;gt; &amp;gt; wb_writeback calculates (MAX_WRITE_PAGES - nr_to_write) &amp; cannot know
&lt;br&gt;&amp;gt; &amp;gt; that the value got changed.
&lt;br&gt;&amp;gt; &amp;gt; 
&lt;br&gt;&amp;gt; &amp;gt; I'm not sure what the test I removed was for.
&lt;br&gt;&amp;gt; &amp;gt; Perhaps 
&lt;br&gt;&amp;gt; &amp;gt; 	if (nr_to_writebump)
&lt;br&gt;&amp;gt; &amp;gt; 		wbc-&amp;gt;nr_to_write -= nr_to_writebump;
&lt;br&gt;&amp;gt; &amp;gt; was intended?
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; Ted's commit 55138e0b added it (just part of the commit):
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; @@ -2914,7 +2994,8 @@ retry:
&lt;br&gt;&amp;gt; &amp;nbsp;out_writepages:
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!no_nrwrite_index_update)
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;no_nrwrite_index_update = 0;
&lt;br&gt;&amp;gt; - &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;nr_to_write -= nr_to_writebump;
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp; &amp;nbsp; if (wbc-&amp;gt;nr_to_write &amp;gt; nr_to_writebump)
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;nr_to_write -= nr_to_writebump;
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;range_start = range_start;
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; trace_ext4_da_writepages_result(inode, wbc, ret, pages_written);
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return ret;
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; so it looks like the intent there was to stop -&amp;gt;nr_to_write from
&lt;br&gt;&amp;gt; going negative ...
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; 
&lt;/div&gt;wb_writeback is OK with negative, it just needs to know how many pages
&lt;br&gt;were written. Then it can decide if it's done the work it was asked to
&lt;br&gt;do. balance_dirty_pages uses this throttle a device by asking for
&lt;br&gt;writeback on a small number of pages. 
&lt;br&gt;regards
&lt;br&gt;Richard 
&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26830271&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH--ext4%3A-return-correct-wbc.nr_to_write-in-ext4_da_writepages-tp26829580p26830271.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26829983</id>
	<title>Re: [PATCH] ext4: return correct wbc.nr_to_write in ext4_da_writepages</title>
	<published>2009-12-17T07:40:25Z</published>
	<updated>2009-12-17T07:40:25Z</updated>
	<author>
		<name>Eric Sandeen-5</name>
	</author>
	<content type="html">Richard Kennedy wrote:
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; ext4: always re-base nr_to_write in ext4_da_writepages
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; When ext4_da_writepages increases the nr_to_write in writeback_control
&lt;br&gt;&amp;gt; then it must always re-base the return value.
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; Without this change, when wb_writeback calculates how many pages were
&lt;br&gt;&amp;gt; actually written it can get a negative value and loop more times than
&lt;br&gt;&amp;gt; necessary. In tests I have seen nearly all the dirty pages pushed out to
&lt;br&gt;&amp;gt; writeback due to this issue.
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; Signed-off-by: Richard Kennedy &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26829983&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;richard@...&lt;/a&gt;&amp;gt;
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; ----
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; patch against 2.6.32
&lt;br&gt;&amp;gt; tested on x86_64
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; wb_writeback calculates (MAX_WRITE_PAGES - nr_to_write) &amp; cannot know
&lt;br&gt;&amp;gt; that the value got changed.
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; I'm not sure what the test I removed was for.
&lt;br&gt;&amp;gt; Perhaps 
&lt;br&gt;&amp;gt; 	if (nr_to_writebump)
&lt;br&gt;&amp;gt; 		wbc-&amp;gt;nr_to_write -= nr_to_writebump;
&lt;br&gt;&amp;gt; was intended?
&lt;/div&gt;&lt;br&gt;Ted's commit 55138e0b added it (just part of the commit):
&lt;br&gt;&lt;br&gt;@@ -2914,7 +2994,8 @@ retry:
&lt;br&gt;&amp;nbsp;out_writepages:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!no_nrwrite_index_update)
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;no_nrwrite_index_update = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;nr_to_write -= nr_to_writebump;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (wbc-&amp;gt;nr_to_write &amp;gt; nr_to_writebump)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;nr_to_write -= nr_to_writebump;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;range_start = range_start;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; trace_ext4_da_writepages_result(inode, wbc, ret, pages_written);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return ret;
&lt;br&gt;&lt;br&gt;so it looks like the intent there was to stop -&amp;gt;nr_to_write from
&lt;br&gt;going negative ...
&lt;br&gt;&lt;br&gt;&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; regards
&lt;br&gt;&amp;gt; Richard
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
&lt;br&gt;&amp;gt; index 2c8caa5..52a573c 100644
&lt;br&gt;&amp;gt; --- a/fs/ext4/inode.c
&lt;br&gt;&amp;gt; +++ b/fs/ext4/inode.c
&lt;br&gt;&amp;gt; @@ -2999,8 +2999,7 @@ retry:
&lt;br&gt;&amp;gt; &amp;nbsp;out_writepages:
&lt;br&gt;&amp;gt; &amp;nbsp;	if (!no_nrwrite_index_update)
&lt;br&gt;&amp;gt; &amp;nbsp;		wbc-&amp;gt;no_nrwrite_index_update = 0;
&lt;br&gt;&amp;gt; -	if (wbc-&amp;gt;nr_to_write &amp;gt; nr_to_writebump)
&lt;br&gt;&amp;gt; -		wbc-&amp;gt;nr_to_write -= nr_to_writebump;
&lt;br&gt;&amp;gt; +	wbc-&amp;gt;nr_to_write -= nr_to_writebump;
&lt;br&gt;&amp;gt; &amp;nbsp;	wbc-&amp;gt;range_start = range_start;
&lt;br&gt;&amp;gt; &amp;nbsp;	trace_ext4_da_writepages_result(inode, wbc, ret, pages_written);
&lt;br&gt;&amp;gt; &amp;nbsp;	return ret;
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; --
&lt;br&gt;&amp;gt; To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;&amp;gt; the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26829983&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;&amp;gt; More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;/div&gt;&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26829983&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH--ext4%3A-return-correct-wbc.nr_to_write-in-ext4_da_writepages-tp26829580p26829983.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26829717</id>
	<title>[PATCH] quota: manage reserved space when quota is not active [v2]</title>
	<published>2009-12-17T07:25:55Z</published>
	<updated>2009-12-17T07:25:55Z</updated>
	<author>
		<name>Dmitry Monakhov-3</name>
	</author>
	<content type="html">Since we implemented generic reserved space management interface,
&lt;br&gt;then it is possible to account reserved space even when quota
&lt;br&gt;is not active (similar to i_blocks/i_bytes).
&lt;br&gt;&lt;br&gt;Without this patch following testcase result in massive comlain from
&lt;br&gt;WARN_ON in dquot_claim_space()
&lt;br&gt;&lt;br&gt;TEST_CASE:
&lt;br&gt;mount /dev/sdb /mnt -oquota
&lt;br&gt;dd if=/dev/zero of=/mnt/test bs=1M count=1
&lt;br&gt;quotaon /mnt
&lt;br&gt;# fs_reserved_spave == 1Mb
&lt;br&gt;# quota_reserved_space == 0, because quota was disabled
&lt;br&gt;dd if=/dev/zero of=/mnt/test seek=1 bs=1M count=1
&lt;br&gt;# fs_reserved_spave == 2Mb
&lt;br&gt;# quota_reserved_space == 1Mb
&lt;br&gt;sync &amp;nbsp;# -&amp;gt;dquot_claim_space() -&amp;gt; WARN_ON
&lt;br&gt;&lt;br&gt;Signed-off-by: Dmitry Monakhov &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26829717&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;dmonakhov@...&lt;/a&gt;&amp;gt;
&lt;br&gt;---
&lt;br&gt;&amp;nbsp;fs/quota/dquot.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; 10 ++++++----
&lt;br&gt;&amp;nbsp;include/linux/quotaops.h | &amp;nbsp; 11 +++++++++--
&lt;br&gt;&amp;nbsp;2 files changed, 15 insertions(+), 6 deletions(-)
&lt;br&gt;&lt;br&gt;diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
&lt;br&gt;index dea86ab..a532d44 100644
&lt;br&gt;--- a/fs/quota/dquot.c
&lt;br&gt;+++ b/fs/quota/dquot.c
&lt;br&gt;@@ -1351,28 +1351,30 @@ static qsize_t *inode_reserved_space(struct inode * inode)
&lt;br&gt;&amp;nbsp;	return inode-&amp;gt;i_sb-&amp;gt;dq_op-&amp;gt;get_reserved_space(inode);
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-static void inode_add_rsv_space(struct inode *inode, qsize_t number)
&lt;br&gt;+void inode_add_rsv_space(struct inode *inode, qsize_t number)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;&amp;nbsp;	spin_lock(&amp;inode-&amp;gt;i_lock);
&lt;br&gt;&amp;nbsp;	*inode_reserved_space(inode) += number;
&lt;br&gt;&amp;nbsp;	spin_unlock(&amp;inode-&amp;gt;i_lock);
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;+EXPORT_SYMBOL(inode_add_rsv_space);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-
&lt;br&gt;-static void inode_claim_rsv_space(struct inode *inode, qsize_t number)
&lt;br&gt;+void inode_claim_rsv_space(struct inode *inode, qsize_t number)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;&amp;nbsp;	spin_lock(&amp;inode-&amp;gt;i_lock);
&lt;br&gt;&amp;nbsp;	*inode_reserved_space(inode) -= number;
&lt;br&gt;&amp;nbsp;	__inode_add_bytes(inode, number);
&lt;br&gt;&amp;nbsp;	spin_unlock(&amp;inode-&amp;gt;i_lock);
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;+EXPORT_SYMBOL(inode_claim_rsv_space);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-static void inode_sub_rsv_space(struct inode *inode, qsize_t number)
&lt;br&gt;+void inode_sub_rsv_space(struct inode *inode, qsize_t number)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;&amp;nbsp;	spin_lock(&amp;inode-&amp;gt;i_lock);
&lt;br&gt;&amp;nbsp;	*inode_reserved_space(inode) -= number;
&lt;br&gt;&amp;nbsp;	spin_unlock(&amp;inode-&amp;gt;i_lock);
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;+EXPORT_SYMBOL(inode_sub_rsv_space);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;static qsize_t inode_get_rsv_space(struct inode *inode)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
&lt;br&gt;index 3ebb231..a529d86 100644
&lt;br&gt;--- a/include/linux/quotaops.h
&lt;br&gt;+++ b/include/linux/quotaops.h
&lt;br&gt;@@ -26,6 +26,10 @@ static inline void writeout_quota_sb(struct super_block *sb, int type)
&lt;br&gt;&amp;nbsp;		sb-&amp;gt;s_qcop-&amp;gt;quota_sync(sb, type);
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&amp;nbsp;
&lt;br&gt;+void inode_add_rsv_space(struct inode *inode, qsize_t number);
&lt;br&gt;+void inode_claim_rsv_space(struct inode *inode, qsize_t number);
&lt;br&gt;+void inode_sub_rsv_space(struct inode *inode, qsize_t number);
&lt;br&gt;+
&lt;br&gt;&amp;nbsp;int dquot_initialize(struct inode *inode, int type);
&lt;br&gt;&amp;nbsp;int dquot_drop(struct inode *inode);
&lt;br&gt;&amp;nbsp;struct dquot *dqget(struct super_block *sb, unsigned int id, int type);
&lt;br&gt;@@ -42,7 +46,6 @@ int dquot_alloc_inode(const struct inode *inode, qsize_t number);
&lt;br&gt;&amp;nbsp;int dquot_reserve_space(struct inode *inode, qsize_t number, int prealloc);
&lt;br&gt;&amp;nbsp;int dquot_claim_space(struct inode *inode, qsize_t number);
&lt;br&gt;&amp;nbsp;void dquot_release_reserved_space(struct inode *inode, qsize_t number);
&lt;br&gt;-qsize_t dquot_get_reserved_space(struct inode *inode);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;int dquot_free_space(struct inode *inode, qsize_t number);
&lt;br&gt;&amp;nbsp;int dquot_free_inode(const struct inode *inode, qsize_t number);
&lt;br&gt;@@ -199,6 +202,8 @@ static inline int vfs_dq_reserve_space(struct inode *inode, qsize_t nr)
&lt;br&gt;&amp;nbsp;		if (inode-&amp;gt;i_sb-&amp;gt;dq_op-&amp;gt;reserve_space(inode, nr, 0) == NO_QUOTA)
&lt;br&gt;&amp;nbsp;			return 1;
&lt;br&gt;&amp;nbsp;	}
&lt;br&gt;+	else
&lt;br&gt;+		inode_add_rsv_space(inode, nr);
&lt;br&gt;&amp;nbsp;	return 0;
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&amp;nbsp;
&lt;br&gt;@@ -221,7 +226,7 @@ static inline int vfs_dq_claim_space(struct inode *inode, qsize_t nr)
&lt;br&gt;&amp;nbsp;		if (inode-&amp;gt;i_sb-&amp;gt;dq_op-&amp;gt;claim_space(inode, nr) == NO_QUOTA)
&lt;br&gt;&amp;nbsp;			return 1;
&lt;br&gt;&amp;nbsp;	} else
&lt;br&gt;-		inode_add_bytes(inode, nr);
&lt;br&gt;+		inode_claim_rsv_space(inode, nr);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	mark_inode_dirty(inode);
&lt;br&gt;&amp;nbsp;	return 0;
&lt;br&gt;@@ -235,6 +240,8 @@ void vfs_dq_release_reservation_space(struct inode *inode, qsize_t nr)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;&amp;nbsp;	if (sb_any_quota_active(inode-&amp;gt;i_sb))
&lt;br&gt;&amp;nbsp;		inode-&amp;gt;i_sb-&amp;gt;dq_op-&amp;gt;release_rsv(inode, nr);
&lt;br&gt;+	else
&lt;br&gt;+		inode_sub_rsv_space(inode, nr);
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;static inline void vfs_dq_free_space_nodirty(struct inode *inode, qsize_t nr)
&lt;br&gt;-- 
&lt;br&gt;1.6.0.4
&lt;br&gt;&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26829717&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Re%3A--PATCH--quota%3A-manage-reserved-space-even-when-quota-is-not-active-tp26828793p26829717.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26829580</id>
	<title>[PATCH] ext4: return correct wbc.nr_to_write in ext4_da_writepages</title>
	<published>2009-12-17T07:17:43Z</published>
	<updated>2009-12-17T07:17:43Z</updated>
	<author>
		<name>Richard Kennedy</name>
	</author>
	<content type="html">ext4: always re-base nr_to_write in ext4_da_writepages
&lt;br&gt;&lt;br&gt;When ext4_da_writepages increases the nr_to_write in writeback_control
&lt;br&gt;then it must always re-base the return value.
&lt;br&gt;&lt;br&gt;Without this change, when wb_writeback calculates how many pages were
&lt;br&gt;actually written it can get a negative value and loop more times than
&lt;br&gt;necessary. In tests I have seen nearly all the dirty pages pushed out to
&lt;br&gt;writeback due to this issue.
&lt;br&gt;&lt;br&gt;Signed-off-by: Richard Kennedy &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26829580&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;richard@...&lt;/a&gt;&amp;gt;
&lt;br&gt;&lt;br&gt;----
&lt;br&gt;&lt;br&gt;patch against 2.6.32
&lt;br&gt;tested on x86_64
&lt;br&gt;&lt;br&gt;wb_writeback calculates (MAX_WRITE_PAGES - nr_to_write) &amp; cannot know
&lt;br&gt;that the value got changed.
&lt;br&gt;&lt;br&gt;I'm not sure what the test I removed was for.
&lt;br&gt;Perhaps 
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (nr_to_writebump)
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;nr_to_write -= nr_to_writebump;
&lt;br&gt;was intended?
&lt;br&gt;&lt;br&gt;regards
&lt;br&gt;Richard
&lt;br&gt;&lt;br&gt;diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
&lt;br&gt;index 2c8caa5..52a573c 100644
&lt;br&gt;--- a/fs/ext4/inode.c
&lt;br&gt;+++ b/fs/ext4/inode.c
&lt;br&gt;@@ -2999,8 +2999,7 @@ retry:
&lt;br&gt;&amp;nbsp;out_writepages:
&lt;br&gt;&amp;nbsp;	if (!no_nrwrite_index_update)
&lt;br&gt;&amp;nbsp;		wbc-&amp;gt;no_nrwrite_index_update = 0;
&lt;br&gt;-	if (wbc-&amp;gt;nr_to_write &amp;gt; nr_to_writebump)
&lt;br&gt;-		wbc-&amp;gt;nr_to_write -= nr_to_writebump;
&lt;br&gt;+	wbc-&amp;gt;nr_to_write -= nr_to_writebump;
&lt;br&gt;&amp;nbsp;	wbc-&amp;gt;range_start = range_start;
&lt;br&gt;&amp;nbsp;	trace_ext4_da_writepages_result(inode, wbc, ret, pages_written);
&lt;br&gt;&amp;nbsp;	return ret;
&lt;br&gt;&lt;br&gt;&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26829580&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH--ext4%3A-return-correct-wbc.nr_to_write-in-ext4_da_writepages-tp26829580p26829580.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26828793</id>
	<title>Re: [PATCH] quota: manage reserved space even when quota is not active</title>
	<published>2009-12-17T06:28:08Z</published>
	<updated>2009-12-17T06:28:08Z</updated>
	<author>
		<name>Jan Kara</name>
	</author>
	<content type="html">On Thu 17-12-09 03:35:25, Dmitry Monakhov wrote:
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; Hi, Jan.
&lt;br&gt;&amp;gt; I've prepared additional patch for quota reserved space management.
&lt;br&gt;&amp;gt; Initially I've overlooked case when quota is not active, but in fact
&lt;br&gt;&amp;gt; it seems reasonable to generalize reservation to that case as we do
&lt;br&gt;&amp;gt; for i_block/i_bytes reservation.
&lt;br&gt;&amp;gt; Possibly it should be folded in to c35fc5af93955aa22efc6568e5ae5b2cadbc086f
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; CHANGE_LOG:
&lt;br&gt;&amp;gt; quota: manage reserved space even when quota is not active
&lt;br&gt;&amp;gt; Since we implemented generic reserved space management interface,
&lt;br&gt;&amp;gt; then it is possible to account reserved space even quota when quota
&lt;br&gt;&amp;gt; is not active (similar to i_blocks/i_bytes).
&lt;/div&gt;&amp;nbsp; Yes, that's reasonable. I'll fold the patch into your
&lt;br&gt;&amp;quot;quota: decouple fs reserved space from quota reservation&amp;quot; but please fix
&lt;br&gt;things I write below.
&lt;br&gt;&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
&lt;br&gt;&amp;gt; index dea86ab..de7e7de 100644
&lt;br&gt;&amp;gt; --- a/fs/quota/dquot.c
&lt;br&gt;&amp;gt; +++ b/fs/quota/dquot.c
&lt;br&gt;&amp;gt; @@ -1351,15 +1351,14 @@ static qsize_t *inode_reserved_space(struct inode * inode)
&lt;br&gt;&amp;gt; &amp;nbsp;	return inode-&amp;gt;i_sb-&amp;gt;dq_op-&amp;gt;get_reserved_space(inode);
&lt;br&gt;&amp;gt; &amp;nbsp;}
&lt;br&gt;&amp;gt; &amp;nbsp;
&lt;br&gt;&amp;gt; -static void inode_add_rsv_space(struct inode *inode, qsize_t number)
&lt;br&gt;&amp;gt; +void inode_add_rsv_space(struct inode *inode, qsize_t number)
&lt;br&gt;&amp;gt; &amp;nbsp;{
&lt;br&gt;&amp;gt; &amp;nbsp;	spin_lock(&amp;inode-&amp;gt;i_lock);
&lt;br&gt;&amp;gt; &amp;nbsp;	*inode_reserved_space(inode) += number;
&lt;br&gt;&amp;gt; &amp;nbsp;	spin_unlock(&amp;inode-&amp;gt;i_lock);
&lt;br&gt;&amp;gt; &amp;nbsp;}
&lt;br&gt;&amp;gt; &amp;nbsp;
&lt;br&gt;&amp;gt; -
&lt;br&gt;&amp;gt; -static void inode_claim_rsv_space(struct inode *inode, qsize_t number)
&lt;br&gt;&amp;gt; +void inode_claim_rsv_space(struct inode *inode, qsize_t number)
&lt;br&gt;&amp;gt; &amp;nbsp;{
&lt;br&gt;&amp;gt; &amp;nbsp;	spin_lock(&amp;inode-&amp;gt;i_lock);
&lt;br&gt;&amp;gt; &amp;nbsp;	*inode_reserved_space(inode) -= number;
&lt;br&gt;&amp;gt; @@ -1367,14 +1366,14 @@ static void inode_claim_rsv_space(struct inode *inode, qsize_t number)
&lt;br&gt;&amp;gt; &amp;nbsp;	spin_unlock(&amp;inode-&amp;gt;i_lock);
&lt;br&gt;&amp;gt; &amp;nbsp;}
&lt;br&gt;&amp;gt; &amp;nbsp;
&lt;br&gt;&amp;gt; -static void inode_sub_rsv_space(struct inode *inode, qsize_t number)
&lt;br&gt;&amp;gt; +void inode_sub_rsv_space(struct inode *inode, qsize_t number)
&lt;br&gt;&amp;gt; &amp;nbsp;{
&lt;br&gt;&amp;gt; &amp;nbsp;	spin_lock(&amp;inode-&amp;gt;i_lock);
&lt;br&gt;&amp;gt; &amp;nbsp;	*inode_reserved_space(inode) -= number;
&lt;br&gt;&amp;gt; &amp;nbsp;	spin_unlock(&amp;inode-&amp;gt;i_lock);
&lt;br&gt;&amp;gt; &amp;nbsp;}
&lt;/div&gt;&amp;nbsp; The above three functions need to be exported (needed when ext4 is a
&lt;br&gt;module).
&lt;br&gt;&lt;br&gt;&amp;gt; -static qsize_t inode_get_rsv_space(struct inode *inode)
&lt;br&gt;&amp;gt; +qsize_t inode_get_rsv_space(struct inode *inode)
&lt;br&gt;&amp;nbsp; I think this does not need to be visible outside.
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Honza
&lt;br&gt;-- 
&lt;br&gt;Jan Kara &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26828793&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;jack@...&lt;/a&gt;&amp;gt;
&lt;br&gt;SUSE Labs, CR
&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26828793&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Re%3A--PATCH--quota%3A-manage-reserved-space-even-when-quota-is-not-active-tp26828793p26828793.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26825775</id>
	<title>Re: [PATCH]  ext4: journalled quota seed-up</title>
	<published>2009-12-17T02:07:24Z</published>
	<updated>2009-12-17T02:07:24Z</updated>
	<author>
		<name>Dmitry Monakhov-3</name>
	</author>
	<content type="html">Dmitry Monakhov &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26825775&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;dmonakhov@...&lt;/a&gt;&amp;gt; writes:
&lt;br&gt;&lt;br&gt;&amp;gt; Dmitry Monakhov &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26825775&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;dmonakhov@...&lt;/a&gt;&amp;gt; writes:
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; Sorry forgot to add &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26825775&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;linux-ext4@...&lt;/a&gt; list to CC
&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;Currently each quota modification result in write_dquot()
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;and later dquot_commit(). &amp;nbsp;This means what each quota modification
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;function must wait for dqio_mutex. Which is *huge* performance
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;penalty on big SMP systems.
&lt;br&gt;performance results:
&lt;br&gt;simple tests-case: pwrite(,,40960,0); ftruncate(,0) in a loop
&lt;br&gt;measured value: ops/ms == loops per msecond
&lt;br&gt;mount: with journaled quota, and nodelalloc in order to force
&lt;br&gt;curspace modification for each operation.
&lt;br&gt;Seems it will be reasonable to prepare same patch for ext3.
&lt;br&gt;| write-truncate | w/o quot | w jquot | w jquot mk_drt patch |
&lt;br&gt;| &amp;nbsp; nodelalloc &amp;nbsp; | &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;|
&lt;br&gt;| &amp;nbsp; &amp;nbsp; NR tasks 1 | &amp;nbsp; &amp;nbsp; 20.4 | &amp;nbsp; &amp;nbsp;14.5 | &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;14.83 |
&lt;br&gt;| &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp; 20.3 | &amp;nbsp; &amp;nbsp;14.7 | &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 14.7 |
&lt;br&gt;| &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp; 20.4 | &amp;nbsp; &amp;nbsp;14.8 | &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 14.8 |
&lt;br&gt;| &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;|
&lt;br&gt;| &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;4 | &amp;nbsp; &amp;nbsp; &amp;nbsp;6.1 | &amp;nbsp; &amp;nbsp;4.76 | &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;6.3 |
&lt;br&gt;| &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp; &amp;nbsp;6.3 | &amp;nbsp; &amp;nbsp; 5.1 | &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;6.1 |
&lt;br&gt;| &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp; &amp;nbsp;6.5 | &amp;nbsp; &amp;nbsp; 4.8 | &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;6.3 |
&lt;br&gt;| &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;|
&lt;br&gt;| &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;8 | &amp;nbsp; &amp;nbsp; 3.75 | &amp;nbsp; &amp;nbsp;2.59 | &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 3.34 |
&lt;br&gt;| &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp; &amp;nbsp;4.0 | &amp;nbsp; &amp;nbsp; 2.6 | &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 3.44 |
&lt;br&gt;| &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp; 3.76 | &amp;nbsp; &amp;nbsp;2.63 | &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 3.47 |
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;ASAIU The core idea of this implementation
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;is to guarantee that each quota modification will be written to journal
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;atomically. But in fact this is not always true, because dquot may be
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;changed after dquot modification, but before it was committed to disk.
&lt;br&gt;&amp;gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;| Task 1 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | Task 2 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;|
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;| alloc_space(nr) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; |
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;| -&amp;gt;spin_lock(dq_data_lock) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; |
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;| -&amp;gt;curspace += nr &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; |
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;| -&amp;gt;spin_unlock(dq_data_lock) &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; |
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;| -&amp;gt;mark_dirty() &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | free_space(nr) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;|
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;| --&amp;gt;write_dquot() &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | -&amp;gt;spin_lock(dq_data_lock) &amp;nbsp; |
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;| ---&amp;gt;dquot_commit() &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | -&amp;gt;curspace -= nr &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;|
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;| ----&amp;gt;commit_dqblk() &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| -&amp;gt;spin_unlock(dq_data_lock) |
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;| -----&amp;gt;spin_lock(dq_data_lock) &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; |
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;| -----&amp;gt;mem2disk_dqblk(ddq, dquot) | &amp;lt;&amp;lt;&amp;lt; Copy updated value &amp;nbsp; &amp;nbsp; &amp;nbsp;|
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;| -----&amp;gt;spin_unlock(dq_data_lock) &amp;nbsp;| &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; |
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;| -----&amp;gt;quota_write() &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; |
&lt;br&gt;&amp;gt;&amp;gt; Quota corruption not happens only because quota modification caller
&lt;br&gt;&amp;gt;&amp;gt; started journal already. And ext3/4 allow only one running quota
&lt;br&gt;&amp;gt;&amp;gt; at a time. Let's exploit this fact and avoid writing quota each time.
&lt;br&gt;&amp;gt;&amp;gt; Act similar to dirty_for_io in general write_back path in page-cache.
&lt;br&gt;&amp;gt;&amp;gt; If we have found what other task already started on copy and write the
&lt;br&gt;&amp;gt;&amp;gt; dquot then we skip actual quota_write stage. And let that task do the job.
&lt;br&gt;&amp;gt;&amp;gt; Side effect: Task which skip real quota_write() will not get an error
&lt;br&gt;&amp;gt;&amp;gt; (if any). But this is not big deal because:
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;1) Any error has global consequences (RO_remount, err_print, etc).
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;2) Real IO is differed till the journall_commit.
&lt;br&gt;&amp;gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt; Signed-off-by: Dmitry Monakhov &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26825775&amp;i=3&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;dmonakhov@...&lt;/a&gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt; ---
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;fs/ext4/super.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; 37 ++++++++++++++++++++++++++++++-------
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;fs/quota/dquot.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; 16 +++++++++++++---
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;include/linux/quotaops.h | &amp;nbsp; &amp;nbsp;1 +
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;3 files changed, 44 insertions(+), 10 deletions(-)
&lt;br&gt;&amp;gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt; diff --git a/fs/ext4/super.c b/fs/ext4/super.c
&lt;br&gt;&amp;gt;&amp;gt; index 3929091..164217e 100644
&lt;br&gt;&amp;gt;&amp;gt; --- a/fs/ext4/super.c
&lt;br&gt;&amp;gt;&amp;gt; +++ b/fs/ext4/super.c
&lt;br&gt;&amp;gt;&amp;gt; @@ -3777,14 +3777,37 @@ static int ext4_release_dquot(struct dquot *dquot)
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;static int ext4_mark_dquot_dirty(struct dquot *dquot)
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;{
&lt;br&gt;&amp;gt;&amp;gt; -	/* Are we journaling quotas? */
&lt;br&gt;&amp;gt;&amp;gt; -	if (EXT4_SB(dquot-&amp;gt;dq_sb)-&amp;gt;s_qf_names[USRQUOTA] ||
&lt;br&gt;&amp;gt;&amp;gt; -	 &amp;nbsp; &amp;nbsp;EXT4_SB(dquot-&amp;gt;dq_sb)-&amp;gt;s_qf_names[GRPQUOTA]) {
&lt;br&gt;&amp;gt;&amp;gt; -		dquot_mark_dquot_dirty(dquot);
&lt;br&gt;&amp;gt;&amp;gt; -		return ext4_write_dquot(dquot);
&lt;br&gt;&amp;gt;&amp;gt; -	} else {
&lt;br&gt;&amp;gt;&amp;gt; +	int ret, err;
&lt;br&gt;&amp;gt;&amp;gt; +	handle_t *handle;
&lt;br&gt;&amp;gt;&amp;gt; +	struct inode *inode;
&lt;br&gt;&amp;gt;&amp;gt; +
&lt;br&gt;&amp;gt;&amp;gt; +	/* Are we not journaling quotas? */
&lt;br&gt;&amp;gt;&amp;gt; +	if (!EXT4_SB(dquot-&amp;gt;dq_sb)-&amp;gt;s_qf_names[USRQUOTA] &amp;&amp;
&lt;br&gt;&amp;gt;&amp;gt; +	 &amp;nbsp; &amp;nbsp;!EXT4_SB(dquot-&amp;gt;dq_sb)-&amp;gt;s_qf_names[GRPQUOTA])
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;		return dquot_mark_dquot_dirty(dquot);
&lt;br&gt;&amp;gt;&amp;gt; -	}
&lt;br&gt;&amp;gt;&amp;gt; +
&lt;br&gt;&amp;gt;&amp;gt; +	/* journaling quotas case */
&lt;br&gt;&amp;gt;&amp;gt; +	inode = dquot_to_inode(dquot);
&lt;br&gt;&amp;gt;&amp;gt; +	handle = ext4_journal_start(inode,
&lt;br&gt;&amp;gt;&amp;gt; +				EXT4_QUOTA_TRANS_BLOCKS(dquot-&amp;gt;dq_sb));
&lt;br&gt;&amp;gt;&amp;gt; +	if (IS_ERR(handle))
&lt;br&gt;&amp;gt;&amp;gt; +		return PTR_ERR(handle);
&lt;br&gt;&amp;gt;&amp;gt; +	if (!__dquot_mark_dquot_dirty(dquot))
&lt;br&gt;&amp;gt;&amp;gt; +		ret = dquot_commit(dquot);
&lt;br&gt;&amp;gt;&amp;gt; +	else
&lt;br&gt;&amp;gt;&amp;gt; +		/*
&lt;br&gt;&amp;gt;&amp;gt; +		 * Dquot was already dirty. This means that other task already
&lt;br&gt;&amp;gt;&amp;gt; +		 * started a transaction but not clear dirty bit yet (see
&lt;br&gt;&amp;gt;&amp;gt; +		 * dquot_commit). Since the only one running transaction is
&lt;br&gt;&amp;gt;&amp;gt; +		 * possible at a time. Then that task belongs to the same
&lt;br&gt;&amp;gt;&amp;gt; +		 * transaction. We don'n have to actually write dquot changes
&lt;br&gt;&amp;gt;&amp;gt; +		 * because that task will write it for for us.
&lt;br&gt;&amp;gt;&amp;gt; +		 */
&lt;br&gt;&amp;gt;&amp;gt; +		ret = 0;
&lt;br&gt;&amp;gt;&amp;gt; +	err = ext4_journal_stop(handle);
&lt;br&gt;&amp;gt;&amp;gt; +	if (!ret)
&lt;br&gt;&amp;gt;&amp;gt; +		ret = err;
&lt;br&gt;&amp;gt;&amp;gt; +	return ret;
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;}
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;static int ext4_write_info(struct super_block *sb, int type)
&lt;br&gt;&amp;gt;&amp;gt; diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
&lt;br&gt;&amp;gt;&amp;gt; index 6979224..e03eea0 100644
&lt;br&gt;&amp;gt;&amp;gt; --- a/fs/quota/dquot.c
&lt;br&gt;&amp;gt;&amp;gt; +++ b/fs/quota/dquot.c
&lt;br&gt;&amp;gt;&amp;gt; @@ -311,14 +311,24 @@ static inline int mark_dquot_dirty(struct dquot *dquot)
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;{
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;	return dquot-&amp;gt;dq_sb-&amp;gt;dq_op-&amp;gt;mark_dirty(dquot);
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;}
&lt;br&gt;&amp;gt;&amp;gt; -
&lt;br&gt;&amp;gt;&amp;gt; -int dquot_mark_dquot_dirty(struct dquot *dquot)
&lt;br&gt;&amp;gt;&amp;gt; +/* mark dquot dirty in atomic meaner, and return old dirty state */
&lt;br&gt;&amp;gt;&amp;gt; +int __dquot_mark_dquot_dirty(struct dquot *dquot)
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;{
&lt;br&gt;&amp;gt;&amp;gt; +	int ret = 1;
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;	spin_lock(&amp;dq_list_lock);
&lt;br&gt;&amp;gt;&amp;gt; -	if (!test_and_set_bit(DQ_MOD_B, &amp;dquot-&amp;gt;dq_flags))
&lt;br&gt;&amp;gt;&amp;gt; +	if (!test_and_set_bit(DQ_MOD_B, &amp;dquot-&amp;gt;dq_flags)) {
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;		list_add(&amp;dquot-&amp;gt;dq_dirty, &amp;sb_dqopt(dquot-&amp;gt;dq_sb)-&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;				info[dquot-&amp;gt;dq_type].dqi_dirty_list);
&lt;br&gt;&amp;gt;&amp;gt; +		ret = 0;
&lt;br&gt;&amp;gt;&amp;gt; +	}
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;	spin_unlock(&amp;dq_list_lock);
&lt;br&gt;&amp;gt;&amp;gt; +	return ret;
&lt;br&gt;&amp;gt;&amp;gt; +}
&lt;br&gt;&amp;gt;&amp;gt; +EXPORT_SYMBOL(__dquot_mark_dquot_dirty);
&lt;br&gt;&amp;gt;&amp;gt; +
&lt;br&gt;&amp;gt;&amp;gt; +int dquot_mark_dquot_dirty(struct dquot *dquot)
&lt;br&gt;&amp;gt;&amp;gt; +{
&lt;br&gt;&amp;gt;&amp;gt; +	__dquot_mark_dquot_dirty(dquot);
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;	return 0;
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;}
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;EXPORT_SYMBOL(dquot_mark_dquot_dirty);
&lt;br&gt;&amp;gt;&amp;gt; diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
&lt;br&gt;&amp;gt;&amp;gt; index ae7ef25..c950f7d 100644
&lt;br&gt;&amp;gt;&amp;gt; --- a/include/linux/quotaops.h
&lt;br&gt;&amp;gt;&amp;gt; +++ b/include/linux/quotaops.h
&lt;br&gt;&amp;gt;&amp;gt; @@ -56,6 +56,7 @@ int dquot_commit(struct dquot *dquot);
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;int dquot_acquire(struct dquot *dquot);
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;int dquot_release(struct dquot *dquot);
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;int dquot_commit_info(struct super_block *sb, int type);
&lt;br&gt;&amp;gt;&amp;gt; +int __dquot_mark_dquot_dirty(struct dquot *dquot);
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;int dquot_mark_dquot_dirty(struct dquot *dquot);
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp;int vfs_quota_on(struct super_block *sb, int type, int format_id,
&lt;br&gt;&amp;gt; --
&lt;br&gt;&amp;gt; To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;&amp;gt; the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26825775&amp;i=4&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;&amp;gt; More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;/div&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26825775&amp;i=5&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Re%3A--PATCH---ext4%3A-journalled-quota-seed-up-tp26821816p26825775.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26824327</id>
	<title>[PATCH] ext4: Update documentation to correct the inode_readahead_blks option name</title>
	<published>2009-12-16T23:40:23Z</published>
	<updated>2009-12-16T23:40:23Z</updated>
	<author>
		<name>Fang Wenqi</name>
	</author>
	<content type="html">Per commit 240799cd, the option name for readahead should be
&lt;br&gt;inode_readahead_blks, not inode_readahead.
&lt;br&gt;&lt;br&gt;Signed-off-by: Fang Wenqi &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26824327&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;antonf@...&lt;/a&gt;&amp;gt;
&lt;br&gt;---
&lt;br&gt;&amp;nbsp;Documentation/filesystems/ext4.txt | &amp;nbsp; &amp;nbsp;2 +-
&lt;br&gt;&amp;nbsp;1 files changed, 1 insertions(+), 1 deletions(-)
&lt;br&gt;&lt;br&gt;diff --git a/Documentation/filesystems/ext4.txt b/Documentation/filesystems/ext4.txt
&lt;br&gt;index af6885c..e1def17 100644
&lt;br&gt;--- a/Documentation/filesystems/ext4.txt
&lt;br&gt;+++ b/Documentation/filesystems/ext4.txt
&lt;br&gt;@@ -196,7 +196,7 @@ nobarrier		This also requires an IO stack which can support
&lt;br&gt;&amp;nbsp;			also be used to enable or disable barriers, for
&lt;br&gt;&amp;nbsp;			consistency with other ext4 mount options.
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-inode_readahead=n	This tuning parameter controls the maximum
&lt;br&gt;+inode_readahead_blks=n	This tuning parameter controls the maximum
&lt;br&gt;&amp;nbsp;			number of inode table blocks that ext4's inode
&lt;br&gt;&amp;nbsp;			table readahead algorithm will pre-read into
&lt;br&gt;&amp;nbsp;			the buffer cache. &amp;nbsp;The default value is 32 blocks.
&lt;br&gt;-- 
&lt;br&gt;1.6.5.2
&lt;br&gt;&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26824327&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH--ext4%3A-Update-documentation-to-correct-the-inode_readahead_blks-option-name-tp26824327p26824327.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26821816</id>
	<title>Re: [PATCH]  ext4: journalled quota seed-up</title>
	<published>2009-12-16T17:33:35Z</published>
	<updated>2009-12-16T17:33:35Z</updated>
	<author>
		<name>Dmitry Monakhov-3</name>
	</author>
	<content type="html">Dmitry Monakhov &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26821816&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;dmonakhov@...&lt;/a&gt;&amp;gt; writes:
&lt;br&gt;&lt;br&gt;Sorry forgot to add &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26821816&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;linux-ext4@...&lt;/a&gt; list to CC
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; &amp;nbsp;Currently each quota modification result in write_dquot()
&lt;br&gt;&amp;gt; &amp;nbsp;and later dquot_commit(). &amp;nbsp;This means what each quota modification
&lt;br&gt;&amp;gt; &amp;nbsp;function must wait for dqio_mutex. Which is *huge* performance
&lt;br&gt;&amp;gt; &amp;nbsp;penalty on big SMP systems. ASAIU The core idea of this implementation
&lt;br&gt;&amp;gt; &amp;nbsp;is to guarantee that each quota modification will be written to journal
&lt;br&gt;&amp;gt; &amp;nbsp;atomically. But in fact this is not always true, because dquot may be
&lt;br&gt;&amp;gt; &amp;nbsp;changed after dquot modification, but before it was committed to disk.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;nbsp;| Task 1 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | Task 2 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;|
&lt;br&gt;&amp;gt; &amp;nbsp;| alloc_space(nr) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; |
&lt;br&gt;&amp;gt; &amp;nbsp;| -&amp;gt;spin_lock(dq_data_lock) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; |
&lt;br&gt;&amp;gt; &amp;nbsp;| -&amp;gt;curspace += nr &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; |
&lt;br&gt;&amp;gt; &amp;nbsp;| -&amp;gt;spin_unlock(dq_data_lock) &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; |
&lt;br&gt;&amp;gt; &amp;nbsp;| -&amp;gt;mark_dirty() &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | free_space(nr) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;|
&lt;br&gt;&amp;gt; &amp;nbsp;| --&amp;gt;write_dquot() &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | -&amp;gt;spin_lock(dq_data_lock) &amp;nbsp; |
&lt;br&gt;&amp;gt; &amp;nbsp;| ---&amp;gt;dquot_commit() &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | -&amp;gt;curspace -= nr &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;|
&lt;br&gt;&amp;gt; &amp;nbsp;| ----&amp;gt;commit_dqblk() &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| -&amp;gt;spin_unlock(dq_data_lock) |
&lt;br&gt;&amp;gt; &amp;nbsp;| -----&amp;gt;spin_lock(dq_data_lock) &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; |
&lt;br&gt;&amp;gt; &amp;nbsp;| -----&amp;gt;mem2disk_dqblk(ddq, dquot) | &amp;lt;&amp;lt;&amp;lt; Copy updated value &amp;nbsp; &amp;nbsp; &amp;nbsp;|
&lt;br&gt;&amp;gt; &amp;nbsp;| -----&amp;gt;spin_unlock(dq_data_lock) &amp;nbsp;| &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; |
&lt;br&gt;&amp;gt; &amp;nbsp;| -----&amp;gt;quota_write() &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; |
&lt;br&gt;&amp;gt; Quota corruption not happens only because quota modification caller
&lt;br&gt;&amp;gt; started journal already. And ext3/4 allow only one running quota
&lt;br&gt;&amp;gt; at a time. Let's exploit this fact and avoid writing quota each time.
&lt;br&gt;&amp;gt; Act similar to dirty_for_io in general write_back path in page-cache.
&lt;br&gt;&amp;gt; If we have found what other task already started on copy and write the
&lt;br&gt;&amp;gt; dquot then we skip actual quota_write stage. And let that task do the job.
&lt;br&gt;&amp;gt; Side effect: Task which skip real quota_write() will not get an error
&lt;br&gt;&amp;gt; (if any). But this is not big deal because:
&lt;br&gt;&amp;gt; &amp;nbsp;1) Any error has global consequences (RO_remount, err_print, etc).
&lt;br&gt;&amp;gt; &amp;nbsp;2) Real IO is differed till the journall_commit.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; Signed-off-by: Dmitry Monakhov &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26821816&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;dmonakhov@...&lt;/a&gt;&amp;gt;
&lt;br&gt;&amp;gt; ---
&lt;br&gt;&amp;gt; &amp;nbsp;fs/ext4/super.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; 37 ++++++++++++++++++++++++++++++-------
&lt;br&gt;&amp;gt; &amp;nbsp;fs/quota/dquot.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; 16 +++++++++++++---
&lt;br&gt;&amp;gt; &amp;nbsp;include/linux/quotaops.h | &amp;nbsp; &amp;nbsp;1 +
&lt;br&gt;&amp;gt; &amp;nbsp;3 files changed, 44 insertions(+), 10 deletions(-)
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; diff --git a/fs/ext4/super.c b/fs/ext4/super.c
&lt;br&gt;&amp;gt; index 3929091..164217e 100644
&lt;br&gt;&amp;gt; --- a/fs/ext4/super.c
&lt;br&gt;&amp;gt; +++ b/fs/ext4/super.c
&lt;br&gt;&amp;gt; @@ -3777,14 +3777,37 @@ static int ext4_release_dquot(struct dquot *dquot)
&lt;br&gt;&amp;gt; &amp;nbsp;
&lt;br&gt;&amp;gt; &amp;nbsp;static int ext4_mark_dquot_dirty(struct dquot *dquot)
&lt;br&gt;&amp;gt; &amp;nbsp;{
&lt;br&gt;&amp;gt; -	/* Are we journaling quotas? */
&lt;br&gt;&amp;gt; -	if (EXT4_SB(dquot-&amp;gt;dq_sb)-&amp;gt;s_qf_names[USRQUOTA] ||
&lt;br&gt;&amp;gt; -	 &amp;nbsp; &amp;nbsp;EXT4_SB(dquot-&amp;gt;dq_sb)-&amp;gt;s_qf_names[GRPQUOTA]) {
&lt;br&gt;&amp;gt; -		dquot_mark_dquot_dirty(dquot);
&lt;br&gt;&amp;gt; -		return ext4_write_dquot(dquot);
&lt;br&gt;&amp;gt; -	} else {
&lt;br&gt;&amp;gt; +	int ret, err;
&lt;br&gt;&amp;gt; +	handle_t *handle;
&lt;br&gt;&amp;gt; +	struct inode *inode;
&lt;br&gt;&amp;gt; +
&lt;br&gt;&amp;gt; +	/* Are we not journaling quotas? */
&lt;br&gt;&amp;gt; +	if (!EXT4_SB(dquot-&amp;gt;dq_sb)-&amp;gt;s_qf_names[USRQUOTA] &amp;&amp;
&lt;br&gt;&amp;gt; +	 &amp;nbsp; &amp;nbsp;!EXT4_SB(dquot-&amp;gt;dq_sb)-&amp;gt;s_qf_names[GRPQUOTA])
&lt;br&gt;&amp;gt; &amp;nbsp;		return dquot_mark_dquot_dirty(dquot);
&lt;br&gt;&amp;gt; -	}
&lt;br&gt;&amp;gt; +
&lt;br&gt;&amp;gt; +	/* journaling quotas case */
&lt;br&gt;&amp;gt; +	inode = dquot_to_inode(dquot);
&lt;br&gt;&amp;gt; +	handle = ext4_journal_start(inode,
&lt;br&gt;&amp;gt; +				EXT4_QUOTA_TRANS_BLOCKS(dquot-&amp;gt;dq_sb));
&lt;br&gt;&amp;gt; +	if (IS_ERR(handle))
&lt;br&gt;&amp;gt; +		return PTR_ERR(handle);
&lt;br&gt;&amp;gt; +	if (!__dquot_mark_dquot_dirty(dquot))
&lt;br&gt;&amp;gt; +		ret = dquot_commit(dquot);
&lt;br&gt;&amp;gt; +	else
&lt;br&gt;&amp;gt; +		/*
&lt;br&gt;&amp;gt; +		 * Dquot was already dirty. This means that other task already
&lt;br&gt;&amp;gt; +		 * started a transaction but not clear dirty bit yet (see
&lt;br&gt;&amp;gt; +		 * dquot_commit). Since the only one running transaction is
&lt;br&gt;&amp;gt; +		 * possible at a time. Then that task belongs to the same
&lt;br&gt;&amp;gt; +		 * transaction. We don'n have to actually write dquot changes
&lt;br&gt;&amp;gt; +		 * because that task will write it for for us.
&lt;br&gt;&amp;gt; +		 */
&lt;br&gt;&amp;gt; +		ret = 0;
&lt;br&gt;&amp;gt; +	err = ext4_journal_stop(handle);
&lt;br&gt;&amp;gt; +	if (!ret)
&lt;br&gt;&amp;gt; +		ret = err;
&lt;br&gt;&amp;gt; +	return ret;
&lt;br&gt;&amp;gt; &amp;nbsp;}
&lt;br&gt;&amp;gt; &amp;nbsp;
&lt;br&gt;&amp;gt; &amp;nbsp;static int ext4_write_info(struct super_block *sb, int type)
&lt;br&gt;&amp;gt; diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
&lt;br&gt;&amp;gt; index 6979224..e03eea0 100644
&lt;br&gt;&amp;gt; --- a/fs/quota/dquot.c
&lt;br&gt;&amp;gt; +++ b/fs/quota/dquot.c
&lt;br&gt;&amp;gt; @@ -311,14 +311,24 @@ static inline int mark_dquot_dirty(struct dquot *dquot)
&lt;br&gt;&amp;gt; &amp;nbsp;{
&lt;br&gt;&amp;gt; &amp;nbsp;	return dquot-&amp;gt;dq_sb-&amp;gt;dq_op-&amp;gt;mark_dirty(dquot);
&lt;br&gt;&amp;gt; &amp;nbsp;}
&lt;br&gt;&amp;gt; -
&lt;br&gt;&amp;gt; -int dquot_mark_dquot_dirty(struct dquot *dquot)
&lt;br&gt;&amp;gt; +/* mark dquot dirty in atomic meaner, and return old dirty state */
&lt;br&gt;&amp;gt; +int __dquot_mark_dquot_dirty(struct dquot *dquot)
&lt;br&gt;&amp;gt; &amp;nbsp;{
&lt;br&gt;&amp;gt; +	int ret = 1;
&lt;br&gt;&amp;gt; &amp;nbsp;	spin_lock(&amp;dq_list_lock);
&lt;br&gt;&amp;gt; -	if (!test_and_set_bit(DQ_MOD_B, &amp;dquot-&amp;gt;dq_flags))
&lt;br&gt;&amp;gt; +	if (!test_and_set_bit(DQ_MOD_B, &amp;dquot-&amp;gt;dq_flags)) {
&lt;br&gt;&amp;gt; &amp;nbsp;		list_add(&amp;dquot-&amp;gt;dq_dirty, &amp;sb_dqopt(dquot-&amp;gt;dq_sb)-&amp;gt;
&lt;br&gt;&amp;gt; &amp;nbsp;				info[dquot-&amp;gt;dq_type].dqi_dirty_list);
&lt;br&gt;&amp;gt; +		ret = 0;
&lt;br&gt;&amp;gt; +	}
&lt;br&gt;&amp;gt; &amp;nbsp;	spin_unlock(&amp;dq_list_lock);
&lt;br&gt;&amp;gt; +	return ret;
&lt;br&gt;&amp;gt; +}
&lt;br&gt;&amp;gt; +EXPORT_SYMBOL(__dquot_mark_dquot_dirty);
&lt;br&gt;&amp;gt; +
&lt;br&gt;&amp;gt; +int dquot_mark_dquot_dirty(struct dquot *dquot)
&lt;br&gt;&amp;gt; +{
&lt;br&gt;&amp;gt; +	__dquot_mark_dquot_dirty(dquot);
&lt;br&gt;&amp;gt; &amp;nbsp;	return 0;
&lt;br&gt;&amp;gt; &amp;nbsp;}
&lt;br&gt;&amp;gt; &amp;nbsp;EXPORT_SYMBOL(dquot_mark_dquot_dirty);
&lt;br&gt;&amp;gt; diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
&lt;br&gt;&amp;gt; index ae7ef25..c950f7d 100644
&lt;br&gt;&amp;gt; --- a/include/linux/quotaops.h
&lt;br&gt;&amp;gt; +++ b/include/linux/quotaops.h
&lt;br&gt;&amp;gt; @@ -56,6 +56,7 @@ int dquot_commit(struct dquot *dquot);
&lt;br&gt;&amp;gt; &amp;nbsp;int dquot_acquire(struct dquot *dquot);
&lt;br&gt;&amp;gt; &amp;nbsp;int dquot_release(struct dquot *dquot);
&lt;br&gt;&amp;gt; &amp;nbsp;int dquot_commit_info(struct super_block *sb, int type);
&lt;br&gt;&amp;gt; +int __dquot_mark_dquot_dirty(struct dquot *dquot);
&lt;br&gt;&amp;gt; &amp;nbsp;int dquot_mark_dquot_dirty(struct dquot *dquot);
&lt;br&gt;&amp;gt; &amp;nbsp;
&lt;br&gt;&amp;gt; &amp;nbsp;int vfs_quota_on(struct super_block *sb, int type, int format_id,
&lt;/div&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26821816&amp;i=3&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Re%3A--PATCH---ext4%3A-journalled-quota-seed-up-tp26821816p26821816.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26818151</id>
	<title>Re: [PATCH 2/2] ext4: flush delalloc blocks when space is low</title>
	<published>2009-12-16T12:46:02Z</published>
	<updated>2009-12-16T12:46:02Z</updated>
	<author>
		<name>Jan Kara</name>
	</author>
	<content type="html">&lt;div class='shrinkable-quote'&gt;&amp;gt; Creating many small files in rapid succession on a small
&lt;br&gt;&amp;gt; filesystem can lead to spurious ENOSPC; on a 104MB filesystem:
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; for i in `seq 1 22500`; do
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; echo -n &amp;gt; $SCRATCH_MNT/$i
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; echo XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX &amp;gt; $SCRATCH_MNT/$i
&lt;br&gt;&amp;gt; done
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; leads to ENOSPC even though after a sync, 40% of the fs is free
&lt;br&gt;&amp;gt; again.
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; This is because we reserve worst-case metadata for delalloc writes,
&lt;br&gt;&amp;gt; and when data is allocated that worst-case reservation is not
&lt;br&gt;&amp;gt; usually needed.
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; When freespace is low, kicking off an async writeback will start
&lt;br&gt;&amp;gt; converting that worst-case space usage into something more realistic,
&lt;br&gt;&amp;gt; almost always freeing up space to continue.
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; This resolves the testcase for me, and survives all 4 generic
&lt;br&gt;&amp;gt; ENOSPC tests in xfstests.
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; We'll still need a hard synchronous sync to squeeze out the last bit,
&lt;br&gt;&amp;gt; but this fixes things up to a large degree.
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; Signed-off-by: Eric Sandeen &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26818151&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;sandeen@...&lt;/a&gt;&amp;gt;
&lt;/div&gt;&amp;nbsp; Looks good.
&lt;br&gt;&lt;br&gt;&amp;nbsp; Acked-by: Jan Kara &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26818151&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;jack@...&lt;/a&gt;&amp;gt;
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Honza
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; ---
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
&lt;br&gt;&amp;gt; index 5c5bc5d..5b3f468 100644
&lt;br&gt;&amp;gt; --- a/fs/ext4/inode.c
&lt;br&gt;&amp;gt; +++ b/fs/ext4/inode.c
&lt;br&gt;&amp;gt; @@ -3024,11 +3024,18 @@ static int ext4_nonda_switch(struct super_block *sb)
&lt;br&gt;&amp;gt; &amp;nbsp;	if (2 * free_blocks &amp;lt; 3 * dirty_blocks ||
&lt;br&gt;&amp;gt; &amp;nbsp;		free_blocks &amp;lt; (dirty_blocks + EXT4_FREEBLOCKS_WATERMARK)) {
&lt;br&gt;&amp;gt; &amp;nbsp;		/*
&lt;br&gt;&amp;gt; -		 * free block count is less that 150% of dirty blocks
&lt;br&gt;&amp;gt; -		 * or free blocks is less that watermark
&lt;br&gt;&amp;gt; +		 * free block count is less than 150% of dirty blocks
&lt;br&gt;&amp;gt; +		 * or free blocks is less than watermark
&lt;br&gt;&amp;gt; &amp;nbsp;		 */
&lt;br&gt;&amp;gt; &amp;nbsp;		return 1;
&lt;br&gt;&amp;gt; &amp;nbsp;	}
&lt;br&gt;&amp;gt; +	/*
&lt;br&gt;&amp;gt; +	 * Even if we don't switch but are nearing capacity,
&lt;br&gt;&amp;gt; +	 * start pushing delalloc when 1/2 of free blocks are dirty.
&lt;br&gt;&amp;gt; +	 */
&lt;br&gt;&amp;gt; +	if (free_blocks &amp;lt; 2 * dirty_blocks)
&lt;br&gt;&amp;gt; +		writeback_inodes_sb_if_idle(sb);
&lt;br&gt;&amp;gt; +
&lt;br&gt;&amp;gt; &amp;nbsp;	return 0;
&lt;br&gt;&amp;gt; &amp;nbsp;}
&lt;br&gt;&amp;gt; &amp;nbsp;
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; --
&lt;br&gt;&amp;gt; To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;&amp;gt; the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26818151&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;&amp;gt; More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;/div&gt;-- 
&lt;br&gt;Jan Kara &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26818151&amp;i=3&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;jack@...&lt;/a&gt;&amp;gt;
&lt;br&gt;SuSE CR Labs
&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26818151&amp;i=4&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH-2-2--ext4%3A-flush-delalloc-blocks-when-space-is-low-tp26752852p26818151.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26818121</id>
	<title>Re: [PATCH 1/2] fs-writeback: Add helper function to start writeback if idle</title>
	<published>2009-12-16T12:44:09Z</published>
	<updated>2009-12-16T12:44:09Z</updated>
	<author>
		<name>Jan Kara</name>
	</author>
	<content type="html">&lt;div class='shrinkable-quote'&gt;&amp;gt; ext4, at least, would like to start pushing on writeback if it starts
&lt;br&gt;&amp;gt; to get close to ENOSPC when reserving worst-case blocks for delalloc
&lt;br&gt;&amp;gt; writes. &amp;nbsp;Writing out delalloc data will convert those worst-case
&lt;br&gt;&amp;gt; predictions into usually smaller actual usage, freeing up space
&lt;br&gt;&amp;gt; before we hit ENOSPC based on this speculation.
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; Thanks to Jens for the suggestion for the helper function,
&lt;br&gt;&amp;gt; &amp; the naming help.
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; I've made the helper return status on whether writeback was
&lt;br&gt;&amp;gt; started even though I don't plan to use it in the ext4 patch;
&lt;br&gt;&amp;gt; it seems like it would be potentially useful to test this
&lt;br&gt;&amp;gt; in some cases.
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; Signed-off-by: Eric Sandeen &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26818121&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;sandeen@...&lt;/a&gt;&amp;gt;
&lt;/div&gt;&amp;nbsp; The patch looks good.
&lt;br&gt;Acked-by: Jan Kara &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26818121&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;jack@...&lt;/a&gt;&amp;gt;
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Honza
&lt;br&gt;&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; ---
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
&lt;br&gt;&amp;gt; index 9d5360c..bff5f77 100644
&lt;br&gt;&amp;gt; --- a/fs/fs-writeback.c
&lt;br&gt;&amp;gt; +++ b/fs/fs-writeback.c
&lt;br&gt;&amp;gt; @@ -1213,6 +1213,23 @@ void writeback_inodes_sb(struct super_block *sb)
&lt;br&gt;&amp;gt; &amp;nbsp;EXPORT_SYMBOL(writeback_inodes_sb);
&lt;br&gt;&amp;gt; &amp;nbsp;
&lt;br&gt;&amp;gt; &amp;nbsp;/**
&lt;br&gt;&amp;gt; + * writeback_inodes_sb_if_idle	-	start writeback if none underway
&lt;br&gt;&amp;gt; + * @sb: the superblock
&lt;br&gt;&amp;gt; + *
&lt;br&gt;&amp;gt; + * Invoke writeback_inodes_sb if no writeback is currently underway.
&lt;br&gt;&amp;gt; + * Returns 1 if writeback was started, 0 if not.
&lt;br&gt;&amp;gt; + */
&lt;br&gt;&amp;gt; +int writeback_inodes_sb_if_idle(struct super_block *sb)
&lt;br&gt;&amp;gt; +{
&lt;br&gt;&amp;gt; +	if (!writeback_in_progress(sb-&amp;gt;s_bdi)) {
&lt;br&gt;&amp;gt; +		writeback_inodes_sb(sb);
&lt;br&gt;&amp;gt; +		return 1;
&lt;br&gt;&amp;gt; +	} else
&lt;br&gt;&amp;gt; +		return 0;
&lt;br&gt;&amp;gt; +}
&lt;br&gt;&amp;gt; +EXPORT_SYMBOL(writeback_inodes_sb_if_idle);
&lt;br&gt;&amp;gt; +
&lt;br&gt;&amp;gt; +/**
&lt;br&gt;&amp;gt; &amp;nbsp; * sync_inodes_sb	-	sync sb inode pages
&lt;br&gt;&amp;gt; &amp;nbsp; * @sb: the superblock
&lt;br&gt;&amp;gt; &amp;nbsp; *
&lt;br&gt;&amp;gt; diff --git a/include/linux/writeback.h b/include/linux/writeback.h
&lt;br&gt;&amp;gt; index 66ebddc..dc52482 100644
&lt;br&gt;&amp;gt; --- a/include/linux/writeback.h
&lt;br&gt;&amp;gt; +++ b/include/linux/writeback.h
&lt;br&gt;&amp;gt; @@ -69,6 +69,7 @@ struct writeback_control {
&lt;br&gt;&amp;gt; &amp;nbsp;struct bdi_writeback;
&lt;br&gt;&amp;gt; &amp;nbsp;int inode_wait(void *);
&lt;br&gt;&amp;gt; &amp;nbsp;void writeback_inodes_sb(struct super_block *);
&lt;br&gt;&amp;gt; +int writeback_inodes_sb_if_idle(struct super_block *);
&lt;br&gt;&amp;gt; &amp;nbsp;void sync_inodes_sb(struct super_block *);
&lt;br&gt;&amp;gt; &amp;nbsp;void writeback_inodes_wbc(struct writeback_control *wbc);
&lt;br&gt;&amp;gt; &amp;nbsp;long wb_do_writeback(struct bdi_writeback *wb, int force_wait);
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; --
&lt;br&gt;&amp;gt; To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;&amp;gt; the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26818121&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;&amp;gt; More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;/div&gt;-- 
&lt;br&gt;Jan Kara &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26818121&amp;i=3&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;jack@...&lt;/a&gt;&amp;gt;
&lt;br&gt;SuSE CR Labs
&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26818121&amp;i=4&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH-1-2--fs-writeback%3A-Add-helper-function-to-start-writeback-if-idle-tp26752829p26818121.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26817987</id>
	<title>Re: Potential data consistency issue with ASYNC_COMMIT feature</title>
	<published>2009-12-16T12:33:03Z</published>
	<updated>2009-12-16T12:33:03Z</updated>
	<author>
		<name>Jan Kara</name>
	</author>
	<content type="html">&amp;gt; However, journal checksums failed horribly when we tried to enable
&lt;br&gt;&amp;gt; them by default during the last merge window, because of bugs in ext4
&lt;br&gt;&amp;gt; where we were modifying certain metadata blocks (in particular
&lt;br&gt;&amp;gt; superblock and xattr's) without journalling them. &amp;nbsp;(Note to self; we
&lt;br&gt;&amp;gt; need to back port those fixes to ext3; the lack of journalling in
&lt;br&gt;&amp;gt; xattr in particular could mean that in some cases we could lose some
&lt;br&gt;&amp;gt; updates that could affect SELINUX after a crash.)
&lt;br&gt;&amp;nbsp; Already done by Eric and merged ;): d965736b8cb42ae51ba9c3f13488035a98d025c6,
&lt;br&gt;b918397542388de75bd86c32fbfa820e5d629fa9.
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Honza
&lt;br&gt;-- 
&lt;br&gt;Jan Kara &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26817987&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;jack@...&lt;/a&gt;&amp;gt;
&lt;br&gt;SuSE CR Labs
&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26817987&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Potential-data-consistency-issue-with-ASYNC_COMMIT-feature-tp26740008p26817987.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26824310</id>
	<title>Confirmation ReferenceNumber:UK/2551256008/07</title>
	<published>2009-12-16T07:31:01Z</published>
	<updated>2009-12-16T07:31:01Z</updated>
	<author>
		<name>Martyn, Janice</name>
	</author>
	<content type="html">Confirmation ReferenceNumber:UK/2551256008/07
&lt;br&gt;You have won £850,000.00 in free lotto email program held 9th
&lt;br&gt;December 2009 in In Liverpool.
&lt;br&gt;Email Ticket Number X-3007893284-Z ReferenceNumber:UK/2551256008/07
&lt;br&gt;Draw Lucky Number:09-22-37-39-41-49-2-7
&lt;br&gt;BatchNumber:JPK14/0115/IP,Serial Number: HMML3214-07
&lt;br&gt;Please note that the validity period of the winning is 24th of
&lt;br&gt;December 2009.
&lt;br&gt;Contact: Mr. Frank Arthur with your Full Name, Home Address, Age,Gender,
&lt;br&gt;Occupation,Country Of Residence,Nationality &amp; Telephone Number.
&lt;br&gt;Email: &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26824310&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;claims-office@...&lt;/a&gt;&amp;lt;mailto:&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26824310&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;claims-office@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Tel: +4470111 83202+, 4470111 83206
&lt;br&gt;+447031994752, +447031978650
&lt;br&gt;NB Please Note do mail back through the alert email contact Mr. Frank Arthur
&lt;br&gt;via email:&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26824310&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;claims-office@...&lt;/a&gt;
&lt;br&gt;Sincerely,
&lt;br&gt;Brooks, Ken
&lt;br&gt;For The British National Lottery
&lt;br&gt;**********************************************************************
&lt;br&gt;This message is intended for the addressee named and may contain
&lt;br&gt;privileged information or confidential information or both. If you
&lt;br&gt;are not the intended recipient please delete it and notify the sender.
&lt;br&gt;**********************************************************************
&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26824310&amp;i=3&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Confirmation-ReferenceNumber%3AUK-2551256008-07-tp26824310p26824310.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26805023</id>
	<title>[RFC PATCH 4/4] ext4: ext4_get_block_write and io_end code cleanup</title>
	<published>2009-12-15T17:41:38Z</published>
	<updated>2009-12-15T17:41:38Z</updated>
	<author>
		<name>Jiaying Zhang-2</name>
	</author>
	<content type="html">ext4: ext4_get_block_write and io_end code cleanup
&lt;br&gt;&lt;br&gt;Move ext4_get_block_write and io_end related code forward to get rid
&lt;br&gt;of function declearation.
&lt;br&gt;&lt;br&gt;Signed-off-by: Jiaying Zhang &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26805023&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;jiayingz@...&lt;/a&gt;&amp;gt;
&lt;br&gt;---
&lt;br&gt;&amp;nbsp;fs/ext4/inode.c | 2179 +++++++++++++++++++++++++++-----------------------------
&lt;br&gt;&amp;nbsp;1 file changed, 1087 insertions(+), 1092 deletions(-)
&lt;br&gt;&lt;br&gt;Index: git-ext4/fs/ext4/inode.c
&lt;br&gt;===================================================================
&lt;br&gt;--- git-ext4.orig/fs/ext4/inode.c &amp;nbsp; &amp;nbsp; &amp;nbsp; 2009-12-15 16:59:06.000000000 -0800
&lt;br&gt;+++ git-ext4/fs/ext4/inode.c &amp;nbsp; &amp;nbsp;2009-12-15 17:02:13.000000000 -0800
&lt;br&gt;@@ -1493,7 +1493,47 @@ static int do_journal_get_write_access(h
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&lt;br&gt;&amp;nbsp;static int ext4_get_block_write(struct inode *inode, sector_t iblock,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;struct buffer_head *bh_result, int create);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;struct buffer_head *bh_result, int create)
&lt;br&gt;+{
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; handle_t *handle = ext4_journal_current_handle();
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; int ret = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; unsigned max_blocks = bh_result-&amp;gt;b_size &amp;gt;&amp;gt; inode-&amp;gt;i_blkbits;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; int dio_credits;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; int started = 0;
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_debug(&amp;quot;ext4_get_block_write: inode %lu, create flag %d\n&amp;quot;,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;inode-&amp;gt;i_ino, create);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* ext4_get_block in prepare for a DIO write or buffer write.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* We allocate an uinitialized extent if blocks haven't been allocated.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* The extent will be converted to initialized after IO complete.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; create = EXT4_GET_BLOCKS_IO_CREATE_EXT;
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!handle) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (max_blocks &amp;gt; DIO_MAX_BLOCKS)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; max_blocks = DIO_MAX_BLOCKS;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dio_credits = ext4_chunk_trans_blocks(inode, max_blocks);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; handle = ext4_journal_start(inode, dio_credits);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (IS_ERR(handle)) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = PTR_ERR(handle);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto out;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; started = 1;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = ext4_get_blocks(handle, inode, iblock, max_blocks, bh_result,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; create);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ret &amp;gt; 0) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; bh_result-&amp;gt;b_size = (ret &amp;lt;&amp;lt; inode-&amp;gt;i_blkbits);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (started)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_journal_stop(handle);
&lt;br&gt;+out:
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; return ret;
&lt;br&gt;+}
&lt;br&gt;+
&lt;br&gt;&amp;nbsp;static int ext4_write_begin(struct file *file, struct address_space *mapping,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;loff_t pos, unsigned len, unsigned flags,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;struct page **pagep, void **fsdata)
&lt;br&gt;@@ -2607,746 +2647,497 @@ out:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return ret;
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&lt;br&gt;-static int ext4_set_bh_endio(struct buffer_head *bh, struct inode *inode);
&lt;br&gt;-static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate);
&lt;br&gt;+static void ext4_free_io_end(ext4_io_end_t *io)
&lt;br&gt;+{
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; BUG_ON(!io);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; iput(io-&amp;gt;inode);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; kfree(io);
&lt;br&gt;+}
&lt;br&gt;+
&lt;br&gt;+static void dump_completed_IO(struct inode * inode)
&lt;br&gt;+{
&lt;br&gt;+#ifdef EXT4_DEBUG
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct list_head *cur, *before, *after;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_io_end_t *io, *io0, *io1;
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (list_empty(&amp;EXT4_I(inode)-&amp;gt;i_completed_io_list)){
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_debug(&amp;quot;inode %lu completed_io list is empty\n&amp;quot;,
&lt;br&gt;inode-&amp;gt;i_ino);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_debug(&amp;quot;Dump inode %lu completed_io list \n&amp;quot;, inode-&amp;gt;i_ino);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; list_for_each_entry(io, &amp;EXT4_I(inode)-&amp;gt;i_completed_io_list, list){
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cur = &amp;io-&amp;gt;list;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; before = cur-&amp;gt;prev;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; io0 = container_of(before, ext4_io_end_t, list);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; after = cur-&amp;gt;next;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; io1 = container_of(after, ext4_io_end_t, list);
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_debug(&amp;quot;io 0x%p from inode %lu,prev 0x%p,next 0x%p\n&amp;quot;,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; io, inode-&amp;gt;i_ino, io0, io1);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+#endif
&lt;br&gt;+}
&lt;br&gt;&lt;br&gt;&amp;nbsp;/*
&lt;br&gt;- * Note that we don't need to start a transaction unless we're journaling data
&lt;br&gt;- * because we should have holes filled from ext4_page_mkwrite(). We even don't
&lt;br&gt;- * need to file the inode to the transaction's list in ordered mode because if
&lt;br&gt;- * we are writing back data added by write(), the inode is already there and if
&lt;br&gt;- * we are writing back data modified via mmap(), noone guarantees in which
&lt;br&gt;- * transaction the data will hit the disk. In case we are journaling data, we
&lt;br&gt;- * cannot start transaction directly because transaction start ranks above page
&lt;br&gt;- * lock so we have to do some magic.
&lt;br&gt;- *
&lt;br&gt;- * This function can get called via...
&lt;br&gt;- * &amp;nbsp; - ext4_da_writepages after taking page lock (have journal handle)
&lt;br&gt;- * &amp;nbsp; - journal_submit_inode_data_buffers (no journal handle)
&lt;br&gt;- * &amp;nbsp; - shrink_page_list via pdflush (no journal handle)
&lt;br&gt;- * &amp;nbsp; - grab_page_cache when doing write_begin (have journal handle)
&lt;br&gt;- *
&lt;br&gt;- * We don't do any block allocation in this function. If we have page with
&lt;br&gt;- * multiple blocks we need to write those buffer_heads that are mapped. This
&lt;br&gt;- * is important for mmaped based write. So if we do with blocksize 1K
&lt;br&gt;- * truncate(f, 1024);
&lt;br&gt;- * a = mmap(f, 0, 4096);
&lt;br&gt;- * a[0] = 'a';
&lt;br&gt;- * truncate(f, 4096);
&lt;br&gt;- * we have in the page first buffer_head mapped via page_mkwrite call back
&lt;br&gt;- * but other bufer_heads would be unmapped but dirty(dirty done via the
&lt;br&gt;- * do_wp_page). So writepage should write the first block. If we modify
&lt;br&gt;- * the mmap area beyond 1024 we will again get a page_fault and the
&lt;br&gt;- * page_mkwrite callback will do the block allocation and mark the
&lt;br&gt;- * buffer_heads mapped.
&lt;br&gt;- *
&lt;br&gt;- * We redirty the page if we have any buffer_heads that is either delay or
&lt;br&gt;- * unwritten in the page.
&lt;br&gt;- *
&lt;br&gt;- * We can get recursively called as show below.
&lt;br&gt;- *
&lt;br&gt;- * &amp;nbsp; &amp;nbsp; ext4_writepage() -&amp;gt; kmalloc() -&amp;gt; __alloc_pages() -&amp;gt; page_launder() -&amp;gt;
&lt;br&gt;- * &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_writepage()
&lt;br&gt;- *
&lt;br&gt;- * But since we don't do any block allocation we should not deadlock.
&lt;br&gt;- * Page also have the dirty flag cleared so we don't get recurive page_lock.
&lt;br&gt;+ * check a range of space and convert unwritten extents to written.
&lt;br&gt;&amp;nbsp;*/
&lt;br&gt;-static int ext4_writepage(struct page *page,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; struct writeback_control *wbc)
&lt;br&gt;+static int ext4_end_io_nolock(ext4_io_end_t *io)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct inode *inode = io-&amp;gt;inode;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; loff_t offset = io-&amp;gt;offset;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; size_t size = io-&amp;gt;size;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;int ret = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; loff_t size;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; unsigned int len;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; struct buffer_head *page_bufs = NULL;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; struct inode *inode = page-&amp;gt;mapping-&amp;gt;host;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; trace_ext4_writepage(inode, page);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; size = i_size_read(inode);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (page-&amp;gt;index == size &amp;gt;&amp;gt; PAGE_CACHE_SHIFT)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; len = size &amp; ~PAGE_CACHE_MASK;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; else
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; len = PAGE_CACHE_SIZE;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_debug(&amp;quot;ext4_end_io_nolock: io 0x%p from inode %lu,list-&amp;gt;next 0x%p,&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;list-&amp;gt;prev 0x%p\n&amp;quot;,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;io, inode-&amp;gt;i_ino, io-&amp;gt;list.next, io-&amp;gt;list.prev);
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (page_has_buffers(page)) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; page_bufs = page_buffers(page);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (walk_page_buffers(NULL, page_bufs, 0, len, NULL,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_bh_delay_or_unwritten)) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* We don't want to do &amp;nbsp;block allocation
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* So redirty the page and return
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* We may reach here when we do a journal commit
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* via journal_submit_inode_data_buffers.
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* If we don't have mapping block we just ignore
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* them. We can also reach here via shrink_page_list
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; redirty_page_for_writepage(wbc, page);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; unlock_page(page);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; } else {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* The test for page_has_buffers() is subtle:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* We know the page is dirty but it lost buffers. That means
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* that at some moment in time after write_begin()/write_end()
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* has been called all buffers have been clean and thus they
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* must have been written at least once. So they are all
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* mapped and we can happily proceed with mapping them
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* and writing the page.
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* Try to initialize the buffer_heads and check whether
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* all are mapped and non delay. We don't want to
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* do block allocation here.
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = block_prepare_write(page, 0, len,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; noalloc_get_block_write);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!ret) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; page_bufs = page_buffers(page);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* check whether all are mapped and non delay */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (walk_page_buffers(NULL, page_bufs, 0, len, NULL,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_bh_delay_or_unwritten)) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; redirty_page_for_writepage(wbc, page);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; unlock_page(page);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; } else {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* We can't do block allocation here
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* so just redity the page and unlock
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* and return
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; redirty_page_for_writepage(wbc, page);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; unlock_page(page);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* now mark the buffer_heads as dirty and uptodate */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; block_commit_write(page, 0, len);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (list_empty(&amp;io-&amp;gt;list))
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return ret;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (PageChecked(page) &amp;&amp; ext4_should_journal_data(inode)) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* It's mmapped pagecache. &amp;nbsp;Add buffers and journal it. &amp;nbsp;There
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* doesn't seem much point in redirtying the page here.
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ClearPageChecked(page);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return __ext4_journalled_writepage(page, len);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (io-&amp;gt;flag != EXT4_IO_WRITTEN)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return ret;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (test_opt(inode-&amp;gt;i_sb, NOBH) &amp;&amp; ext4_should_writeback_data(inode))
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = nobh_writepage(page, noalloc_get_block_write, wbc);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; else if (page_bufs &amp;&amp; buffer_uninit(page_bufs)) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_set_bh_endio(page_bufs, inode);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = block_write_full_page_endio(page, noalloc_get_block_write,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc, ext4_end_io_buffer_write);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; } else
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = block_write_full_page(page, noalloc_get_block_write,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = ext4_convert_unwritten_extents(inode, offset, size);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ret &amp;lt; 0) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; printk(KERN_EMERG &amp;quot;%s: failed to convert unwritten&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;quot;extents to written extents, error is %d&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;quot; io is still on inode %lu aio dio list\n&amp;quot;,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; __func__, ret, inode-&amp;gt;i_ino);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return ret;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; /* clear the DIO AIO unwritten flag */
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; io-&amp;gt;flag = 0;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return ret;
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&lt;br&gt;&amp;nbsp;/*
&lt;br&gt;- * This is called via ext4_da_writepages() to
&lt;br&gt;- * calulate the total number of credits to reserve to fit
&lt;br&gt;- * a single extent allocation into a single transaction,
&lt;br&gt;- * ext4_da_writpeages() will loop calling this before
&lt;br&gt;- * the block allocation.
&lt;br&gt;+ * work on completed aio dio IO, to convert unwritten extents to extents
&lt;br&gt;&amp;nbsp;*/
&lt;br&gt;-
&lt;br&gt;-static int ext4_da_writepages_trans_blocks(struct inode *inode)
&lt;br&gt;+static void ext4_end_io_work(struct work_struct *work)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; int max_blocks = EXT4_I(inode)-&amp;gt;i_reserved_data_blocks;
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* With non-extent format the journal credit needed to
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* insert nrblocks contiguous block is dependent on
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* number of contiguous block. So we will limit
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* number of contiguous block to a sane value
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!(EXT4_I(inode)-&amp;gt;i_flags &amp; EXT4_EXTENTS_FL) &amp;&amp;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (max_blocks &amp;gt; EXT4_MAX_TRANS_DATA))
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; max_blocks = EXT4_MAX_TRANS_DATA;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_io_end_t *io &amp;nbsp;= container_of(work, ext4_io_end_t, work);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct inode *inode = io-&amp;gt;inode;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; int ret = 0;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; return ext4_chunk_trans_blocks(inode, max_blocks);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; mutex_lock(&amp;inode-&amp;gt;i_mutex);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = ext4_end_io_nolock(io);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ret &amp;gt;= 0) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!list_empty(&amp;io-&amp;gt;list))
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; list_del_init(&amp;io-&amp;gt;list);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_free_io_end(io);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; mutex_unlock(&amp;inode-&amp;gt;i_mutex);
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&lt;br&gt;-static int ext4_da_writepages(struct address_space *mapping,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; struct writeback_control *wbc)
&lt;br&gt;-{
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; pgoff_t index;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; int range_whole = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; handle_t *handle = NULL;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; struct mpage_da_data mpd;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; struct inode *inode = mapping-&amp;gt;host;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; int no_nrwrite_index_update;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; int pages_written = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; long pages_skipped;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; unsigned int max_pages;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; int range_cyclic, cycled = 1, io_done = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; int needed_blocks, ret = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; long desired_nr_to_write, nr_to_writebump = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; loff_t range_start = wbc-&amp;gt;range_start;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; struct ext4_sb_info *sbi = EXT4_SB(mapping-&amp;gt;host-&amp;gt;i_sb);
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; trace_ext4_da_writepages(inode, wbc);
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* No pages to write? This is mainly a kludge to avoid starting
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* a transaction for special inodes like journal inode on last iput()
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* because that could violate lock ordering on umount
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!mapping-&amp;gt;nrpages || !mapping_tagged(mapping, PAGECACHE_TAG_DIRTY))
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 0;
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* If the filesystem has aborted, it is read-only, so return
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* right away instead of dumping stack traces later on that
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* will obscure the real source of the problem. &amp;nbsp;We test
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* EXT4_MF_FS_ABORTED instead of sb-&amp;gt;s_flag's MS_RDONLY because
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* the latter could be true if the filesystem is mounted
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* read-only, and in that case, ext4_da_writepages should
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* *never* be called, so if that ever happens, we would want
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* the stack trace.
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (unlikely(sbi-&amp;gt;s_mount_flags &amp; EXT4_MF_FS_ABORTED))
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return -EROFS;
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (wbc-&amp;gt;range_start == 0 &amp;&amp; wbc-&amp;gt;range_end == LLONG_MAX)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; range_whole = 1;
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; range_cyclic = wbc-&amp;gt;range_cyclic;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (wbc-&amp;gt;range_cyclic) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; index = mapping-&amp;gt;writeback_index;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (index)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cycled = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;range_start = index &amp;lt;&amp;lt; PAGE_CACHE_SHIFT;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;range_end &amp;nbsp;= LLONG_MAX;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;range_cyclic = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; } else
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; index = wbc-&amp;gt;range_start &amp;gt;&amp;gt; PAGE_CACHE_SHIFT;
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* This works around two forms of stupidity. &amp;nbsp;The first is in
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* the writeback code, which caps the maximum number of pages
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* written to be 1024 pages. &amp;nbsp;This is wrong on multiple
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* levels; different architectues have a different page size,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* which changes the maximum amount of data which gets
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* written. &amp;nbsp;Secondly, 4 megabytes is way too small. &amp;nbsp;XFS
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* forces this value to be 16 megabytes by multiplying
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* nr_to_write parameter by four, and then relies on its
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* allocator to allocate larger extents to make them
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* contiguous. &amp;nbsp;Unfortunately this brings us to the second
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* stupidity, which is that ext4's mballoc code only allocates
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* at most 2048 blocks. &amp;nbsp;So we force contiguous writes up to
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* the number of dirty blocks in the inode, or
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* sbi-&amp;gt;max_writeback_mb_bump whichever is smaller.
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; max_pages = sbi-&amp;gt;s_max_writeback_mb_bump &amp;lt;&amp;lt; (20 - PAGE_CACHE_SHIFT);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!range_cyclic &amp;&amp; range_whole)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; desired_nr_to_write = wbc-&amp;gt;nr_to_write * 8;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; else
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; desired_nr_to_write = ext4_num_dirty_pages(inode, index,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;max_pages);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (desired_nr_to_write &amp;gt; max_pages)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; desired_nr_to_write = max_pages;
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (wbc-&amp;gt;nr_to_write &amp;lt; desired_nr_to_write) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; nr_to_writebump = desired_nr_to_write - wbc-&amp;gt;nr_to_write;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;nr_to_write = desired_nr_to_write;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.wbc = wbc;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.inode = mapping-&amp;gt;host;
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* we don't want write_cache_pages to update
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* nr_to_write and writeback_index
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; no_nrwrite_index_update = wbc-&amp;gt;no_nrwrite_index_update;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;no_nrwrite_index_update = 1;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; pages_skipped = wbc-&amp;gt;pages_skipped;
&lt;br&gt;-
&lt;br&gt;-retry:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; while (!ret &amp;&amp; wbc-&amp;gt;nr_to_write &amp;gt; 0) {
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* we &amp;nbsp;insert one extent at a time. So we need
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* credit needed for single extent allocation.
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* journalled mode is currently not supported
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* by delalloc
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; BUG_ON(ext4_should_journal_data(inode));
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; needed_blocks = ext4_da_writepages_trans_blocks(inode);
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* start a new transaction*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; handle = ext4_journal_start(inode, needed_blocks);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (IS_ERR(handle)) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = PTR_ERR(handle);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_msg(inode-&amp;gt;i_sb, KERN_CRIT, &amp;quot;%s: jbd2_start: &amp;quot;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;%ld pages, ino %lu; err %d\n&amp;quot;, __func__,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;nr_to_write, inode-&amp;gt;i_ino, ret);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto out_writepages;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* Now call __mpage_da_writepage to find the next
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* contiguous region of logical blocks that need
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* blocks to be allocated by ext4. &amp;nbsp;We don't actually
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* submit the blocks for I/O here, even though
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* write_cache_pages thinks it will, and will set the
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* pages as clean for write before calling
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* __mpage_da_writepage().
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.b_size = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.b_state = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.b_blocknr = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.first_page = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.next_page = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.io_done = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.pages_written = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.retval = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = write_cache_pages(mapping, wbc, __mpage_da_writepage,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;mpd);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* If we have a contigous extent of pages and we
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* haven't done the I/O yet, map the blocks and submit
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* them for I/O.
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!mpd.io_done &amp;&amp; mpd.next_page != mpd.first_page) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (mpage_da_map_blocks(&amp;mpd) == 0)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpage_da_submit_io(&amp;mpd);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.io_done = 1;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = MPAGE_DA_EXTENT_TAIL;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; trace_ext4_da_write_pages(inode, &amp;mpd);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;nr_to_write -= mpd.pages_written;
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_journal_stop(handle);
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if ((mpd.retval == -ENOSPC) &amp;&amp; sbi-&amp;gt;s_journal) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* commit the transaction which would
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* free blocks released in the transaction
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* and try again
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; jbd2_journal_force_commit_nested(sbi-&amp;gt;s_journal);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;pages_skipped = pages_skipped;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; } else if (ret == MPAGE_DA_EXTENT_TAIL) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* got one extent now try with
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* rest of the pages
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; pages_written += mpd.pages_written;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;pages_skipped = pages_skipped;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; io_done = 1;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; } else if (wbc-&amp;gt;nr_to_write)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* There is no more writeout needed
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* or we requested for a noblocking writeout
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* and we found the device congested
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; break;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!io_done &amp;&amp; !cycled) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cycled = 1;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; index = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;range_start = index &amp;lt;&amp;lt; PAGE_CACHE_SHIFT;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;range_end &amp;nbsp;= mapping-&amp;gt;writeback_index - 1;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto retry;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (pages_skipped != wbc-&amp;gt;pages_skipped)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_msg(inode-&amp;gt;i_sb, KERN_CRIT,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;This should not happen leaving %s &amp;quot;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;with nr_to_write = %ld ret = %d\n&amp;quot;,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;__func__, wbc-&amp;gt;nr_to_write, ret);
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; /* Update index */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; index += pages_written;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;range_cyclic = range_cyclic;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (wbc-&amp;gt;range_cyclic || (range_whole &amp;&amp; wbc-&amp;gt;nr_to_write &amp;gt; 0))
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* set the writeback_index so that range_cyclic
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* mode will write it back later
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mapping-&amp;gt;writeback_index = index;
&lt;br&gt;-
&lt;br&gt;-out_writepages:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!no_nrwrite_index_update)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;no_nrwrite_index_update = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (wbc-&amp;gt;nr_to_write &amp;gt; nr_to_writebump)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;nr_to_write -= nr_to_writebump;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;range_start = range_start;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; trace_ext4_da_writepages_result(inode, wbc, ret, pages_written);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; return ret;
&lt;br&gt;-}
&lt;br&gt;-
&lt;br&gt;-#define FALL_BACK_TO_NONDELALLOC 1
&lt;br&gt;-static int ext4_nonda_switch(struct super_block *sb)
&lt;br&gt;-{
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; s64 free_blocks, dirty_blocks;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; struct ext4_sb_info *sbi = EXT4_SB(sb);
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* switch to non delalloc mode if we are running low
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* on free block. The free block accounting via percpu
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* counters can get slightly wrong with percpu_counter_batch getting
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* accumulated on each CPU without updating global counters
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* Delalloc need an accurate free block accounting. So switch
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* to non delalloc when we are near to error range.
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; free_blocks &amp;nbsp;= percpu_counter_read_positive(&amp;sbi-&amp;gt;s_freeblocks_counter);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; dirty_blocks =
&lt;br&gt;percpu_counter_read_positive(&amp;sbi-&amp;gt;s_dirtyblocks_counter);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (2 * free_blocks &amp;lt; 3 * dirty_blocks ||
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; free_blocks &amp;lt; (dirty_blocks + EXT4_FREEBLOCKS_WATERMARK)) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* free block count is less that 150% of dirty blocks
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* or free blocks is less that watermark
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 1;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; return 0;
&lt;br&gt;-}
&lt;br&gt;-
&lt;br&gt;-static int ext4_da_write_begin(struct file *file, struct
&lt;br&gt;address_space *mapping,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;loff_t pos, unsigned len, unsigned flags,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;struct page **pagep, void **fsdata)
&lt;br&gt;+/*
&lt;br&gt;+ * This function is called from ext4_sync_file().
&lt;br&gt;+ *
&lt;br&gt;+ * When IO is completed, the work to convert unwritten extents to
&lt;br&gt;+ * written is queued on workqueue but may not get immediately
&lt;br&gt;+ * scheduled. When fsync is called, we need to ensure the
&lt;br&gt;+ * conversion is complete before fsync returns.
&lt;br&gt;+ * The inode keeps track of a list of pending/completed IO that
&lt;br&gt;+ * might needs to do the conversion. This function walks through
&lt;br&gt;+ * the list and convert the related unwritten extents for completed IO
&lt;br&gt;+ * to written.
&lt;br&gt;+ * The function return the number of pending IOs on success.
&lt;br&gt;+ */
&lt;br&gt;+int flush_completed_IO(struct inode *inode)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; int ret, retries = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; struct page *page;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; pgoff_t index;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; unsigned from, to;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; struct inode *inode = mapping-&amp;gt;host;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; handle_t *handle;
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; index = pos &amp;gt;&amp;gt; PAGE_CACHE_SHIFT;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; from = pos &amp; (PAGE_CACHE_SIZE - 1);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; to = from + len;
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ext4_nonda_switch(inode-&amp;gt;i_sb)) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; *fsdata = (void *)FALL_BACK_TO_NONDELALLOC;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return ext4_write_begin(file, mapping, pos,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; len, flags, pagep, fsdata);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; *fsdata = (void *)0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; trace_ext4_da_write_begin(inode, pos, len, flags);
&lt;br&gt;-retry:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* With delayed allocation, we don't log the i_disksize update
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* if there is delayed block allocation. But we still need
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* to journalling the i_disksize update if writes to the end
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* of file which has an already mapped buffer.
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; handle = ext4_journal_start(inode, 1);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (IS_ERR(handle)) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = PTR_ERR(handle);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto out;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; /* We cannot recurse into the filesystem as the transaction is already
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* started */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; flags |= AOP_FLAG_NOFS;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_io_end_t *io, *tmp;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; int ret = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; int ret2 = 0;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; page = grab_cache_page_write_begin(mapping, index, flags);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!page) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_journal_stop(handle);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = -ENOMEM;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto out;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; *pagep = page;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (list_empty(&amp;EXT4_I(inode)-&amp;gt;i_completed_io_list))
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return ret;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_da_get_block_prep);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ret &amp;lt; 0) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; unlock_page(page);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_journal_stop(handle);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; page_cache_release(page);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; dump_completed_IO(inode);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; list_for_each_entry_safe(io, tmp,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;EXT4_I(inode)-&amp;gt;i_completed_io_list, list) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (io-&amp;gt;flag == EXT4_IO_UNWRITTEN)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; continue;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* block_write_begin may have instantiated a few blocks
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* outside i_size. &amp;nbsp;Trim these off again. Don't need
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* i_size_read because we hold i_mutex.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* Calling ext4_end_io_nolock() to convert completed
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* IO to written.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* When ext4_sync_file() is called, run_queue() may already
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* about to flush the work corresponding to this io structure.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* It will be upset if it founds the io structure related
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* to the work-to-be schedule is freed.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* Thus we need to keep the io structure still valid here after
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* convertion finished. The io structure has a flag to
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* avoid double converting from both fsync and background work
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* queue work.
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (pos + len &amp;gt; inode-&amp;gt;i_size)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_truncate(inode);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = ext4_end_io_nolock(io);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ret &amp;lt; 0)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret2 = ret;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; else
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; list_del_init(&amp;io-&amp;gt;list);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ret == -ENOSPC &amp;&amp; ext4_should_retry_alloc(inode-&amp;gt;i_sb, &amp;retries))
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto retry;
&lt;br&gt;-out:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; return ret;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; return (ret2 &amp;lt; 0) ? ret2 : 0;
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&lt;br&gt;-/*
&lt;br&gt;- * Check if we should update i_disksize
&lt;br&gt;- * when write to the end of file but not require block allocation
&lt;br&gt;- */
&lt;br&gt;-static int ext4_da_should_update_i_disksize(struct page *page,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; unsigned long offset)
&lt;br&gt;+static ext4_io_end_t *ext4_init_io_end (struct inode *inode)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; struct buffer_head *bh;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; struct inode *inode = page-&amp;gt;mapping-&amp;gt;host;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; unsigned int idx;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; int i;
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; bh = page_buffers(page);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; idx = offset &amp;gt;&amp;gt; inode-&amp;gt;i_blkbits;
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; for (i = 0; i &amp;lt; idx; i++)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; bh = bh-&amp;gt;b_this_page;
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!buffer_mapped(bh) || (buffer_delay(bh)) || buffer_unwritten(bh))
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; return 1;
&lt;br&gt;-}
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_io_end_t *io = NULL;
&lt;br&gt;&lt;br&gt;-static int ext4_da_write_end(struct file *file,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;struct address_space *mapping,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;loff_t pos, unsigned len, unsigned copied,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;struct page *page, void *fsdata)
&lt;br&gt;-{
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; struct inode *inode = mapping-&amp;gt;host;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; int ret = 0, ret2;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; handle_t *handle = ext4_journal_current_handle();
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; loff_t new_i_size;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; unsigned long start, end;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; int write_mode = (int)(unsigned long)fsdata;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; io = kmalloc(sizeof(*io), GFP_NOFS);
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (write_mode == FALL_BACK_TO_NONDELALLOC) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ext4_should_order_data(inode)) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return ext4_ordered_write_end(file, mapping, pos,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; len, copied, page, fsdata);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; } else if (ext4_should_writeback_data(inode)) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return ext4_writeback_write_end(file, mapping, pos,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; len, copied, page, fsdata);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; } else {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; BUG();
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (io) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; igrab(inode);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; io-&amp;gt;inode = inode;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; io-&amp;gt;flag = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; io-&amp;gt;offset = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; io-&amp;gt;size = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; io-&amp;gt;error = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; INIT_WORK(&amp;io-&amp;gt;work, ext4_end_io_work);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; INIT_LIST_HEAD(&amp;io-&amp;gt;list);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; trace_ext4_da_write_end(inode, pos, len, copied);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; start = pos &amp; (PAGE_CACHE_SIZE - 1);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; end = start + copied - 1;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; return io;
&lt;br&gt;+}
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* generic_write_end() will run mark_inode_dirty() if i_size
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* changes. &amp;nbsp;So let's piggyback the i_disksize mark_inode_dirty
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* into that.
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ssize_t size, void *private)
&lt;br&gt;+{
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ext4_io_end_t *io_end = iocb-&amp;gt;private;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct workqueue_struct *wq;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; new_i_size = pos + copied;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (new_i_size &amp;gt; EXT4_I(inode)-&amp;gt;i_disksize) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ext4_da_should_update_i_disksize(page, end)) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; down_write(&amp;EXT4_I(inode)-&amp;gt;i_data_sem);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (new_i_size &amp;gt; EXT4_I(inode)-&amp;gt;i_disksize) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* Updating i_disksize when extending file
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* without needing block allocation
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ext4_should_order_data(inode))
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = ext4_jbd2_file_inode(handle,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;inode);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; /* if not async direct IO or dio with 0 bytes write, just return */
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!io_end || !size)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; EXT4_I(inode)-&amp;gt;i_disksize = new_i_size;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; up_write(&amp;EXT4_I(inode)-&amp;gt;i_data_sem);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* We need to mark inode dirty even if
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* new_i_size is less that inode-&amp;gt;i_size
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* bu greater than i_disksize.(hint delalloc)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_mark_inode_dirty(handle, inode);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ext_debug(&amp;quot;ext4_end_io_dio(): io_end 0x%p&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;quot;for inode %lu, iocb 0x%p, offset %llu, size %llu\n&amp;quot;,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; iocb-&amp;gt;private, io_end-&amp;gt;inode-&amp;gt;i_ino, iocb, offset,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; size);
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; /* if not aio dio with unwritten extents, just free io and return */
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (io_end-&amp;gt;flag != EXT4_IO_UNWRITTEN){
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_free_io_end(io_end);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; iocb-&amp;gt;private = NULL;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ret2 = generic_write_end(file, mapping, pos, len, copied,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; page, fsdata);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; copied = ret2;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ret2 &amp;lt; 0)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = ret2;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ret2 = ext4_journal_stop(handle);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!ret)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = ret2;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; return ret ? ret : copied;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; io_end-&amp;gt;offset = offset;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; io_end-&amp;gt;size = size;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; io_end-&amp;gt;flag = EXT4_IO_WRITTEN;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; wq = EXT4_SB(io_end-&amp;gt;inode-&amp;gt;i_sb)-&amp;gt;dio_unwritten_wq;
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; /* queue the work to convert unwritten extents to written */
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; queue_work(wq, &amp;io_end-&amp;gt;work);
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; /* Add the io_end to per-inode completed aio dio list*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; list_add_tail(&amp;io_end-&amp;gt;list,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;EXT4_I(io_end-&amp;gt;inode)-&amp;gt;i_completed_io_list);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; iocb-&amp;gt;private = NULL;
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&lt;br&gt;-static void ext4_da_invalidatepage(struct page *page, unsigned long offset)
&lt;br&gt;+static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* Drop reserved blocks
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; BUG_ON(!PageLocked(page));
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!page_has_buffers(page))
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_io_end_t *io_end = bh-&amp;gt;b_private;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct workqueue_struct *wq;
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!io_end)
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;goto out;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; io_end-&amp;gt;flag = EXT4_IO_WRITTEN;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; wq = EXT4_SB(io_end-&amp;gt;inode-&amp;gt;i_sb)-&amp;gt;dio_unwritten_wq;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; /* queue the work to convert unwritten extents to written */
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; queue_work(wq, &amp;io_end-&amp;gt;work);
&lt;br&gt;+out:
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; bh-&amp;gt;b_private = NULL;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; bh-&amp;gt;b_end_io = NULL;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; clear_buffer_uninit(bh);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; end_buffer_async_write(bh, uptodate);
&lt;br&gt;+}
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_da_page_release_reservation(page, offset);
&lt;br&gt;+static int ext4_set_bh_endio(struct buffer_head *bh, struct inode *inode)
&lt;br&gt;+{
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_io_end_t *io_end;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct page *page = bh-&amp;gt;b_page;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; loff_t offset = (sector_t)page-&amp;gt;index &amp;lt;&amp;lt; PAGE_CACHE_SHIFT;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; size_t size = bh-&amp;gt;b_size;
&lt;br&gt;&lt;br&gt;-out:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_invalidatepage(page, offset);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; io_end = ext4_init_io_end(inode);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!io_end)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return -ENOMEM;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; io_end-&amp;gt;offset = offset;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; io_end-&amp;gt;size = size;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; io_end-&amp;gt;flag = EXT4_IO_UNWRITTEN;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; /* Add the io_end to per-inode completed io list*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; list_add_tail(&amp;io_end-&amp;gt;list,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;EXT4_I(io_end-&amp;gt;inode)-&amp;gt;i_completed_io_list);
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; return;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; bh-&amp;gt;b_private = io_end;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; bh-&amp;gt;b_end_io = ext4_end_io_buffer_write;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; return 0;
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&lt;br&gt;&amp;nbsp;/*
&lt;br&gt;- * Force all delayed allocation blocks to be allocated for a given inode.
&lt;br&gt;+ * Note that we don't need to start a transaction unless we're journaling data
&lt;br&gt;+ * because we should have holes filled from ext4_page_mkwrite(). We even don't
&lt;br&gt;+ * need to file the inode to the transaction's list in ordered mode because if
&lt;br&gt;+ * we are writing back data added by write(), the inode is already there and if
&lt;br&gt;+ * we are writing back data modified via mmap(), noone guarantees in which
&lt;br&gt;+ * transaction the data will hit the disk. In case we are journaling data, we
&lt;br&gt;+ * cannot start transaction directly because transaction start ranks above page
&lt;br&gt;+ * lock so we have to do some magic.
&lt;br&gt;+ *
&lt;br&gt;+ * This function can get called via...
&lt;br&gt;+ * &amp;nbsp; - ext4_da_writepages after taking page lock (have journal handle)
&lt;br&gt;+ * &amp;nbsp; - journal_submit_inode_data_buffers (no journal handle)
&lt;br&gt;+ * &amp;nbsp; - shrink_page_list via pdflush (no journal handle)
&lt;br&gt;+ * &amp;nbsp; - grab_page_cache when doing write_begin (have journal handle)
&lt;br&gt;+ *
&lt;br&gt;+ * We don't do any block allocation in this function. If we have page with
&lt;br&gt;+ * multiple blocks we need to write those buffer_heads that are mapped. This
&lt;br&gt;+ * is important for mmaped based write. So if we do with blocksize 1K
&lt;br&gt;+ * truncate(f, 1024);
&lt;br&gt;+ * a = mmap(f, 0, 4096);
&lt;br&gt;+ * a[0] = 'a';
&lt;br&gt;+ * truncate(f, 4096);
&lt;br&gt;+ * we have in the page first buffer_head mapped via page_mkwrite call back
&lt;br&gt;+ * but other bufer_heads would be unmapped but dirty(dirty done via the
&lt;br&gt;+ * do_wp_page). So writepage should write the first block. If we modify
&lt;br&gt;+ * the mmap area beyond 1024 we will again get a page_fault and the
&lt;br&gt;+ * page_mkwrite callback will do the block allocation and mark the
&lt;br&gt;+ * buffer_heads mapped.
&lt;br&gt;+ *
&lt;br&gt;+ * We redirty the page if we have any buffer_heads that is either delay or
&lt;br&gt;+ * unwritten in the page.
&lt;br&gt;+ *
&lt;br&gt;+ * We can get recursively called as show below.
&lt;br&gt;+ *
&lt;br&gt;+ * &amp;nbsp; &amp;nbsp; ext4_writepage() -&amp;gt; kmalloc() -&amp;gt; __alloc_pages() -&amp;gt; page_launder() -&amp;gt;
&lt;br&gt;+ * &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_writepage()
&lt;br&gt;+ *
&lt;br&gt;+ * But since we don't do any block allocation we should not deadlock.
&lt;br&gt;+ * Page also have the dirty flag cleared so we don't get recurive page_lock.
&lt;br&gt;&amp;nbsp;*/
&lt;br&gt;-#if 1
&lt;br&gt;-int ext4_alloc_da_blocks(struct inode *inode)
&lt;br&gt;+static int ext4_writepage(struct page *page,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; struct writeback_control *wbc)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; trace_ext4_alloc_da_blocks(inode);
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!EXT4_I(inode)-&amp;gt;i_reserved_data_blocks &amp;&amp;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; !EXT4_I(inode)-&amp;gt;i_reserved_meta_blocks)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; int ret = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; loff_t size;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; unsigned int len;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct buffer_head *page_bufs = NULL;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct inode *inode = page-&amp;gt;mapping-&amp;gt;host;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* We do something simple for now. &amp;nbsp;The filemap_flush() will
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* also start triggering a write of the data blocks, which is
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* not strictly speaking necessary (and for users of
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* laptop_mode, not even desirable). &amp;nbsp;However, to do otherwise
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* would require replicating code paths in:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* ext4_da_writepages() -&amp;gt;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* &amp;nbsp; &amp;nbsp;write_cache_pages() ---&amp;gt; (via passed in callback function)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;__mpage_da_writepage() --&amp;gt;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpage_add_bh_to_extent()
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpage_da_map_blocks()
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* The problem is that write_cache_pages(), located in
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* mm/page-writeback.c, marks pages clean in preparation for
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* doing I/O, which is not desirable if we're not planning on
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* doing I/O at all.
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* We could call write_cache_pages(), and then redirty all of
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* the pages by calling redirty_page_for_writeback() but that
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* would be ugly in the extreme. &amp;nbsp;So instead we would need to
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* replicate parts of the code in the above functions,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* simplifying them becuase we wouldn't actually intend to
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* write out the pages, but rather only collect contiguous
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* logical block extents, call the multi-block allocator, and
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* then update the buffer heads with the block allocations.
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* For now, though, we'll cheat by calling filemap_flush(),
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* which will map the blocks, and start the I/O, but not
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* actually wait for the I/O to complete.
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; return filemap_flush(inode-&amp;gt;i_mapping);
&lt;br&gt;-}
&lt;br&gt;-#else
&lt;br&gt;-static int flush_alloc_da_page(struct page *page, struct mpage_da_data *mpd)
&lt;br&gt;-{
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; struct inode *inode = mpd-&amp;gt;inode;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; struct buffer_head *bh, *head;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; sector_t logical;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; trace_ext4_writepage(inode, page);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; size = i_size_read(inode);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (page-&amp;gt;index == size &amp;gt;&amp;gt; PAGE_CACHE_SHIFT)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; len = size &amp; ~PAGE_CACHE_MASK;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; else
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; len = PAGE_CACHE_SIZE;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* Can we merge this page to current extent?
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (mpd-&amp;gt;next_page != page-&amp;gt;index) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (page_has_buffers(page)) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; page_bufs = page_buffers(page);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (walk_page_buffers(NULL, page_bufs, 0, len, NULL,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_bh_delay_or_unwritten)) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* We don't want to do &amp;nbsp;block allocation
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* So redirty the page and return
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* We may reach here when we do a journal commit
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* via journal_submit_inode_data_buffers.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* If we don't have mapping block we just ignore
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* them. We can also reach here via shrink_page_list
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; redirty_page_for_writepage(wbc, page);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; unlock_page(page);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; } else {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* Nope, we can't. So, we map non-allocated blocks
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* and start IO on them using writepage()
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* The test for page_has_buffers() is subtle:
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* We know the page is dirty but it lost buffers. That means
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* that at some moment in time after write_begin()/write_end()
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* has been called all buffers have been clean and thus they
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* must have been written at least once. So they are all
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* mapped and we can happily proceed with mapping them
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* and writing the page.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* Try to initialize the buffer_heads and check whether
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* all are mapped and non delay. We don't want to
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* do block allocation here.
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (mpd-&amp;gt;next_page != mpd-&amp;gt;first_page) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; printk(KERN_INFO
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;flush_alloc_da_page map_blocks: &amp;quot;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;ino %lu blk %llu, size %u\n&amp;quot;,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mpd-&amp;gt;inode-&amp;gt;i_ino, mpd-&amp;gt;b_blocknr,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mpd-&amp;gt;b_size &amp;gt;&amp;gt; mpd-&amp;gt;inode-&amp;gt;i_blkbits);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpage_da_map_blocks(mpd);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = block_prepare_write(page, 0, len,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; noalloc_get_block_write);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!ret) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; page_bufs = page_buffers(page);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* check whether all are mapped and non delay */
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (walk_page_buffers(NULL, page_bufs, 0, len, NULL,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_bh_delay_or_unwritten)) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; redirty_page_for_writepage(wbc, page);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; unlock_page(page);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; } else {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* skip rest of the page in the page_vec
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* We can't do block allocation here
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* so just redity the page and unlock
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* and return
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; redirty_page_for_writepage(wbc, page);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;unlock_page(page);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return MPAGE_DA_EXTENT_TAIL;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 0;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* now mark the buffer_heads as dirty and uptodate */
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; block_commit_write(page, 0, len);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (PageChecked(page) &amp;&amp; ext4_should_journal_data(inode)) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* Start next extent of pages ...
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd-&amp;gt;first_page = page-&amp;gt;index;
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* ... and blocks
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* It's mmapped pagecache. &amp;nbsp;Add buffers and journal it. &amp;nbsp;There
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* doesn't seem much point in redirtying the page here.
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd-&amp;gt;b_size = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd-&amp;gt;b_state = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd-&amp;gt;b_blocknr = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ClearPageChecked(page);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return __ext4_journalled_writepage(page, len);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd-&amp;gt;next_page = page-&amp;gt;index + 1;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; logical = (sector_t) page-&amp;gt;index &amp;lt;&amp;lt;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (PAGE_CACHE_SHIFT - inode-&amp;gt;i_blkbits);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (test_opt(inode-&amp;gt;i_sb, NOBH) &amp;&amp; ext4_should_writeback_data(inode))
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = nobh_writepage(page, noalloc_get_block_write, wbc);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; else if (page_bufs &amp;&amp; buffer_uninit(page_bufs)) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_set_bh_endio(page_bufs, inode);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = block_write_full_page_endio(page, noalloc_get_block_write,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc, ext4_end_io_buffer_write);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; } else
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = block_write_full_page(page, noalloc_get_block_write,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc);
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!page_has_buffers(page)) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpage_add_bh_to_extent(mpd, logical, PAGE_CACHE_SIZE,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(1 &amp;lt;&amp;lt; BH_Dirty) | (1 &amp;lt;&amp;lt; BH_Uptodate));
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; } else {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* Page with regular buffer heads, just add all dirty ones
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; head = page_buffers(page);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; bh = head;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; do {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; BUG_ON(buffer_locked(bh));
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* We need to try to allocate
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* unmapped blocks in the same page.
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* Otherwise we won't make progress
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* with the page in ext4_writepage
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ext4_bh_delay_or_unwritten(NULL, bh)) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpage_add_bh_to_extent(mpd, logical,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;bh-&amp;gt;b_size,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;bh-&amp;gt;b_state);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; } else if (buffer_dirty(bh) &amp;&amp; (buffer_mapped(bh))) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* mapped dirty buffer. We need to update
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* the b_state because we look at
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* b_state in mpage_da_map_blocks. We don't
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* update b_size because if we find an
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* unmapped buffer_head later we need to
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* use the b_state flag of that buffer_head.
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (mpd-&amp;gt;b_size == 0)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd-&amp;gt;b_state = bh-&amp;gt;b_state &amp; BH_FLAGS;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; logical++;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; } while ((bh = bh-&amp;gt;b_this_page) != head);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; return 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; return ret;
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&lt;br&gt;-int ext4_alloc_da_blocks(struct inode *inode)
&lt;br&gt;+/*
&lt;br&gt;+ * This is called via ext4_da_writepages() to
&lt;br&gt;+ * calulate the total number of credits to reserve to fit
&lt;br&gt;+ * a single extent allocation into a single transaction,
&lt;br&gt;+ * ext4_da_writpeages() will loop calling this before
&lt;br&gt;+ * the block allocation.
&lt;br&gt;+ */
&lt;br&gt;+
&lt;br&gt;+static int ext4_da_writepages_trans_blocks(struct inode *inode)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; struct address_space *mapping = inode-&amp;gt;i_mapping;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; struct pagevec pvec;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; pgoff_t index = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; int max_blocks = EXT4_I(inode)-&amp;gt;i_reserved_data_blocks;
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* With non-extent format the journal credit needed to
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* insert nrblocks contiguous block is dependent on
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* number of contiguous block. So we will limit
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* number of contiguous block to a sane value
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!(EXT4_I(inode)-&amp;gt;i_flags &amp; EXT4_EXTENTS_FL) &amp;&amp;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (max_blocks &amp;gt; EXT4_MAX_TRANS_DATA))
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; max_blocks = EXT4_MAX_TRANS_DATA;
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; return ext4_chunk_trans_blocks(inode, max_blocks);
&lt;br&gt;+}
&lt;br&gt;+
&lt;br&gt;+static int ext4_da_writepages(struct address_space *mapping,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; struct writeback_control *wbc)
&lt;br&gt;+{
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; pgoff_t index;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; int range_whole = 0;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;handle_t *handle = NULL;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;struct mpage_da_data mpd;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; int i;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; int nr_pages;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct inode *inode = mapping-&amp;gt;host;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; int no_nrwrite_index_update;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; int pages_written = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; long pages_skipped;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; unsigned int max_pages;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; int range_cyclic, cycled = 1, io_done = 0;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;int needed_blocks, ret = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; long desired_nr_to_write, nr_to_writebump = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; loff_t range_start = wbc-&amp;gt;range_start;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;struct ext4_sb_info *sbi = EXT4_SB(mapping-&amp;gt;host-&amp;gt;i_sb);
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ext4_should_journal_data(inode))
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; trace_ext4_da_writepages(inode, wbc);
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* If no pages to write, return right away.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* No pages to write? This is mainly a kludge to avoid starting
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* a transaction for special inodes like journal inode on last iput()
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* because that could violate lock ordering on umount
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (!mapping-&amp;gt;nrpages || !mapping_tagged(mapping, PAGECACHE_TAG_DIRTY))
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return 0;
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* If the filesystem has aborted, return immediately with an
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* EROFS error.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* If the filesystem has aborted, it is read-only, so return
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* right away instead of dumping stack traces later on that
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* will obscure the real source of the problem. &amp;nbsp;We test
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* EXT4_MF_FS_ABORTED instead of sb-&amp;gt;s_flag's MS_RDONLY because
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* the latter could be true if the filesystem is mounted
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* read-only, and in that case, ext4_da_writepages should
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* *never* be called, so if that ever happens, we would want
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* the stack trace.
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (unlikely(sbi-&amp;gt;s_mount_flags &amp; EXT4_MF_FS_ABORTED))
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return -EROFS;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; printk(KERN_INFO &amp;quot;ext4_alloc_da_pages(%lu)\n&amp;quot;, inode-&amp;gt;i_ino);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (wbc-&amp;gt;range_start == 0 &amp;&amp; wbc-&amp;gt;range_end == LLONG_MAX)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; range_whole = 1;
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; range_cyclic = wbc-&amp;gt;range_cyclic;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (wbc-&amp;gt;range_cyclic) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; index = mapping-&amp;gt;writeback_index;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (index)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cycled = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;range_start = index &amp;lt;&amp;lt; PAGE_CACHE_SHIFT;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;range_end &amp;nbsp;= LLONG_MAX;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;range_cyclic = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; } else
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; index = wbc-&amp;gt;range_start &amp;gt;&amp;gt; PAGE_CACHE_SHIFT;
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* This works around two forms of stupidity. &amp;nbsp;The first is in
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* the writeback code, which caps the maximum number of pages
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* written to be 1024 pages. &amp;nbsp;This is wrong on multiple
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* levels; different architectues have a different page size,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* which changes the maximum amount of data which gets
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* written. &amp;nbsp;Secondly, 4 megabytes is way too small. &amp;nbsp;XFS
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* forces this value to be 16 megabytes by multiplying
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* nr_to_write parameter by four, and then relies on its
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* allocator to allocate larger extents to make them
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* contiguous. &amp;nbsp;Unfortunately this brings us to the second
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* stupidity, which is that ext4's mballoc code only allocates
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* at most 2048 blocks. &amp;nbsp;So we force contiguous writes up to
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* the number of dirty blocks in the inode, or
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* sbi-&amp;gt;max_writeback_mb_bump whichever is smaller.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; max_pages = sbi-&amp;gt;s_max_writeback_mb_bump &amp;lt;&amp;lt; (20 - PAGE_CACHE_SHIFT);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!range_cyclic &amp;&amp; range_whole)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; desired_nr_to_write = wbc-&amp;gt;nr_to_write * 8;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; else
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; desired_nr_to_write = ext4_num_dirty_pages(inode, index,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;max_pages);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (desired_nr_to_write &amp;gt; max_pages)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; desired_nr_to_write = max_pages;
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (wbc-&amp;gt;nr_to_write &amp;lt; desired_nr_to_write) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; nr_to_writebump = desired_nr_to_write - wbc-&amp;gt;nr_to_write;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;nr_to_write = desired_nr_to_write;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.wbc = wbc;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mpd.inode = mapping-&amp;gt;host;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; while (1) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* we don't want write_cache_pages to update
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* nr_to_write and writeback_index
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; no_nrwrite_index_update = wbc-&amp;gt;no_nrwrite_index_update;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;no_nrwrite_index_update = 1;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; pages_skipped = wbc-&amp;gt;pages_skipped;
&lt;br&gt;+
&lt;br&gt;+retry:
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; while (!ret &amp;&amp; wbc-&amp;gt;nr_to_write &amp;gt; 0) {
&lt;br&gt;+
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* we insert one extent at a time. So we need
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* we &amp;nbsp;insert one extent at a time. So we need
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; * credit needed for single extent allocation.
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; * journalled mode is currently not supported
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; * by delalloc
&lt;br&gt;@@ -3354,67 +3145,48 @@ int ext4_alloc_da_blocks(struct inode *i
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;BUG_ON(ext4_should_journal_data(inode));
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;needed_blocks = ext4_da_writepages_trans_blocks(inode);
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; pagevec_init(&amp;pvec, 0);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; nr_pages = pagevec_lookup_tag(&amp;pvec, mapping, &amp;index,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; PAGECACHE_TAG_DIRTY,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (pgoff_t)PAGEVEC_SIZE);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (nr_pages == 0)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; break;
&lt;br&gt;-
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/* start a new transaction*/
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;handle = ext4_journal_start(inode, needed_blocks);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (IS_ERR(handle))
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; break;
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.b_size = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.b_state = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.b_blocknr = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.first_page = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.next_page = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.io_done = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.pages_written = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.retval = 0;
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; do {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; for (i = 0; i &amp;lt; nr_pages; i++) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; struct page *page = pvec.pages[i];
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; lock_page(page);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (unlikely(page-&amp;gt;mapping != mapping) ||
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; !PageDirty(page) ||
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; PageWriteback(page)) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; unlock_page(page);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; continue;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = flush_alloc_da_page(page, &amp;mpd);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ret) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; pagevec_release(&amp;pvec);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto map_extent;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; pagevec_release(&amp;pvec);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cond_resched();
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; nr_pages = pagevec_lookup_tag(&amp;pvec, mapping, &amp;index,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; PAGECACHE_TAG_DIRTY,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (pgoff_t)PAGEVEC_SIZE);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; } while (nr_pages);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (IS_ERR(handle)) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = PTR_ERR(handle);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_msg(inode-&amp;gt;i_sb, KERN_CRIT, &amp;quot;%s: jbd2_start: &amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;%ld pages, ino %lu; err %d\n&amp;quot;, __func__,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;nr_to_write, inode-&amp;gt;i_ino, ret);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto out_writepages;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* Now call __mpage_da_writepage to find the next
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* contiguous region of logical blocks that need
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* blocks to be allocated by ext4. &amp;nbsp;We don't actually
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* submit the blocks for I/O here, even though
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* write_cache_pages thinks it will, and will set the
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* pages as clean for write before calling
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* __mpage_da_writepage().
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.b_size = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.b_state = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.b_blocknr = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.first_page = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.next_page = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.io_done = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.pages_written = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.retval = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = write_cache_pages(mapping, wbc, __mpage_da_writepage,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;mpd);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; * If we have a contigous extent of pages and we
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; * haven't done the I/O yet, map the blocks and submit
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; * them for I/O.
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; map_extent:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (!mpd.io_done &amp;&amp; mpd.next_page != mpd.first_page) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; printk(KERN_INFO
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;ext4_alloc_da_blocks map_blocks: &amp;quot;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;ino %lu blk %llu, size %u\n&amp;quot;,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mpd.inode-&amp;gt;i_ino, mpd.b_blocknr,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mpd.b_size &amp;gt;&amp;gt; mpd.inode-&amp;gt;i_blkbits);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpage_da_map_blocks(&amp;mpd);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (mpage_da_map_blocks(&amp;mpd) == 0)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpage_da_submit_io(&amp;mpd);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.io_done = 1;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = MPAGE_DA_EXTENT_TAIL;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; trace_ext4_da_write_pages(inode, &amp;mpd);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;nr_to_write -= mpd.pages_written;
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ext4_journal_stop(handle);
&lt;br&gt;&lt;br&gt;@@ -3424,484 +3196,707 @@ int ext4_alloc_da_blocks(struct inode *i
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; * and try again
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;jbd2_journal_force_commit_nested(sbi-&amp;gt;s_journal);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;pages_skipped = pages_skipped;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; } else if (ret == MPAGE_DA_EXTENT_TAIL) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* got one extent now try with
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* rest of the pages
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; pages_written += mpd.pages_written;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;pages_skipped = pages_skipped;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; io_done = 1;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; } else if (wbc-&amp;gt;nr_to_write)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* There is no more writeout needed
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* or we requested for a noblocking writeout
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* and we found the device congested
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; break;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; printk(KERN_INFO &amp;quot;ext4_alloc_da_pages(%lu) exit\n&amp;quot;, inode-&amp;gt;i_ino);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!io_done &amp;&amp; !cycled) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cycled = 1;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; index = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;range_start = index &amp;lt;&amp;lt; PAGE_CACHE_SHIFT;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;range_end &amp;nbsp;= mapping-&amp;gt;writeback_index - 1;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto retry;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (pages_skipped != wbc-&amp;gt;pages_skipped)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_msg(inode-&amp;gt;i_sb, KERN_CRIT,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;This should not happen leaving %s &amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;with nr_to_write = %ld ret = %d\n&amp;quot;,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;__func__, wbc-&amp;gt;nr_to_write, ret);
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; /* Update index */
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; index += pages_written;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;range_cyclic = range_cyclic;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (wbc-&amp;gt;range_cyclic || (range_whole &amp;&amp; wbc-&amp;gt;nr_to_write &amp;gt; 0))
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* set the writeback_index so that range_cyclic
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* mode will write it back later
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mapping-&amp;gt;writeback_index = index;
&lt;br&gt;+
&lt;br&gt;+out_writepages:
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!no_nrwrite_index_update)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;no_nrwrite_index_update = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (wbc-&amp;gt;nr_to_write &amp;gt; nr_to_writebump)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;nr_to_write -= nr_to_writebump;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc-&amp;gt;range_start = range_start;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; trace_ext4_da_writepages_result(inode, wbc, ret, pages_written);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return ret;
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;-#endif
&lt;br&gt;&lt;br&gt;-/*
&lt;br&gt;- * bmap() is special. &amp;nbsp;It gets used by applications such as lilo and by
&lt;br&gt;- * the swapper to find the on-disk block of a specific piece of data.
&lt;br&gt;- *
&lt;br&gt;- * Naturally, this is dangerous if the block concerned is still in the
&lt;br&gt;- * journal. &amp;nbsp;If somebody makes a swapfile on an ext4 data-journaling
&lt;br&gt;- * filesystem and enables swap, then they may get a nasty shock when the
&lt;br&gt;- * data getting swapped to that swapfile suddenly gets overwritten by
&lt;br&gt;- * the original zero's written out previously to the journal and
&lt;br&gt;- * awaiting writeback in the kernel's buffer cache.
&lt;br&gt;- *
&lt;br&gt;- * So, if we see any bmap calls here on a modified, data-journaled file,
&lt;br&gt;- * take extra steps to flush any blocks which might be in the cache.
&lt;br&gt;- */
&lt;br&gt;-static sector_t ext4_bmap(struct address_space *mapping, sector_t block)
&lt;br&gt;+#define FALL_BACK_TO_NONDELALLOC 1
&lt;br&gt;+static int ext4_nonda_switch(struct super_block *sb)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; struct inode *inode = mapping-&amp;gt;host;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; journal_t *journal;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; int err;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; s64 free_blocks, dirty_blocks;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct ext4_sb_info *sbi = EXT4_SB(sb);
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (mapping_tagged(mapping, PAGECACHE_TAG_DIRTY) &amp;&amp;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; test_opt(inode-&amp;gt;i_sb, DELALLOC)) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* switch to non delalloc mode if we are running low
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* on free block. The free block accounting via percpu
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* counters can get slightly wrong with percpu_counter_batch getting
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* accumulated on each CPU without updating global counters
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* Delalloc need an accurate free block accounting. So switch
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* to non delalloc when we are near to error range.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; free_blocks &amp;nbsp;= percpu_counter_read_positive(&amp;sbi-&amp;gt;s_freeblocks_counter);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; dirty_blocks =
&lt;br&gt;percpu_counter_read_positive(&amp;sbi-&amp;gt;s_dirtyblocks_counter);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (2 * free_blocks &amp;lt; 3 * dirty_blocks ||
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; free_blocks &amp;lt; (dirty_blocks + EXT4_FREEBLOCKS_WATERMARK)) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* With delalloc we want to sync the file
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* so that we can make sure we allocate
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* blocks for file
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* free block count is less that 150% of dirty blocks
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* or free blocks is less that watermark
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; filemap_write_and_wait(mapping);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 1;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; return 0;
&lt;br&gt;+}
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (EXT4_JOURNAL(inode) &amp;&amp; EXT4_I(inode)-&amp;gt;i_state &amp; EXT4_STATE_JDATA) {
&lt;br&gt;+static int ext4_da_write_begin(struct file *file, struct
&lt;br&gt;address_space *mapping,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;loff_t pos, unsigned len, unsigned flags,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;struct page **pagep, void **fsdata)
&lt;br&gt;+{
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; int ret, retries = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct page *page;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; pgoff_t index;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; unsigned from, to;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct inode *inode = mapping-&amp;gt;host;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; handle_t *handle;
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; index = pos &amp;gt;&amp;gt; PAGE_CACHE_SHIFT;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; from = pos &amp; (PAGE_CACHE_SIZE - 1);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; to = from + len;
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ext4_nonda_switch(inode-&amp;gt;i_sb)) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; *fsdata = (void *)FALL_BACK_TO_NONDELALLOC;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return ext4_write_begin(file, mapping, pos,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; len, flags, pagep, fsdata);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; *fsdata = (void *)0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; trace_ext4_da_write_begin(inode, pos, len, flags);
&lt;br&gt;+retry:
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* With delayed allocation, we don't log the i_disksize update
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* if there is delayed block allocation. But we still need
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* to journalling the i_disksize update if writes to the end
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* of file which has an already mapped buffer.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; handle = ext4_journal_start(inode, 1);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (IS_ERR(handle)) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = PTR_ERR(handle);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto out;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; /* We cannot recurse into the filesystem as the transaction is already
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* started */
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; flags |= AOP_FLAG_NOFS;
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; page = grab_cache_page_write_begin(mapping, index, flags);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!page) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_journal_stop(handle);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = -ENOMEM;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto out;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; *pagep = page;
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_da_get_block_prep);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ret &amp;lt; 0) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; unlock_page(page);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_journal_stop(handle);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; page_cache_release(page);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* This is a REALLY heavyweight approach, but the use of
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* bmap on dirty files is expected to be extremely rare:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* only if we run lilo or swapon on a freshly made file
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* do we expect this to happen.
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* (bmap requires CAP_SYS_RAWIO so this does not
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* represent an unprivileged user DOS attack --- we'd be
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* in trouble if mortal users could trigger this path at
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* will.)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* NB. EXT4_STATE_JDATA is not set on files other than
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* regular files. &amp;nbsp;If somebody wants to bmap a directory
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* or symlink and gets confused because the buffer
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* hasn't yet been flushed to disk, they deserve
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* everything they get.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* block_write_begin may have instantiated a few blocks
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* outside i_size. &amp;nbsp;Trim these off again. Don't need
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* i_size_read because we hold i_mutex.
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (pos + len &amp;gt; inode-&amp;gt;i_size)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_truncate(inode);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; EXT4_I(inode)-&amp;gt;i_state &amp;= ~EXT4_STATE_JDATA;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; journal = EXT4_JOURNAL(inode);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; jbd2_journal_lock_updates(journal);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; err = jbd2_journal_flush(journal);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; jbd2_journal_unlock_updates(journal);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ret == -ENOSPC &amp;&amp; ext4_should_retry_alloc(inode-&amp;gt;i_sb, &amp;retries))
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto retry;
&lt;br&gt;+out:
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; return ret;
&lt;br&gt;+}
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (err)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 0;
&lt;br&gt;+/*
&lt;br&gt;+ * Check if we should update i_disksize
&lt;br&gt;+ * when write to the end of file but not require block allocation
&lt;br&gt;+ */
&lt;br&gt;+static int ext4_da_should_update_i_disksize(struct page *page,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; unsigned long offset)
&lt;br&gt;+{
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct buffer_head *bh;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct inode *inode = page-&amp;gt;mapping-&amp;gt;host;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; unsigned int idx;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; int i;
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; bh = page_buffers(page);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; idx = offset &amp;gt;&amp;gt; inode-&amp;gt;i_blkbits;
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; for (i = 0; i &amp;lt; idx; i++)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; bh = bh-&amp;gt;b_this_page;
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!buffer_mapped(bh) || (buffer_delay(bh)) || buffer_unwritten(bh))
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; return 1;
&lt;br&gt;+}
&lt;br&gt;+
&lt;br&gt;+static int ext4_da_write_end(struct file *file,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;struct address_space *mapping,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;loff_t pos, unsigned len, unsigned copied,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;struct page *page, void *fsdata)
&lt;br&gt;+{
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct inode *inode = mapping-&amp;gt;host;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; int ret = 0, ret2;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; handle_t *handle = ext4_journal_current_handle();
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; loff_t new_i_size;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; unsigned long start, end;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; int write_mode = (int)(unsigned long)fsdata;
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (write_mode == FALL_BACK_TO_NONDELALLOC) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ext4_should_order_data(inode)) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return ext4_ordered_write_end(file, mapping, pos,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; len, copied, page, fsdata);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; } else if (ext4_should_writeback_data(inode)) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return ext4_writeback_write_end(file, mapping, pos,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; len, copied, page, fsdata);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; } else {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; BUG();
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; return generic_block_bmap(mapping, block, ext4_get_block);
&lt;br&gt;-}
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; trace_ext4_da_write_end(inode, pos, len, copied);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; start = pos &amp; (PAGE_CACHE_SIZE - 1);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; end = start + copied - 1;
&lt;br&gt;&lt;br&gt;-static int ext4_readpage(struct file *file, struct page *page)
&lt;br&gt;-{
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; return mpage_readpage(page, ext4_get_block);
&lt;br&gt;-}
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* generic_write_end() will run mark_inode_dirty() if i_size
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* changes. &amp;nbsp;So let's piggyback the i_disksize mark_inode_dirty
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* into that.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;&lt;br&gt;-static int
&lt;br&gt;-ext4_readpages(struct file *file, struct address_space *mapping,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; struct list_head *pages, unsigned nr_pages)
&lt;br&gt;-{
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; return mpage_readpages(mapping, pages, nr_pages, ext4_get_block);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; new_i_size = pos + copied;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (new_i_size &amp;gt; EXT4_I(inode)-&amp;gt;i_disksize) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ext4_da_should_update_i_disksize(page, end)) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; down_write(&amp;EXT4_I(inode)-&amp;gt;i_data_sem);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (new_i_size &amp;gt; EXT4_I(inode)-&amp;gt;i_disksize) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* Updating i_disksize when extending file
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* without needing block allocation
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ext4_should_order_data(inode))
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = ext4_jbd2_file_inode(handle,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;inode);
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; EXT4_I(inode)-&amp;gt;i_disksize = new_i_size;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; up_write(&amp;EXT4_I(inode)-&amp;gt;i_data_sem);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* We need to mark inode dirty even if
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* new_i_size is less that inode-&amp;gt;i_size
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* bu greater than i_disksize.(hint delalloc)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_mark_inode_dirty(handle, inode);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ret2 = generic_write_end(file, mapping, pos, len, copied,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; page, fsdata);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; copied = ret2;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ret2 &amp;lt; 0)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = ret2;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ret2 = ext4_journal_stop(handle);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!ret)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = ret2;
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; return ret ? ret : copied;
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&lt;br&gt;-static void ext4_invalidatepage(struct page *page, unsigned long offset)
&lt;br&gt;+static void ext4_da_invalidatepage(struct page *page, unsigned long offset)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; journal_t *journal = EXT4_JOURNAL(page-&amp;gt;mapping-&amp;gt;host);
&lt;br&gt;-
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* If it's a full truncate we just forget about the pending dirtying
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* Drop reserved blocks
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (offset == 0)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ClearPageChecked(page);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; BUG_ON(!PageLocked(page));
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!page_has_buffers(page))
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto out;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (journal)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; jbd2_journal_invalidatepage(journal, page, offset);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; else
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; block_invalidatepage(page, offset);
&lt;br&gt;-}
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_da_page_release_reservation(page, offset);
&lt;br&gt;&lt;br&gt;-static int ext4_releasepage(struct page *page, gfp_t wait)
&lt;br&gt;-{
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; journal_t *journal = EXT4_JOURNAL(page-&amp;gt;mapping-&amp;gt;host);
&lt;br&gt;+out:
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_invalidatepage(page, offset);
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; WARN_ON(PageChecked(page));
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!page_has_buffers(page))
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (journal)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return jbd2_journal_try_to_free_buffers(journal, page, wait);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; else
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return try_to_free_buffers(page);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; return;
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&lt;br&gt;&amp;nbsp;/*
&lt;br&gt;- * O_DIRECT for ext3 (or indirect map) based files
&lt;br&gt;- *
&lt;br&gt;- * If the O_DIRECT write will extend the file then add this inode to the
&lt;br&gt;- * orphan list. &amp;nbsp;So recovery will truncate it back to the original size
&lt;br&gt;- * if the machine crashes during the write.
&lt;br&gt;- *
&lt;br&gt;- * If the O_DIRECT write is intantiating holes inside i_size and the machine
&lt;br&gt;- * crashes then stale disk data _may_ be exposed inside the file. But current
&lt;br&gt;- * VFS code falls back into buffered path in that case so we are safe.
&lt;br&gt;+ * Force all delayed allocation blocks to be allocated for a given inode.
&lt;br&gt;&amp;nbsp;*/
&lt;br&gt;-static ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; const struct iovec *iov, loff_t offset,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; unsigned long nr_segs)
&lt;br&gt;+#if 1
&lt;br&gt;+int ext4_alloc_da_blocks(struct inode *inode)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; struct file *file = iocb-&amp;gt;ki_filp;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; struct inode *inode = file-&amp;gt;f_mapping-&amp;gt;host;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; struct ext4_inode_info *ei = EXT4_I(inode);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; handle_t *handle;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ssize_t ret;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; int orphan = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; size_t count = iov_length(iov, nr_segs);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; int retries = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; trace_ext4_alloc_da_blocks(inode);
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (rw == WRITE) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; loff_t final_size = offset + count;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!EXT4_I(inode)-&amp;gt;i_reserved_data_blocks &amp;&amp;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; !EXT4_I(inode)-&amp;gt;i_reserved_meta_blocks)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 0;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (final_size &amp;gt; inode-&amp;gt;i_size) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* Credits for sb + inode write */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; handle = ext4_journal_start(inode, 2);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (IS_ERR(handle)) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = PTR_ERR(handle);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto out;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = ext4_orphan_add(handle, inode);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ret) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_journal_stop(handle);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto out;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; orphan = 1;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ei-&amp;gt;i_disksize = inode-&amp;gt;i_size;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_journal_stop(handle);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* We do something simple for now. &amp;nbsp;The filemap_flush() will
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* also start triggering a write of the data blocks, which is
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* not strictly speaking necessary (and for users of
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* laptop_mode, not even desirable). &amp;nbsp;However, to do otherwise
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* would require replicating code paths in:
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* ext4_da_writepages() -&amp;gt;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* &amp;nbsp; &amp;nbsp;write_cache_pages() ---&amp;gt; (via passed in callback function)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;__mpage_da_writepage() --&amp;gt;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpage_add_bh_to_extent()
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpage_da_map_blocks()
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* The problem is that write_cache_pages(), located in
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* mm/page-writeback.c, marks pages clean in preparation for
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* doing I/O, which is not desirable if we're not planning on
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* doing I/O at all.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* We could call write_cache_pages(), and then redirty all of
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* the pages by calling redirty_page_for_writeback() but that
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* would be ugly in the extreme. &amp;nbsp;So instead we would need to
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* replicate parts of the code in the above functions,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* simplifying them becuase we wouldn't actually intend to
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* write out the pages, but rather only collect contiguous
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* logical block extents, call the multi-block allocator, and
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* then update the buffer heads with the block allocations.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* For now, though, we'll cheat by calling filemap_flush(),
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* which will map the blocks, and start the I/O, but not
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* actually wait for the I/O to complete.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; return filemap_flush(inode-&amp;gt;i_mapping);
&lt;br&gt;+}
&lt;br&gt;+#else
&lt;br&gt;+static int flush_alloc_da_page(struct page *page, struct mpage_da_data *mpd)
&lt;br&gt;+{
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct inode *inode = mpd-&amp;gt;inode;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct buffer_head *bh, *head;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; sector_t logical;
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* Can we merge this page to current extent?
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (mpd-&amp;gt;next_page != page-&amp;gt;index) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* Nope, we can't. So, we map non-allocated blocks
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* and start IO on them using writepage()
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (mpd-&amp;gt;next_page != mpd-&amp;gt;first_page) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; printk(KERN_INFO
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;flush_alloc_da_page map_blocks: &amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;ino %lu blk %llu, size %u\n&amp;quot;,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mpd-&amp;gt;inode-&amp;gt;i_ino, mpd-&amp;gt;b_blocknr,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mpd-&amp;gt;b_size &amp;gt;&amp;gt; mpd-&amp;gt;inode-&amp;gt;i_blkbits);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpage_da_map_blocks(mpd);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* skip rest of the page in the page_vec
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; unlock_page(page);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return MPAGE_DA_EXTENT_TAIL;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;&lt;br&gt;-retry:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (rw == READ &amp;&amp; test_opt(inode-&amp;gt;i_sb, DIOREAD_NOLOCK)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;&amp; (EXT4_I(inode)-&amp;gt;i_flags &amp; EXT4_EXTENTS_FL))
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = blockdev_direct_IO_no_locking(rw, iocb, inode,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;inode-&amp;gt;i_sb-&amp;gt;s_bdev, iov,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;offset, nr_segs,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ext4_get_block, NULL);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; else
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = blockdev_direct_IO(rw, iocb, inode,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;inode-&amp;gt;i_sb-&amp;gt;s_bdev, iov,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;offset, nr_segs,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ext4_get_block, NULL);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ret == -ENOSPC &amp;&amp; ext4_should_retry_alloc(inode-&amp;gt;i_sb, &amp;retries))
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto retry;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* Start next extent of pages ...
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd-&amp;gt;first_page = page-&amp;gt;index;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (orphan) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; int err;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* ... and blocks
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd-&amp;gt;b_size = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd-&amp;gt;b_state = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd-&amp;gt;b_blocknr = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* Credits for sb + inode write */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; handle = ext4_journal_start(inode, 2);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (IS_ERR(handle)) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* This is really bad luck. We've written the data
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* but cannot extend i_size. Bail out and pretend
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* the write failed... */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = PTR_ERR(handle);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto out;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (inode-&amp;gt;i_nlink)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_orphan_del(handle, inode);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ret &amp;gt; 0) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; loff_t end = offset + ret;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (end &amp;gt; inode-&amp;gt;i_size) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ei-&amp;gt;i_disksize = end;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; i_size_write(inode, end);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd-&amp;gt;next_page = page-&amp;gt;index + 1;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; logical = (sector_t) page-&amp;gt;index &amp;lt;&amp;lt;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (PAGE_CACHE_SHIFT - inode-&amp;gt;i_blkbits);
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!page_has_buffers(page)) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpage_add_bh_to_extent(mpd, logical, PAGE_CACHE_SIZE,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(1 &amp;lt;&amp;lt; BH_Dirty) | (1 &amp;lt;&amp;lt; BH_Uptodate));
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; } else {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* Page with regular buffer heads, just add all dirty ones
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; head = page_buffers(page);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; bh = head;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; do {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; BUG_ON(buffer_locked(bh));
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* We need to try to allocate
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* unmapped blocks in the same page.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* Otherwise we won't make progress
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* with the page in ext4_writepage
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ext4_bh_delay_or_unwritten(NULL, bh)) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpage_add_bh_to_extent(mpd, logical,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;bh-&amp;gt;b_size,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;bh-&amp;gt;b_state);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; } else if (buffer_dirty(bh) &amp;&amp; (buffer_mapped(bh))) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* We're going to return a positive `ret'
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* here due to non-zero-length I/O, so there's
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* no way of reporting error returns from
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* ext4_mark_inode_dirty() to userspace. &amp;nbsp;So
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* ignore it.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* mapped dirty buffer. We need to update
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* the b_state because we look at
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* b_state in mpage_da_map_blocks. We don't
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* update b_size because if we find an
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* unmapped buffer_head later we need to
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* use the b_state flag of that buffer_head.
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_mark_inode_dirty(handle, inode);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (mpd-&amp;gt;b_size == 0)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd-&amp;gt;b_state = bh-&amp;gt;b_state &amp; BH_FLAGS;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; err = ext4_journal_stop(handle);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ret == 0)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = err;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; logical++;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; } while ((bh = bh-&amp;gt;b_this_page) != head);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;-out:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; return ret;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; return 0;
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&lt;br&gt;-static int ext4_get_block_write(struct inode *inode, sector_t iblock,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;struct buffer_head *bh_result, int create)
&lt;br&gt;+int ext4_alloc_da_blocks(struct inode *inode)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; handle_t *handle = ext4_journal_current_handle();
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; int ret = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; unsigned max_blocks = bh_result-&amp;gt;b_size &amp;gt;&amp;gt; inode-&amp;gt;i_blkbits;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; int dio_credits;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; int started = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct address_space *mapping = inode-&amp;gt;i_mapping;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct pagevec pvec;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; pgoff_t index = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; handle_t *handle = NULL;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct mpage_da_data mpd;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; int i;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; int nr_pages;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; int needed_blocks, ret = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct ext4_sb_info *sbi = EXT4_SB(mapping-&amp;gt;host-&amp;gt;i_sb);
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ext4_should_journal_data(inode))
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 0;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_debug(&amp;quot;ext4_get_block_write: inode %lu, create flag %d\n&amp;quot;,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;inode-&amp;gt;i_ino, create);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* ext4_get_block in prepare for a DIO write or buffer write.
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* We allocate an uinitialized extent if blocks haven't been allocated.
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* The extent will be converted to initialized after IO complete.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* If no pages to write, return right away.
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; create = EXT4_GET_BLOCKS_IO_CREATE_EXT;
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!handle) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (max_blocks &amp;gt; DIO_MAX_BLOCKS)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; max_blocks = DIO_MAX_BLOCKS;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dio_credits = ext4_chunk_trans_blocks(inode, max_blocks);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; handle = ext4_journal_start(inode, dio_credits);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (IS_ERR(handle)) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = PTR_ERR(handle);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto out;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; started = 1;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = ext4_get_blocks(handle, inode, iblock, max_blocks, bh_result,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; create);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ret &amp;gt; 0) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; bh_result-&amp;gt;b_size = (ret &amp;lt;&amp;lt; inode-&amp;gt;i_blkbits);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (started)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_journal_stop(handle);
&lt;br&gt;-out:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; return ret;
&lt;br&gt;-}
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!mapping-&amp;gt;nrpages || !mapping_tagged(mapping, PAGECACHE_TAG_DIRTY))
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 0;
&lt;br&gt;&lt;br&gt;-static void ext4_free_io_end(ext4_io_end_t *io)
&lt;br&gt;-{
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; BUG_ON(!io);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; iput(io-&amp;gt;inode);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; kfree(io);
&lt;br&gt;-}
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* If the filesystem has aborted, return immediately with an
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* EROFS error.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (unlikely(sbi-&amp;gt;s_mount_flags &amp; EXT4_MF_FS_ABORTED))
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return -EROFS;
&lt;br&gt;&lt;br&gt;-static void dump_completed_IO(struct inode * inode)
&lt;br&gt;-{
&lt;br&gt;-#ifdef EXT4_DEBUG
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; struct list_head *cur, *before, *after;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_io_end_t *io, *io0, *io1;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; printk(KERN_INFO &amp;quot;ext4_alloc_da_pages(%lu)\n&amp;quot;, inode-&amp;gt;i_ino);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.inode = mapping-&amp;gt;host;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (list_empty(&amp;EXT4_I(inode)-&amp;gt;i_completed_io_list)){
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_debug(&amp;quot;inode %lu completed_io list is empty\n&amp;quot;,
&lt;br&gt;inode-&amp;gt;i_ino);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; while (1) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* we insert one extent at a time. So we need
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* credit needed for single extent allocation.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* journalled mode is currently not supported
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* by delalloc
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; BUG_ON(ext4_should_journal_data(inode));
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; needed_blocks = ext4_da_writepages_trans_blocks(inode);
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_debug(&amp;quot;Dump inode %lu completed_io list \n&amp;quot;, inode-&amp;gt;i_ino);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; list_for_each_entry(io, &amp;EXT4_I(inode)-&amp;gt;i_completed_io_list, list){
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cur = &amp;io-&amp;gt;list;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; before = cur-&amp;gt;prev;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; io0 = container_of(before, ext4_io_end_t, list);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; after = cur-&amp;gt;next;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; io1 = container_of(after, ext4_io_end_t, list);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; pagevec_init(&amp;pvec, 0);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; nr_pages = pagevec_lookup_tag(&amp;pvec, mapping, &amp;index,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; PAGECACHE_TAG_DIRTY,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (pgoff_t)PAGEVEC_SIZE);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (nr_pages == 0)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; break;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_debug(&amp;quot;io 0x%p from inode %lu,prev 0x%p,next 0x%p\n&amp;quot;,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; io, inode-&amp;gt;i_ino, io0, io1);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;-#endif
&lt;br&gt;-}
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* start a new transaction*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; handle = ext4_journal_start(inode, needed_blocks);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (IS_ERR(handle))
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; break;
&lt;br&gt;&lt;br&gt;-/*
&lt;br&gt;- * check a range of space and convert unwritten extents to written.
&lt;br&gt;- */
&lt;br&gt;-static int ext4_end_io_nolock(ext4_io_end_t *io)
&lt;br&gt;-{
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; struct inode *inode = io-&amp;gt;inode;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; loff_t offset = io-&amp;gt;offset;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; size_t size = io-&amp;gt;size;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; int ret = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.b_size = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.b_state = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.b_blocknr = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.first_page = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.next_page = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.io_done = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.pages_written = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpd.retval = 0;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_debug(&amp;quot;ext4_end_io_nolock: io 0x%p from inode %lu,list-&amp;gt;next 0x%p,&amp;quot;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;list-&amp;gt;prev 0x%p\n&amp;quot;,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;io, inode-&amp;gt;i_ino, io-&amp;gt;list.next, io-&amp;gt;list.prev);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; do {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; for (i = 0; i &amp;lt; nr_pages; i++) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; struct page *page = pvec.pages[i];
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (list_empty(&amp;io-&amp;gt;list))
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return ret;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; lock_page(page);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (unlikely(page-&amp;gt;mapping != mapping) ||
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; !PageDirty(page) ||
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; PageWriteback(page)) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; unlock_page(page);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; continue;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (io-&amp;gt;flag != EXT4_IO_WRITTEN)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return ret;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = flush_alloc_da_page(page, &amp;mpd);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ret) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; pagevec_release(&amp;pvec);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto map_extent;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; pagevec_release(&amp;pvec);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cond_resched();
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = ext4_convert_unwritten_extents(inode, offset, size);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ret &amp;lt; 0) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; printk(KERN_EMERG &amp;quot;%s: failed to convert unwritten&amp;quot;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;quot;extents to written extents, error is %d&amp;quot;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;quot; io is still on inode %lu aio dio list\n&amp;quot;,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; __func__, ret, inode-&amp;gt;i_ino);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return ret;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; nr_pages = pagevec_lookup_tag(&amp;pvec, mapping, &amp;index,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; PAGECACHE_TAG_DIRTY,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (pgoff_t)PAGEVEC_SIZE);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; } while (nr_pages);
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; /* clear the DIO AIO unwritten flag */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; io-&amp;gt;flag = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; return ret;
&lt;br&gt;-}
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* If we have a contigous extent of pages and we
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* haven't done the I/O yet, map the blocks and submit
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* them for I/O.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; map_extent:
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!mpd.io_done &amp;&amp; mpd.next_page != mpd.first_page) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; printk(KERN_INFO
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;ext4_alloc_da_blocks map_blocks: &amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;ino %lu blk %llu, size %u\n&amp;quot;,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mpd.inode-&amp;gt;i_ino, mpd.b_blocknr,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mpd.b_size &amp;gt;&amp;gt; mpd.inode-&amp;gt;i_blkbits);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mpage_da_map_blocks(&amp;mpd);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;&lt;br&gt;-/*
&lt;br&gt;- * work on completed aio dio IO, to convert unwritten extents to extents
&lt;br&gt;- */
&lt;br&gt;-static void ext4_end_io_work(struct work_struct *work)
&lt;br&gt;-{
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_io_end_t *io &amp;nbsp;= container_of(work, ext4_io_end_t, work);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; struct inode *inode = io-&amp;gt;inode;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; int ret = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_journal_stop(handle);
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; mutex_lock(&amp;inode-&amp;gt;i_mutex);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = ext4_end_io_nolock(io);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ret &amp;gt;= 0) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!list_empty(&amp;io-&amp;gt;list))
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; list_del_init(&amp;io-&amp;gt;list);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_free_io_end(io);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if ((mpd.retval == -ENOSPC) &amp;&amp; sbi-&amp;gt;s_journal) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* commit the transaction which would
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* free blocks released in the transaction
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* and try again
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; jbd2_journal_force_commit_nested(sbi-&amp;gt;s_journal);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; mutex_unlock(&amp;inode-&amp;gt;i_mutex);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; printk(KERN_INFO &amp;quot;ext4_alloc_da_pages(%lu) exit\n&amp;quot;, inode-&amp;gt;i_ino);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; return ret;
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;+#endif
&lt;br&gt;&lt;br&gt;&amp;nbsp;/*
&lt;br&gt;- * This function is called from ext4_sync_file().
&lt;br&gt;+ * bmap() is special. &amp;nbsp;It gets used by applications such as lilo and by
&lt;br&gt;+ * the swapper to find the on-disk block of a specific piece of data.
&lt;br&gt;&amp;nbsp;*
&lt;br&gt;- * When IO is completed, the work to convert unwritten extents to
&lt;br&gt;- * written is queued on workqueue but may not get immediately
&lt;br&gt;- * scheduled. When fsync is called, we need to ensure the
&lt;br&gt;- * conversion is complete before fsync returns.
&lt;br&gt;- * The inode keeps track of a list of pending/completed IO that
&lt;br&gt;- * might needs to do the conversion. This function walks through
&lt;br&gt;- * the list and convert the related unwritten extents for completed IO
&lt;br&gt;- * to written.
&lt;br&gt;- * The function return the number of pending IOs on success.
&lt;br&gt;+ * Naturally, this is dangerous if the block concerned is still in the
&lt;br&gt;+ * journal. &amp;nbsp;If somebody makes a swapfile on an ext4 data-journaling
&lt;br&gt;+ * filesystem and enables swap, then they may get a nasty shock when the
&lt;br&gt;+ * data getting swapped to that swapfile suddenly gets overwritten by
&lt;br&gt;+ * the original zero's written out previously to the journal and
&lt;br&gt;+ * awaiting writeback in the kernel's buffer cache.
&lt;br&gt;+ *
&lt;br&gt;+ * So, if we see any bmap calls here on a modified, data-journaled file,
&lt;br&gt;+ * take extra steps to flush any blocks which might be in the cache.
&lt;br&gt;&amp;nbsp;*/
&lt;br&gt;-int flush_completed_IO(struct inode *inode)
&lt;br&gt;+static sector_t ext4_bmap(struct address_space *mapping, sector_t block)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_io_end_t *io, *tmp;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; int ret = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; int ret2 = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct inode *inode = mapping-&amp;gt;host;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; journal_t *journal;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; int err;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (list_empty(&amp;EXT4_I(inode)-&amp;gt;i_completed_io_list))
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return ret;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (mapping_tagged(mapping, PAGECACHE_TAG_DIRTY) &amp;&amp;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; test_opt(inode-&amp;gt;i_sb, DELALLOC)) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* With delalloc we want to sync the file
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* so that we can make sure we allocate
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* blocks for file
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; filemap_write_and_wait(mapping);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; dump_completed_IO(inode);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; list_for_each_entry_safe(io, tmp,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;EXT4_I(inode)-&amp;gt;i_completed_io_list, list) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (io-&amp;gt;flag == EXT4_IO_UNWRITTEN)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; continue;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (EXT4_JOURNAL(inode) &amp;&amp; EXT4_I(inode)-&amp;gt;i_state &amp; EXT4_STATE_JDATA) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* Calling ext4_end_io_nolock() to convert completed
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* IO to written.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* This is a REALLY heavyweight approach, but the use of
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* bmap on dirty files is expected to be extremely rare:
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* only if we run lilo or swapon on a freshly made file
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* do we expect this to happen.
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; *
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* When ext4_sync_file() is called, run_queue() may already
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* about to flush the work corresponding to this io structure.
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* It will be upset if it founds the io structure related
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* to the work-to-be schedule is freed.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* (bmap requires CAP_SYS_RAWIO so this does not
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* represent an unprivileged user DOS attack --- we'd be
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* in trouble if mortal users could trigger this path at
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* will.)
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; *
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* Thus we need to keep the io structure still valid here after
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* convertion finished. The io structure has a flag to
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* avoid double converting from both fsync and background work
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* queue work.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* NB. EXT4_STATE_JDATA is not set on files other than
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* regular files. &amp;nbsp;If somebody wants to bmap a directory
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* or symlink and gets confused because the buffer
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* hasn't yet been flushed to disk, they deserve
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* everything they get.
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = ext4_end_io_nolock(io);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ret &amp;lt; 0)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret2 = ret;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; else
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; list_del_init(&amp;io-&amp;gt;list);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; return (ret2 &amp;lt; 0) ? ret2 : 0;
&lt;br&gt;-}
&lt;br&gt;-
&lt;br&gt;-static ext4_io_end_t *ext4_init_io_end (struct inode *inode)
&lt;br&gt;-{
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_io_end_t *io = NULL;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; io = kmalloc(sizeof(*io), GFP_NOFS);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; EXT4_I(inode)-&amp;gt;i_state &amp;= ~EXT4_STATE_JDATA;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; journal = EXT4_JOURNAL(inode);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; jbd2_journal_lock_updates(journal);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; err = jbd2_journal_flush(journal);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; jbd2_journal_unlock_updates(journal);
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (io) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; igrab(inode);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; io-&amp;gt;inode = inode;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; io-&amp;gt;flag = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; io-&amp;gt;offset = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; io-&amp;gt;size = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; io-&amp;gt;error = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; INIT_WORK(&amp;io-&amp;gt;work, ext4_end_io_work);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; INIT_LIST_HEAD(&amp;io-&amp;gt;list);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (err)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 0;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; return io;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; return generic_block_bmap(mapping, block, ext4_get_block);
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&lt;br&gt;-static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ssize_t size, void *private)
&lt;br&gt;+static int ext4_readpage(struct file *file, struct page *page)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ext4_io_end_t *io_end = iocb-&amp;gt;private;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; struct workqueue_struct *wq;
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; /* if not async direct IO or dio with 0 bytes write, just return */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!io_end || !size)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return;
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ext_debug(&amp;quot;ext4_end_io_dio(): io_end 0x%p&amp;quot;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;quot;for inode %lu, iocb 0x%p, offset %llu, size %llu\n&amp;quot;,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; iocb-&amp;gt;private, io_end-&amp;gt;inode-&amp;gt;i_ino, iocb, offset,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; size);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; return mpage_readpage(page, ext4_get_block);
&lt;br&gt;+}
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; /* if not aio dio with unwritten extents, just free io and return */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (io_end-&amp;gt;flag != EXT4_IO_UNWRITTEN){
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_free_io_end(io_end);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; iocb-&amp;gt;private = NULL;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+static int
&lt;br&gt;+ext4_readpages(struct file *file, struct address_space *mapping,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; struct list_head *pages, unsigned nr_pages)
&lt;br&gt;+{
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; return mpage_readpages(mapping, pages, nr_pages, ext4_get_block);
&lt;br&gt;+}
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; io_end-&amp;gt;offset = offset;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; io_end-&amp;gt;size = size;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; io_end-&amp;gt;flag = EXT4_IO_WRITTEN;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; wq = EXT4_SB(io_end-&amp;gt;inode-&amp;gt;i_sb)-&amp;gt;dio_unwritten_wq;
&lt;br&gt;+static void ext4_invalidatepage(struct page *page, unsigned long offset)
&lt;br&gt;+{
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; journal_t *journal = EXT4_JOURNAL(page-&amp;gt;mapping-&amp;gt;host);
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; /* queue the work to convert unwritten extents to written */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; queue_work(wq, &amp;io_end-&amp;gt;work);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* If it's a full truncate we just forget about the pending dirtying
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (offset == 0)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ClearPageChecked(page);
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; /* Add the io_end to per-inode completed aio dio list*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; list_add_tail(&amp;io_end-&amp;gt;list,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;EXT4_I(io_end-&amp;gt;inode)-&amp;gt;i_completed_io_list);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; iocb-&amp;gt;private = NULL;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (journal)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; jbd2_journal_invalidatepage(journal, page, offset);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; else
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; block_invalidatepage(page, offset);
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&lt;br&gt;-static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate)
&lt;br&gt;+static int ext4_releasepage(struct page *page, gfp_t wait)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_io_end_t *io_end = bh-&amp;gt;b_private;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; struct workqueue_struct *wq;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; journal_t *journal = EXT4_JOURNAL(page-&amp;gt;mapping-&amp;gt;host);
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!io_end)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto out;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; io_end-&amp;gt;flag = EXT4_IO_WRITTEN;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; wq = EXT4_SB(io_end-&amp;gt;inode-&amp;gt;i_sb)-&amp;gt;dio_unwritten_wq;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; /* queue the work to convert unwritten extents to written */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; queue_work(wq, &amp;io_end-&amp;gt;work);
&lt;br&gt;-out:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; bh-&amp;gt;b_private = NULL;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; bh-&amp;gt;b_end_io = NULL;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; clear_buffer_uninit(bh);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; end_buffer_async_write(bh, uptodate);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; WARN_ON(PageChecked(page));
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!page_has_buffers(page))
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (journal)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return jbd2_journal_try_to_free_buffers(journal, page, wait);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; else
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return try_to_free_buffers(page);
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&lt;br&gt;-static int ext4_set_bh_endio(struct buffer_head *bh, struct inode *inode)
&lt;br&gt;+/*
&lt;br&gt;+ * O_DIRECT for ext3 (or indirect map) based files
&lt;br&gt;+ *
&lt;br&gt;+ * If the O_DIRECT write will extend the file then add this inode to the
&lt;br&gt;+ * orphan list. &amp;nbsp;So recovery will truncate it back to the original size
&lt;br&gt;+ * if the machine crashes during the write.
&lt;br&gt;+ *
&lt;br&gt;+ * If the O_DIRECT write is intantiating holes inside i_size and the machine
&lt;br&gt;+ * crashes then stale disk data _may_ be exposed inside the file. But current
&lt;br&gt;+ * VFS code falls back into buffered path in that case so we are safe.
&lt;br&gt;+ */
&lt;br&gt;+static ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; const struct iovec *iov, loff_t offset,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; unsigned long nr_segs)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_io_end_t *io_end;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; struct page *page = bh-&amp;gt;b_page;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; loff_t offset = (sector_t)page-&amp;gt;index &amp;lt;&amp;lt; PAGE_CACHE_SHIFT;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; size_t size = bh-&amp;gt;b_size;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct file *file = iocb-&amp;gt;ki_filp;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct inode *inode = file-&amp;gt;f_mapping-&amp;gt;host;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct ext4_inode_info *ei = EXT4_I(inode);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; handle_t *handle;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ssize_t ret;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; int orphan = 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; size_t count = iov_length(iov, nr_segs);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; int retries = 0;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; io_end = ext4_init_io_end(inode);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!io_end)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return -ENOMEM;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; io_end-&amp;gt;offset = offset;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; io_end-&amp;gt;size = size;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; io_end-&amp;gt;flag = EXT4_IO_UNWRITTEN;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; /* Add the io_end to per-inode completed io list*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; list_add_tail(&amp;io_end-&amp;gt;list,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;EXT4_I(io_end-&amp;gt;inode)-&amp;gt;i_completed_io_list);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (rw == WRITE) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; loff_t final_size = offset + count;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; bh-&amp;gt;b_private = io_end;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; bh-&amp;gt;b_end_io = ext4_end_io_buffer_write;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; return 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (final_size &amp;gt; inode-&amp;gt;i_size) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* Credits for sb + inode write */
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; handle = ext4_journal_start(inode, 2);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (IS_ERR(handle)) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = PTR_ERR(handle);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto out;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = ext4_orphan_add(handle, inode);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ret) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_journal_stop(handle);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto out;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; orphan = 1;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ei-&amp;gt;i_disksize = inode-&amp;gt;i_size;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_journal_stop(handle);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+
&lt;br&gt;+retry:
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (rw == READ &amp;&amp; test_opt(inode-&amp;gt;i_sb, DIOREAD_NOLOCK)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;&amp; (EXT4_I(inode)-&amp;gt;i_flags &amp; EXT4_EXTENTS_FL))
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = blockdev_direct_IO_no_locking(rw, iocb, inode,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;inode-&amp;gt;i_sb-&amp;gt;s_bdev, iov,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;offset, nr_segs,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ext4_get_block, NULL);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; else
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = blockdev_direct_IO(rw, iocb, inode,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;inode-&amp;gt;i_sb-&amp;gt;s_bdev, iov,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;offset, nr_segs,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ext4_get_block, NULL);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ret == -ENOSPC &amp;&amp; ext4_should_retry_alloc(inode-&amp;gt;i_sb, &amp;retries))
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto retry;
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (orphan) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; int err;
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* Credits for sb + inode write */
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; handle = ext4_journal_start(inode, 2);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (IS_ERR(handle)) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* This is really bad luck. We've written the data
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* but cannot extend i_size. Bail out and pretend
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* the write failed... */
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = PTR_ERR(handle);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto out;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (inode-&amp;gt;i_nlink)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_orphan_del(handle, inode);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ret &amp;gt; 0) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; loff_t end = offset + ret;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (end &amp;gt; inode-&amp;gt;i_size) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ei-&amp;gt;i_disksize = end;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; i_size_write(inode, end);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* We're going to return a positive `ret'
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* here due to non-zero-length I/O, so there's
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* no way of reporting error returns from
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* ext4_mark_inode_dirty() to userspace. &amp;nbsp;So
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* ignore it.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_mark_inode_dirty(handle, inode);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; err = ext4_journal_stop(handle);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ret == 0)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = err;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+out:
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; return ret;
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&lt;br&gt;&amp;nbsp;/*
&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26805023&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-RFC-PATCH-4-4--ext4%3A-ext4_get_block_write-and-io_end-code-cleanup-tp26805023p26805023.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26805017</id>
	<title>[RFC PATCH 3/4] ext4: use direct_IO_no_locking in ext4 DIO read</title>
	<published>2009-12-15T17:40:54Z</published>
	<updated>2009-12-15T17:40:54Z</updated>
	<author>
		<name>Jiaying Zhang-2</name>
	</author>
	<content type="html">ext4: use direct_IO_no_locking in ext4 dio read.
&lt;br&gt;&lt;br&gt;Signed-off-by: Jiaying Zhang &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26805017&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;jiayingz@...&lt;/a&gt;&amp;gt;
&lt;br&gt;---
&lt;br&gt;&amp;nbsp;fs/ext4/inode.c | &amp;nbsp; 10 +++++++++-
&lt;br&gt;&amp;nbsp;1 file changed, 9 insertions(+), 1 deletion(-)
&lt;br&gt;&lt;br&gt;Index: git-ext4/fs/ext4/inode.c
&lt;br&gt;===================================================================
&lt;br&gt;--- git-ext4.orig/fs/ext4/inode.c &amp;nbsp; &amp;nbsp; &amp;nbsp; 2009-12-15 16:03:15.000000000 -0800
&lt;br&gt;+++ git-ext4/fs/ext4/inode.c &amp;nbsp; &amp;nbsp;2009-12-15 16:04:03.000000000 -0800
&lt;br&gt;@@ -3580,7 +3580,15 @@ static ssize_t ext4_ind_direct_IO(int rw
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;&lt;br&gt;&amp;nbsp;retry:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = blockdev_direct_IO(rw, iocb, inode, inode-&amp;gt;i_sb-&amp;gt;s_bdev, iov,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (rw == READ &amp;&amp; test_opt(inode-&amp;gt;i_sb, DIOREAD_NOLOCK)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;&amp; (EXT4_I(inode)-&amp;gt;i_flags &amp; EXT4_EXTENTS_FL))
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = blockdev_direct_IO_no_locking(rw, iocb, inode,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;inode-&amp;gt;i_sb-&amp;gt;s_bdev, iov,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;offset, nr_segs,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ext4_get_block, NULL);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; else
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = blockdev_direct_IO(rw, iocb, inode,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;inode-&amp;gt;i_sb-&amp;gt;s_bdev, iov,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; offset, nr_segs,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_get_block, NULL);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (ret == -ENOSPC &amp;&amp; ext4_should_retry_alloc(inode-&amp;gt;i_sb, &amp;retries))
&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26805017&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-RFC-PATCH-3-4--ext4%3A-use-direct_IO_no_locking-in-ext4-DIO-read-tp26805017p26805017.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26805004</id>
	<title>[RFC PATCH 2/4] ext4: use ext4_get_block_write in buffer write</title>
	<published>2009-12-15T17:39:08Z</published>
	<updated>2009-12-15T17:39:08Z</updated>
	<author>
		<name>Jiaying Zhang-2</name>
	</author>
	<content type="html">ext4: use ext4_get_block_write in buffer write
&lt;br&gt;&lt;br&gt;Allocate uninitialized extent before ext4 buffer write and
&lt;br&gt;convert the extent to initialized after io completes.
&lt;br&gt;The purpose is to make sure an extent can only be marked
&lt;br&gt;initialized after it has been written with new data so
&lt;br&gt;we can safely drop the i_mutex lock in ext4 DIO read without
&lt;br&gt;exposing stale data. This helps to improve multi-thread DIO
&lt;br&gt;read performance on high-speed disks.
&lt;br&gt;&lt;br&gt;Skip the nobh and data=journal mount cases to make things simple for now.
&lt;br&gt;&lt;br&gt;Signed-off-by: Jiaying Zhang &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26805004&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;jiayingz@...&lt;/a&gt;&amp;gt;
&lt;br&gt;---
&lt;br&gt;&amp;nbsp;fs/ext4/ext4.h &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp;5 +++
&lt;br&gt;&amp;nbsp;fs/ext4/extents.c | &amp;nbsp; 10 +++---
&lt;br&gt;&amp;nbsp;fs/ext4/fsync.c &amp;nbsp; | &amp;nbsp; &amp;nbsp;3 ++
&lt;br&gt;&amp;nbsp;fs/ext4/inode.c &amp;nbsp; | &amp;nbsp; 81 ++++++++++++++++++++++++++++++++++++++++++++++--------
&lt;br&gt;&amp;nbsp;fs/ext4/super.c &amp;nbsp; | &amp;nbsp; 30 +++++++++++++++++---
&lt;br&gt;&amp;nbsp;5 files changed, 108 insertions(+), 21 deletions(-)
&lt;br&gt;&lt;br&gt;Index: git-ext4/fs/ext4/extents.c
&lt;br&gt;===================================================================
&lt;br&gt;--- git-ext4.orig/fs/ext4/extents.c &amp;nbsp; &amp;nbsp; 2009-12-15 16:03:05.000000000 -0800
&lt;br&gt;+++ git-ext4/fs/ext4/extents.c &amp;nbsp;2009-12-15 16:03:15.000000000 -0800
&lt;br&gt;@@ -3052,6 +3052,7 @@ ext4_ext_handle_uninitialized_extents(ha
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;io-&amp;gt;flag = EXT4_IO_UNWRITTEN;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;else
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;EXT4_I(inode)-&amp;gt;i_state |= EXT4_STATE_DIO_UNWRITTEN;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; set_buffer_uninit(bh_result);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;goto out;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/* IO end_io complete, convert the filled extent to written */
&lt;br&gt;@@ -3291,11 +3292,9 @@ int ext4_ext_get_blocks(handle_t *handle
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (flags &amp; EXT4_GET_BLOCKS_UNINIT_EXT){
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ext4_ext_mark_uninitialized(&amp;newex);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* io_end structure was created for every async
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* direct IO write to the middle of the file.
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* To avoid unecessary convertion for every aio dio rewrite
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* to the mid of file, here we flag the IO that is really
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* need the convertion.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* io_end structure was created for every IO write to an
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* uninitialized extent. To avoid unecessary convertion,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* here we flag the IO that really needs the convertion.
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; * For non asycn direct IO case, flag the inode state
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; * that we need to perform convertion when IO is done.
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */
&lt;br&gt;@@ -3306,6 +3305,7 @@ int ext4_ext_get_blocks(handle_t *handle
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;EXT4_I(inode)-&amp;gt;i_state |=
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;EXT4_STATE_DIO_UNWRITTEN;;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; set_buffer_uninit(bh_result);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;err = ext4_ext_insert_extent(handle, inode, path, &amp;newex, flags);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (err) {
&lt;br&gt;Index: git-ext4/fs/ext4/ext4.h
&lt;br&gt;===================================================================
&lt;br&gt;--- git-ext4.orig/fs/ext4/ext4.h &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;2009-12-15 16:03:05.000000000 -0800
&lt;br&gt;+++ git-ext4/fs/ext4/ext4.h &amp;nbsp; &amp;nbsp; 2009-12-15 16:03:15.000000000 -0800
&lt;br&gt;@@ -134,6 +134,7 @@ struct mpage_da_data {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;int retval;
&lt;br&gt;&amp;nbsp;};
&lt;br&gt;&amp;nbsp;#define &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;EXT4_IO_UNWRITTEN &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x1
&lt;br&gt;+#define &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;EXT4_IO_WRITTEN &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x2
&lt;br&gt;&amp;nbsp;typedef struct ext4_io_end {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;struct list_head &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;list; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* per-file finished AIO list */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;struct inode &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*inode; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* file being written to */
&lt;br&gt;@@ -752,6 +753,7 @@ struct ext4_inode_info {
&lt;br&gt;&amp;nbsp;#define EXT4_MOUNT_QUOTA &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x80000 /* Some quota option set */
&lt;br&gt;&amp;nbsp;#define EXT4_MOUNT_USRQUOTA &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x100000 /* &amp;quot;old&amp;quot; user quota */
&lt;br&gt;&amp;nbsp;#define EXT4_MOUNT_GRPQUOTA &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x200000 /* &amp;quot;old&amp;quot; group quota */
&lt;br&gt;+#define EXT4_MOUNT_DIOREAD_NOLOCK &amp;nbsp; &amp;nbsp; &amp;nbsp;0x400000 /* Enable support for
&lt;br&gt;dio read nolocking */
&lt;br&gt;&amp;nbsp;#define EXT4_MOUNT_JOURNAL_CHECKSUM &amp;nbsp; &amp;nbsp;0x800000 /* Journal checksums */
&lt;br&gt;&amp;nbsp;#define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x1000000 /* Journal
&lt;br&gt;Async Commit */
&lt;br&gt;&amp;nbsp;#define EXT4_MOUNT_I_VERSION &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x2000000 /* i_version support */
&lt;br&gt;@@ -1764,6 +1766,9 @@ static inline void set_bitmap_uptodate(s
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;set_bit(BH_BITMAP_UPTODATE, &amp;(bh)-&amp;gt;b_state);
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&lt;br&gt;+/* BH_Uninit flag: blocks are allocated but uninitialized on disk */
&lt;br&gt;+#define BH_Uninit (BH_JBDPrivateStart + 1)
&lt;br&gt;+BUFFER_FNS(Uninit, uninit)
&lt;br&gt;&amp;nbsp;#endif /* __KERNEL__ */
&lt;br&gt;&lt;br&gt;&amp;nbsp;#endif /* _EXT4_H */
&lt;br&gt;Index: git-ext4/fs/ext4/super.c
&lt;br&gt;===================================================================
&lt;br&gt;--- git-ext4.orig/fs/ext4/super.c &amp;nbsp; &amp;nbsp; &amp;nbsp; 2009-12-15 16:03:05.000000000 -0800
&lt;br&gt;+++ git-ext4/fs/ext4/super.c &amp;nbsp; &amp;nbsp;2009-12-15 16:03:15.000000000 -0800
&lt;br&gt;@@ -921,6 +921,9 @@ static int ext4_show_options(struct seq_
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (test_opt(sb, NOLOAD))
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;seq_puts(seq, &amp;quot;,norecovery&amp;quot;);
&lt;br&gt;&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (test_opt(sb, DIOREAD_NOLOCK))
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; seq_puts(seq, &amp;quot;,dioread_nolock&amp;quot;);
&lt;br&gt;+
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ext4_show_quota_options(seq, sb);
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return 0;
&lt;br&gt;@@ -1103,6 +1106,7 @@ enum {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Opt_stripe, Opt_delalloc, Opt_nodelalloc,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Opt_block_validity, Opt_noblock_validity,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Opt_inode_readahead_blks, Opt_journal_ioprio,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; Opt_dioread_nolock, Opt_dioread_lock,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Opt_discard, Opt_nodiscard, Opt_akpm_lock_hack
&lt;br&gt;&amp;nbsp;};
&lt;br&gt;&lt;br&gt;@@ -1171,6 +1175,8 @@ static const match_table_t tokens = {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{Opt_auto_da_alloc, &amp;quot;auto_da_alloc=%u&amp;quot;},
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{Opt_auto_da_alloc, &amp;quot;auto_da_alloc&amp;quot;},
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{Opt_noauto_da_alloc, &amp;quot;noauto_da_alloc&amp;quot;},
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; {Opt_dioread_nolock, &amp;quot;dioread_nolock&amp;quot;},
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; {Opt_dioread_lock, &amp;quot;dioread_lock&amp;quot;},
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{Opt_discard, &amp;quot;discard&amp;quot;},
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{Opt_nodiscard, &amp;quot;nodiscard&amp;quot;},
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{Opt_err, NULL},
&lt;br&gt;@@ -1603,6 +1609,12 @@ set_qf_format:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;case Opt_nodiscard:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;clear_opt(sbi-&amp;gt;s_mount_opt, DISCARD);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;break;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case Opt_dioread_nolock:
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; set_opt(sbi-&amp;gt;s_mount_opt, DIOREAD_NOLOCK);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; break;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case Opt_dioread_lock:
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; clear_opt(sbi-&amp;gt;s_mount_opt, DIOREAD_NOLOCK);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; break;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;case Opt_akpm_lock_hack:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;set_opt(sbi-&amp;gt;s_mount_opt, AKPM_LOCK_HACK);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;break;
&lt;br&gt;@@ -2769,7 +2781,7 @@ static int ext4_fill_super(struct super_
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ext4_msg(sb, KERN_ERR, &amp;quot;required journal recovery &amp;quot;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;quot;suppressed and not mounted read-only&amp;quot;);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto failed_mount4;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto failed_mount_wq;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;} else {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;clear_opt(sbi-&amp;gt;s_mount_opt, DATA_FLAGS);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;set_opt(sbi-&amp;gt;s_mount_opt, WRITEBACK_DATA);
&lt;br&gt;@@ -2782,7 +2794,7 @@ static int ext4_fill_super(struct super_
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;!jbd2_journal_set_features(EXT4_SB(sb)-&amp;gt;s_journal, 0, 0,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; JBD2_FEATURE_INCOMPAT_64BIT)) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ext4_msg(sb, KERN_ERR, &amp;quot;Failed to set 64-bit journal feature&amp;quot;);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto failed_mount4;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto failed_mount_wq;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) {
&lt;br&gt;@@ -2821,7 +2833,7 @@ static int ext4_fill_super(struct super_
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(sbi-&amp;gt;s_journal, 0, 0, JBD2_FEATURE_INCOMPAT_REVOKE)) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ext4_msg(sb, KERN_ERR, &amp;quot;Journal does not support &amp;quot;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;quot;requested data journaling mode&amp;quot;);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto failed_mount4;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto failed_mount_wq;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;default:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;break;
&lt;br&gt;@@ -2829,13 +2841,17 @@ static int ext4_fill_super(struct super_
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;set_task_ioprio(sbi-&amp;gt;s_journal-&amp;gt;j_task, journal_ioprio);
&lt;br&gt;&lt;br&gt;&amp;nbsp;no_journal:
&lt;br&gt;-
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (test_opt(sb, NOBH)) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (!(test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ext4_msg(sb, KERN_WARNING, &amp;quot;Ignoring nobh option - &amp;quot;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;its supported only with writeback mode&amp;quot;);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;clear_opt(sbi-&amp;gt;s_mount_opt, NOBH);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (test_opt(sb, DIOREAD_NOLOCK)) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_msg(sb, KERN_WARNING, &amp;quot;dioread_nolock option is &amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;quot;not supported with nobh mode&amp;quot;);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto failed_mount_wq;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;EXT4_SB(sb)-&amp;gt;dio_unwritten_wq = create_workqueue(&amp;quot;ext4-dio-unwritten&amp;quot;);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (!EXT4_SB(sb)-&amp;gt;dio_unwritten_wq) {
&lt;br&gt;@@ -2900,6 +2916,12 @@ no_journal:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;quot;requested data journaling mode&amp;quot;);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;clear_opt(sbi-&amp;gt;s_mount_opt, DELALLOC);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (test_opt(sb, DIOREAD_NOLOCK) &amp;&amp;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_msg(sb, KERN_WARNING, &amp;quot;Ignoring dioread_nolock option - &amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;requested data journaling mode&amp;quot;);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; clear_opt(sbi-&amp;gt;s_mount_opt, DIOREAD_NOLOCK);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;err = ext4_setup_system_zone(sb);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (err) {
&lt;br&gt;Index: git-ext4/fs/ext4/inode.c
&lt;br&gt;===================================================================
&lt;br&gt;--- git-ext4.orig/fs/ext4/inode.c &amp;nbsp; &amp;nbsp; &amp;nbsp; 2009-12-15 16:03:05.000000000 -0800
&lt;br&gt;+++ git-ext4/fs/ext4/inode.c &amp;nbsp; &amp;nbsp;2009-12-15 16:03:15.000000000 -0800
&lt;br&gt;@@ -1492,6 +1492,8 @@ static int do_journal_get_write_access(h
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return ext4_journal_get_write_access(handle, bh);
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&lt;br&gt;+static int ext4_get_block_write(struct inode *inode, sector_t iblock,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;struct buffer_head *bh_result, int create);
&lt;br&gt;&amp;nbsp;static int ext4_write_begin(struct file *file, struct address_space *mapping,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;loff_t pos, unsigned len, unsigned flags,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;struct page **pagep, void **fsdata)
&lt;br&gt;@@ -1533,8 +1535,12 @@ retry:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*pagep = page;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_get_block);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (test_opt(inode-&amp;gt;i_sb, DIOREAD_NOLOCK))
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = block_write_begin(file, mapping, pos, len, flags, pagep,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fsdata, ext4_get_block_write);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; else
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = block_write_begin(file, mapping, pos, len, flags, pagep,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fsdata, ext4_get_block);
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (!ret &amp;&amp; ext4_should_journal_data(inode)) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ret = walk_page_buffers(handle, page_buffers(page),
&lt;br&gt;@@ -2053,6 +2059,8 @@ static void mpage_put_bnr_to_bhs(struct
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;} else if (buffer_mapped(bh))
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;BUG_ON(bh-&amp;gt;b_blocknr != pblock);
&lt;br&gt;&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (buffer_uninit(exbh))
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; set_buffer_uninit(bh);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;cur_logical++;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;pblock++;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;} while ((bh = bh-&amp;gt;b_this_page) != head);
&lt;br&gt;@@ -2183,6 +2191,8 @@ static int mpage_da_map_blocks(struct mp
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;new.b_state = 0;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;get_blocks_flags = (EXT4_GET_BLOCKS_CREATE |
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;EXT4_GET_BLOCKS_DELALLOC_RESERVE);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (test_opt(mpd-&amp;gt;inode-&amp;gt;i_sb, DIOREAD_NOLOCK))
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; get_blocks_flags |= EXT4_GET_BLOCKS_IO_CREATE_EXT;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (mpd-&amp;gt;b_state &amp; (1 &amp;lt;&amp;lt; BH_Delay))
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;get_blocks_flags |= EXT4_GET_BLOCKS_UPDATE_RESERVE_SPACE;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;blks = ext4_get_blocks(handle, mpd-&amp;gt;inode, next, max_blocks,
&lt;br&gt;@@ -2597,6 +2607,9 @@ out:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return ret;
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&lt;br&gt;+static int ext4_set_bh_endio(struct buffer_head *bh, struct inode *inode);
&lt;br&gt;+static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate);
&lt;br&gt;+
&lt;br&gt;&amp;nbsp;/*
&lt;br&gt;&amp;nbsp;* Note that we don't need to start a transaction unless we're journaling data
&lt;br&gt;&amp;nbsp;* because we should have holes filled from ext4_page_mkwrite(). We even don't
&lt;br&gt;@@ -2644,7 +2657,7 @@ static int ext4_writepage(struct page *p
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;int ret = 0;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;loff_t size;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;unsigned int len;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; struct buffer_head *page_bufs;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct buffer_head *page_bufs = NULL;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;struct inode *inode = page-&amp;gt;mapping-&amp;gt;host;
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;trace_ext4_writepage(inode, page);
&lt;br&gt;@@ -2720,7 +2733,11 @@ static int ext4_writepage(struct page *p
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (test_opt(inode-&amp;gt;i_sb, NOBH) &amp;&amp; ext4_should_writeback_data(inode))
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ret = nobh_writepage(page, noalloc_get_block_write, wbc);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; else
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; else if (page_bufs &amp;&amp; buffer_uninit(page_bufs)) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_set_bh_endio(page_bufs, inode);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = block_write_full_page_endio(page, noalloc_get_block_write,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wbc, ext4_end_io_buffer_write);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; } else
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ret = block_write_full_page(page, noalloc_get_block_write,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;wbc);
&lt;br&gt;&lt;br&gt;@@ -3697,12 +3714,10 @@ static int ext4_end_io_nolock(ext4_io_en
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (list_empty(&amp;io-&amp;gt;list))
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return ret;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (io-&amp;gt;flag != EXT4_IO_UNWRITTEN)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (io-&amp;gt;flag != EXT4_IO_WRITTEN)
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return ret;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (offset + size &amp;lt;= i_size_read(inode))
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = ext4_convert_unwritten_extents(inode, offset, size);
&lt;br&gt;-
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = ext4_convert_unwritten_extents(inode, offset, size);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (ret &amp;lt; 0) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;printk(KERN_EMERG &amp;quot;%s: failed to convert unwritten&amp;quot;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;extents to written extents, error is %d&amp;quot;
&lt;br&gt;@@ -3750,7 +3765,7 @@ static void ext4_end_io_work(struct work
&lt;br&gt;&amp;nbsp;*/
&lt;br&gt;&amp;nbsp;int flush_completed_IO(struct inode *inode)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_io_end_t *io;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_io_end_t *io, *tmp;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;int ret = 0;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;int ret2 = 0;
&lt;br&gt;&lt;br&gt;@@ -3758,9 +3773,10 @@ int flush_completed_IO(struct inode *ino
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return ret;
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;dump_completed_IO(inode);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; while (!list_empty(&amp;EXT4_I(inode)-&amp;gt;i_completed_io_list)){
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; io = list_entry(EXT4_I(inode)-&amp;gt;i_completed_io_list.next,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_io_end_t, list);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; list_for_each_entry_safe(io, tmp,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;EXT4_I(inode)-&amp;gt;i_completed_io_list, list) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (io-&amp;gt;flag == EXT4_IO_UNWRITTEN)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; continue;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/*
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; * Calling ext4_end_io_nolock() to convert completed
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; * IO to written.
&lt;br&gt;@@ -3828,6 +3844,7 @@ static void ext4_end_io_dio(struct kiocb
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;io_end-&amp;gt;offset = offset;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;io_end-&amp;gt;size = size;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; io_end-&amp;gt;flag = EXT4_IO_WRITTEN;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;wq = EXT4_SB(io_end-&amp;gt;inode-&amp;gt;i_sb)-&amp;gt;dio_unwritten_wq;
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/* queue the work to convert unwritten extents to written */
&lt;br&gt;@@ -3839,6 +3856,46 @@ static void ext4_end_io_dio(struct kiocb
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;iocb-&amp;gt;private = NULL;
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&lt;br&gt;+static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate)
&lt;br&gt;+{
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_io_end_t *io_end = bh-&amp;gt;b_private;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct workqueue_struct *wq;
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!io_end)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto out;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; io_end-&amp;gt;flag = EXT4_IO_WRITTEN;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; wq = EXT4_SB(io_end-&amp;gt;inode-&amp;gt;i_sb)-&amp;gt;dio_unwritten_wq;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; /* queue the work to convert unwritten extents to written */
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; queue_work(wq, &amp;io_end-&amp;gt;work);
&lt;br&gt;+out:
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; bh-&amp;gt;b_private = NULL;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; bh-&amp;gt;b_end_io = NULL;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; clear_buffer_uninit(bh);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; end_buffer_async_write(bh, uptodate);
&lt;br&gt;+}
&lt;br&gt;+
&lt;br&gt;+static int ext4_set_bh_endio(struct buffer_head *bh, struct inode *inode)
&lt;br&gt;+{
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_io_end_t *io_end;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct page *page = bh-&amp;gt;b_page;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; loff_t offset = (sector_t)page-&amp;gt;index &amp;lt;&amp;lt; PAGE_CACHE_SHIFT;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; size_t size = bh-&amp;gt;b_size;
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; io_end = ext4_init_io_end(inode);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!io_end)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return -ENOMEM;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; io_end-&amp;gt;offset = offset;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; io_end-&amp;gt;size = size;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; io_end-&amp;gt;flag = EXT4_IO_UNWRITTEN;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; /* Add the io_end to per-inode completed io list*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; list_add_tail(&amp;io_end-&amp;gt;list,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;EXT4_I(io_end-&amp;gt;inode)-&amp;gt;i_completed_io_list);
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; bh-&amp;gt;b_private = io_end;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; bh-&amp;gt;b_end_io = ext4_end_io_buffer_write;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; return 0;
&lt;br&gt;+}
&lt;br&gt;+
&lt;br&gt;&amp;nbsp;/*
&lt;br&gt;&amp;nbsp;* For ext4 extent files, ext4 will do direct-io write to holes,
&lt;br&gt;&amp;nbsp;* preallocated extents, and those write extend the file, no need to
&lt;br&gt;Index: git-ext4/fs/ext4/fsync.c
&lt;br&gt;===================================================================
&lt;br&gt;--- git-ext4.orig/fs/ext4/fsync.c &amp;nbsp; &amp;nbsp; &amp;nbsp; 2009-12-15 16:03:05.000000000 -0800
&lt;br&gt;+++ git-ext4/fs/ext4/fsync.c &amp;nbsp; &amp;nbsp;2009-12-15 16:03:15.000000000 -0800
&lt;br&gt;@@ -101,6 +101,9 @@ int ext4_sync_file(struct file *file, st
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (ret == 0)
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ret = err;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ret == 0)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; flush_completed_IO(inode);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; BUG_ON(!list_empty(&amp;EXT4_I(inode)-&amp;gt;i_completed_io_list));
&lt;br&gt;&amp;nbsp;out:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (journal &amp;&amp; (journal-&amp;gt;j_flags &amp; JBD2_BARRIER))
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;blkdev_issue_flush(inode-&amp;gt;i_sb-&amp;gt;s_bdev, NULL);
&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26805004&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-RFC-PATCH-2-4--ext4%3A-use-ext4_get_block_write-in-buffer-write-tp26805004p26805004.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26804991</id>
	<title>[RFC PATCH 1/4] ext4: DIO get_block code cleanup</title>
	<published>2009-12-15T17:37:53Z</published>
	<updated>2009-12-15T17:37:53Z</updated>
	<author>
		<name>Jiaying Zhang-2</name>
	</author>
	<content type="html">ext4: dio get_block code cleanup in prepare for it to be used by buffer write
&lt;br&gt;&lt;br&gt;Renaming the dio block allocation flags, variables and functions
&lt;br&gt;introduced in Mingming's &amp;quot;Direct IO for holes and fallocate&amp;quot;
&lt;br&gt;patches so that they can be used by ext4 buffer write as well.
&lt;br&gt;&lt;br&gt;Signed-off-by: Jiaying Zhang &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26804991&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;jiayingz@...&lt;/a&gt;&amp;gt;
&lt;br&gt;---
&lt;br&gt;&amp;nbsp;fs/ext4/ext4.h &amp;nbsp; &amp;nbsp;| &amp;nbsp; 18 ++++----
&lt;br&gt;&amp;nbsp;fs/ext4/extents.c | &amp;nbsp; 24 +++++------
&lt;br&gt;&amp;nbsp;fs/ext4/fsync.c &amp;nbsp; | &amp;nbsp; &amp;nbsp;2
&lt;br&gt;&amp;nbsp;fs/ext4/inode.c &amp;nbsp; | &amp;nbsp;112 ++++++++++++++++++++++++++----------------------------
&lt;br&gt;&amp;nbsp;fs/ext4/super.c &amp;nbsp; | &amp;nbsp; &amp;nbsp;2
&lt;br&gt;&amp;nbsp;5 files changed, 78 insertions(+), 80 deletions(-)
&lt;br&gt;&lt;br&gt;Index: git-ext4/fs/ext4/extents.c
&lt;br&gt;===================================================================
&lt;br&gt;--- git-ext4.orig/fs/ext4/extents.c &amp;nbsp; &amp;nbsp; 2009-12-15 15:14:34.000000000 -0800
&lt;br&gt;+++ git-ext4/fs/ext4/extents.c &amp;nbsp;2009-12-15 16:03:05.000000000 -0800
&lt;br&gt;@@ -1603,7 +1603,7 @@ int ext4_ext_insert_extent(handle_t *han
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;BUG_ON(path[depth].p_hdr == NULL);
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/* try to insert block into found extent and return */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ex &amp;&amp; (flag != EXT4_GET_BLOCKS_DIO_CREATE_EXT)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ex &amp;&amp; !(flag &amp; EXT4_GET_BLOCKS_PRE_IO)
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;&amp; ext4_can_extents_be_merged(inode, ex, newext)) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ext_debug(&amp;quot;append [%d]%d block to %d:[%d]%d (from %llu)\n&amp;quot;,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ext4_ext_is_uninitialized(newext),
&lt;br&gt;@@ -1724,7 +1724,7 @@ has_space:
&lt;br&gt;&lt;br&gt;&amp;nbsp;merge:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/* try to merge extents to the right */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (flag != EXT4_GET_BLOCKS_DIO_CREATE_EXT)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!(flag &amp; EXT4_GET_BLOCKS_PRE_IO))
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ext4_ext_try_to_merge(inode, path, nearex);
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/* try to merge extents to the left */
&lt;br&gt;@@ -2966,7 +2966,7 @@ fix_extent_len:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ext4_ext_dirty(handle, inode, path + depth);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return err;
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;-static int ext4_convert_unwritten_extents_dio(handle_t *handle,
&lt;br&gt;+static int ext4_convert_unwritten_extents_endio(handle_t *handle,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;struct inode *inode,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;struct ext4_ext_path *path)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;@@ -3038,8 +3038,8 @@ ext4_ext_handle_uninitialized_extents(ha
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;flags, allocated);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ext4_ext_show_leaf(inode, path);
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; /* DIO get_block() before submit the IO, split the extent */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (flags == EXT4_GET_BLOCKS_DIO_CREATE_EXT) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; /* get_block() before submit the IO, split the extent */
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if ((flags &amp; EXT4_GET_BLOCKS_PRE_IO)) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ret = ext4_split_unwritten_extents(handle,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;inode, path, iblock,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;max_blocks, flags);
&lt;br&gt;@@ -3049,14 +3049,14 @@ ext4_ext_handle_uninitialized_extents(ha
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; * completed
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (io)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; io-&amp;gt;flag = DIO_AIO_UNWRITTEN;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; io-&amp;gt;flag = EXT4_IO_UNWRITTEN;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;else
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;EXT4_I(inode)-&amp;gt;i_state |= EXT4_STATE_DIO_UNWRITTEN;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;goto out;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; /* async DIO end_io complete, convert the filled extent to written */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (flags == EXT4_GET_BLOCKS_DIO_CONVERT_EXT) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = ext4_convert_unwritten_extents_dio(handle, inode,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; /* IO end_io complete, convert the filled extent to written */
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if ((flags &amp; EXT4_GET_BLOCKS_CONVERT)) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = ext4_convert_unwritten_extents_endio(handle, inode,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;path);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;goto out2;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;@@ -3299,9 +3299,9 @@ int ext4_ext_get_blocks(handle_t *handle
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; * For non asycn direct IO case, flag the inode state
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; * that we need to perform convertion when IO is done.
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (flags == EXT4_GET_BLOCKS_DIO_CREATE_EXT) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if ((flags &amp; EXT4_GET_BLOCKS_PRE_IO)) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (io)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; io-&amp;gt;flag = DIO_AIO_UNWRITTEN;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; io-&amp;gt;flag = EXT4_IO_UNWRITTEN;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;else
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;EXT4_I(inode)-&amp;gt;i_state |=
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;EXT4_STATE_DIO_UNWRITTEN;;
&lt;br&gt;@@ -3561,7 +3561,7 @@ int ext4_convert_unwritten_extents(struc
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;map_bh.b_state = 0;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ret = ext4_get_blocks(handle, inode, block,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;max_blocks, &amp;map_bh,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; EXT4_GET_BLOCKS_DIO_CONVERT_EXT);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; EXT4_GET_BLOCKS_IO_CONVERT_EXT);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (ret &amp;lt;= 0) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;WARN_ON(ret &amp;lt;= 0);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;printk(KERN_ERR &amp;quot;%s: ext4_ext_get_blocks &amp;quot;
&lt;br&gt;Index: git-ext4/fs/ext4/ext4.h
&lt;br&gt;===================================================================
&lt;br&gt;--- git-ext4.orig/fs/ext4/ext4.h &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;2009-12-15 15:14:34.000000000 -0800
&lt;br&gt;+++ git-ext4/fs/ext4/ext4.h &amp;nbsp; &amp;nbsp; 2009-12-15 16:03:05.000000000 -0800
&lt;br&gt;@@ -133,7 +133,7 @@ struct mpage_da_data {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;int pages_written;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;int retval;
&lt;br&gt;&amp;nbsp;};
&lt;br&gt;-#define &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;DIO_AIO_UNWRITTEN &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x1
&lt;br&gt;+#define &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;EXT4_IO_UNWRITTEN &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x1
&lt;br&gt;&amp;nbsp;typedef struct ext4_io_end {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;struct list_head &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;list; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* per-file finished AIO list */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;struct inode &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*inode; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* file being written to */
&lt;br&gt;@@ -367,13 +367,13 @@ struct ext4_new_group_data {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/* caller is from the direct IO path, request to creation of an
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;unitialized extents if not allocated, split the uninitialized
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;extent if blocks has been preallocated already*/
&lt;br&gt;-#define EXT4_GET_BLOCKS_DIO &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x0010
&lt;br&gt;+#define EXT4_GET_BLOCKS_PRE_IO &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x0010
&lt;br&gt;&amp;nbsp;#define EXT4_GET_BLOCKS_CONVERT &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0x0020
&lt;br&gt;-#define EXT4_GET_BLOCKS_DIO_CREATE_EXT &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (EXT4_GET_BLOCKS_DIO|\
&lt;br&gt;+#define EXT4_GET_BLOCKS_IO_CREATE_EXT &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(EXT4_GET_BLOCKS_PRE_IO|\
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;EXT4_GET_BLOCKS_CREATE_UNINIT_EXT)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; /* Convert extent to initialized after IO complete */
&lt;br&gt;+#define EXT4_GET_BLOCKS_IO_CONVERT_EXT &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (EXT4_GET_BLOCKS_CONVERT|\
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; EXT4_GET_BLOCKS_CREATE_UNINIT_EXT)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; /* Convert extent to initialized after direct IO complete */
&lt;br&gt;-#define EXT4_GET_BLOCKS_DIO_CONVERT_EXT
&lt;br&gt;(EXT4_GET_BLOCKS_CONVERT|\
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;EXT4_GET_BLOCKS_DIO_CREATE_EXT)
&lt;br&gt;&lt;br&gt;&amp;nbsp;/*
&lt;br&gt;&amp;nbsp;* Flags used by ext4_free_blocks
&lt;br&gt;@@ -707,8 +707,8 @@ struct ext4_inode_info {
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;spinlock_t i_block_reservation_lock;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; /* completed async DIOs that might need unwritten extents handling */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; struct list_head i_aio_dio_complete_list;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; /* completed IOs that might need unwritten extents handling */
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; struct list_head i_completed_io_list;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/* current io_end structure for async DIO write*/
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ext4_io_end_t *cur_aio_dio;
&lt;br&gt;&amp;nbsp;};
&lt;br&gt;@@ -1432,7 +1432,7 @@ extern int ext4_block_truncate_page(hand
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;struct address_space *mapping, loff_t from);
&lt;br&gt;&amp;nbsp;extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf);
&lt;br&gt;&amp;nbsp;extern qsize_t ext4_get_reserved_space(struct inode *inode);
&lt;br&gt;-extern int flush_aio_dio_completed_IO(struct inode *inode);
&lt;br&gt;+extern int flush_completed_IO(struct inode *inode);
&lt;br&gt;&amp;nbsp;/* ioctl.c */
&lt;br&gt;&amp;nbsp;extern long ext4_ioctl(struct file *, unsigned int, unsigned long);
&lt;br&gt;&amp;nbsp;extern long ext4_compat_ioctl(struct file *, unsigned int, unsigned long);
&lt;br&gt;Index: git-ext4/fs/ext4/super.c
&lt;br&gt;===================================================================
&lt;br&gt;--- git-ext4.orig/fs/ext4/super.c &amp;nbsp; &amp;nbsp; &amp;nbsp; 2009-12-15 15:14:34.000000000 -0800
&lt;br&gt;+++ git-ext4/fs/ext4/super.c &amp;nbsp; &amp;nbsp;2009-12-15 16:03:05.000000000 -0800
&lt;br&gt;@@ -711,7 +711,7 @@ static struct inode *ext4_alloc_inode(st
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ei-&amp;gt;i_allocated_meta_blocks = 0;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ei-&amp;gt;i_delalloc_reserved_flag = 0;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;spin_lock_init(&amp;(ei-&amp;gt;i_block_reservation_lock));
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; INIT_LIST_HEAD(&amp;ei-&amp;gt;i_aio_dio_complete_list);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; INIT_LIST_HEAD(&amp;ei-&amp;gt;i_completed_io_list);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ei-&amp;gt;cur_aio_dio = NULL;
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return &amp;ei-&amp;gt;vfs_inode;
&lt;br&gt;Index: git-ext4/fs/ext4/fsync.c
&lt;br&gt;===================================================================
&lt;br&gt;--- git-ext4.orig/fs/ext4/fsync.c &amp;nbsp; &amp;nbsp; &amp;nbsp; 2009-12-15 15:14:34.000000000 -0800
&lt;br&gt;+++ git-ext4/fs/ext4/fsync.c &amp;nbsp; &amp;nbsp;2009-12-15 16:03:05.000000000 -0800
&lt;br&gt;@@ -58,7 +58,7 @@ int ext4_sync_file(struct file *file, st
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;trace_ext4_sync_file(file, dentry, datasync);
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = flush_aio_dio_completed_IO(inode);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = flush_completed_IO(inode);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (ret &amp;lt; 0)
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return ret;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/*
&lt;br&gt;Index: git-ext4/fs/ext4/inode.c
&lt;br&gt;===================================================================
&lt;br&gt;--- git-ext4.orig/fs/ext4/inode.c &amp;nbsp; &amp;nbsp; &amp;nbsp; 2009-12-15 15:14:34.000000000 -0800
&lt;br&gt;+++ git-ext4/fs/ext4/inode.c &amp;nbsp; &amp;nbsp;2009-12-15 16:03:05.000000000 -0800
&lt;br&gt;@@ -3606,52 +3606,44 @@ out:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return ret;
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&lt;br&gt;-static int ext4_get_block_dio_write(struct inode *inode, sector_t iblock,
&lt;br&gt;+static int ext4_get_block_write(struct inode *inode, sector_t iblock,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; struct buffer_head *bh_result, int create)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; handle_t *handle = NULL;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; handle_t *handle = ext4_journal_current_handle();
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;int ret = 0;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;unsigned max_blocks = bh_result-&amp;gt;b_size &amp;gt;&amp;gt; inode-&amp;gt;i_blkbits;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;int dio_credits;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; int started = 0;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_debug(&amp;quot;ext4_get_block_dio_write: inode %lu, create flag %d\n&amp;quot;,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_debug(&amp;quot;ext4_get_block_write: inode %lu, create flag %d\n&amp;quot;,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; inode-&amp;gt;i_ino, create);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* DIO VFS code passes create = 0 flag for write to
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* the middle of file. It does this to avoid block
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* allocation for holes, to prevent expose stale data
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* out when there is parallel buffered read (which does
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* not hold the i_mutex lock) while direct IO write has
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* not completed. DIO request on holes finally falls back
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* to buffered IO for this reason.
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* For ext4 extent based file, since we support fallocate,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* new allocated extent as uninitialized, for holes, we
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* could fallocate blocks for holes, thus parallel
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* buffered IO read will zero out the page when read on
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* a hole while parallel DIO write to the hole has not completed.
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* when we come here, we know it's a direct IO write to
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* to the middle of file (&amp;lt;i_size)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* so it's safe to override the create flag from VFS.
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; create = EXT4_GET_BLOCKS_DIO_CREATE_EXT;
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (max_blocks &amp;gt; DIO_MAX_BLOCKS)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; max_blocks = DIO_MAX_BLOCKS;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; dio_credits = ext4_chunk_trans_blocks(inode, max_blocks);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; handle = ext4_journal_start(inode, dio_credits);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (IS_ERR(handle)) {
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = PTR_ERR(handle);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto out;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* ext4_get_block in prepare for a DIO write or buffer write.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* We allocate an uinitialized extent if blocks haven't been allocated.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* The extent will be converted to initialized after IO complete.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; create = EXT4_GET_BLOCKS_IO_CREATE_EXT;
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!handle) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (max_blocks &amp;gt; DIO_MAX_BLOCKS)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; max_blocks = DIO_MAX_BLOCKS;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dio_credits = ext4_chunk_trans_blocks(inode, max_blocks);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; handle = ext4_journal_start(inode, dio_credits);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (IS_ERR(handle)) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = PTR_ERR(handle);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto out;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; started = 1;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;+
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ret = ext4_get_blocks(handle, inode, iblock, max_blocks, bh_result,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;create);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (ret &amp;gt; 0) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;bh_result-&amp;gt;b_size = (ret &amp;lt;&amp;lt; inode-&amp;gt;i_blkbits);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ret = 0;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_journal_stop(handle);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (started)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_journal_stop(handle);
&lt;br&gt;&amp;nbsp;out:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return ret;
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;@@ -3662,19 +3654,20 @@ static void ext4_free_io_end(ext4_io_end
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;iput(io-&amp;gt;inode);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;kfree(io);
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;-static void dump_aio_dio_list(struct inode * inode)
&lt;br&gt;+
&lt;br&gt;+static void dump_completed_IO(struct inode * inode)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;&amp;nbsp;#ifdef EXT4_DEBUG
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;struct list_head *cur, *before, *after;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ext4_io_end_t *io, *io0, *io1;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (list_empty(&amp;EXT4_I(inode)-&amp;gt;i_aio_dio_complete_list)){
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_debug(&amp;quot;inode %lu aio dio list is empty\n&amp;quot;, inode-&amp;gt;i_ino);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (list_empty(&amp;EXT4_I(inode)-&amp;gt;i_completed_io_list)){
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_debug(&amp;quot;inode %lu completed_io list is empty\n&amp;quot;,
&lt;br&gt;inode-&amp;gt;i_ino);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_debug(&amp;quot;Dump inode %lu aio_dio_completed_IO list \n&amp;quot;, inode-&amp;gt;i_ino);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; list_for_each_entry(io, &amp;EXT4_I(inode)-&amp;gt;i_aio_dio_complete_list, list){
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_debug(&amp;quot;Dump inode %lu completed_io list \n&amp;quot;, inode-&amp;gt;i_ino);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; list_for_each_entry(io, &amp;EXT4_I(inode)-&amp;gt;i_completed_io_list, list){
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;cur = &amp;io-&amp;gt;list;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;before = cur-&amp;gt;prev;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;io0 = container_of(before, ext4_io_end_t, list);
&lt;br&gt;@@ -3690,21 +3683,21 @@ static void dump_aio_dio_list(struct ino
&lt;br&gt;&amp;nbsp;/*
&lt;br&gt;&amp;nbsp;* check a range of space and convert unwritten extents to written.
&lt;br&gt;&amp;nbsp;*/
&lt;br&gt;-static int ext4_end_aio_dio_nolock(ext4_io_end_t *io)
&lt;br&gt;+static int ext4_end_io_nolock(ext4_io_end_t *io)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;struct inode *inode = io-&amp;gt;inode;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;loff_t offset = io-&amp;gt;offset;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;size_t size = io-&amp;gt;size;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;int ret = 0;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_debug(&amp;quot;end_aio_dio_onlock: io 0x%p from inode %lu,list-&amp;gt;next 0x%p,&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_debug(&amp;quot;ext4_end_io_nolock: io 0x%p from inode %lu,list-&amp;gt;next 0x%p,&amp;quot;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;quot;list-&amp;gt;prev 0x%p\n&amp;quot;,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; io, inode-&amp;gt;i_ino, io-&amp;gt;list.next, io-&amp;gt;list.prev);
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (list_empty(&amp;io-&amp;gt;list))
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return ret;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (io-&amp;gt;flag != DIO_AIO_UNWRITTEN)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (io-&amp;gt;flag != EXT4_IO_UNWRITTEN)
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return ret;
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (offset + size &amp;lt;= i_size_read(inode))
&lt;br&gt;@@ -3722,17 +3715,18 @@ static int ext4_end_aio_dio_nolock(ext4_
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;io-&amp;gt;flag = 0;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return ret;
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;+
&lt;br&gt;&amp;nbsp;/*
&lt;br&gt;&amp;nbsp;* work on completed aio dio IO, to convert unwritten extents to extents
&lt;br&gt;&amp;nbsp;*/
&lt;br&gt;-static void ext4_end_aio_dio_work(struct work_struct *work)
&lt;br&gt;+static void ext4_end_io_work(struct work_struct *work)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ext4_io_end_t *io &amp;nbsp;= container_of(work, ext4_io_end_t, work);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;struct inode *inode = io-&amp;gt;inode;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;int ret = 0;
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mutex_lock(&amp;inode-&amp;gt;i_mutex);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = ext4_end_aio_dio_nolock(io);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = ext4_end_io_nolock(io);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (ret &amp;gt;= 0) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (!list_empty(&amp;io-&amp;gt;list))
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;list_del_init(&amp;io-&amp;gt;list);
&lt;br&gt;@@ -3740,32 +3734,35 @@ static void ext4_end_aio_dio_work(struct
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mutex_unlock(&amp;inode-&amp;gt;i_mutex);
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;+
&lt;br&gt;&amp;nbsp;/*
&lt;br&gt;&amp;nbsp;* This function is called from ext4_sync_file().
&lt;br&gt;&amp;nbsp;*
&lt;br&gt;- * When AIO DIO IO is completed, the work to convert unwritten
&lt;br&gt;- * extents to written is queued on workqueue but may not get immediately
&lt;br&gt;+ * When IO is completed, the work to convert unwritten extents to
&lt;br&gt;+ * written is queued on workqueue but may not get immediately
&lt;br&gt;&amp;nbsp;* scheduled. When fsync is called, we need to ensure the
&lt;br&gt;&amp;nbsp;* conversion is complete before fsync returns.
&lt;br&gt;- * The inode keeps track of a list of completed AIO from DIO path
&lt;br&gt;- * that might needs to do the conversion. This function walks through
&lt;br&gt;- * the list and convert the related unwritten extents to written.
&lt;br&gt;+ * The inode keeps track of a list of pending/completed IO that
&lt;br&gt;+ * might needs to do the conversion. This function walks through
&lt;br&gt;+ * the list and convert the related unwritten extents for completed IO
&lt;br&gt;+ * to written.
&lt;br&gt;+ * The function return the number of pending IOs on success.
&lt;br&gt;&amp;nbsp;*/
&lt;br&gt;-int flush_aio_dio_completed_IO(struct inode *inode)
&lt;br&gt;+int flush_completed_IO(struct inode *inode)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ext4_io_end_t *io;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;int ret = 0;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;int ret2 = 0;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (list_empty(&amp;EXT4_I(inode)-&amp;gt;i_aio_dio_complete_list))
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (list_empty(&amp;EXT4_I(inode)-&amp;gt;i_completed_io_list))
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return ret;
&lt;br&gt;&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; dump_aio_dio_list(inode);
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; while (!list_empty(&amp;EXT4_I(inode)-&amp;gt;i_aio_dio_complete_list)){
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; io = list_entry(EXT4_I(inode)-&amp;gt;i_aio_dio_complete_list.next,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; dump_completed_IO(inode);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; while (!list_empty(&amp;EXT4_I(inode)-&amp;gt;i_completed_io_list)){
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; io = list_entry(EXT4_I(inode)-&amp;gt;i_completed_io_list.next,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ext4_io_end_t, list);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* Calling ext4_end_aio_dio_nolock() to convert completed
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* Calling ext4_end_io_nolock() to convert completed
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; * IO to written.
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; *
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; * When ext4_sync_file() is called, run_queue() may already
&lt;br&gt;@@ -3778,7 +3775,7 @@ int flush_aio_dio_completed_IO(struct in
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; * avoid double converting from both fsync and background work
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; * queue work.
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = ext4_end_aio_dio_nolock(io);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = ext4_end_io_nolock(io);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (ret &amp;lt; 0)
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ret2 = ret;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;else
&lt;br&gt;@@ -3800,7 +3797,7 @@ static ext4_io_end_t *ext4_init_io_end (
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;io-&amp;gt;offset = 0;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;io-&amp;gt;size = 0;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;io-&amp;gt;error = 0;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; INIT_WORK(&amp;io-&amp;gt;work, ext4_end_aio_dio_work);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; INIT_WORK(&amp;io-&amp;gt;work, ext4_end_io_work);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;INIT_LIST_HEAD(&amp;io-&amp;gt;list);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;&lt;br&gt;@@ -3823,7 +3820,7 @@ static void ext4_end_io_dio(struct kiocb
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;size);
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/* if not aio dio with unwritten extents, just free io and return */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; if (io_end-&amp;gt;flag != DIO_AIO_UNWRITTEN){
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; if (io_end-&amp;gt;flag != EXT4_IO_UNWRITTEN){
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ext4_free_io_end(io_end);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;iocb-&amp;gt;private = NULL;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return;
&lt;br&gt;@@ -3838,9 +3835,10 @@ static void ext4_end_io_dio(struct kiocb
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/* Add the io_end to per-inode completed aio dio list*/
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;list_add_tail(&amp;io_end-&amp;gt;list,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;EXT4_I(io_end-&amp;gt;inode)-&amp;gt;i_aio_dio_complete_list);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;EXT4_I(io_end-&amp;gt;inode)-&amp;gt;i_completed_io_list);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;iocb-&amp;gt;private = NULL;
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;+
&lt;br&gt;&amp;nbsp;/*
&lt;br&gt;&amp;nbsp;* For ext4 extent files, ext4 will do direct-io write to holes,
&lt;br&gt;&amp;nbsp;* preallocated extents, and those write extend the file, no need to
&lt;br&gt;@@ -3910,7 +3908,7 @@ static ssize_t ext4_ext_direct_IO(int rw
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ret = blockdev_direct_IO(rw, iocb, inode,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; inode-&amp;gt;i_sb-&amp;gt;s_bdev, iov,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; offset, nr_segs,
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ext4_get_block_dio_write,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ext4_get_block_write,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ext4_end_io_dio);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (iocb-&amp;gt;private)
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;EXT4_I(inode)-&amp;gt;cur_aio_dio = NULL;
&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26804991&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-RFC-PATCH-1-4--ext4%3A-DIO-get_block-code-cleanup-tp26804991p26804991.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26804978</id>
	<title>[RFC PATCH 0/4] ext4: implement DIO read nolocking</title>
	<published>2009-12-15T17:36:23Z</published>
	<updated>2009-12-15T17:36:23Z</updated>
	<author>
		<name>Jiaying Zhang-2</name>
	</author>
	<content type="html">Hi all,
&lt;br&gt;&lt;br&gt;Several weeks ago, we proposed the idea of always allocating uninitialized
&lt;br&gt;extent during ext4 DIO write and/or buffer write and convert the extent into
&lt;br&gt;initialized after IO complete. This allows us to drop the i_mutex lock during
&lt;br&gt;ext4 DIO read, which would help improve ext4 DIO read performance with
&lt;br&gt;multiple threads or AIOs running on high-speed SSDs. FYI, here is the email
&lt;br&gt;thread referred to: &lt;a href=&quot;http://marc.info/?l=linux-ext4&amp;m=125513220225086&amp;w=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://marc.info/?l=linux-ext4&amp;m=125513220225086&amp;w=2&lt;/a&gt;&lt;br&gt;&lt;br&gt;Following this email are our RFC patches to implement the proposed idea.
&lt;br&gt;We haven't tested these patches much so they are probably very buggy.
&lt;br&gt;&lt;br&gt;Any feedback would be greatly appreciated!
&lt;br&gt;&lt;br&gt;Regards,
&lt;br&gt;&lt;br&gt;Jiaying
&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26804978&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-RFC-PATCH-0-4--ext4%3A-implement-DIO-read-nolocking-tp26804978p26804978.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26803971</id>
	<title>Re: [PATCH] ext4: fix sleep inside spinlock issue aka #14739 V2</title>
	<published>2009-12-15T15:44:10Z</published>
	<updated>2009-12-15T15:44:10Z</updated>
	<author>
		<name>Jan Kara</name>
	</author>
	<content type="html">On Wed 16-12-09 02:16:36, Dmitry Monakhov wrote:
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; 2009/12/16 Jan Kara &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26803971&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;jack@...&lt;/a&gt;&amp;gt;:
&lt;br&gt;&amp;gt; &amp;gt; On Thu 10-12-09 20:22:16, Dmitry Monakhov wrote:
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt; drop i_block_reservation_lock before vfs_dq_reserve_block().
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt; this patch fix &lt;a href=&quot;http://bugzilla.kernel.org/show_bug.cgi?id=14739&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://bugzilla.kernel.org/show_bug.cgi?id=14739&lt;/a&gt;&lt;br&gt;&amp;gt; &amp;gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt; changes from previous version:
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt;  - simplify the patch according to Jan's comments
&lt;br&gt;&amp;gt; &amp;gt;  Dmitry, I suppose I should also merge this patch together with your other
&lt;br&gt;&amp;gt; &amp;gt; fixes, right? For some reason, it was not part of the last submission of
&lt;br&gt;&amp;gt; &amp;gt; your patch series...
&lt;br&gt;&amp;gt; yes. it is not in the series because it is another bug, and it is not
&lt;br&gt;&amp;gt; depended from
&lt;br&gt;&amp;gt; other patches.
&lt;br&gt;&amp;gt; Please merge newst version of the patch &lt;a href=&quot;http://patchwork.ozlabs.org/patch/40896/&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://patchwork.ozlabs.org/patch/40896/&lt;/a&gt;&lt;br&gt;&amp;gt; This version is affected by stupid bug, see at the bottom of the patch.
&lt;br&gt;&amp;gt; In fact this patch does help Justin Maggard to overcome his issue.
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; BTW &amp;nbsp;i've also have another patch &lt;a href=&quot;http://patchwork.ozlabs.org/patch/40805/&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://patchwork.ozlabs.org/patch/40805/&lt;/a&gt;&lt;br&gt;&amp;gt; it was acked by you, but ASAIK it was't pushed to the ext4 queue yet.
&lt;/div&gt;&amp;nbsp; OK, I've added both patches to my tree. Usually Ted takes care of ext4
&lt;br&gt;fixes but given that I carry also other ext4 quota fixes, I think I can
&lt;br&gt;merge these as well if he does not object.
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Honza
&lt;br&gt;-- 
&lt;br&gt;Jan Kara &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26803971&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;jack@...&lt;/a&gt;&amp;gt;
&lt;br&gt;SUSE Labs, CR
&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26803971&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH--ext4%3A-fix-sleep-inside-spinlock-issue-aka--14739-tp26720891p26803971.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26803668</id>
	<title>Re: [PATCH] ext4: fix sleep inside spinlock issue aka #14739 V2</title>
	<published>2009-12-15T15:16:36Z</published>
	<updated>2009-12-15T15:16:36Z</updated>
	<author>
		<name>Dmitry Monakhov-2</name>
	</author>
	<content type="html">2009/12/16 Jan Kara &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26803668&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;jack@...&lt;/a&gt;&amp;gt;:
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; On Thu 10-12-09 20:22:16, Dmitry Monakhov wrote:
&lt;br&gt;&amp;gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt; drop i_block_reservation_lock before vfs_dq_reserve_block().
&lt;br&gt;&amp;gt;&amp;gt; this patch fix &lt;a href=&quot;http://bugzilla.kernel.org/show_bug.cgi?id=14739&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://bugzilla.kernel.org/show_bug.cgi?id=14739&lt;/a&gt;&lt;br&gt;&amp;gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt; changes from previous version:
&lt;br&gt;&amp;gt;&amp;gt;  - simplify the patch according to Jan's comments
&lt;br&gt;&amp;gt;  Dmitry, I suppose I should also merge this patch together with your other
&lt;br&gt;&amp;gt; fixes, right? For some reason, it was not part of the last submission of
&lt;br&gt;&amp;gt; your patch series...
&lt;/div&gt;yes. it is not in the series because it is another bug, and it is not
&lt;br&gt;depended from
&lt;br&gt;other patches.
&lt;br&gt;Please merge newst version of the patch &lt;a href=&quot;http://patchwork.ozlabs.org/patch/40896/&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://patchwork.ozlabs.org/patch/40896/&lt;/a&gt;&lt;br&gt;This version is affected by stupid bug, see at the bottom of the patch.
&lt;br&gt;In fact this patch does help Justin Maggard to overcome his issue.
&lt;br&gt;&lt;br&gt;BTW &amp;nbsp;i've also have another patch &lt;a href=&quot;http://patchwork.ozlabs.org/patch/40805/&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://patchwork.ozlabs.org/patch/40805/&lt;/a&gt;&lt;br&gt;it was acked by you, but ASAIK it was't pushed to the ext4 queue yet.
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt;                                                                Honza
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt; Signed-off-by: Dmitry Monakhov &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26803668&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;dmonakhov@...&lt;/a&gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt; ---
&lt;br&gt;&amp;gt;&amp;gt;  fs/ext4/inode.c |    6 +++---
&lt;br&gt;&amp;gt;&amp;gt;  1 files changed, 3 insertions(+), 3 deletions(-)
&lt;br&gt;&amp;gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
&lt;br&gt;&amp;gt;&amp;gt; index 942e183..2327f7a 100644
&lt;br&gt;&amp;gt;&amp;gt; --- a/fs/ext4/inode.c
&lt;br&gt;&amp;gt;&amp;gt; +++ b/fs/ext4/inode.c
&lt;br&gt;&amp;gt;&amp;gt; @@ -1851,6 +1851,7 @@ repeat:
&lt;br&gt;&amp;gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt;       md_needed = mdblocks - EXT4_I(inode)-&amp;gt;i_reserved_meta_blocks;
&lt;br&gt;&amp;gt;&amp;gt;       total = md_needed + nrblocks;
&lt;br&gt;&amp;gt;&amp;gt; +     spin_unlock(&amp;EXT4_I(inode)-&amp;gt;i_block_reservation_lock);
&lt;br&gt;&amp;gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt;       /*
&lt;br&gt;&amp;gt;&amp;gt;        * Make quota reservation here to prevent quota overflow
&lt;br&gt;&amp;gt;&amp;gt; @@ -1858,12 +1859,10 @@ repeat:
&lt;br&gt;&amp;gt;&amp;gt;        * time.
&lt;br&gt;&amp;gt;&amp;gt;        */
&lt;br&gt;&amp;gt;&amp;gt;       if (vfs_dq_reserve_block(inode, total)) {
&lt;br&gt;&amp;gt;&amp;gt; -             spin_unlock(&amp;EXT4_I(inode)-&amp;gt;i_block_reservation_lock);
&lt;br&gt;&amp;gt;&amp;gt;               return -EDQUOT;
&lt;br&gt;&amp;gt;&amp;gt;       }
&lt;br&gt;&amp;gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt;       if (ext4_claim_free_blocks(sbi, total)) {
&lt;br&gt;&amp;gt;&amp;gt; -             spin_unlock(&amp;EXT4_I(inode)-&amp;gt;i_block_reservation_lock);
&lt;br&gt;&amp;gt;&amp;gt;               vfs_dq_release_reservation_block(inode, total);
&lt;br&gt;&amp;gt;&amp;gt;               if (ext4_should_retry_alloc(inode-&amp;gt;i_sb, &amp;retries)) {
&lt;br&gt;&amp;gt;&amp;gt;                       yield();
&lt;br&gt;&amp;gt;&amp;gt; @@ -1871,10 +1870,11 @@ repeat:
&lt;br&gt;&amp;gt;&amp;gt;               }
&lt;br&gt;&amp;gt;&amp;gt;               return -ENOSPC;
&lt;br&gt;&amp;gt;&amp;gt;       }
&lt;br&gt;&amp;gt;&amp;gt; +     spin_lock(&amp;EXT4_I(inode)-&amp;gt;i_block_reservation_lock);
&lt;br&gt;&amp;gt;&amp;gt;       EXT4_I(inode)-&amp;gt;i_reserved_data_blocks += nrblocks;
&lt;br&gt;&amp;gt;&amp;gt;       EXT4_I(inode)-&amp;gt;i_reserved_meta_blocks = mdblocks;
&lt;/div&gt;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
&lt;br&gt;meta_blocks may be changed after we dropped the lock, so we have to
&lt;br&gt;use add here:
&lt;br&gt;EXT4_I(inode)-&amp;gt;i_reserved_meta_blocks += mb_needed;
&lt;br&gt;I've overlooked this simple bug, and in fact i'm able to catch it only
&lt;br&gt;with havy io load
&lt;br&gt;./fsstress -p16 .....
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt;&amp;gt; -
&lt;br&gt;&amp;gt;&amp;gt;       spin_unlock(&amp;EXT4_I(inode)-&amp;gt;i_block_reservation_lock);
&lt;br&gt;&amp;gt;&amp;gt; +
&lt;br&gt;&amp;gt;&amp;gt;       return 0;       /* success */
&lt;br&gt;&amp;gt;&amp;gt;  }
&lt;br&gt;&amp;gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt; --
&lt;br&gt;&amp;gt;&amp;gt; 1.6.0.4
&lt;br&gt;&amp;gt;&amp;gt;
&lt;br&gt;&amp;gt; --
&lt;br&gt;&amp;gt; Jan Kara &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26803668&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;jack@...&lt;/a&gt;&amp;gt;
&lt;br&gt;&amp;gt; SUSE Labs, CR
&lt;br&gt;&amp;gt;
&lt;/div&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26803668&amp;i=3&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH--ext4%3A-fix-sleep-inside-spinlock-issue-aka--14739-tp26720891p26803668.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26803028</id>
	<title>Re: [PATCH] ext4: Ensure zeroout blocks have no dirty metadata</title>
	<published>2009-12-15T14:33:29Z</published>
	<updated>2009-12-15T14:33:29Z</updated>
	<author>
		<name>Curt Wohlgemuth</name>
	</author>
	<content type="html">On Fri, Dec 11, 2009 at 3:27 PM, Andreas Dilger &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26803028&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;adilger@...&lt;/a&gt;&amp;gt; wrote:
&lt;br&gt;&amp;gt; On 2009-12-11, at 15:01, Curt Wohlgemuth wrote:
&lt;br&gt;&lt;br&gt;&amp;gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt; Good point, Andreas.  I changed this to send in the handle to
&lt;br&gt;&amp;gt;&amp;gt; ext4_ext_zeroout().
&lt;br&gt;&lt;br&gt;&amp;gt; I was just thinking of checking EXT4_SB(inode-&amp;gt;i_sb)-&amp;gt;s_journal == NULL.  I
&lt;br&gt;&amp;gt; also thought about checking EXT4_HAS_INCOMPAT_FEATURE(sb, NEEDS_RECOVERY),
&lt;br&gt;&amp;gt; but I don't know if that is 100% safe (i.e. is it possible to mount such a
&lt;br&gt;&amp;gt; filesystem with &amp;quot;norecovery&amp;quot;?).
&lt;br&gt;&lt;br&gt;Arggh. &amp;nbsp;There are too many ways to check the journal use/mode... &amp;nbsp;This
&lt;br&gt;patch is considerably simpler.
&lt;br&gt;&lt;br&gt;=====================================================
&lt;br&gt;&lt;br&gt;This fixes a bug with no journal being used, in which new blocks returned
&lt;br&gt;from an extent created with ext4_ext_zeroout() can have dirty metadata still
&lt;br&gt;associated with them.
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Signed-off-by: Curt Wohlgemuth &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26803028&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;curtw@...&lt;/a&gt;&amp;gt;
&lt;br&gt;---
&lt;br&gt;&lt;br&gt;This is for the problem I reported on 23 Nov (&amp;quot;Bug in extent zeroout: blocks
&lt;br&gt;not marked as new&amp;quot;). &amp;nbsp;I'm not seeing the corruption with this fix that I was
&lt;br&gt;seeing without it.
&lt;br&gt;&lt;br&gt;diff -uprN orig/fs/ext4/extents.c new/fs/ext4/extents.c
&lt;br&gt;--- orig/fs/ext4/extents.c	2009-12-09 15:09:25.000000000 -0800
&lt;br&gt;+++ new/fs/ext4/extents.c	2009-12-15 13:26:29.000000000 -0800
&lt;br&gt;@@ -2474,9 +2474,28 @@ static int ext4_ext_zeroout(struct inode
&lt;br&gt;&amp;nbsp;		submit_bio(WRITE, bio);
&lt;br&gt;&amp;nbsp;		wait_for_completion(&amp;event);
&lt;br&gt;&lt;br&gt;-		if (test_bit(BIO_UPTODATE, &amp;bio-&amp;gt;bi_flags))
&lt;br&gt;+		if (test_bit(BIO_UPTODATE, &amp;bio-&amp;gt;bi_flags)) {
&lt;br&gt;+
&lt;br&gt;&amp;nbsp;			ret = 0;
&lt;br&gt;-		else {
&lt;br&gt;+
&lt;br&gt;+			/* On success, if there is no journal through which
&lt;br&gt;+			 * metadata is committed, we need to insure all
&lt;br&gt;+			 * metadata associated with each of these blocks is
&lt;br&gt;+			 * unmapped. */
&lt;br&gt;+			if (EXT4_SB(inode-&amp;gt;i_sb)-&amp;gt;s_journal == NULL) {
&lt;br&gt;+				sector_t block = ee_pblock;
&lt;br&gt;+
&lt;br&gt;+				done = 0;
&lt;br&gt;+				while (done &amp;lt; len) {
&lt;br&gt;+					unmap_underlying_metadata(inode-&amp;gt;i_sb-&amp;gt;
&lt;br&gt;+									s_bdev,
&lt;br&gt;+								 &amp;nbsp;block);
&lt;br&gt;+
&lt;br&gt;+					done++;
&lt;br&gt;+					block++;
&lt;br&gt;+				}
&lt;br&gt;+			}
&lt;br&gt;+		} else {
&lt;br&gt;&amp;nbsp;			ret = -EIO;
&lt;br&gt;&amp;nbsp;			break;
&lt;br&gt;&amp;nbsp;		}
&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26803028&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH--ext4%3A-Ensure-zeroout-blocks-have-no-dirty-metadata-tp26731303p26803028.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26802637</id>
	<title>[merged] tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function.patch removed from -mm tree</title>
	<published>2009-12-15T13:57:46Z</published>
	<updated>2009-12-15T13:57:46Z</updated>
	<author>
		<name>tip-bot for akpm@linux-foundation.org</name>
	</author>
	<content type="html">&lt;br&gt;The patch titled
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;tree-wide: convert open calls to remove spaces to skip_spaces() lib function
&lt;br&gt;has been removed from the -mm tree. &amp;nbsp;Its filename was
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function.patch
&lt;br&gt;&lt;br&gt;This patch was dropped because it was merged into mainline or a subsystem tree
&lt;br&gt;&lt;br&gt;The current -mm tree may be found at &lt;a href=&quot;http://userweb.kernel.org/~akpm/mmotm/&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://userweb.kernel.org/~akpm/mmotm/&lt;/a&gt;&lt;br&gt;&lt;br&gt;------------------------------------------------------
&lt;br&gt;Subject: tree-wide: convert open calls to remove spaces to skip_spaces() lib function
&lt;br&gt;From: André Goddard Rosa &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26802637&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;andre.goddard@...&lt;/a&gt;&amp;gt;
&lt;br&gt;&lt;br&gt;Makes use of skip_spaces() defined in lib/string.c for removing leading
&lt;br&gt;spaces from strings all over the tree.
&lt;br&gt;&lt;br&gt;It decreases lib.a code size by 47 bytes and reuses the function tree-wide:
&lt;br&gt;&amp;nbsp; &amp;nbsp;text &amp;nbsp; &amp;nbsp;data &amp;nbsp; &amp;nbsp; bss &amp;nbsp; &amp;nbsp; dec &amp;nbsp; &amp;nbsp; hex filename
&lt;br&gt;&amp;nbsp; 64688 &amp;nbsp; &amp;nbsp; 584 &amp;nbsp; &amp;nbsp; 592 &amp;nbsp; 65864 &amp;nbsp; 10148 (TOTALS-BEFORE)
&lt;br&gt;&amp;nbsp; 64641 &amp;nbsp; &amp;nbsp; 584 &amp;nbsp; &amp;nbsp; 592 &amp;nbsp; 65817 &amp;nbsp; 10119 (TOTALS-AFTER)
&lt;br&gt;&lt;br&gt;Also, while at it, if we see (*str &amp;&amp; isspace(*str)), we can be sure to
&lt;br&gt;remove the first condition (*str) as the second one (isspace(*str)) also
&lt;br&gt;evaluates to 0 whenever *str == 0, making it redundant. In other words,
&lt;br&gt;&amp;quot;a char equals zero is never a space&amp;quot;.
&lt;br&gt;&lt;br&gt;Julia Lawall tried the semantic patch (&lt;a href=&quot;http://coccinelle.lip6.fr&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://coccinelle.lip6.fr&lt;/a&gt;) below,
&lt;br&gt;and found occurrences of this pattern on 3 more files:
&lt;br&gt;&amp;nbsp; &amp;nbsp; drivers/leds/led-class.c
&lt;br&gt;&amp;nbsp; &amp;nbsp; drivers/leds/ledtrig-timer.c
&lt;br&gt;&amp;nbsp; &amp;nbsp; drivers/video/output.c
&lt;br&gt;&lt;br&gt;@@
&lt;br&gt;expression str;
&lt;br&gt;@@
&lt;br&gt;&lt;br&gt;( // ignore skip_spaces cases
&lt;br&gt;while (*str &amp;&amp; &amp;nbsp;isspace(*str)) { \(str++;\|++str;\) }
&lt;br&gt;|
&lt;br&gt;- *str &amp;&amp;
&lt;br&gt;isspace(*str)
&lt;br&gt;)
&lt;br&gt;&lt;br&gt;Signed-off-by: André Goddard Rosa &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26802637&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;andre.goddard@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: Julia Lawall &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26802637&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;julia@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: Martin Schwidefsky &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26802637&amp;i=3&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;schwidefsky@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: Jeff Dike &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26802637&amp;i=4&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;jdike@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: Ingo Molnar &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26802637&amp;i=5&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;mingo@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: Thomas Gleixner &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26802637&amp;i=6&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;tglx@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: &amp;quot;H. Peter Anvin&amp;quot; &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26802637&amp;i=7&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;hpa@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: Richard Purdie &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26802637&amp;i=8&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rpurdie@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: Neil Brown &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26802637&amp;i=9&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;neilb@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: Kyle McMartin &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26802637&amp;i=10&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;kyle@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: Henrique de Moraes Holschuh &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26802637&amp;i=11&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;hmh@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: David Howells &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26802637&amp;i=12&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;dhowells@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26802637&amp;i=13&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;linux-ext4@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: Samuel Ortiz &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26802637&amp;i=14&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;samuel@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: Patrick McHardy &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26802637&amp;i=15&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;kaber@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: Takashi Iwai &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26802637&amp;i=16&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;tiwai@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Signed-off-by: Andrew Morton &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26802637&amp;i=17&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;akpm@...&lt;/a&gt;&amp;gt;
&lt;br&gt;---
&lt;br&gt;&lt;br&gt;&amp;nbsp;arch/s390/kernel/debug.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp;3 +-
&lt;br&gt;&amp;nbsp;arch/um/drivers/mconsole_kern.c &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; 16 ++++------
&lt;br&gt;&amp;nbsp;arch/x86/kernel/cpu/mtrr/if.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; 11 ++-----
&lt;br&gt;&amp;nbsp;drivers/leds/led-class.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp;2 -
&lt;br&gt;&amp;nbsp;drivers/leds/ledtrig-timer.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp;4 +-
&lt;br&gt;&amp;nbsp;drivers/md/dm-table.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; &amp;nbsp;6 +---
&lt;br&gt;&amp;nbsp;drivers/md/md.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; &amp;nbsp;4 +-
&lt;br&gt;&amp;nbsp;drivers/parisc/pdc_stable.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; &amp;nbsp;9 ++----
&lt;br&gt;&amp;nbsp;drivers/platform/x86/thinkpad_acpi.c &amp;nbsp;| &amp;nbsp; &amp;nbsp;7 +---
&lt;br&gt;&amp;nbsp;drivers/pnp/interface.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; 36 ++++++------------------
&lt;br&gt;&amp;nbsp;drivers/s390/block/dasd_proc.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp;5 ++-
&lt;br&gt;&amp;nbsp;drivers/video/backlight/lcd.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; &amp;nbsp;4 +-
&lt;br&gt;&amp;nbsp;drivers/video/display/display-sysfs.c | &amp;nbsp; &amp;nbsp;2 -
&lt;br&gt;&amp;nbsp;drivers/video/output.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp;2 -
&lt;br&gt;&amp;nbsp;fs/cachefiles/daemon.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp;4 +-
&lt;br&gt;&amp;nbsp;fs/ext4/super.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; &amp;nbsp;7 +---
&lt;br&gt;&amp;nbsp;kernel/params.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; &amp;nbsp;8 ++---
&lt;br&gt;&amp;nbsp;lib/argv_split.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; 13 ++------
&lt;br&gt;&amp;nbsp;lib/dynamic_debug.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; &amp;nbsp;4 +-
&lt;br&gt;&amp;nbsp;lib/vsprintf.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; 15 ++--------
&lt;br&gt;&amp;nbsp;net/irda/irnet/irnet.h &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp;1 
&lt;br&gt;&amp;nbsp;net/irda/irnet/irnet_ppp.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp;8 ++---
&lt;br&gt;&amp;nbsp;net/netfilter/xt_recent.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; &amp;nbsp;3 --
&lt;br&gt;&amp;nbsp;sound/pci/hda/hda_hwdep.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; &amp;nbsp;7 ++--
&lt;br&gt;&amp;nbsp;24 files changed, 66 insertions(+), 115 deletions(-)
&lt;br&gt;&lt;br&gt;diff -puN arch/s390/kernel/debug.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function arch/s390/kernel/debug.c
&lt;br&gt;--- a/arch/s390/kernel/debug.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/arch/s390/kernel/debug.c
&lt;br&gt;@@ -18,6 +18,7 @@
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/errno.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/slab.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/ctype.h&amp;gt;
&lt;br&gt;+#include &amp;lt;linux/string.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/sysctl.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;asm/uaccess.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/module.h&amp;gt;
&lt;br&gt;@@ -1178,7 +1179,7 @@ debug_get_uint(char *buf)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;&amp;nbsp;	int rc;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	for(; isspace(*buf); buf++);
&lt;br&gt;+	buf = skip_spaces(buf);
&lt;br&gt;&amp;nbsp;	rc = simple_strtoul(buf, &amp;buf, 10);
&lt;br&gt;&amp;nbsp;	if(*buf){
&lt;br&gt;&amp;nbsp;		rc = -EINVAL;
&lt;br&gt;diff -puN arch/um/drivers/mconsole_kern.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function arch/um/drivers/mconsole_kern.c
&lt;br&gt;--- a/arch/um/drivers/mconsole_kern.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/arch/um/drivers/mconsole_kern.c
&lt;br&gt;@@ -6,6 +6,7 @@
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/console.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/ctype.h&amp;gt;
&lt;br&gt;+#include &amp;lt;linux/string.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/interrupt.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/list.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/mm.h&amp;gt;
&lt;br&gt;@@ -131,7 +132,7 @@ void mconsole_proc(struct mc_request *re
&lt;br&gt;&amp;nbsp;	char *ptr = req-&amp;gt;request.data, *buf;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	ptr += strlen(&amp;quot;proc&amp;quot;);
&lt;br&gt;-	while (isspace(*ptr)) ptr++;
&lt;br&gt;+	ptr = skip_spaces(ptr);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	proc = get_fs_type(&amp;quot;proc&amp;quot;);
&lt;br&gt;&amp;nbsp;	if (proc == NULL) {
&lt;br&gt;@@ -212,8 +213,7 @@ void mconsole_proc(struct mc_request *re
&lt;br&gt;&amp;nbsp;	char *ptr = req-&amp;gt;request.data;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	ptr += strlen(&amp;quot;proc&amp;quot;);
&lt;br&gt;-	while (isspace(*ptr))
&lt;br&gt;-		ptr++;
&lt;br&gt;+	ptr = skip_spaces(ptr);
&lt;br&gt;&amp;nbsp;	snprintf(path, sizeof(path), &amp;quot;/proc/%s&amp;quot;, ptr);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	fd = sys_open(path, 0, 0);
&lt;br&gt;@@ -560,8 +560,7 @@ void mconsole_config(struct mc_request *
&lt;br&gt;&amp;nbsp;	int err;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	ptr += strlen(&amp;quot;config&amp;quot;);
&lt;br&gt;-	while (isspace(*ptr))
&lt;br&gt;-		ptr++;
&lt;br&gt;+	ptr = skip_spaces(ptr);
&lt;br&gt;&amp;nbsp;	dev = mconsole_find_dev(ptr);
&lt;br&gt;&amp;nbsp;	if (dev == NULL) {
&lt;br&gt;&amp;nbsp;		mconsole_reply(req, &amp;quot;Bad configuration option&amp;quot;, 1, 0);
&lt;br&gt;@@ -588,7 +587,7 @@ void mconsole_remove(struct mc_request *
&lt;br&gt;&amp;nbsp;	int err, start, end, n;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	ptr += strlen(&amp;quot;remove&amp;quot;);
&lt;br&gt;-	while (isspace(*ptr)) ptr++;
&lt;br&gt;+	ptr = skip_spaces(ptr);
&lt;br&gt;&amp;nbsp;	dev = mconsole_find_dev(ptr);
&lt;br&gt;&amp;nbsp;	if (dev == NULL) {
&lt;br&gt;&amp;nbsp;		mconsole_reply(req, &amp;quot;Bad remove option&amp;quot;, 1, 0);
&lt;br&gt;@@ -712,7 +711,7 @@ void mconsole_sysrq(struct mc_request *r
&lt;br&gt;&amp;nbsp;	char *ptr = req-&amp;gt;request.data;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	ptr += strlen(&amp;quot;sysrq&amp;quot;);
&lt;br&gt;-	while (isspace(*ptr)) ptr++;
&lt;br&gt;+	ptr = skip_spaces(ptr);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	/*
&lt;br&gt;&amp;nbsp;	 * With 'b', the system will shut down without a chance to reply,
&lt;br&gt;@@ -757,8 +756,7 @@ void mconsole_stack(struct mc_request *r
&lt;br&gt;&amp;nbsp;	 */
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	ptr += strlen(&amp;quot;stack&amp;quot;);
&lt;br&gt;-	while (isspace(*ptr))
&lt;br&gt;-		ptr++;
&lt;br&gt;+	ptr = skip_spaces(ptr);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	/*
&lt;br&gt;&amp;nbsp;	 * Should really check for multiple pids or reject bad args here
&lt;br&gt;diff -puN arch/x86/kernel/cpu/mtrr/if.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function arch/x86/kernel/cpu/mtrr/if.c
&lt;br&gt;--- a/arch/x86/kernel/cpu/mtrr/if.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/arch/x86/kernel/cpu/mtrr/if.c
&lt;br&gt;@@ -4,6 +4,7 @@
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/proc_fs.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/module.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/ctype.h&amp;gt;
&lt;br&gt;+#include &amp;lt;linux/string.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/init.h&amp;gt;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;#define LINE_SIZE 80
&lt;br&gt;@@ -133,8 +134,7 @@ mtrr_write(struct file *file, const char
&lt;br&gt;&amp;nbsp;		return -EINVAL;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	base = simple_strtoull(line + 5, &amp;ptr, 0);
&lt;br&gt;-	while (isspace(*ptr))
&lt;br&gt;-		ptr++;
&lt;br&gt;+	ptr = skip_spaces(ptr);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	if (strncmp(ptr, &amp;quot;size=&amp;quot;, 5))
&lt;br&gt;&amp;nbsp;		return -EINVAL;
&lt;br&gt;@@ -142,14 +142,11 @@ mtrr_write(struct file *file, const char
&lt;br&gt;&amp;nbsp;	size = simple_strtoull(ptr + 5, &amp;ptr, 0);
&lt;br&gt;&amp;nbsp;	if ((base &amp; 0xfff) || (size &amp; 0xfff))
&lt;br&gt;&amp;nbsp;		return -EINVAL;
&lt;br&gt;-	while (isspace(*ptr))
&lt;br&gt;-		ptr++;
&lt;br&gt;+	ptr = skip_spaces(ptr);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	if (strncmp(ptr, &amp;quot;type=&amp;quot;, 5))
&lt;br&gt;&amp;nbsp;		return -EINVAL;
&lt;br&gt;-	ptr += 5;
&lt;br&gt;-	while (isspace(*ptr))
&lt;br&gt;-		ptr++;
&lt;br&gt;+	ptr = skip_spaces(ptr + 5);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	for (i = 0; i &amp;lt; MTRR_NUM_TYPES; ++i) {
&lt;br&gt;&amp;nbsp;		if (strcmp(ptr, mtrr_strings[i]))
&lt;br&gt;diff -puN drivers/leds/led-class.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function drivers/leds/led-class.c
&lt;br&gt;--- a/drivers/leds/led-class.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/drivers/leds/led-class.c
&lt;br&gt;@@ -50,7 +50,7 @@ static ssize_t led_brightness_store(stru
&lt;br&gt;&amp;nbsp;	unsigned long state = simple_strtoul(buf, &amp;after, 10);
&lt;br&gt;&amp;nbsp;	size_t count = after - buf;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	if (*after &amp;&amp; isspace(*after))
&lt;br&gt;+	if (isspace(*after))
&lt;br&gt;&amp;nbsp;		count++;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	if (count == size) {
&lt;br&gt;diff -puN drivers/leds/ledtrig-timer.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function drivers/leds/ledtrig-timer.c
&lt;br&gt;--- a/drivers/leds/ledtrig-timer.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/drivers/leds/ledtrig-timer.c
&lt;br&gt;@@ -83,7 +83,7 @@ static ssize_t led_delay_on_store(struct
&lt;br&gt;&amp;nbsp;	unsigned long state = simple_strtoul(buf, &amp;after, 10);
&lt;br&gt;&amp;nbsp;	size_t count = after - buf;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	if (*after &amp;&amp; isspace(*after))
&lt;br&gt;+	if (isspace(*after))
&lt;br&gt;&amp;nbsp;		count++;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	if (count == size) {
&lt;br&gt;@@ -127,7 +127,7 @@ static ssize_t led_delay_off_store(struc
&lt;br&gt;&amp;nbsp;	unsigned long state = simple_strtoul(buf, &amp;after, 10);
&lt;br&gt;&amp;nbsp;	size_t count = after - buf;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	if (*after &amp;&amp; isspace(*after))
&lt;br&gt;+	if (isspace(*after))
&lt;br&gt;&amp;nbsp;		count++;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	if (count == size) {
&lt;br&gt;diff -puN drivers/md/dm-table.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function drivers/md/dm-table.c
&lt;br&gt;--- a/drivers/md/dm-table.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/drivers/md/dm-table.c
&lt;br&gt;@@ -12,6 +12,7 @@
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/blkdev.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/namei.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/ctype.h&amp;gt;
&lt;br&gt;+#include &amp;lt;linux/string.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/slab.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/interrupt.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/mutex.h&amp;gt;
&lt;br&gt;@@ -600,11 +601,8 @@ int dm_split_args(int *argc, char ***arg
&lt;br&gt;&amp;nbsp;		return -ENOMEM;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	while (1) {
&lt;br&gt;-		start = end;
&lt;br&gt;-
&lt;br&gt;&amp;nbsp;		/* Skip whitespace */
&lt;br&gt;-		while (*start &amp;&amp; isspace(*start))
&lt;br&gt;-			start++;
&lt;br&gt;+		start = skip_spaces(end);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;		if (!*start)
&lt;br&gt;&amp;nbsp;			break;	/* success, we hit the end */
&lt;br&gt;diff -puN drivers/md/md.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function drivers/md/md.c
&lt;br&gt;--- a/drivers/md/md.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/drivers/md/md.c
&lt;br&gt;@@ -39,6 +39,7 @@
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/buffer_head.h&amp;gt; /* for invalidate_bdev */
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/poll.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/ctype.h&amp;gt;
&lt;br&gt;+#include &amp;lt;linux/string.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/hdreg.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/proc_fs.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/random.h&amp;gt;
&lt;br&gt;@@ -3246,8 +3247,7 @@ bitmap_store(mddev_t *mddev, const char 
&lt;br&gt;&amp;nbsp;		}
&lt;br&gt;&amp;nbsp;		if (*end &amp;&amp; !isspace(*end)) break;
&lt;br&gt;&amp;nbsp;		bitmap_dirty_bits(mddev-&amp;gt;bitmap, chunk, end_chunk);
&lt;br&gt;-		buf = end;
&lt;br&gt;-		while (isspace(*buf)) buf++;
&lt;br&gt;+		buf = skip_spaces(end);
&lt;br&gt;&amp;nbsp;	}
&lt;br&gt;&amp;nbsp;	bitmap_unplug(mddev-&amp;gt;bitmap); /* flush the bits to disk */
&lt;br&gt;&amp;nbsp;out:
&lt;br&gt;diff -puN drivers/parisc/pdc_stable.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function drivers/parisc/pdc_stable.c
&lt;br&gt;--- a/drivers/parisc/pdc_stable.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/drivers/parisc/pdc_stable.c
&lt;br&gt;@@ -779,12 +779,9 @@ static ssize_t pdcs_auto_write(struct ko
&lt;br&gt;&amp;nbsp;	read_unlock(&amp;pathentry-&amp;gt;rw_lock);
&lt;br&gt;&amp;nbsp;	
&lt;br&gt;&amp;nbsp;	DPRINTK(&amp;quot;%s: flags before: 0x%X\n&amp;quot;, __func__, flags);
&lt;br&gt;-			
&lt;br&gt;-	temp = in;
&lt;br&gt;-	
&lt;br&gt;-	while (*temp &amp;&amp; isspace(*temp))
&lt;br&gt;-		temp++;
&lt;br&gt;-	
&lt;br&gt;+
&lt;br&gt;+	temp = skip_spaces(in);
&lt;br&gt;+
&lt;br&gt;&amp;nbsp;	c = *temp++ - '0';
&lt;br&gt;&amp;nbsp;	if ((c != 0) &amp;&amp; (c != 1))
&lt;br&gt;&amp;nbsp;		goto parse_error;
&lt;br&gt;diff -puN drivers/platform/x86/thinkpad_acpi.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function drivers/platform/x86/thinkpad_acpi.c
&lt;br&gt;--- a/drivers/platform/x86/thinkpad_acpi.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/drivers/platform/x86/thinkpad_acpi.c
&lt;br&gt;@@ -1006,11 +1006,8 @@ static int parse_strtoul(const char *buf
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;&amp;nbsp;	char *endp;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	while (*buf &amp;&amp; isspace(*buf))
&lt;br&gt;-		buf++;
&lt;br&gt;-	*value = simple_strtoul(buf, &amp;endp, 0);
&lt;br&gt;-	while (*endp &amp;&amp; isspace(*endp))
&lt;br&gt;-		endp++;
&lt;br&gt;+	*value = simple_strtoul(skip_spaces(buf), &amp;endp, 0);
&lt;br&gt;+	endp = skip_spaces(endp);
&lt;br&gt;&amp;nbsp;	if (*endp || *value &amp;gt; max)
&lt;br&gt;&amp;nbsp;		return -EINVAL;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;diff -puN drivers/pnp/interface.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function drivers/pnp/interface.c
&lt;br&gt;--- a/drivers/pnp/interface.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/drivers/pnp/interface.c
&lt;br&gt;@@ -310,8 +310,7 @@ static ssize_t pnp_set_current_resources
&lt;br&gt;&amp;nbsp;		goto done;
&lt;br&gt;&amp;nbsp;	}
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	while (isspace(*buf))
&lt;br&gt;-		++buf;
&lt;br&gt;+	buf = skip_spaces(buf);
&lt;br&gt;&amp;nbsp;	if (!strnicmp(buf, &amp;quot;disable&amp;quot;, 7)) {
&lt;br&gt;&amp;nbsp;		retval = pnp_disable_dev(dev);
&lt;br&gt;&amp;nbsp;		goto done;
&lt;br&gt;@@ -353,19 +352,13 @@ static ssize_t pnp_set_current_resources
&lt;br&gt;&amp;nbsp;		pnp_init_resources(dev);
&lt;br&gt;&amp;nbsp;		mutex_lock(&amp;pnp_res_mutex);
&lt;br&gt;&amp;nbsp;		while (1) {
&lt;br&gt;-			while (isspace(*buf))
&lt;br&gt;-				++buf;
&lt;br&gt;+			buf = skip_spaces(buf);
&lt;br&gt;&amp;nbsp;			if (!strnicmp(buf, &amp;quot;io&amp;quot;, 2)) {
&lt;br&gt;-				buf += 2;
&lt;br&gt;-				while (isspace(*buf))
&lt;br&gt;-					++buf;
&lt;br&gt;+				buf = skip_spaces(buf + 2);
&lt;br&gt;&amp;nbsp;				start = simple_strtoul(buf, &amp;buf, 0);
&lt;br&gt;-				while (isspace(*buf))
&lt;br&gt;-					++buf;
&lt;br&gt;+				buf = skip_spaces(buf);
&lt;br&gt;&amp;nbsp;				if (*buf == '-') {
&lt;br&gt;-					buf += 1;
&lt;br&gt;-					while (isspace(*buf))
&lt;br&gt;-						++buf;
&lt;br&gt;+					buf = skip_spaces(buf + 1);
&lt;br&gt;&amp;nbsp;					end = simple_strtoul(buf, &amp;buf, 0);
&lt;br&gt;&amp;nbsp;				} else
&lt;br&gt;&amp;nbsp;					end = start;
&lt;br&gt;@@ -373,16 +366,11 @@ static ssize_t pnp_set_current_resources
&lt;br&gt;&amp;nbsp;				continue;
&lt;br&gt;&amp;nbsp;			}
&lt;br&gt;&amp;nbsp;			if (!strnicmp(buf, &amp;quot;mem&amp;quot;, 3)) {
&lt;br&gt;-				buf += 3;
&lt;br&gt;-				while (isspace(*buf))
&lt;br&gt;-					++buf;
&lt;br&gt;+				buf = skip_spaces(buf + 3);
&lt;br&gt;&amp;nbsp;				start = simple_strtoul(buf, &amp;buf, 0);
&lt;br&gt;-				while (isspace(*buf))
&lt;br&gt;-					++buf;
&lt;br&gt;+				buf = skip_spaces(buf);
&lt;br&gt;&amp;nbsp;				if (*buf == '-') {
&lt;br&gt;-					buf += 1;
&lt;br&gt;-					while (isspace(*buf))
&lt;br&gt;-						++buf;
&lt;br&gt;+					buf = skip_spaces(buf + 1);
&lt;br&gt;&amp;nbsp;					end = simple_strtoul(buf, &amp;buf, 0);
&lt;br&gt;&amp;nbsp;				} else
&lt;br&gt;&amp;nbsp;					end = start;
&lt;br&gt;@@ -390,17 +378,13 @@ static ssize_t pnp_set_current_resources
&lt;br&gt;&amp;nbsp;				continue;
&lt;br&gt;&amp;nbsp;			}
&lt;br&gt;&amp;nbsp;			if (!strnicmp(buf, &amp;quot;irq&amp;quot;, 3)) {
&lt;br&gt;-				buf += 3;
&lt;br&gt;-				while (isspace(*buf))
&lt;br&gt;-					++buf;
&lt;br&gt;+				buf = skip_spaces(buf + 3);
&lt;br&gt;&amp;nbsp;				start = simple_strtoul(buf, &amp;buf, 0);
&lt;br&gt;&amp;nbsp;				pnp_add_irq_resource(dev, start, 0);
&lt;br&gt;&amp;nbsp;				continue;
&lt;br&gt;&amp;nbsp;			}
&lt;br&gt;&amp;nbsp;			if (!strnicmp(buf, &amp;quot;dma&amp;quot;, 3)) {
&lt;br&gt;-				buf += 3;
&lt;br&gt;-				while (isspace(*buf))
&lt;br&gt;-					++buf;
&lt;br&gt;+				buf = skip_spaces(buf + 3);
&lt;br&gt;&amp;nbsp;				start = simple_strtoul(buf, &amp;buf, 0);
&lt;br&gt;&amp;nbsp;				pnp_add_dma_resource(dev, start, 0);
&lt;br&gt;&amp;nbsp;				continue;
&lt;br&gt;diff -puN drivers/s390/block/dasd_proc.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function drivers/s390/block/dasd_proc.c
&lt;br&gt;--- a/drivers/s390/block/dasd_proc.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/drivers/s390/block/dasd_proc.c
&lt;br&gt;@@ -14,6 +14,7 @@
&lt;br&gt;&amp;nbsp;#define KMSG_COMPONENT &amp;quot;dasd&amp;quot;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/ctype.h&amp;gt;
&lt;br&gt;+#include &amp;lt;linux/string.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/seq_file.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/vmalloc.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/proc_fs.h&amp;gt;
&lt;br&gt;@@ -272,10 +273,10 @@ dasd_statistics_write(struct file *file,
&lt;br&gt;&amp;nbsp;	DBF_EVENT(DBF_DEBUG, &amp;quot;/proc/dasd/statictics: '%s'\n&amp;quot;, buffer);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	/* check for valid verbs */
&lt;br&gt;-	for (str = buffer; isspace(*str); str++);
&lt;br&gt;+	str = skip_spaces(buffer);
&lt;br&gt;&amp;nbsp;	if (strncmp(str, &amp;quot;set&amp;quot;, 3) == 0 &amp;&amp; isspace(str[3])) {
&lt;br&gt;&amp;nbsp;		/* 'set xxx' was given */
&lt;br&gt;-		for (str = str + 4; isspace(*str); str++);
&lt;br&gt;+		str = skip_spaces(str + 4);
&lt;br&gt;&amp;nbsp;		if (strcmp(str, &amp;quot;on&amp;quot;) == 0) {
&lt;br&gt;&amp;nbsp;			/* switch on statistics profiling */
&lt;br&gt;&amp;nbsp;			dasd_profile_level = DASD_PROFILE_ON;
&lt;br&gt;diff -puN drivers/video/backlight/lcd.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function drivers/video/backlight/lcd.c
&lt;br&gt;--- a/drivers/video/backlight/lcd.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/drivers/video/backlight/lcd.c
&lt;br&gt;@@ -101,7 +101,7 @@ static ssize_t lcd_store_power(struct de
&lt;br&gt;&amp;nbsp;	int power = simple_strtoul(buf, &amp;endp, 0);
&lt;br&gt;&amp;nbsp;	size_t size = endp - buf;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	if (*endp &amp;&amp; isspace(*endp))
&lt;br&gt;+	if (isspace(*endp))
&lt;br&gt;&amp;nbsp;		size++;
&lt;br&gt;&amp;nbsp;	if (size != count)
&lt;br&gt;&amp;nbsp;		return -EINVAL;
&lt;br&gt;@@ -140,7 +140,7 @@ static ssize_t lcd_store_contrast(struct
&lt;br&gt;&amp;nbsp;	int contrast = simple_strtoul(buf, &amp;endp, 0);
&lt;br&gt;&amp;nbsp;	size_t size = endp - buf;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	if (*endp &amp;&amp; isspace(*endp))
&lt;br&gt;+	if (isspace(*endp))
&lt;br&gt;&amp;nbsp;		size++;
&lt;br&gt;&amp;nbsp;	if (size != count)
&lt;br&gt;&amp;nbsp;		return -EINVAL;
&lt;br&gt;diff -puN drivers/video/display/display-sysfs.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function drivers/video/display/display-sysfs.c
&lt;br&gt;--- a/drivers/video/display/display-sysfs.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/drivers/video/display/display-sysfs.c
&lt;br&gt;@@ -67,7 +67,7 @@ static ssize_t display_store_contrast(st
&lt;br&gt;&amp;nbsp;	contrast = simple_strtoul(buf, &amp;endp, 0);
&lt;br&gt;&amp;nbsp;	size = endp - buf;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	if (*endp &amp;&amp; isspace(*endp))
&lt;br&gt;+	if (isspace(*endp))
&lt;br&gt;&amp;nbsp;		size++;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	if (size != count)
&lt;br&gt;diff -puN drivers/video/output.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function drivers/video/output.c
&lt;br&gt;--- a/drivers/video/output.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/drivers/video/output.c
&lt;br&gt;@@ -50,7 +50,7 @@ static ssize_t video_output_store_state(
&lt;br&gt;&amp;nbsp;	int request_state = simple_strtoul(buf,&amp;endp,0);
&lt;br&gt;&amp;nbsp;	size_t size = endp - buf;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	if (*endp &amp;&amp; isspace(*endp))
&lt;br&gt;+	if (isspace(*endp))
&lt;br&gt;&amp;nbsp;		size++;
&lt;br&gt;&amp;nbsp;	if (size != count)
&lt;br&gt;&amp;nbsp;		return -EINVAL;
&lt;br&gt;diff -puN fs/cachefiles/daemon.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function fs/cachefiles/daemon.c
&lt;br&gt;--- a/fs/cachefiles/daemon.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/fs/cachefiles/daemon.c
&lt;br&gt;@@ -21,6 +21,7 @@
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/mount.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/statfs.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/ctype.h&amp;gt;
&lt;br&gt;+#include &amp;lt;linux/string.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/fs_struct.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;quot;internal.h&amp;quot;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;@@ -257,8 +258,7 @@ static ssize_t cachefiles_daemon_write(s
&lt;br&gt;&amp;nbsp;		if (args == data)
&lt;br&gt;&amp;nbsp;			goto error;
&lt;br&gt;&amp;nbsp;		*args = '\0';
&lt;br&gt;-		for (args++; isspace(*args); args++)
&lt;br&gt;-			continue;
&lt;br&gt;+		args = skip_spaces(++args);
&lt;br&gt;&amp;nbsp;	}
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	/* run the appropriate command handler */
&lt;br&gt;diff -puN fs/ext4/super.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function fs/ext4/super.c
&lt;br&gt;--- a/fs/ext4/super.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/fs/ext4/super.c
&lt;br&gt;@@ -2137,11 +2137,8 @@ static int parse_strtoul(const char *buf
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;&amp;nbsp;	char *endp;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	while (*buf &amp;&amp; isspace(*buf))
&lt;br&gt;-		buf++;
&lt;br&gt;-	*value = simple_strtoul(buf, &amp;endp, 0);
&lt;br&gt;-	while (*endp &amp;&amp; isspace(*endp))
&lt;br&gt;-		endp++;
&lt;br&gt;+	*value = simple_strtoul(skip_spaces(buf), &amp;endp, 0);
&lt;br&gt;+	endp = skip_spaces(endp);
&lt;br&gt;&amp;nbsp;	if (*endp || *value &amp;gt; max)
&lt;br&gt;&amp;nbsp;		return -EINVAL;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;diff -puN kernel/params.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function kernel/params.c
&lt;br&gt;--- a/kernel/params.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/kernel/params.c
&lt;br&gt;@@ -24,6 +24,7 @@
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/err.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/slab.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/ctype.h&amp;gt;
&lt;br&gt;+#include &amp;lt;linux/string.h&amp;gt;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;#if 0
&lt;br&gt;&amp;nbsp;#define DEBUGP printk
&lt;br&gt;@@ -122,9 +123,7 @@ static char *next_arg(char *args, char *
&lt;br&gt;&amp;nbsp;		next = args + i;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	/* Chew up trailing spaces. */
&lt;br&gt;-	while (isspace(*next))
&lt;br&gt;-		next++;
&lt;br&gt;-	return next;
&lt;br&gt;+	return skip_spaces(next);
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;/* Args looks like &amp;quot;foo=bar,bar2 baz=fuz wiz&amp;quot;. */
&lt;br&gt;@@ -139,8 +138,7 @@ int parse_args(const char *name,
&lt;br&gt;&amp;nbsp;	DEBUGP(&amp;quot;Parsing ARGS: %s\n&amp;quot;, args);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	/* Chew leading spaces */
&lt;br&gt;-	while (isspace(*args))
&lt;br&gt;-		args++;
&lt;br&gt;+	args = skip_spaces(args);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	while (*args) {
&lt;br&gt;&amp;nbsp;		int ret;
&lt;br&gt;diff -puN lib/argv_split.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function lib/argv_split.c
&lt;br&gt;--- a/lib/argv_split.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/lib/argv_split.c
&lt;br&gt;@@ -4,17 +4,10 @@
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/kernel.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/ctype.h&amp;gt;
&lt;br&gt;+#include &amp;lt;linux/string.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/slab.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/module.h&amp;gt;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-static const char *skip_sep(const char *cp)
&lt;br&gt;-{
&lt;br&gt;-	while (*cp &amp;&amp; isspace(*cp))
&lt;br&gt;-		cp++;
&lt;br&gt;-
&lt;br&gt;-	return cp;
&lt;br&gt;-}
&lt;br&gt;-
&lt;br&gt;&amp;nbsp;static const char *skip_arg(const char *cp)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;&amp;nbsp;	while (*cp &amp;&amp; !isspace(*cp))
&lt;br&gt;@@ -28,7 +21,7 @@ static int count_argc(const char *str)
&lt;br&gt;&amp;nbsp;	int count = 0;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	while (*str) {
&lt;br&gt;-		str = skip_sep(str);
&lt;br&gt;+		str = skip_spaces(str);
&lt;br&gt;&amp;nbsp;		if (*str) {
&lt;br&gt;&amp;nbsp;			count++;
&lt;br&gt;&amp;nbsp;			str = skip_arg(str);
&lt;br&gt;@@ -82,7 +75,7 @@ char **argv_split(gfp_t gfp, const char 
&lt;br&gt;&amp;nbsp;	argvp = argv;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	while (*str) {
&lt;br&gt;-		str = skip_sep(str);
&lt;br&gt;+		str = skip_spaces(str);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;		if (*str) {
&lt;br&gt;&amp;nbsp;			const char *p = str;
&lt;br&gt;diff -puN lib/dynamic_debug.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function lib/dynamic_debug.c
&lt;br&gt;--- a/lib/dynamic_debug.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/lib/dynamic_debug.c
&lt;br&gt;@@ -21,6 +21,7 @@
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/list.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/sysctl.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/ctype.h&amp;gt;
&lt;br&gt;+#include &amp;lt;linux/string.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/uaccess.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/dynamic_debug.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/debugfs.h&amp;gt;
&lt;br&gt;@@ -209,8 +210,7 @@ static int ddebug_tokenize(char *buf, ch
&lt;br&gt;&amp;nbsp;		char *end;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;		/* Skip leading whitespace */
&lt;br&gt;-		while (*buf &amp;&amp; isspace(*buf))
&lt;br&gt;-			buf++;
&lt;br&gt;+		buf = skip_spaces(buf);
&lt;br&gt;&amp;nbsp;		if (!*buf)
&lt;br&gt;&amp;nbsp;			break;	/* oh, it was trailing whitespace */
&lt;br&gt;&amp;nbsp;
&lt;br&gt;diff -puN lib/vsprintf.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function lib/vsprintf.c
&lt;br&gt;--- a/lib/vsprintf.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/lib/vsprintf.c
&lt;br&gt;@@ -1766,13 +1766,6 @@ EXPORT_SYMBOL_GPL(bprintf);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;#endif /* CONFIG_BINARY_PRINTF */
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-static noinline char *skip_space(const char *str)
&lt;br&gt;-{
&lt;br&gt;-	while (isspace(*str))
&lt;br&gt;-		++str;
&lt;br&gt;-	return (char *)str;
&lt;br&gt;-}
&lt;br&gt;-
&lt;br&gt;&amp;nbsp;/**
&lt;br&gt;&amp;nbsp; * vsscanf - Unformat a buffer into a list of arguments
&lt;br&gt;&amp;nbsp; * @buf:	input buffer
&lt;br&gt;@@ -1794,8 +1787,8 @@ int vsscanf(const char *buf, const char 
&lt;br&gt;&amp;nbsp;		 * white space, including none, in the input.
&lt;br&gt;&amp;nbsp;		 */
&lt;br&gt;&amp;nbsp;		if (isspace(*fmt)) {
&lt;br&gt;-			fmt = skip_space(fmt);
&lt;br&gt;-			str = skip_space(str);
&lt;br&gt;+			fmt = skip_spaces(++fmt);
&lt;br&gt;+			str = skip_spaces(str);
&lt;br&gt;&amp;nbsp;		}
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;		/* anything that is not a conversion must match exactly */
&lt;br&gt;@@ -1865,7 +1858,7 @@ int vsscanf(const char *buf, const char 
&lt;br&gt;&amp;nbsp;			if (field_width == -1)
&lt;br&gt;&amp;nbsp;				field_width = INT_MAX;
&lt;br&gt;&amp;nbsp;			/* first, skip leading white space in buffer */
&lt;br&gt;-			str = skip_space(str);
&lt;br&gt;+			str = skip_spaces(str);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;			/* now copy until next white space */
&lt;br&gt;&amp;nbsp;			while (*str &amp;&amp; !isspace(*str) &amp;&amp; field_width--)
&lt;br&gt;@@ -1907,7 +1900,7 @@ int vsscanf(const char *buf, const char 
&lt;br&gt;&amp;nbsp;		/* have some sort of integer conversion.
&lt;br&gt;&amp;nbsp;		 * first, skip white space in buffer.
&lt;br&gt;&amp;nbsp;		 */
&lt;br&gt;-		str = skip_space(str);
&lt;br&gt;+		str = skip_spaces(str);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;		digit = *str;
&lt;br&gt;&amp;nbsp;		if (is_sign &amp;&amp; digit == '-')
&lt;br&gt;diff -puN net/irda/irnet/irnet.h~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function net/irda/irnet/irnet.h
&lt;br&gt;--- a/net/irda/irnet/irnet.h~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/net/irda/irnet/irnet.h
&lt;br&gt;@@ -249,6 +249,7 @@
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/poll.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/capability.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/ctype.h&amp;gt;	/* isspace() */
&lt;br&gt;+#include &amp;lt;linux/string.h&amp;gt;	/* skip_spaces() */
&lt;br&gt;&amp;nbsp;#include &amp;lt;asm/uaccess.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/init.h&amp;gt;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;diff -puN net/irda/irnet/irnet_ppp.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function net/irda/irnet/irnet_ppp.c
&lt;br&gt;--- a/net/irda/irnet/irnet_ppp.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/net/irda/irnet/irnet_ppp.c
&lt;br&gt;@@ -76,9 +76,8 @@ irnet_ctrl_write(irnet_socket *	ap,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/* Look at the next command */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;start = next;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp;/* Scrap whitespaces before the command */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp;while(isspace(*start))
&lt;br&gt;-	start++;
&lt;br&gt;+	/* Scrap whitespaces before the command */
&lt;br&gt;+	start = skip_spaces(start);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/* ',' is our command separator */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;next = strchr(start, ',');
&lt;br&gt;@@ -133,8 +132,7 @@ irnet_ctrl_write(irnet_socket *	ap,
&lt;br&gt;&amp;nbsp;	 &amp;nbsp; &amp;nbsp; &amp;nbsp;char *	endp;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	 &amp;nbsp; &amp;nbsp; &amp;nbsp;/* Scrap whitespaces before the command */
&lt;br&gt;-	 &amp;nbsp; &amp;nbsp; &amp;nbsp;while(isspace(*begp))
&lt;br&gt;-		begp++;
&lt;br&gt;+	 &amp;nbsp; &amp;nbsp; &amp;nbsp;begp = skip_spaces(begp);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	 &amp;nbsp; &amp;nbsp; &amp;nbsp;/* Convert argument to a number (last arg is the base) */
&lt;br&gt;&amp;nbsp;	 &amp;nbsp; &amp;nbsp; &amp;nbsp;addr = simple_strtoul(begp, &amp;endp, 16);
&lt;br&gt;diff -puN net/netfilter/xt_recent.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function net/netfilter/xt_recent.c
&lt;br&gt;--- a/net/netfilter/xt_recent.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/net/netfilter/xt_recent.c
&lt;br&gt;@@ -482,8 +482,7 @@ static ssize_t recent_old_proc_write(str
&lt;br&gt;&amp;nbsp;	if (copy_from_user(buf, input, size))
&lt;br&gt;&amp;nbsp;		return -EFAULT;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	while (isspace(*c))
&lt;br&gt;-		c++;
&lt;br&gt;+	c = skip_spaces(c);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	if (size - (c - buf) &amp;lt; 5)
&lt;br&gt;&amp;nbsp;		return c - buf;
&lt;br&gt;diff -puN sound/pci/hda/hda_hwdep.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function sound/pci/hda/hda_hwdep.c
&lt;br&gt;--- a/sound/pci/hda/hda_hwdep.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/sound/pci/hda/hda_hwdep.c
&lt;br&gt;@@ -24,6 +24,7 @@
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/compat.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/mutex.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/ctype.h&amp;gt;
&lt;br&gt;+#include &amp;lt;linux/string.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/firmware.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;sound/core.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;quot;hda_codec.h&amp;quot;
&lt;br&gt;@@ -428,8 +429,7 @@ static int parse_hints(struct hda_codec 
&lt;br&gt;&amp;nbsp;	char *key, *val;
&lt;br&gt;&amp;nbsp;	struct hda_hint *hint;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	while (isspace(*buf))
&lt;br&gt;-		buf++;
&lt;br&gt;+	buf = skip_spaces(buf);
&lt;br&gt;&amp;nbsp;	if (!*buf || *buf == '#' || *buf == '\n')
&lt;br&gt;&amp;nbsp;		return 0;
&lt;br&gt;&amp;nbsp;	if (*buf == '=')
&lt;br&gt;@@ -444,8 +444,7 @@ static int parse_hints(struct hda_codec 
&lt;br&gt;&amp;nbsp;		return -EINVAL;
&lt;br&gt;&amp;nbsp;	}
&lt;br&gt;&amp;nbsp;	*val++ = 0;
&lt;br&gt;-	while (isspace(*val))
&lt;br&gt;-		val++;
&lt;br&gt;+	val = skip_spaces(val);
&lt;br&gt;&amp;nbsp;	remove_trail_spaces(key);
&lt;br&gt;&amp;nbsp;	remove_trail_spaces(val);
&lt;br&gt;&amp;nbsp;	hint = get_hint(codec, key);
&lt;br&gt;_
&lt;br&gt;&lt;br&gt;Patches currently in -mm which might be from &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26802637&amp;i=18&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;andre.goddard@...&lt;/a&gt; are
&lt;br&gt;&lt;br&gt;origin.patch
&lt;br&gt;pid-tighten-pidmap-spinlock-critical-section-by-removing-kfree.patch
&lt;br&gt;pid-reduce-code-size-by-using-a-pointer-to-iterate-over-array.patch
&lt;br&gt;&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26802637&amp;i=19&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-merged--tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function.patch-removed-from--mm-tree-tp26802637p26802637.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26802390</id>
	<title>Re: [PATCH] ext4: fix sleep inside spinlock issue aka #14739 V2</title>
	<published>2009-12-15T13:48:06Z</published>
	<updated>2009-12-15T13:48:06Z</updated>
	<author>
		<name>Jan Kara</name>
	</author>
	<content type="html">On Thu 10-12-09 20:22:16, Dmitry Monakhov wrote:
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; drop i_block_reservation_lock before vfs_dq_reserve_block().
&lt;br&gt;&amp;gt; this patch fix &lt;a href=&quot;http://bugzilla.kernel.org/show_bug.cgi?id=14739&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://bugzilla.kernel.org/show_bug.cgi?id=14739&lt;/a&gt;&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; changes from previous version:
&lt;br&gt;&amp;gt; &amp;nbsp;- simplify the patch according to Jan's comments
&lt;br&gt;&amp;nbsp; Dmitry, I suppose I should also merge this patch together with your other
&lt;br&gt;fixes, right? For some reason, it was not part of the last submission of
&lt;br&gt;your patch series...
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Honza
&lt;br&gt;&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; Signed-off-by: Dmitry Monakhov &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26802390&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;dmonakhov@...&lt;/a&gt;&amp;gt;
&lt;br&gt;&amp;gt; ---
&lt;br&gt;&amp;gt; &amp;nbsp;fs/ext4/inode.c | &amp;nbsp; &amp;nbsp;6 +++---
&lt;br&gt;&amp;gt; &amp;nbsp;1 files changed, 3 insertions(+), 3 deletions(-)
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
&lt;br&gt;&amp;gt; index 942e183..2327f7a 100644
&lt;br&gt;&amp;gt; --- a/fs/ext4/inode.c
&lt;br&gt;&amp;gt; +++ b/fs/ext4/inode.c
&lt;br&gt;&amp;gt; @@ -1851,6 +1851,7 @@ repeat:
&lt;br&gt;&amp;gt; &amp;nbsp;
&lt;br&gt;&amp;gt; &amp;nbsp;	md_needed = mdblocks - EXT4_I(inode)-&amp;gt;i_reserved_meta_blocks;
&lt;br&gt;&amp;gt; &amp;nbsp;	total = md_needed + nrblocks;
&lt;br&gt;&amp;gt; +	spin_unlock(&amp;EXT4_I(inode)-&amp;gt;i_block_reservation_lock);
&lt;br&gt;&amp;gt; &amp;nbsp;
&lt;br&gt;&amp;gt; &amp;nbsp;	/*
&lt;br&gt;&amp;gt; &amp;nbsp;	 * Make quota reservation here to prevent quota overflow
&lt;br&gt;&amp;gt; @@ -1858,12 +1859,10 @@ repeat:
&lt;br&gt;&amp;gt; &amp;nbsp;	 * time.
&lt;br&gt;&amp;gt; &amp;nbsp;	 */
&lt;br&gt;&amp;gt; &amp;nbsp;	if (vfs_dq_reserve_block(inode, total)) {
&lt;br&gt;&amp;gt; -		spin_unlock(&amp;EXT4_I(inode)-&amp;gt;i_block_reservation_lock);
&lt;br&gt;&amp;gt; &amp;nbsp;		return -EDQUOT;
&lt;br&gt;&amp;gt; &amp;nbsp;	}
&lt;br&gt;&amp;gt; &amp;nbsp;
&lt;br&gt;&amp;gt; &amp;nbsp;	if (ext4_claim_free_blocks(sbi, total)) {
&lt;br&gt;&amp;gt; -		spin_unlock(&amp;EXT4_I(inode)-&amp;gt;i_block_reservation_lock);
&lt;br&gt;&amp;gt; &amp;nbsp;		vfs_dq_release_reservation_block(inode, total);
&lt;br&gt;&amp;gt; &amp;nbsp;		if (ext4_should_retry_alloc(inode-&amp;gt;i_sb, &amp;retries)) {
&lt;br&gt;&amp;gt; &amp;nbsp;			yield();
&lt;br&gt;&amp;gt; @@ -1871,10 +1870,11 @@ repeat:
&lt;br&gt;&amp;gt; &amp;nbsp;		}
&lt;br&gt;&amp;gt; &amp;nbsp;		return -ENOSPC;
&lt;br&gt;&amp;gt; &amp;nbsp;	}
&lt;br&gt;&amp;gt; +	spin_lock(&amp;EXT4_I(inode)-&amp;gt;i_block_reservation_lock);
&lt;br&gt;&amp;gt; &amp;nbsp;	EXT4_I(inode)-&amp;gt;i_reserved_data_blocks += nrblocks;
&lt;br&gt;&amp;gt; &amp;nbsp;	EXT4_I(inode)-&amp;gt;i_reserved_meta_blocks = mdblocks;
&lt;br&gt;&amp;gt; -
&lt;br&gt;&amp;gt; &amp;nbsp;	spin_unlock(&amp;EXT4_I(inode)-&amp;gt;i_block_reservation_lock);
&lt;br&gt;&amp;gt; +
&lt;br&gt;&amp;gt; &amp;nbsp;	return 0; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* success */
&lt;br&gt;&amp;gt; &amp;nbsp;}
&lt;br&gt;&amp;gt; &amp;nbsp;
&lt;br&gt;&amp;gt; -- 
&lt;br&gt;&amp;gt; 1.6.0.4
&lt;br&gt;&amp;gt; 
&lt;/div&gt;-- 
&lt;br&gt;Jan Kara &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26802390&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;jack@...&lt;/a&gt;&amp;gt;
&lt;br&gt;SUSE Labs, CR
&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26802390&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH--ext4%3A-fix-sleep-inside-spinlock-issue-aka--14739-tp26720891p26802390.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26800856</id>
	<title>Re: [PATCH] Possible data loss on ext[34], reiserfs with external journal</title>
	<published>2009-12-15T12:01:32Z</published>
	<updated>2009-12-15T12:01:32Z</updated>
	<author>
		<name>Oleg Drokin</name>
	</author>
	<content type="html">Hello!
&lt;br&gt;&lt;br&gt;On Dec 15, 2009, at 11:45 AM, &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26800856&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;tytso@...&lt;/a&gt; wrote:
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; +	/* 
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; +	 * If the journal is not located on the file system device,
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; +	 * then we must flush the file system device before we issue
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; +	 * the commit record
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; +	 */
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; +	if (commit_transaction-&amp;gt;t_flushed_data_blocks &amp;&amp;
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; +	 &amp;nbsp; &amp;nbsp;(journal-&amp;gt;j_fs_dev != journal-&amp;gt;j_dev) &amp;&amp;
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; +	 &amp;nbsp; &amp;nbsp;(journal-&amp;gt;j_flags &amp; JBD2_BARRIER))
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; +		blkdev_issue_flush(journal-&amp;gt;j_fs_dev, NULL);
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; +
&lt;br&gt;&amp;gt;&amp;gt; I am afraid this is not enough. This code is called after journal
&lt;br&gt;&amp;gt;&amp;gt; was flushed for async commit case, so it leaves a race window where
&lt;br&gt;&amp;gt;&amp;gt; journal transaction is already on disk and complete, but the data is
&lt;br&gt;&amp;gt;&amp;gt; still in cache somewhere.
&lt;br&gt;&amp;gt; No, that's actually fine. &amp;nbsp;In the ASYNC_COMMIT case, the commit won't
&lt;br&gt;&amp;gt; be valid until the checksum is correct, and we won't have written any
&lt;br&gt;&amp;gt; descriptor blocks yet at this point. &amp;nbsp;So there is no race because
&lt;/div&gt;&lt;br&gt;What do you mean by descriptor blocks? Actual logged blocks?
&lt;br&gt;&lt;br&gt;&amp;gt; during that window, the commit is written but we won't write any
&lt;br&gt;&amp;gt; descriptor blocks until after the barrier returns.
&lt;br&gt;&lt;br&gt;From my reading of the code, in jbd2_journal_commit_transaction:
&lt;br&gt;After first &amp;quot;JBD: commit phase 2&amp;quot; message we submit actual data buffers.
&lt;br&gt;Then after second &amp;quot;JBD: commit phase 2&amp;quot; message (in the
&lt;br&gt;&amp;quot;while (commit_transaction-&amp;gt;t_buffers) {&amp;quot; loop) we actually iterate
&lt;br&gt;through all metadata changes and submit them to disk (after
&lt;br&gt;start_journal_io: label)
&lt;br&gt;Then journal_submit_commit_record writes commit record.
&lt;br&gt;At this point on we have entire transacton + commit
&lt;br&gt;block in the write queue (or partially already on disk) +
&lt;br&gt;all the data blocks in the write queue.
&lt;br&gt;Next blkdev_issue_flush on journal device is done, cementing the transaction
&lt;br&gt;on the permanent storage, but the actual data is still potentially not
&lt;br&gt;there abd it is not until the call to journal_finish_inode_data_buffers()
&lt;br&gt;where that data is flushed too.
&lt;br&gt;&lt;br&gt;If you refer to the code after &amp;quot;JBD: commit phase 3&amp;quot; that waits on actual
&lt;br&gt;transaction blocks buffers to make sure they made it to the disk,
&lt;br&gt;my reading of blkdev_issue_flush is that it adds the flush at the end of the
&lt;br&gt;queue, i.e. after all of the journalled blocks that are sitting in there,
&lt;br&gt;so they all would be already copleted by the time blkdev_issue_flush returns.
&lt;br&gt;&lt;br&gt;Bye,
&lt;br&gt;&amp;nbsp; &amp;nbsp; Oleg--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26800856&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH--Possible-data-loss-on-ext-34-%2C-reiserfs-with-external-journal-tp26741055p26800856.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26797829</id>
	<title>Re: [PATCH] Possible data loss on ext[34], reiserfs with external journal</title>
	<published>2009-12-15T08:45:03Z</published>
	<updated>2009-12-15T08:45:03Z</updated>
	<author>
		<name>tytso</name>
	</author>
	<content type="html">On Tue, Dec 15, 2009 at 01:19:57AM -0500, Oleg Drokin wrote:
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; &amp;gt; +	/* 
&lt;br&gt;&amp;gt; &amp;gt; +	 * If the journal is not located on the file system device,
&lt;br&gt;&amp;gt; &amp;gt; +	 * then we must flush the file system device before we issue
&lt;br&gt;&amp;gt; &amp;gt; +	 * the commit record
&lt;br&gt;&amp;gt; &amp;gt; +	 */
&lt;br&gt;&amp;gt; &amp;gt; +	if (commit_transaction-&amp;gt;t_flushed_data_blocks &amp;&amp;
&lt;br&gt;&amp;gt; &amp;gt; +	 &amp;nbsp; &amp;nbsp;(journal-&amp;gt;j_fs_dev != journal-&amp;gt;j_dev) &amp;&amp;
&lt;br&gt;&amp;gt; &amp;gt; +	 &amp;nbsp; &amp;nbsp;(journal-&amp;gt;j_flags &amp; JBD2_BARRIER))
&lt;br&gt;&amp;gt; &amp;gt; +		blkdev_issue_flush(journal-&amp;gt;j_fs_dev, NULL);
&lt;br&gt;&amp;gt; &amp;gt; +
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; I am afraid this is not enough. This code is called after journal
&lt;br&gt;&amp;gt; was flushed for async commit case, so it leaves a race window where
&lt;br&gt;&amp;gt; journal transaction is already on disk and complete, but the data is
&lt;br&gt;&amp;gt; still in cache somewhere.
&lt;/div&gt;&lt;br&gt;No, that's actually fine. &amp;nbsp;In the ASYNC_COMMIT case, the commit won't
&lt;br&gt;be valid until the checksum is correct, and we won't have written any
&lt;br&gt;descriptor blocks yet at this point. &amp;nbsp;So there is no race because
&lt;br&gt;during that window, the commit is written but we won't write any
&lt;br&gt;descriptor blocks until after the barrier returns.
&lt;br&gt;&lt;br&gt;&amp;gt; Also the callsite has this comment which is misleading, I think:
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* This is the right place to wait for data buffers both for ASYNC
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* and !ASYNC commit. If commit is ASYNC, we need to wait only after
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* the commit block went to disk (which happens above). If commit is
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* SYNC, we need to wait for data buffers before we start writing
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* commit block, which happens below in such setting.
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;&lt;br&gt;Yeah, that comment is confusing and not entirely accurate. &amp;nbsp;I thought
&lt;br&gt;about cleaning it up, and then decided to do that in a separate patch.
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 	 &amp;nbsp; &amp;nbsp; &amp;nbsp; 	 &amp;nbsp; &amp;nbsp; &amp;nbsp;	 &amp;nbsp; &amp;nbsp; &amp;nbsp; 	 &amp;nbsp; &amp;nbsp; &amp;nbsp; 	 &amp;nbsp;- Ted
&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26797829&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH--Possible-data-loss-on-ext-34-%2C-reiserfs-with-external-journal-tp26741055p26797829.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26791731</id>
	<title>[Bug 14256] kernel BUG at fs/ext3/super.c:435</title>
	<published>2009-12-15T01:08:48Z</published>
	<updated>2009-12-15T01:08:48Z</updated>
	<author>
		<name>Bugzilla from bugzilla-daemon@bugzilla.kernel.org</name>
	</author>
	<content type="html">&lt;a href=&quot;http://bugzilla.kernel.org/show_bug.cgi?id=14256&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://bugzilla.kernel.org/show_bug.cgi?id=14256&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;--- Comment #16 from Mikael Pettersson &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26791731&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;mikpe@...&lt;/a&gt;&amp;gt; &amp;nbsp;2009-12-15 09:08:45 ---
&lt;br&gt;The affected file system is /tmp. There's nothing special about it, except it
&lt;br&gt;being separate from / and /home. The builds are plain &amp;quot;rpmbuild --rebuild&amp;quot; so
&lt;br&gt;they do most accesses under /usr/src/ and /var/tmp/, both on /, but the glibc
&lt;br&gt;test suite will create temporary files on /tmp. I have no idea what those files
&lt;br&gt;are.
&lt;br&gt;&lt;br&gt;-- 
&lt;br&gt;Configure bugmail: &lt;a href=&quot;http://bugzilla.kernel.org/userprefs.cgi?tab=email&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://bugzilla.kernel.org/userprefs.cgi?tab=email&lt;/a&gt;&lt;br&gt;------- You are receiving this mail because: -------
&lt;br&gt;You are watching the assignee of the bug.
&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26791731&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-Bug-14256--New%3A-kernel-BUG-at-fs-ext3-super.c%3A435-tp25671543p26791731.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26790100</id>
	<title>Re: [PATCH] Possible data loss on ext[34], reiserfs with external journal</title>
	<published>2009-12-14T22:19:57Z</published>
	<updated>2009-12-14T22:19:57Z</updated>
	<author>
		<name>Oleg Drokin</name>
	</author>
	<content type="html">Hello!
&lt;br&gt;&lt;br&gt;On Dec 15, 2009, at 12:32 AM, &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26790100&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;tytso@...&lt;/a&gt; wrote:
&lt;br&gt;&amp;gt; Can you separate this patch into separate ones for each file system?
&lt;br&gt;&lt;br&gt;Sure.
&lt;br&gt;&lt;br&gt;&amp;gt; I think we can actually do better for ext4; for example, in the case
&lt;br&gt;&amp;gt; of data=journal or data=writeback, it's not necessary to flush the fs
&lt;br&gt;&amp;gt; data device. &amp;nbsp;It's only the case of data=ordered that we need to send
&lt;br&gt;&amp;gt; a barrier. &amp;nbsp;With that optimization, we do need to add a barrier in the
&lt;br&gt;&amp;gt; case of fsync() and when we are doing a journal checkpoint, but the
&lt;br&gt;&amp;gt; extra code complexity is worth not having to force a barrier for the
&lt;br&gt;&amp;gt; fs data device for every single commit, especially in the data=journal
&lt;br&gt;&amp;gt; mode with a heavy fsync workload.
&lt;br&gt;&lt;br&gt;Indeed, this is a good idea too.
&lt;br&gt;I think we still can squeeze a bit more juice out of it if we can
&lt;br&gt;submit the data device flush right after submitting all the data, but
&lt;br&gt;only do the waiting for it before issuing journal device flush in normal
&lt;br&gt;journaling mode (we need to do the waiting before writing commit block
&lt;br&gt;in async journaling mode).
&lt;br&gt;&lt;br&gt;&amp;gt; Do you have a test case that will allow you to easily try out this
&lt;br&gt;&amp;gt; patch, in all of ext4's various journalling modes? &amp;nbsp;Thanks!!
&lt;br&gt;&lt;br&gt;Not for vanilla kernel, but I'll see if I can construct something easily
&lt;br&gt;for it.
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; @@ -277,6 +278,16 @@ static int journal_finish_inode_data_buffers(journal_t *journal,
&lt;br&gt;&amp;gt; 	struct jbd2_inode *jinode, *next_i;
&lt;br&gt;&amp;gt; 	int err, ret = 0;
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; +	/* 
&lt;br&gt;&amp;gt; +	 * If the journal is not located on the file system device,
&lt;br&gt;&amp;gt; +	 * then we must flush the file system device before we issue
&lt;br&gt;&amp;gt; +	 * the commit record
&lt;br&gt;&amp;gt; +	 */
&lt;br&gt;&amp;gt; +	if (commit_transaction-&amp;gt;t_flushed_data_blocks &amp;&amp;
&lt;br&gt;&amp;gt; +	 &amp;nbsp; &amp;nbsp;(journal-&amp;gt;j_fs_dev != journal-&amp;gt;j_dev) &amp;&amp;
&lt;br&gt;&amp;gt; +	 &amp;nbsp; &amp;nbsp;(journal-&amp;gt;j_flags &amp; JBD2_BARRIER))
&lt;br&gt;&amp;gt; +		blkdev_issue_flush(journal-&amp;gt;j_fs_dev, NULL);
&lt;br&gt;&amp;gt; +
&lt;/div&gt;&lt;br&gt;I am afraid this is not enough. This code is called after journal was flushed for
&lt;br&gt;async commit case, so it leaves a race window where journal transaction is already
&lt;br&gt;on disk and complete, but the data is still in cache somewhere.
&lt;br&gt;&lt;br&gt;Also the callsite has this comment which is misleading, I think:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* This is the right place to wait for data buffers both for ASYNC
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* and !ASYNC commit. If commit is ASYNC, we need to wait only after
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* the commit block went to disk (which happens above). If commit is
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* SYNC, we need to wait for data buffers before we start writing
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* commit block, which happens below in such setting.
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;&lt;br&gt;In fact it is only safe to wait here in ASYNC mode (and internal journal only) because
&lt;br&gt;the device was already flushed (and I hope all device drivers drain the queue too, if not,
&lt;br&gt;even this might be problematic) by the blkdev_issue_flush.
&lt;br&gt;&lt;br&gt;Bye,
&lt;br&gt;&amp;nbsp; &amp;nbsp; Oleg
&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26790100&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH--Possible-data-loss-on-ext-34-%2C-reiserfs-with-external-journal-tp26741055p26790100.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26789713</id>
	<title>Re: [PATCH] Possible data loss on ext[34], reiserfs with external journal</title>
	<published>2009-12-14T21:32:07Z</published>
	<updated>2009-12-14T21:32:07Z</updated>
	<author>
		<name>tytso</name>
	</author>
	<content type="html">On Fri, Dec 11, 2009 at 11:16:08AM +0300, Oleg Drokin wrote:
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; Hello!
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp;It seems when external journal device is used for ext3, ext4 and reiserfs
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp;(possibly others, but I can only readily confirm these three) and
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp;main filesystem device had writeback cache enabled, a very real
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp;data loss is possible because we never flush main device cache on commit.
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp;As a result if we just wrote some files in ordered mode and then
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp;transaction was committed, the journal data makes it to the disk
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp;(provided that barriers are in use), but the actual file data only made
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp;it to the device cache. As such sudden loss of power at this stage
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp;would lead to files in place, but their content replaced with
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp;whatever happened to be in those blocks before.
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp;This simple patch at the end should remedy the problem.
&lt;/div&gt;&lt;br&gt;Can you separate this patch into separate ones for each file system?
&lt;br&gt;I think we can actually do better for ext4; for example, in the case
&lt;br&gt;of data=journal or data=writeback, it's not necessary to flush the fs
&lt;br&gt;data device. &amp;nbsp;It's only the case of data=ordered that we need to send
&lt;br&gt;a barrier. &amp;nbsp;With that optimization, we do need to add a barrier in the
&lt;br&gt;case of fsync() and when we are doing a journal checkpoint, but the
&lt;br&gt;extra code complexity is worth not having to force a barrier for the
&lt;br&gt;fs data device for every single commit, especially in the data=journal
&lt;br&gt;mode with a heavy fsync workload.
&lt;br&gt;&lt;br&gt;Do you have a test case that will allow you to easily try out this
&lt;br&gt;patch, in all of ext4's various journalling modes? &amp;nbsp;Thanks!!
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;	 &amp;nbsp; &amp;nbsp; &amp;nbsp;	 			 &amp;nbsp; &amp;nbsp;- Ted
&lt;br&gt;&lt;br&gt;commit 4ba96b277f26952097d15736f6e960bc84cf4c0c
&lt;br&gt;Author: Theodore Ts'o &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26789713&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;tytso@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Date: &amp;nbsp; Tue Dec 15 00:31:12 2009 -0500
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; ext4, jbd2: Add barriers for file systems with exernal journals
&lt;br&gt;&amp;nbsp; &amp;nbsp; 
&lt;br&gt;&amp;nbsp; &amp;nbsp; This is a bit complicated because we are trying to optimize when we
&lt;br&gt;&amp;nbsp; &amp;nbsp; send barriers to the fs data disk. &amp;nbsp;We could just throw in an extra
&lt;br&gt;&amp;nbsp; &amp;nbsp; barrier to the data disk whenever we send a barrier to the journal
&lt;br&gt;&amp;nbsp; &amp;nbsp; disk, but that's not always strictly necessary.
&lt;br&gt;&amp;nbsp; &amp;nbsp; 
&lt;br&gt;&amp;nbsp; &amp;nbsp; We only need to send a barrier during a commit when there are data
&lt;br&gt;&amp;nbsp; &amp;nbsp; blocks which are must be written out due to an inode written in
&lt;br&gt;&amp;nbsp; &amp;nbsp; ordered mode, or if fsync() depends on the commit to force data blocks
&lt;br&gt;&amp;nbsp; &amp;nbsp; to disk. &amp;nbsp;Finally, before we drop transactions from the beginning of
&lt;br&gt;&amp;nbsp; &amp;nbsp; the journal during a checkpoint operation, we need to guarantee that
&lt;br&gt;&amp;nbsp; &amp;nbsp; any blocks that were flushed out to the data disk are firmly on the
&lt;br&gt;&amp;nbsp; &amp;nbsp; rust platter before we drop the transaction from the journal.
&lt;br&gt;&amp;nbsp; &amp;nbsp; 
&lt;br&gt;&amp;nbsp; &amp;nbsp; Thanks to Oleg Drokin for pointing out this flaw in ext3/ext4.
&lt;br&gt;&amp;nbsp; &amp;nbsp; 
&lt;br&gt;&amp;nbsp; &amp;nbsp; Signed-off-by: &amp;quot;Theodore Ts'o&amp;quot; &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26789713&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;tytso@...&lt;/a&gt;&amp;gt;
&lt;br&gt;&lt;br&gt;diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c
&lt;br&gt;index 0b22497..98bd140 100644
&lt;br&gt;--- a/fs/ext4/fsync.c
&lt;br&gt;+++ b/fs/ext4/fsync.c
&lt;br&gt;@@ -88,9 +88,21 @@ int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync)
&lt;br&gt;&amp;nbsp;		return ext4_force_commit(inode-&amp;gt;i_sb);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	commit_tid = datasync ? ei-&amp;gt;i_datasync_tid : ei-&amp;gt;i_sync_tid;
&lt;br&gt;-	if (jbd2_log_start_commit(journal, commit_tid))
&lt;br&gt;+	if (jbd2_log_start_commit(journal, commit_tid)) {
&lt;br&gt;+		/*
&lt;br&gt;+		 * When the journal is on a different device than the
&lt;br&gt;+		 * fs data disk, we need to issue the barrier in
&lt;br&gt;+		 * writeback mode. &amp;nbsp;(In ordered mode, the jbd2 layer
&lt;br&gt;+		 * will take care of issuing the barrier. &amp;nbsp;In
&lt;br&gt;+		 * data=journal, all of the data blocks are written to
&lt;br&gt;+		 * the journal device.)
&lt;br&gt;+		 */
&lt;br&gt;+		if (ext4_should_writeback_data(inode) &amp;&amp;
&lt;br&gt;+		 &amp;nbsp; &amp;nbsp;(journal-&amp;gt;j_fs_dev != journal-&amp;gt;j_dev) &amp;&amp;
&lt;br&gt;+		 &amp;nbsp; &amp;nbsp;(journal-&amp;gt;j_flags &amp; JBD2_BARRIER))
&lt;br&gt;+			blkdev_issue_flush(inode-&amp;gt;i_sb-&amp;gt;s_bdev, NULL);
&lt;br&gt;&amp;nbsp;		jbd2_log_wait_commit(journal, commit_tid);
&lt;br&gt;-	else if (journal-&amp;gt;j_flags &amp; JBD2_BARRIER)
&lt;br&gt;+	} else if (journal-&amp;gt;j_flags &amp; JBD2_BARRIER)
&lt;br&gt;&amp;nbsp;		blkdev_issue_flush(inode-&amp;gt;i_sb-&amp;gt;s_bdev, NULL);
&lt;br&gt;&amp;nbsp;	return ret;
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c
&lt;br&gt;index ca0f5eb..8868493 100644
&lt;br&gt;--- a/fs/jbd2/checkpoint.c
&lt;br&gt;+++ b/fs/jbd2/checkpoint.c
&lt;br&gt;@@ -22,6 +22,7 @@
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/jbd2.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/errno.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/slab.h&amp;gt;
&lt;br&gt;+#include &amp;lt;linux/blkdev.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;trace/events/jbd2.h&amp;gt;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;/*
&lt;br&gt;@@ -515,6 +516,20 @@ int jbd2_cleanup_journal_tail(journal_t *journal)
&lt;br&gt;&amp;nbsp;	journal-&amp;gt;j_tail_sequence = first_tid;
&lt;br&gt;&amp;nbsp;	journal-&amp;gt;j_tail = blocknr;
&lt;br&gt;&amp;nbsp;	spin_unlock(&amp;journal-&amp;gt;j_state_lock);
&lt;br&gt;+
&lt;br&gt;+	/*
&lt;br&gt;+	 * If there is an external journal, we need to make sure that
&lt;br&gt;+	 * any data blocks that were recently written out --- perhaps
&lt;br&gt;+	 * by jbd2_log_do_checkpoint() --- are flushed out before we
&lt;br&gt;+	 * drop the transactions from the external journal. &amp;nbsp;It's
&lt;br&gt;+	 * unlikely this will be necessary, especially with a
&lt;br&gt;+	 * appropriately sized journal, but we need this to guarantee
&lt;br&gt;+	 * correctness. &amp;nbsp;Fortunately jbd2_cleanup_journal_tail()
&lt;br&gt;+	 * doesn't get called all that often.
&lt;br&gt;+	 */
&lt;br&gt;+	if ((journal-&amp;gt;j_fs_dev != journal-&amp;gt;j_dev) &amp;&amp;
&lt;br&gt;+	 &amp;nbsp; &amp;nbsp;(journal-&amp;gt;j_flags &amp; JBD2_BARRIER))
&lt;br&gt;+		blkdev_issue_flush(journal-&amp;gt;j_fs_dev, NULL);
&lt;br&gt;&amp;nbsp;	if (!(journal-&amp;gt;j_flags &amp; JBD2_ABORT))
&lt;br&gt;&amp;nbsp;		jbd2_journal_update_superblock(journal, 1);
&lt;br&gt;&amp;nbsp;	return 0;
&lt;br&gt;diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
&lt;br&gt;index 6a10238..5b78f9a 100644
&lt;br&gt;--- a/fs/jbd2/commit.c
&lt;br&gt;+++ b/fs/jbd2/commit.c
&lt;br&gt;@@ -259,6 +259,7 @@ static int journal_submit_data_buffers(journal_t *journal,
&lt;br&gt;&amp;nbsp;			ret = err;
&lt;br&gt;&amp;nbsp;		spin_lock(&amp;journal-&amp;gt;j_list_lock);
&lt;br&gt;&amp;nbsp;		J_ASSERT(jinode-&amp;gt;i_transaction == commit_transaction);
&lt;br&gt;+		commit_transaction-&amp;gt;t_flushed_data_blocks = 1;
&lt;br&gt;&amp;nbsp;		jinode-&amp;gt;i_flags &amp;= ~JI_COMMIT_RUNNING;
&lt;br&gt;&amp;nbsp;		wake_up_bit(&amp;jinode-&amp;gt;i_flags, __JI_COMMIT_RUNNING);
&lt;br&gt;&amp;nbsp;	}
&lt;br&gt;@@ -277,6 +278,16 @@ static int journal_finish_inode_data_buffers(journal_t *journal,
&lt;br&gt;&amp;nbsp;	struct jbd2_inode *jinode, *next_i;
&lt;br&gt;&amp;nbsp;	int err, ret = 0;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;+	/* 
&lt;br&gt;+	 * If the journal is not located on the file system device,
&lt;br&gt;+	 * then we must flush the file system device before we issue
&lt;br&gt;+	 * the commit record
&lt;br&gt;+	 */
&lt;br&gt;+	if (commit_transaction-&amp;gt;t_flushed_data_blocks &amp;&amp;
&lt;br&gt;+	 &amp;nbsp; &amp;nbsp;(journal-&amp;gt;j_fs_dev != journal-&amp;gt;j_dev) &amp;&amp;
&lt;br&gt;+	 &amp;nbsp; &amp;nbsp;(journal-&amp;gt;j_flags &amp; JBD2_BARRIER))
&lt;br&gt;+		blkdev_issue_flush(journal-&amp;gt;j_fs_dev, NULL);
&lt;br&gt;+
&lt;br&gt;&amp;nbsp;	/* For locking, see the comment in journal_submit_data_buffers() */
&lt;br&gt;&amp;nbsp;	spin_lock(&amp;journal-&amp;gt;j_list_lock);
&lt;br&gt;&amp;nbsp;	list_for_each_entry(jinode, &amp;commit_transaction-&amp;gt;t_inode_list, i_list) {
&lt;br&gt;diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
&lt;br&gt;index f1011f7..638ce45 100644
&lt;br&gt;--- a/include/linux/jbd2.h
&lt;br&gt;+++ b/include/linux/jbd2.h
&lt;br&gt;@@ -653,6 +653,7 @@ struct transaction_s
&lt;br&gt;&amp;nbsp;	 * waiting for it to finish.
&lt;br&gt;&amp;nbsp;	 */
&lt;br&gt;&amp;nbsp;	unsigned int t_synchronous_commit:1;
&lt;br&gt;+	unsigned int t_flushed_data_blocks:1;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	/*
&lt;br&gt;&amp;nbsp;	 * For use by the filesystem to store fs-specific data
&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26789713&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH--Possible-data-loss-on-ext-34-%2C-reiserfs-with-external-journal-tp26741055p26789713.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26788252</id>
	<title>[patch 156/196] tree-wide: convert open calls to remove spaces to skip_spaces() lib function</title>
	<published>2009-12-14T18:01:06Z</published>
	<updated>2009-12-14T18:01:06Z</updated>
	<author>
		<name>tip-bot for akpm@linux-foundation.org</name>
	</author>
	<content type="html">From: André Goddard Rosa &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26788252&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;andre.goddard@...&lt;/a&gt;&amp;gt;
&lt;br&gt;&lt;br&gt;Makes use of skip_spaces() defined in lib/string.c for removing leading
&lt;br&gt;spaces from strings all over the tree.
&lt;br&gt;&lt;br&gt;It decreases lib.a code size by 47 bytes and reuses the function tree-wide:
&lt;br&gt;&amp;nbsp; &amp;nbsp;text &amp;nbsp; &amp;nbsp;data &amp;nbsp; &amp;nbsp; bss &amp;nbsp; &amp;nbsp; dec &amp;nbsp; &amp;nbsp; hex filename
&lt;br&gt;&amp;nbsp; 64688 &amp;nbsp; &amp;nbsp; 584 &amp;nbsp; &amp;nbsp; 592 &amp;nbsp; 65864 &amp;nbsp; 10148 (TOTALS-BEFORE)
&lt;br&gt;&amp;nbsp; 64641 &amp;nbsp; &amp;nbsp; 584 &amp;nbsp; &amp;nbsp; 592 &amp;nbsp; 65817 &amp;nbsp; 10119 (TOTALS-AFTER)
&lt;br&gt;&lt;br&gt;Also, while at it, if we see (*str &amp;&amp; isspace(*str)), we can be sure to
&lt;br&gt;remove the first condition (*str) as the second one (isspace(*str)) also
&lt;br&gt;evaluates to 0 whenever *str == 0, making it redundant. In other words,
&lt;br&gt;&amp;quot;a char equals zero is never a space&amp;quot;.
&lt;br&gt;&lt;br&gt;Julia Lawall tried the semantic patch (&lt;a href=&quot;http://coccinelle.lip6.fr&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://coccinelle.lip6.fr&lt;/a&gt;) below,
&lt;br&gt;and found occurrences of this pattern on 3 more files:
&lt;br&gt;&amp;nbsp; &amp;nbsp; drivers/leds/led-class.c
&lt;br&gt;&amp;nbsp; &amp;nbsp; drivers/leds/ledtrig-timer.c
&lt;br&gt;&amp;nbsp; &amp;nbsp; drivers/video/output.c
&lt;br&gt;&lt;br&gt;@@
&lt;br&gt;expression str;
&lt;br&gt;@@
&lt;br&gt;&lt;br&gt;( // ignore skip_spaces cases
&lt;br&gt;while (*str &amp;&amp; &amp;nbsp;isspace(*str)) { \(str++;\|++str;\) }
&lt;br&gt;|
&lt;br&gt;- *str &amp;&amp;
&lt;br&gt;isspace(*str)
&lt;br&gt;)
&lt;br&gt;&lt;br&gt;Signed-off-by: André Goddard Rosa &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26788252&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;andre.goddard@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: Julia Lawall &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26788252&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;julia@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: Martin Schwidefsky &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26788252&amp;i=3&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;schwidefsky@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: Jeff Dike &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26788252&amp;i=4&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;jdike@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: Ingo Molnar &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26788252&amp;i=5&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;mingo@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: Thomas Gleixner &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26788252&amp;i=6&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;tglx@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: &amp;quot;H. Peter Anvin&amp;quot; &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26788252&amp;i=7&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;hpa@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: Richard Purdie &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26788252&amp;i=8&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rpurdie@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: Neil Brown &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26788252&amp;i=9&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;neilb@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: Kyle McMartin &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26788252&amp;i=10&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;kyle@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: Henrique de Moraes Holschuh &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26788252&amp;i=11&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;hmh@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: David Howells &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26788252&amp;i=12&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;dhowells@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26788252&amp;i=13&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;linux-ext4@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: Samuel Ortiz &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26788252&amp;i=14&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;samuel@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: Patrick McHardy &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26788252&amp;i=15&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;kaber@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Cc: Takashi Iwai &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26788252&amp;i=16&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;tiwai@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Signed-off-by: Andrew Morton &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26788252&amp;i=17&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;akpm@...&lt;/a&gt;&amp;gt;
&lt;br&gt;---
&lt;br&gt;&lt;br&gt;&amp;nbsp;arch/s390/kernel/debug.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp;3 +-
&lt;br&gt;&amp;nbsp;arch/um/drivers/mconsole_kern.c &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; 16 ++++------
&lt;br&gt;&amp;nbsp;arch/x86/kernel/cpu/mtrr/if.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; 11 ++-----
&lt;br&gt;&amp;nbsp;drivers/leds/led-class.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp;2 -
&lt;br&gt;&amp;nbsp;drivers/leds/ledtrig-timer.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp;4 +-
&lt;br&gt;&amp;nbsp;drivers/md/dm-table.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; &amp;nbsp;6 +---
&lt;br&gt;&amp;nbsp;drivers/md/md.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; &amp;nbsp;4 +-
&lt;br&gt;&amp;nbsp;drivers/parisc/pdc_stable.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; &amp;nbsp;9 ++----
&lt;br&gt;&amp;nbsp;drivers/platform/x86/thinkpad_acpi.c &amp;nbsp;| &amp;nbsp; &amp;nbsp;7 +---
&lt;br&gt;&amp;nbsp;drivers/pnp/interface.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; 36 ++++++------------------
&lt;br&gt;&amp;nbsp;drivers/s390/block/dasd_proc.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp;5 ++-
&lt;br&gt;&amp;nbsp;drivers/video/backlight/lcd.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; &amp;nbsp;4 +-
&lt;br&gt;&amp;nbsp;drivers/video/display/display-sysfs.c | &amp;nbsp; &amp;nbsp;2 -
&lt;br&gt;&amp;nbsp;drivers/video/output.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp;2 -
&lt;br&gt;&amp;nbsp;fs/cachefiles/daemon.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp;4 +-
&lt;br&gt;&amp;nbsp;fs/ext4/super.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; &amp;nbsp;7 +---
&lt;br&gt;&amp;nbsp;kernel/params.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; &amp;nbsp;8 ++---
&lt;br&gt;&amp;nbsp;lib/argv_split.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; 13 ++------
&lt;br&gt;&amp;nbsp;lib/dynamic_debug.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; &amp;nbsp;4 +-
&lt;br&gt;&amp;nbsp;lib/vsprintf.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; 15 ++--------
&lt;br&gt;&amp;nbsp;net/irda/irnet/irnet.h &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp;1 
&lt;br&gt;&amp;nbsp;net/irda/irnet/irnet_ppp.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp;8 ++---
&lt;br&gt;&amp;nbsp;net/netfilter/xt_recent.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; &amp;nbsp;3 --
&lt;br&gt;&amp;nbsp;sound/pci/hda/hda_hwdep.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; &amp;nbsp;7 ++--
&lt;br&gt;&amp;nbsp;24 files changed, 66 insertions(+), 115 deletions(-)
&lt;br&gt;&lt;br&gt;diff -puN arch/s390/kernel/debug.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function arch/s390/kernel/debug.c
&lt;br&gt;--- a/arch/s390/kernel/debug.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/arch/s390/kernel/debug.c
&lt;br&gt;@@ -18,6 +18,7 @@
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/errno.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/slab.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/ctype.h&amp;gt;
&lt;br&gt;+#include &amp;lt;linux/string.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/sysctl.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;asm/uaccess.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/module.h&amp;gt;
&lt;br&gt;@@ -1178,7 +1179,7 @@ debug_get_uint(char *buf)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;&amp;nbsp;	int rc;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	for(; isspace(*buf); buf++);
&lt;br&gt;+	buf = skip_spaces(buf);
&lt;br&gt;&amp;nbsp;	rc = simple_strtoul(buf, &amp;buf, 10);
&lt;br&gt;&amp;nbsp;	if(*buf){
&lt;br&gt;&amp;nbsp;		rc = -EINVAL;
&lt;br&gt;diff -puN arch/um/drivers/mconsole_kern.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function arch/um/drivers/mconsole_kern.c
&lt;br&gt;--- a/arch/um/drivers/mconsole_kern.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/arch/um/drivers/mconsole_kern.c
&lt;br&gt;@@ -6,6 +6,7 @@
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/console.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/ctype.h&amp;gt;
&lt;br&gt;+#include &amp;lt;linux/string.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/interrupt.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/list.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/mm.h&amp;gt;
&lt;br&gt;@@ -131,7 +132,7 @@ void mconsole_proc(struct mc_request *re
&lt;br&gt;&amp;nbsp;	char *ptr = req-&amp;gt;request.data, *buf;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	ptr += strlen(&amp;quot;proc&amp;quot;);
&lt;br&gt;-	while (isspace(*ptr)) ptr++;
&lt;br&gt;+	ptr = skip_spaces(ptr);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	proc = get_fs_type(&amp;quot;proc&amp;quot;);
&lt;br&gt;&amp;nbsp;	if (proc == NULL) {
&lt;br&gt;@@ -212,8 +213,7 @@ void mconsole_proc(struct mc_request *re
&lt;br&gt;&amp;nbsp;	char *ptr = req-&amp;gt;request.data;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	ptr += strlen(&amp;quot;proc&amp;quot;);
&lt;br&gt;-	while (isspace(*ptr))
&lt;br&gt;-		ptr++;
&lt;br&gt;+	ptr = skip_spaces(ptr);
&lt;br&gt;&amp;nbsp;	snprintf(path, sizeof(path), &amp;quot;/proc/%s&amp;quot;, ptr);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	fd = sys_open(path, 0, 0);
&lt;br&gt;@@ -560,8 +560,7 @@ void mconsole_config(struct mc_request *
&lt;br&gt;&amp;nbsp;	int err;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	ptr += strlen(&amp;quot;config&amp;quot;);
&lt;br&gt;-	while (isspace(*ptr))
&lt;br&gt;-		ptr++;
&lt;br&gt;+	ptr = skip_spaces(ptr);
&lt;br&gt;&amp;nbsp;	dev = mconsole_find_dev(ptr);
&lt;br&gt;&amp;nbsp;	if (dev == NULL) {
&lt;br&gt;&amp;nbsp;		mconsole_reply(req, &amp;quot;Bad configuration option&amp;quot;, 1, 0);
&lt;br&gt;@@ -588,7 +587,7 @@ void mconsole_remove(struct mc_request *
&lt;br&gt;&amp;nbsp;	int err, start, end, n;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	ptr += strlen(&amp;quot;remove&amp;quot;);
&lt;br&gt;-	while (isspace(*ptr)) ptr++;
&lt;br&gt;+	ptr = skip_spaces(ptr);
&lt;br&gt;&amp;nbsp;	dev = mconsole_find_dev(ptr);
&lt;br&gt;&amp;nbsp;	if (dev == NULL) {
&lt;br&gt;&amp;nbsp;		mconsole_reply(req, &amp;quot;Bad remove option&amp;quot;, 1, 0);
&lt;br&gt;@@ -712,7 +711,7 @@ void mconsole_sysrq(struct mc_request *r
&lt;br&gt;&amp;nbsp;	char *ptr = req-&amp;gt;request.data;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	ptr += strlen(&amp;quot;sysrq&amp;quot;);
&lt;br&gt;-	while (isspace(*ptr)) ptr++;
&lt;br&gt;+	ptr = skip_spaces(ptr);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	/*
&lt;br&gt;&amp;nbsp;	 * With 'b', the system will shut down without a chance to reply,
&lt;br&gt;@@ -757,8 +756,7 @@ void mconsole_stack(struct mc_request *r
&lt;br&gt;&amp;nbsp;	 */
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	ptr += strlen(&amp;quot;stack&amp;quot;);
&lt;br&gt;-	while (isspace(*ptr))
&lt;br&gt;-		ptr++;
&lt;br&gt;+	ptr = skip_spaces(ptr);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	/*
&lt;br&gt;&amp;nbsp;	 * Should really check for multiple pids or reject bad args here
&lt;br&gt;diff -puN arch/x86/kernel/cpu/mtrr/if.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function arch/x86/kernel/cpu/mtrr/if.c
&lt;br&gt;--- a/arch/x86/kernel/cpu/mtrr/if.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/arch/x86/kernel/cpu/mtrr/if.c
&lt;br&gt;@@ -4,6 +4,7 @@
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/proc_fs.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/module.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/ctype.h&amp;gt;
&lt;br&gt;+#include &amp;lt;linux/string.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/init.h&amp;gt;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;#define LINE_SIZE 80
&lt;br&gt;@@ -133,8 +134,7 @@ mtrr_write(struct file *file, const char
&lt;br&gt;&amp;nbsp;		return -EINVAL;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	base = simple_strtoull(line + 5, &amp;ptr, 0);
&lt;br&gt;-	while (isspace(*ptr))
&lt;br&gt;-		ptr++;
&lt;br&gt;+	ptr = skip_spaces(ptr);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	if (strncmp(ptr, &amp;quot;size=&amp;quot;, 5))
&lt;br&gt;&amp;nbsp;		return -EINVAL;
&lt;br&gt;@@ -142,14 +142,11 @@ mtrr_write(struct file *file, const char
&lt;br&gt;&amp;nbsp;	size = simple_strtoull(ptr + 5, &amp;ptr, 0);
&lt;br&gt;&amp;nbsp;	if ((base &amp; 0xfff) || (size &amp; 0xfff))
&lt;br&gt;&amp;nbsp;		return -EINVAL;
&lt;br&gt;-	while (isspace(*ptr))
&lt;br&gt;-		ptr++;
&lt;br&gt;+	ptr = skip_spaces(ptr);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	if (strncmp(ptr, &amp;quot;type=&amp;quot;, 5))
&lt;br&gt;&amp;nbsp;		return -EINVAL;
&lt;br&gt;-	ptr += 5;
&lt;br&gt;-	while (isspace(*ptr))
&lt;br&gt;-		ptr++;
&lt;br&gt;+	ptr = skip_spaces(ptr + 5);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	for (i = 0; i &amp;lt; MTRR_NUM_TYPES; ++i) {
&lt;br&gt;&amp;nbsp;		if (strcmp(ptr, mtrr_strings[i]))
&lt;br&gt;diff -puN drivers/leds/led-class.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function drivers/leds/led-class.c
&lt;br&gt;--- a/drivers/leds/led-class.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/drivers/leds/led-class.c
&lt;br&gt;@@ -50,7 +50,7 @@ static ssize_t led_brightness_store(stru
&lt;br&gt;&amp;nbsp;	unsigned long state = simple_strtoul(buf, &amp;after, 10);
&lt;br&gt;&amp;nbsp;	size_t count = after - buf;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	if (*after &amp;&amp; isspace(*after))
&lt;br&gt;+	if (isspace(*after))
&lt;br&gt;&amp;nbsp;		count++;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	if (count == size) {
&lt;br&gt;diff -puN drivers/leds/ledtrig-timer.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function drivers/leds/ledtrig-timer.c
&lt;br&gt;--- a/drivers/leds/ledtrig-timer.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/drivers/leds/ledtrig-timer.c
&lt;br&gt;@@ -83,7 +83,7 @@ static ssize_t led_delay_on_store(struct
&lt;br&gt;&amp;nbsp;	unsigned long state = simple_strtoul(buf, &amp;after, 10);
&lt;br&gt;&amp;nbsp;	size_t count = after - buf;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	if (*after &amp;&amp; isspace(*after))
&lt;br&gt;+	if (isspace(*after))
&lt;br&gt;&amp;nbsp;		count++;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	if (count == size) {
&lt;br&gt;@@ -127,7 +127,7 @@ static ssize_t led_delay_off_store(struc
&lt;br&gt;&amp;nbsp;	unsigned long state = simple_strtoul(buf, &amp;after, 10);
&lt;br&gt;&amp;nbsp;	size_t count = after - buf;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	if (*after &amp;&amp; isspace(*after))
&lt;br&gt;+	if (isspace(*after))
&lt;br&gt;&amp;nbsp;		count++;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	if (count == size) {
&lt;br&gt;diff -puN drivers/md/dm-table.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function drivers/md/dm-table.c
&lt;br&gt;--- a/drivers/md/dm-table.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/drivers/md/dm-table.c
&lt;br&gt;@@ -12,6 +12,7 @@
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/blkdev.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/namei.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/ctype.h&amp;gt;
&lt;br&gt;+#include &amp;lt;linux/string.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/slab.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/interrupt.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/mutex.h&amp;gt;
&lt;br&gt;@@ -600,11 +601,8 @@ int dm_split_args(int *argc, char ***arg
&lt;br&gt;&amp;nbsp;		return -ENOMEM;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	while (1) {
&lt;br&gt;-		start = end;
&lt;br&gt;-
&lt;br&gt;&amp;nbsp;		/* Skip whitespace */
&lt;br&gt;-		while (*start &amp;&amp; isspace(*start))
&lt;br&gt;-			start++;
&lt;br&gt;+		start = skip_spaces(end);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;		if (!*start)
&lt;br&gt;&amp;nbsp;			break;	/* success, we hit the end */
&lt;br&gt;diff -puN drivers/md/md.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function drivers/md/md.c
&lt;br&gt;--- a/drivers/md/md.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/drivers/md/md.c
&lt;br&gt;@@ -39,6 +39,7 @@
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/buffer_head.h&amp;gt; /* for invalidate_bdev */
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/poll.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/ctype.h&amp;gt;
&lt;br&gt;+#include &amp;lt;linux/string.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/hdreg.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/proc_fs.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/random.h&amp;gt;
&lt;br&gt;@@ -3246,8 +3247,7 @@ bitmap_store(mddev_t *mddev, const char 
&lt;br&gt;&amp;nbsp;		}
&lt;br&gt;&amp;nbsp;		if (*end &amp;&amp; !isspace(*end)) break;
&lt;br&gt;&amp;nbsp;		bitmap_dirty_bits(mddev-&amp;gt;bitmap, chunk, end_chunk);
&lt;br&gt;-		buf = end;
&lt;br&gt;-		while (isspace(*buf)) buf++;
&lt;br&gt;+		buf = skip_spaces(end);
&lt;br&gt;&amp;nbsp;	}
&lt;br&gt;&amp;nbsp;	bitmap_unplug(mddev-&amp;gt;bitmap); /* flush the bits to disk */
&lt;br&gt;&amp;nbsp;out:
&lt;br&gt;diff -puN drivers/parisc/pdc_stable.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function drivers/parisc/pdc_stable.c
&lt;br&gt;--- a/drivers/parisc/pdc_stable.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/drivers/parisc/pdc_stable.c
&lt;br&gt;@@ -779,12 +779,9 @@ static ssize_t pdcs_auto_write(struct ko
&lt;br&gt;&amp;nbsp;	read_unlock(&amp;pathentry-&amp;gt;rw_lock);
&lt;br&gt;&amp;nbsp;	
&lt;br&gt;&amp;nbsp;	DPRINTK(&amp;quot;%s: flags before: 0x%X\n&amp;quot;, __func__, flags);
&lt;br&gt;-			
&lt;br&gt;-	temp = in;
&lt;br&gt;-	
&lt;br&gt;-	while (*temp &amp;&amp; isspace(*temp))
&lt;br&gt;-		temp++;
&lt;br&gt;-	
&lt;br&gt;+
&lt;br&gt;+	temp = skip_spaces(in);
&lt;br&gt;+
&lt;br&gt;&amp;nbsp;	c = *temp++ - '0';
&lt;br&gt;&amp;nbsp;	if ((c != 0) &amp;&amp; (c != 1))
&lt;br&gt;&amp;nbsp;		goto parse_error;
&lt;br&gt;diff -puN drivers/platform/x86/thinkpad_acpi.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function drivers/platform/x86/thinkpad_acpi.c
&lt;br&gt;--- a/drivers/platform/x86/thinkpad_acpi.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/drivers/platform/x86/thinkpad_acpi.c
&lt;br&gt;@@ -1006,11 +1006,8 @@ static int parse_strtoul(const char *buf
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;&amp;nbsp;	char *endp;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	while (*buf &amp;&amp; isspace(*buf))
&lt;br&gt;-		buf++;
&lt;br&gt;-	*value = simple_strtoul(buf, &amp;endp, 0);
&lt;br&gt;-	while (*endp &amp;&amp; isspace(*endp))
&lt;br&gt;-		endp++;
&lt;br&gt;+	*value = simple_strtoul(skip_spaces(buf), &amp;endp, 0);
&lt;br&gt;+	endp = skip_spaces(endp);
&lt;br&gt;&amp;nbsp;	if (*endp || *value &amp;gt; max)
&lt;br&gt;&amp;nbsp;		return -EINVAL;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;diff -puN drivers/pnp/interface.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function drivers/pnp/interface.c
&lt;br&gt;--- a/drivers/pnp/interface.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/drivers/pnp/interface.c
&lt;br&gt;@@ -310,8 +310,7 @@ static ssize_t pnp_set_current_resources
&lt;br&gt;&amp;nbsp;		goto done;
&lt;br&gt;&amp;nbsp;	}
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	while (isspace(*buf))
&lt;br&gt;-		++buf;
&lt;br&gt;+	buf = skip_spaces(buf);
&lt;br&gt;&amp;nbsp;	if (!strnicmp(buf, &amp;quot;disable&amp;quot;, 7)) {
&lt;br&gt;&amp;nbsp;		retval = pnp_disable_dev(dev);
&lt;br&gt;&amp;nbsp;		goto done;
&lt;br&gt;@@ -353,19 +352,13 @@ static ssize_t pnp_set_current_resources
&lt;br&gt;&amp;nbsp;		pnp_init_resources(dev);
&lt;br&gt;&amp;nbsp;		mutex_lock(&amp;pnp_res_mutex);
&lt;br&gt;&amp;nbsp;		while (1) {
&lt;br&gt;-			while (isspace(*buf))
&lt;br&gt;-				++buf;
&lt;br&gt;+			buf = skip_spaces(buf);
&lt;br&gt;&amp;nbsp;			if (!strnicmp(buf, &amp;quot;io&amp;quot;, 2)) {
&lt;br&gt;-				buf += 2;
&lt;br&gt;-				while (isspace(*buf))
&lt;br&gt;-					++buf;
&lt;br&gt;+				buf = skip_spaces(buf + 2);
&lt;br&gt;&amp;nbsp;				start = simple_strtoul(buf, &amp;buf, 0);
&lt;br&gt;-				while (isspace(*buf))
&lt;br&gt;-					++buf;
&lt;br&gt;+				buf = skip_spaces(buf);
&lt;br&gt;&amp;nbsp;				if (*buf == '-') {
&lt;br&gt;-					buf += 1;
&lt;br&gt;-					while (isspace(*buf))
&lt;br&gt;-						++buf;
&lt;br&gt;+					buf = skip_spaces(buf + 1);
&lt;br&gt;&amp;nbsp;					end = simple_strtoul(buf, &amp;buf, 0);
&lt;br&gt;&amp;nbsp;				} else
&lt;br&gt;&amp;nbsp;					end = start;
&lt;br&gt;@@ -373,16 +366,11 @@ static ssize_t pnp_set_current_resources
&lt;br&gt;&amp;nbsp;				continue;
&lt;br&gt;&amp;nbsp;			}
&lt;br&gt;&amp;nbsp;			if (!strnicmp(buf, &amp;quot;mem&amp;quot;, 3)) {
&lt;br&gt;-				buf += 3;
&lt;br&gt;-				while (isspace(*buf))
&lt;br&gt;-					++buf;
&lt;br&gt;+				buf = skip_spaces(buf + 3);
&lt;br&gt;&amp;nbsp;				start = simple_strtoul(buf, &amp;buf, 0);
&lt;br&gt;-				while (isspace(*buf))
&lt;br&gt;-					++buf;
&lt;br&gt;+				buf = skip_spaces(buf);
&lt;br&gt;&amp;nbsp;				if (*buf == '-') {
&lt;br&gt;-					buf += 1;
&lt;br&gt;-					while (isspace(*buf))
&lt;br&gt;-						++buf;
&lt;br&gt;+					buf = skip_spaces(buf + 1);
&lt;br&gt;&amp;nbsp;					end = simple_strtoul(buf, &amp;buf, 0);
&lt;br&gt;&amp;nbsp;				} else
&lt;br&gt;&amp;nbsp;					end = start;
&lt;br&gt;@@ -390,17 +378,13 @@ static ssize_t pnp_set_current_resources
&lt;br&gt;&amp;nbsp;				continue;
&lt;br&gt;&amp;nbsp;			}
&lt;br&gt;&amp;nbsp;			if (!strnicmp(buf, &amp;quot;irq&amp;quot;, 3)) {
&lt;br&gt;-				buf += 3;
&lt;br&gt;-				while (isspace(*buf))
&lt;br&gt;-					++buf;
&lt;br&gt;+				buf = skip_spaces(buf + 3);
&lt;br&gt;&amp;nbsp;				start = simple_strtoul(buf, &amp;buf, 0);
&lt;br&gt;&amp;nbsp;				pnp_add_irq_resource(dev, start, 0);
&lt;br&gt;&amp;nbsp;				continue;
&lt;br&gt;&amp;nbsp;			}
&lt;br&gt;&amp;nbsp;			if (!strnicmp(buf, &amp;quot;dma&amp;quot;, 3)) {
&lt;br&gt;-				buf += 3;
&lt;br&gt;-				while (isspace(*buf))
&lt;br&gt;-					++buf;
&lt;br&gt;+				buf = skip_spaces(buf + 3);
&lt;br&gt;&amp;nbsp;				start = simple_strtoul(buf, &amp;buf, 0);
&lt;br&gt;&amp;nbsp;				pnp_add_dma_resource(dev, start, 0);
&lt;br&gt;&amp;nbsp;				continue;
&lt;br&gt;diff -puN drivers/s390/block/dasd_proc.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function drivers/s390/block/dasd_proc.c
&lt;br&gt;--- a/drivers/s390/block/dasd_proc.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/drivers/s390/block/dasd_proc.c
&lt;br&gt;@@ -14,6 +14,7 @@
&lt;br&gt;&amp;nbsp;#define KMSG_COMPONENT &amp;quot;dasd&amp;quot;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/ctype.h&amp;gt;
&lt;br&gt;+#include &amp;lt;linux/string.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/seq_file.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/vmalloc.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/proc_fs.h&amp;gt;
&lt;br&gt;@@ -272,10 +273,10 @@ dasd_statistics_write(struct file *file,
&lt;br&gt;&amp;nbsp;	DBF_EVENT(DBF_DEBUG, &amp;quot;/proc/dasd/statictics: '%s'\n&amp;quot;, buffer);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	/* check for valid verbs */
&lt;br&gt;-	for (str = buffer; isspace(*str); str++);
&lt;br&gt;+	str = skip_spaces(buffer);
&lt;br&gt;&amp;nbsp;	if (strncmp(str, &amp;quot;set&amp;quot;, 3) == 0 &amp;&amp; isspace(str[3])) {
&lt;br&gt;&amp;nbsp;		/* 'set xxx' was given */
&lt;br&gt;-		for (str = str + 4; isspace(*str); str++);
&lt;br&gt;+		str = skip_spaces(str + 4);
&lt;br&gt;&amp;nbsp;		if (strcmp(str, &amp;quot;on&amp;quot;) == 0) {
&lt;br&gt;&amp;nbsp;			/* switch on statistics profiling */
&lt;br&gt;&amp;nbsp;			dasd_profile_level = DASD_PROFILE_ON;
&lt;br&gt;diff -puN drivers/video/backlight/lcd.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function drivers/video/backlight/lcd.c
&lt;br&gt;--- a/drivers/video/backlight/lcd.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/drivers/video/backlight/lcd.c
&lt;br&gt;@@ -101,7 +101,7 @@ static ssize_t lcd_store_power(struct de
&lt;br&gt;&amp;nbsp;	int power = simple_strtoul(buf, &amp;endp, 0);
&lt;br&gt;&amp;nbsp;	size_t size = endp - buf;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	if (*endp &amp;&amp; isspace(*endp))
&lt;br&gt;+	if (isspace(*endp))
&lt;br&gt;&amp;nbsp;		size++;
&lt;br&gt;&amp;nbsp;	if (size != count)
&lt;br&gt;&amp;nbsp;		return -EINVAL;
&lt;br&gt;@@ -140,7 +140,7 @@ static ssize_t lcd_store_contrast(struct
&lt;br&gt;&amp;nbsp;	int contrast = simple_strtoul(buf, &amp;endp, 0);
&lt;br&gt;&amp;nbsp;	size_t size = endp - buf;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	if (*endp &amp;&amp; isspace(*endp))
&lt;br&gt;+	if (isspace(*endp))
&lt;br&gt;&amp;nbsp;		size++;
&lt;br&gt;&amp;nbsp;	if (size != count)
&lt;br&gt;&amp;nbsp;		return -EINVAL;
&lt;br&gt;diff -puN drivers/video/display/display-sysfs.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function drivers/video/display/display-sysfs.c
&lt;br&gt;--- a/drivers/video/display/display-sysfs.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/drivers/video/display/display-sysfs.c
&lt;br&gt;@@ -67,7 +67,7 @@ static ssize_t display_store_contrast(st
&lt;br&gt;&amp;nbsp;	contrast = simple_strtoul(buf, &amp;endp, 0);
&lt;br&gt;&amp;nbsp;	size = endp - buf;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	if (*endp &amp;&amp; isspace(*endp))
&lt;br&gt;+	if (isspace(*endp))
&lt;br&gt;&amp;nbsp;		size++;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	if (size != count)
&lt;br&gt;diff -puN drivers/video/output.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function drivers/video/output.c
&lt;br&gt;--- a/drivers/video/output.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/drivers/video/output.c
&lt;br&gt;@@ -50,7 +50,7 @@ static ssize_t video_output_store_state(
&lt;br&gt;&amp;nbsp;	int request_state = simple_strtoul(buf,&amp;endp,0);
&lt;br&gt;&amp;nbsp;	size_t size = endp - buf;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	if (*endp &amp;&amp; isspace(*endp))
&lt;br&gt;+	if (isspace(*endp))
&lt;br&gt;&amp;nbsp;		size++;
&lt;br&gt;&amp;nbsp;	if (size != count)
&lt;br&gt;&amp;nbsp;		return -EINVAL;
&lt;br&gt;diff -puN fs/cachefiles/daemon.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function fs/cachefiles/daemon.c
&lt;br&gt;--- a/fs/cachefiles/daemon.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/fs/cachefiles/daemon.c
&lt;br&gt;@@ -21,6 +21,7 @@
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/mount.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/statfs.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/ctype.h&amp;gt;
&lt;br&gt;+#include &amp;lt;linux/string.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/fs_struct.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;quot;internal.h&amp;quot;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;@@ -257,8 +258,7 @@ static ssize_t cachefiles_daemon_write(s
&lt;br&gt;&amp;nbsp;		if (args == data)
&lt;br&gt;&amp;nbsp;			goto error;
&lt;br&gt;&amp;nbsp;		*args = '\0';
&lt;br&gt;-		for (args++; isspace(*args); args++)
&lt;br&gt;-			continue;
&lt;br&gt;+		args = skip_spaces(++args);
&lt;br&gt;&amp;nbsp;	}
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	/* run the appropriate command handler */
&lt;br&gt;diff -puN fs/ext4/super.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function fs/ext4/super.c
&lt;br&gt;--- a/fs/ext4/super.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/fs/ext4/super.c
&lt;br&gt;@@ -2137,11 +2137,8 @@ static int parse_strtoul(const char *buf
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;&amp;nbsp;	char *endp;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	while (*buf &amp;&amp; isspace(*buf))
&lt;br&gt;-		buf++;
&lt;br&gt;-	*value = simple_strtoul(buf, &amp;endp, 0);
&lt;br&gt;-	while (*endp &amp;&amp; isspace(*endp))
&lt;br&gt;-		endp++;
&lt;br&gt;+	*value = simple_strtoul(skip_spaces(buf), &amp;endp, 0);
&lt;br&gt;+	endp = skip_spaces(endp);
&lt;br&gt;&amp;nbsp;	if (*endp || *value &amp;gt; max)
&lt;br&gt;&amp;nbsp;		return -EINVAL;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;diff -puN kernel/params.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function kernel/params.c
&lt;br&gt;--- a/kernel/params.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/kernel/params.c
&lt;br&gt;@@ -24,6 +24,7 @@
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/err.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/slab.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/ctype.h&amp;gt;
&lt;br&gt;+#include &amp;lt;linux/string.h&amp;gt;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;#if 0
&lt;br&gt;&amp;nbsp;#define DEBUGP printk
&lt;br&gt;@@ -122,9 +123,7 @@ static char *next_arg(char *args, char *
&lt;br&gt;&amp;nbsp;		next = args + i;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	/* Chew up trailing spaces. */
&lt;br&gt;-	while (isspace(*next))
&lt;br&gt;-		next++;
&lt;br&gt;-	return next;
&lt;br&gt;+	return skip_spaces(next);
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;/* Args looks like &amp;quot;foo=bar,bar2 baz=fuz wiz&amp;quot;. */
&lt;br&gt;@@ -139,8 +138,7 @@ int parse_args(const char *name,
&lt;br&gt;&amp;nbsp;	DEBUGP(&amp;quot;Parsing ARGS: %s\n&amp;quot;, args);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	/* Chew leading spaces */
&lt;br&gt;-	while (isspace(*args))
&lt;br&gt;-		args++;
&lt;br&gt;+	args = skip_spaces(args);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	while (*args) {
&lt;br&gt;&amp;nbsp;		int ret;
&lt;br&gt;diff -puN lib/argv_split.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function lib/argv_split.c
&lt;br&gt;--- a/lib/argv_split.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/lib/argv_split.c
&lt;br&gt;@@ -4,17 +4,10 @@
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/kernel.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/ctype.h&amp;gt;
&lt;br&gt;+#include &amp;lt;linux/string.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/slab.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/module.h&amp;gt;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-static const char *skip_sep(const char *cp)
&lt;br&gt;-{
&lt;br&gt;-	while (*cp &amp;&amp; isspace(*cp))
&lt;br&gt;-		cp++;
&lt;br&gt;-
&lt;br&gt;-	return cp;
&lt;br&gt;-}
&lt;br&gt;-
&lt;br&gt;&amp;nbsp;static const char *skip_arg(const char *cp)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;&amp;nbsp;	while (*cp &amp;&amp; !isspace(*cp))
&lt;br&gt;@@ -28,7 +21,7 @@ static int count_argc(const char *str)
&lt;br&gt;&amp;nbsp;	int count = 0;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	while (*str) {
&lt;br&gt;-		str = skip_sep(str);
&lt;br&gt;+		str = skip_spaces(str);
&lt;br&gt;&amp;nbsp;		if (*str) {
&lt;br&gt;&amp;nbsp;			count++;
&lt;br&gt;&amp;nbsp;			str = skip_arg(str);
&lt;br&gt;@@ -82,7 +75,7 @@ char **argv_split(gfp_t gfp, const char 
&lt;br&gt;&amp;nbsp;	argvp = argv;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	while (*str) {
&lt;br&gt;-		str = skip_sep(str);
&lt;br&gt;+		str = skip_spaces(str);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;		if (*str) {
&lt;br&gt;&amp;nbsp;			const char *p = str;
&lt;br&gt;diff -puN lib/dynamic_debug.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function lib/dynamic_debug.c
&lt;br&gt;--- a/lib/dynamic_debug.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/lib/dynamic_debug.c
&lt;br&gt;@@ -21,6 +21,7 @@
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/list.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/sysctl.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/ctype.h&amp;gt;
&lt;br&gt;+#include &amp;lt;linux/string.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/uaccess.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/dynamic_debug.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/debugfs.h&amp;gt;
&lt;br&gt;@@ -209,8 +210,7 @@ static int ddebug_tokenize(char *buf, ch
&lt;br&gt;&amp;nbsp;		char *end;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;		/* Skip leading whitespace */
&lt;br&gt;-		while (*buf &amp;&amp; isspace(*buf))
&lt;br&gt;-			buf++;
&lt;br&gt;+		buf = skip_spaces(buf);
&lt;br&gt;&amp;nbsp;		if (!*buf)
&lt;br&gt;&amp;nbsp;			break;	/* oh, it was trailing whitespace */
&lt;br&gt;&amp;nbsp;
&lt;br&gt;diff -puN lib/vsprintf.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function lib/vsprintf.c
&lt;br&gt;--- a/lib/vsprintf.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/lib/vsprintf.c
&lt;br&gt;@@ -1766,13 +1766,6 @@ EXPORT_SYMBOL_GPL(bprintf);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;#endif /* CONFIG_BINARY_PRINTF */
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-static noinline char *skip_space(const char *str)
&lt;br&gt;-{
&lt;br&gt;-	while (isspace(*str))
&lt;br&gt;-		++str;
&lt;br&gt;-	return (char *)str;
&lt;br&gt;-}
&lt;br&gt;-
&lt;br&gt;&amp;nbsp;/**
&lt;br&gt;&amp;nbsp; * vsscanf - Unformat a buffer into a list of arguments
&lt;br&gt;&amp;nbsp; * @buf:	input buffer
&lt;br&gt;@@ -1794,8 +1787,8 @@ int vsscanf(const char *buf, const char 
&lt;br&gt;&amp;nbsp;		 * white space, including none, in the input.
&lt;br&gt;&amp;nbsp;		 */
&lt;br&gt;&amp;nbsp;		if (isspace(*fmt)) {
&lt;br&gt;-			fmt = skip_space(fmt);
&lt;br&gt;-			str = skip_space(str);
&lt;br&gt;+			fmt = skip_spaces(++fmt);
&lt;br&gt;+			str = skip_spaces(str);
&lt;br&gt;&amp;nbsp;		}
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;		/* anything that is not a conversion must match exactly */
&lt;br&gt;@@ -1865,7 +1858,7 @@ int vsscanf(const char *buf, const char 
&lt;br&gt;&amp;nbsp;			if (field_width == -1)
&lt;br&gt;&amp;nbsp;				field_width = INT_MAX;
&lt;br&gt;&amp;nbsp;			/* first, skip leading white space in buffer */
&lt;br&gt;-			str = skip_space(str);
&lt;br&gt;+			str = skip_spaces(str);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;			/* now copy until next white space */
&lt;br&gt;&amp;nbsp;			while (*str &amp;&amp; !isspace(*str) &amp;&amp; field_width--)
&lt;br&gt;@@ -1907,7 +1900,7 @@ int vsscanf(const char *buf, const char 
&lt;br&gt;&amp;nbsp;		/* have some sort of integer conversion.
&lt;br&gt;&amp;nbsp;		 * first, skip white space in buffer.
&lt;br&gt;&amp;nbsp;		 */
&lt;br&gt;-		str = skip_space(str);
&lt;br&gt;+		str = skip_spaces(str);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;		digit = *str;
&lt;br&gt;&amp;nbsp;		if (is_sign &amp;&amp; digit == '-')
&lt;br&gt;diff -puN net/irda/irnet/irnet.h~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function net/irda/irnet/irnet.h
&lt;br&gt;--- a/net/irda/irnet/irnet.h~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/net/irda/irnet/irnet.h
&lt;br&gt;@@ -249,6 +249,7 @@
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/poll.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/capability.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/ctype.h&amp;gt;	/* isspace() */
&lt;br&gt;+#include &amp;lt;linux/string.h&amp;gt;	/* skip_spaces() */
&lt;br&gt;&amp;nbsp;#include &amp;lt;asm/uaccess.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/init.h&amp;gt;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;diff -puN net/irda/irnet/irnet_ppp.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function net/irda/irnet/irnet_ppp.c
&lt;br&gt;--- a/net/irda/irnet/irnet_ppp.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/net/irda/irnet/irnet_ppp.c
&lt;br&gt;@@ -76,9 +76,8 @@ irnet_ctrl_write(irnet_socket *	ap,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/* Look at the next command */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;start = next;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp;/* Scrap whitespaces before the command */
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp;while(isspace(*start))
&lt;br&gt;-	start++;
&lt;br&gt;+	/* Scrap whitespaces before the command */
&lt;br&gt;+	start = skip_spaces(start);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/* ',' is our command separator */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;next = strchr(start, ',');
&lt;br&gt;@@ -133,8 +132,7 @@ irnet_ctrl_write(irnet_socket *	ap,
&lt;br&gt;&amp;nbsp;	 &amp;nbsp; &amp;nbsp; &amp;nbsp;char *	endp;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	 &amp;nbsp; &amp;nbsp; &amp;nbsp;/* Scrap whitespaces before the command */
&lt;br&gt;-	 &amp;nbsp; &amp;nbsp; &amp;nbsp;while(isspace(*begp))
&lt;br&gt;-		begp++;
&lt;br&gt;+	 &amp;nbsp; &amp;nbsp; &amp;nbsp;begp = skip_spaces(begp);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	 &amp;nbsp; &amp;nbsp; &amp;nbsp;/* Convert argument to a number (last arg is the base) */
&lt;br&gt;&amp;nbsp;	 &amp;nbsp; &amp;nbsp; &amp;nbsp;addr = simple_strtoul(begp, &amp;endp, 16);
&lt;br&gt;diff -puN net/netfilter/xt_recent.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function net/netfilter/xt_recent.c
&lt;br&gt;--- a/net/netfilter/xt_recent.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/net/netfilter/xt_recent.c
&lt;br&gt;@@ -482,8 +482,7 @@ static ssize_t recent_old_proc_write(str
&lt;br&gt;&amp;nbsp;	if (copy_from_user(buf, input, size))
&lt;br&gt;&amp;nbsp;		return -EFAULT;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	while (isspace(*c))
&lt;br&gt;-		c++;
&lt;br&gt;+	c = skip_spaces(c);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	if (size - (c - buf) &amp;lt; 5)
&lt;br&gt;&amp;nbsp;		return c - buf;
&lt;br&gt;diff -puN sound/pci/hda/hda_hwdep.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function sound/pci/hda/hda_hwdep.c
&lt;br&gt;--- a/sound/pci/hda/hda_hwdep.c~tree-wide-convert-open-calls-to-remove-spaces-to-skip_spaces-lib-function
&lt;br&gt;+++ a/sound/pci/hda/hda_hwdep.c
&lt;br&gt;@@ -24,6 +24,7 @@
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/compat.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/mutex.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/ctype.h&amp;gt;
&lt;br&gt;+#include &amp;lt;linux/string.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;linux/firmware.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;lt;sound/core.h&amp;gt;
&lt;br&gt;&amp;nbsp;#include &amp;quot;hda_codec.h&amp;quot;
&lt;br&gt;@@ -428,8 +429,7 @@ static int parse_hints(struct hda_codec 
&lt;br&gt;&amp;nbsp;	char *key, *val;
&lt;br&gt;&amp;nbsp;	struct hda_hint *hint;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	while (isspace(*buf))
&lt;br&gt;-		buf++;
&lt;br&gt;+	buf = skip_spaces(buf);
&lt;br&gt;&amp;nbsp;	if (!*buf || *buf == '#' || *buf == '\n')
&lt;br&gt;&amp;nbsp;		return 0;
&lt;br&gt;&amp;nbsp;	if (*buf == '=')
&lt;br&gt;@@ -444,8 +444,7 @@ static int parse_hints(struct hda_codec 
&lt;br&gt;&amp;nbsp;		return -EINVAL;
&lt;br&gt;&amp;nbsp;	}
&lt;br&gt;&amp;nbsp;	*val++ = 0;
&lt;br&gt;-	while (isspace(*val))
&lt;br&gt;-		val++;
&lt;br&gt;+	val = skip_spaces(val);
&lt;br&gt;&amp;nbsp;	remove_trail_spaces(key);
&lt;br&gt;&amp;nbsp;	remove_trail_spaces(val);
&lt;br&gt;&amp;nbsp;	hint = get_hint(codec, key);
&lt;br&gt;_
&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26788252&amp;i=18&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-patch-156-196--tree-wide%3A-convert-open-calls-to-remove-spaces-to-skip_spaces%28%29-lib-function-tp26788252p26788252.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26784349</id>
	<title>[PATCH] ext3: Fix data / filesystem corruption when write fails to copy data</title>
	<published>2009-12-14T12:35:57Z</published>
	<updated>2009-12-14T12:35:57Z</updated>
	<author>
		<name>Jan Kara</name>
	</author>
	<content type="html">When ext3_write_begin fails after allocating some blocks or
&lt;br&gt;generic_perform_write fails to copy data to write, we truncate blocks already
&lt;br&gt;instantiated beyond i_size. Although these blocks were never inside i_size, we
&lt;br&gt;have to truncate pagecache of these blocks so that corresponding buffers get
&lt;br&gt;unmapped. Otherwise subsequent __block_prepare_write (called because we are
&lt;br&gt;retrying the write) will find the buffers mapped, not call -&amp;gt;get_block, and
&lt;br&gt;thus the page will be backed by already freed blocks leading to filesystem and
&lt;br&gt;data corruption.
&lt;br&gt;&lt;br&gt;Reported-by: James Y Knight &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26784349&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;foom@...&lt;/a&gt;&amp;gt;
&lt;br&gt;Signed-off-by: Jan Kara &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26784349&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;jack@...&lt;/a&gt;&amp;gt;
&lt;br&gt;---
&lt;br&gt;&amp;nbsp;fs/ext3/inode.c | &amp;nbsp; 18 ++++++++++++++----
&lt;br&gt;&amp;nbsp;1 files changed, 14 insertions(+), 4 deletions(-)
&lt;br&gt;&lt;br&gt;The bug has been introduced by commit 9eaaa2d5759837402ec5eee13b2a97921808c3eb
&lt;br&gt;and thus this fix needs to be applied to 2.6.31 and 2.6.32 kernels. Currently,
&lt;br&gt;it's in Linus's tree as commit 68eb3db08344286733adac48304d9fb7a0e53b27.
&lt;br&gt;&lt;br&gt;diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
&lt;br&gt;index 354ed3b..f9d6937 100644
&lt;br&gt;--- a/fs/ext3/inode.c
&lt;br&gt;+++ b/fs/ext3/inode.c
&lt;br&gt;@@ -1151,6 +1151,16 @@ static int do_journal_get_write_access(handle_t *handle,
&lt;br&gt;&amp;nbsp;	return ext3_journal_get_write_access(handle, bh);
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&amp;nbsp;
&lt;br&gt;+/*
&lt;br&gt;+ * Truncate blocks that were not used by write. We have to truncate the
&lt;br&gt;+ * pagecache as well so that corresponding buffers get properly unmapped.
&lt;br&gt;+ */
&lt;br&gt;+static void ext3_truncate_failed_write(struct inode *inode)
&lt;br&gt;+{
&lt;br&gt;+	truncate_inode_pages(inode-&amp;gt;i_mapping, inode-&amp;gt;i_size);
&lt;br&gt;+	ext3_truncate(inode);
&lt;br&gt;+}
&lt;br&gt;+
&lt;br&gt;&amp;nbsp;static int ext3_write_begin(struct file *file, struct address_space *mapping,
&lt;br&gt;&amp;nbsp;				loff_t pos, unsigned len, unsigned flags,
&lt;br&gt;&amp;nbsp;				struct page **pagep, void **fsdata)
&lt;br&gt;@@ -1209,7 +1219,7 @@ write_begin_failed:
&lt;br&gt;&amp;nbsp;		unlock_page(page);
&lt;br&gt;&amp;nbsp;		page_cache_release(page);
&lt;br&gt;&amp;nbsp;		if (pos + len &amp;gt; inode-&amp;gt;i_size)
&lt;br&gt;-			ext3_truncate(inode);
&lt;br&gt;+			ext3_truncate_failed_write(inode);
&lt;br&gt;&amp;nbsp;	}
&lt;br&gt;&amp;nbsp;	if (ret == -ENOSPC &amp;&amp; ext3_should_retry_alloc(inode-&amp;gt;i_sb, &amp;retries))
&lt;br&gt;&amp;nbsp;		goto retry;
&lt;br&gt;@@ -1304,7 +1314,7 @@ static int ext3_ordered_write_end(struct file *file,
&lt;br&gt;&amp;nbsp;	page_cache_release(page);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	if (pos + len &amp;gt; inode-&amp;gt;i_size)
&lt;br&gt;-		ext3_truncate(inode);
&lt;br&gt;+		ext3_truncate_failed_write(inode);
&lt;br&gt;&amp;nbsp;	return ret ? ret : copied;
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&amp;nbsp;
&lt;br&gt;@@ -1330,7 +1340,7 @@ static int ext3_writeback_write_end(struct file *file,
&lt;br&gt;&amp;nbsp;	page_cache_release(page);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	if (pos + len &amp;gt; inode-&amp;gt;i_size)
&lt;br&gt;-		ext3_truncate(inode);
&lt;br&gt;+		ext3_truncate_failed_write(inode);
&lt;br&gt;&amp;nbsp;	return ret ? ret : copied;
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&amp;nbsp;
&lt;br&gt;@@ -1383,7 +1393,7 @@ static int ext3_journalled_write_end(struct file *file,
&lt;br&gt;&amp;nbsp;	page_cache_release(page);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	if (pos + len &amp;gt; inode-&amp;gt;i_size)
&lt;br&gt;-		ext3_truncate(inode);
&lt;br&gt;+		ext3_truncate_failed_write(inode);
&lt;br&gt;&amp;nbsp;	return ret ? ret : copied;
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-- 
&lt;br&gt;1.6.4.2
&lt;br&gt;&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26784349&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH--ext3%3A-Fix-data---filesystem-corruption-when-write-fails-to-copy-data-tp26784349p26784349.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26782927</id>
	<title>[PATCH 4/4] ext3: Replace lock/unlock_super() with an explicit lock for resizing</title>
	<published>2009-12-14T11:01:05Z</published>
	<updated>2009-12-14T11:01:05Z</updated>
	<author>
		<name>Eric Sandeen-5</name>
	</author>
	<content type="html">From: Theodore Ts'o &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26782927&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;tytso@...&lt;/a&gt;&amp;gt;
&lt;br&gt;&lt;br&gt;Use a separate lock to protect s_groups_count and the other block
&lt;br&gt;group descriptors which get changed via an on-line resize operation,
&lt;br&gt;so we can stop overloading the use of lock_super().
&lt;br&gt;&lt;br&gt;Crossport of 32ed5058ce90024efcd811254b4b1de0468099df
&lt;br&gt;&lt;br&gt;Signed-off-by: Eric Sandeen &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26782927&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;sandeen@...&lt;/a&gt;&amp;gt;
&lt;br&gt;---
&lt;br&gt;&amp;nbsp;fs/ext3/resize.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; 35 ++++++++++++++++++-----------------
&lt;br&gt;&amp;nbsp;fs/ext3/super.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp;1 +
&lt;br&gt;&amp;nbsp;include/linux/ext3_fs_sb.h | &amp;nbsp; &amp;nbsp;1 +
&lt;br&gt;&amp;nbsp;3 files changed, 20 insertions(+), 17 deletions(-)
&lt;br&gt;&lt;br&gt;diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c
&lt;br&gt;index 8359e7b..57a5bc9 100644
&lt;br&gt;--- a/fs/ext3/resize.c
&lt;br&gt;+++ b/fs/ext3/resize.c
&lt;br&gt;@@ -209,7 +209,7 @@ static int setup_new_group_blocks(struct super_block *sb,
&lt;br&gt;&amp;nbsp;	if (IS_ERR(handle))
&lt;br&gt;&amp;nbsp;		return PTR_ERR(handle);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	lock_super(sb);
&lt;br&gt;+	mutex_lock(&amp;sbi-&amp;gt;s_resize_lock);
&lt;br&gt;&amp;nbsp;	if (input-&amp;gt;group != sbi-&amp;gt;s_groups_count) {
&lt;br&gt;&amp;nbsp;		err = -EBUSY;
&lt;br&gt;&amp;nbsp;		goto exit_journal;
&lt;br&gt;@@ -324,7 +324,7 @@ exit_bh:
&lt;br&gt;&amp;nbsp;	brelse(bh);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;exit_journal:
&lt;br&gt;-	unlock_super(sb);
&lt;br&gt;+	mutex_unlock(&amp;sbi-&amp;gt;s_resize_lock);
&lt;br&gt;&amp;nbsp;	if ((err2 = ext3_journal_stop(handle)) &amp;&amp; !err)
&lt;br&gt;&amp;nbsp;		err = err2;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;@@ -662,11 +662,12 @@ exit_free:
&lt;br&gt;&amp;nbsp; * important part is that the new block and inode counts are in the backup
&lt;br&gt;&amp;nbsp; * superblocks, and the location of the new group metadata in the GDT backups.
&lt;br&gt;&amp;nbsp; *
&lt;br&gt;- * We do not need lock_super() for this, because these blocks are not
&lt;br&gt;- * otherwise touched by the filesystem code when it is mounted. &amp;nbsp;We don't
&lt;br&gt;- * need to worry about last changing from sbi-&amp;gt;s_groups_count, because the
&lt;br&gt;- * worst that can happen is that we do not copy the full number of backups
&lt;br&gt;- * at this time. &amp;nbsp;The resize which changed s_groups_count will backup again.
&lt;br&gt;+ * We do not need take the s_resize_lock for this, because these
&lt;br&gt;+ * blocks are not otherwise touched by the filesystem code when it is
&lt;br&gt;+ * mounted. &amp;nbsp;We don't need to worry about last changing from
&lt;br&gt;+ * sbi-&amp;gt;s_groups_count, because the worst that can happen is that we
&lt;br&gt;+ * do not copy the full number of backups at this time. &amp;nbsp;The resize
&lt;br&gt;+ * which changed s_groups_count will backup again.
&lt;br&gt;&amp;nbsp; */
&lt;br&gt;&amp;nbsp;static void update_backups(struct super_block *sb,
&lt;br&gt;&amp;nbsp;			 &amp;nbsp; int blk_off, char *data, int size)
&lt;br&gt;@@ -825,7 +826,7 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input)
&lt;br&gt;&amp;nbsp;		goto exit_put;
&lt;br&gt;&amp;nbsp;	}
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	lock_super(sb);
&lt;br&gt;+	mutex_lock(&amp;sbi-&amp;gt;s_resize_lock);
&lt;br&gt;&amp;nbsp;	if (input-&amp;gt;group != sbi-&amp;gt;s_groups_count) {
&lt;br&gt;&amp;nbsp;		ext3_warning(sb, __func__,
&lt;br&gt;&amp;nbsp;			 &amp;nbsp; &amp;nbsp; &amp;quot;multiple resizers run on filesystem!&amp;quot;);
&lt;br&gt;@@ -856,7 +857,7 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input)
&lt;br&gt;&amp;nbsp;	/*
&lt;br&gt;&amp;nbsp;	 * OK, now we've set up the new group. &amp;nbsp;Time to make it active.
&lt;br&gt;&amp;nbsp;	 *
&lt;br&gt;-	 * Current kernels don't lock all allocations via lock_super(),
&lt;br&gt;+	 * We do not lock all allocations via s_resize_lock
&lt;br&gt;&amp;nbsp;	 * so we have to be safe wrt. concurrent accesses the group
&lt;br&gt;&amp;nbsp;	 * data. &amp;nbsp;So we need to be careful to set all of the relevant
&lt;br&gt;&amp;nbsp;	 * group descriptor data etc. *before* we enable the group.
&lt;br&gt;@@ -900,12 +901,12 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input)
&lt;br&gt;&amp;nbsp;	 *
&lt;br&gt;&amp;nbsp;	 * The precise rules we use are:
&lt;br&gt;&amp;nbsp;	 *
&lt;br&gt;-	 * * Writers of s_groups_count *must* hold lock_super
&lt;br&gt;+	 * * Writers of s_groups_count *must* hold s_resize_lock
&lt;br&gt;&amp;nbsp;	 * AND
&lt;br&gt;&amp;nbsp;	 * * Writers must perform a smp_wmb() after updating all dependent
&lt;br&gt;&amp;nbsp;	 * &amp;nbsp; data and before modifying the groups count
&lt;br&gt;&amp;nbsp;	 *
&lt;br&gt;-	 * * Readers must hold lock_super() over the access
&lt;br&gt;+	 * * Readers must hold s_resize_lock over the access
&lt;br&gt;&amp;nbsp;	 * OR
&lt;br&gt;&amp;nbsp;	 * * Readers must perform an smp_rmb() after reading the groups count
&lt;br&gt;&amp;nbsp;	 * &amp;nbsp; and before reading any dependent data.
&lt;br&gt;@@ -936,7 +937,7 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input)
&lt;br&gt;&amp;nbsp;	ext3_journal_dirty_metadata(handle, sbi-&amp;gt;s_sbh);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;exit_journal:
&lt;br&gt;-	unlock_super(sb);
&lt;br&gt;+	mutex_unlock(&amp;sbi-&amp;gt;s_resize_lock);
&lt;br&gt;&amp;nbsp;	if ((err2 = ext3_journal_stop(handle)) &amp;&amp; !err)
&lt;br&gt;&amp;nbsp;		err = err2;
&lt;br&gt;&amp;nbsp;	if (!err) {
&lt;br&gt;@@ -973,7 +974,7 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es,
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	/* We don't need to worry about locking wrt other resizers just
&lt;br&gt;&amp;nbsp;	 * yet: we're going to revalidate es-&amp;gt;s_blocks_count after
&lt;br&gt;-	 * taking lock_super() below. */
&lt;br&gt;+	 * taking the s_resize_lock below. */
&lt;br&gt;&amp;nbsp;	o_blocks_count = le32_to_cpu(es-&amp;gt;s_blocks_count);
&lt;br&gt;&amp;nbsp;	o_groups_count = EXT3_SB(sb)-&amp;gt;s_groups_count;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;@@ -1045,11 +1046,11 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es,
&lt;br&gt;&amp;nbsp;		goto exit_put;
&lt;br&gt;&amp;nbsp;	}
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	lock_super(sb);
&lt;br&gt;+	mutex_lock(&amp;EXT3_SB(sb)-&amp;gt;s_resize_lock);
&lt;br&gt;&amp;nbsp;	if (o_blocks_count != le32_to_cpu(es-&amp;gt;s_blocks_count)) {
&lt;br&gt;&amp;nbsp;		ext3_warning(sb, __func__,
&lt;br&gt;&amp;nbsp;			 &amp;nbsp; &amp;nbsp; &amp;quot;multiple resizers run on filesystem!&amp;quot;);
&lt;br&gt;-		unlock_super(sb);
&lt;br&gt;+		mutex_unlock(&amp;EXT3_SB(sb)-&amp;gt;s_resize_lock);
&lt;br&gt;&amp;nbsp;		ext3_journal_stop(handle);
&lt;br&gt;&amp;nbsp;		err = -EBUSY;
&lt;br&gt;&amp;nbsp;		goto exit_put;
&lt;br&gt;@@ -1059,13 +1060,13 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es,
&lt;br&gt;&amp;nbsp;						 EXT3_SB(sb)-&amp;gt;s_sbh))) {
&lt;br&gt;&amp;nbsp;		ext3_warning(sb, __func__,
&lt;br&gt;&amp;nbsp;			 &amp;nbsp; &amp;nbsp; &amp;quot;error %d on journal write access&amp;quot;, err);
&lt;br&gt;-		unlock_super(sb);
&lt;br&gt;+		mutex_unlock(&amp;EXT3_SB(sb)-&amp;gt;s_resize_lock);
&lt;br&gt;&amp;nbsp;		ext3_journal_stop(handle);
&lt;br&gt;&amp;nbsp;		goto exit_put;
&lt;br&gt;&amp;nbsp;	}
&lt;br&gt;&amp;nbsp;	es-&amp;gt;s_blocks_count = cpu_to_le32(o_blocks_count + add);
&lt;br&gt;&amp;nbsp;	ext3_journal_dirty_metadata(handle, EXT3_SB(sb)-&amp;gt;s_sbh);
&lt;br&gt;-	unlock_super(sb);
&lt;br&gt;+	mutex_unlock(&amp;EXT3_SB(sb)-&amp;gt;s_resize_lock);
&lt;br&gt;&amp;nbsp;	ext3_debug(&amp;quot;freeing blocks %lu through &amp;quot;E3FSBLK&amp;quot;\n&amp;quot;, o_blocks_count,
&lt;br&gt;&amp;nbsp;		 &amp;nbsp; o_blocks_count + add);
&lt;br&gt;&amp;nbsp;	ext3_free_blocks_sb(handle, sb, o_blocks_count, add, &amp;freed_blocks);
&lt;br&gt;diff --git a/fs/ext3/super.c b/fs/ext3/super.c
&lt;br&gt;index 534557c..53d3c53 100644
&lt;br&gt;--- a/fs/ext3/super.c
&lt;br&gt;+++ b/fs/ext3/super.c
&lt;br&gt;@@ -1891,6 +1891,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
&lt;br&gt;&amp;nbsp;#endif
&lt;br&gt;&amp;nbsp;	INIT_LIST_HEAD(&amp;sbi-&amp;gt;s_orphan); /* unlinked but open files */
&lt;br&gt;&amp;nbsp;	mutex_init(&amp;sbi-&amp;gt;s_orphan_lock);
&lt;br&gt;+	mutex_init(&amp;sbi-&amp;gt;s_resize_lock);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	sb-&amp;gt;s_root = NULL;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;diff --git a/include/linux/ext3_fs_sb.h b/include/linux/ext3_fs_sb.h
&lt;br&gt;index dd61d83..258088a 100644
&lt;br&gt;--- a/include/linux/ext3_fs_sb.h
&lt;br&gt;+++ b/include/linux/ext3_fs_sb.h
&lt;br&gt;@@ -73,6 +73,7 @@ struct ext3_sb_info {
&lt;br&gt;&amp;nbsp;	struct journal_s * s_journal;
&lt;br&gt;&amp;nbsp;	struct list_head s_orphan;
&lt;br&gt;&amp;nbsp;	struct mutex s_orphan_lock;
&lt;br&gt;+	struct mutex s_resize_lock;
&lt;br&gt;&amp;nbsp;	unsigned long s_commit_interval;
&lt;br&gt;&amp;nbsp;	struct block_device *journal_bdev;
&lt;br&gt;&amp;nbsp;#ifdef CONFIG_JBD_DEBUG
&lt;br&gt;-- 1.6.0.6
&lt;br&gt;&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26782927&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH-0-4--ext3%3A-crossport-ext3-sb_lock-changes-tp26782848p26782927.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26782925</id>
	<title>[PATCH 3/4] ext3: Replace lock/unlock_super() with an explicit lock for the orphan list</title>
	<published>2009-12-14T11:00:30Z</published>
	<updated>2009-12-14T11:00:30Z</updated>
	<author>
		<name>Eric Sandeen-5</name>
	</author>
	<content type="html">From: Theodore Ts'o &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26782925&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;tytso@...&lt;/a&gt;&amp;gt;
&lt;br&gt;&lt;br&gt;Use a separate lock to protect the orphan list, so we can stop
&lt;br&gt;overloading the use of lock_super().
&lt;br&gt;&lt;br&gt;Crossport of 3b9d4ed26680771295d904a6b83e88e620780893
&lt;br&gt;&lt;br&gt;Signed-off-by: Eric Sandeen &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26782925&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;sandeen@...&lt;/a&gt;&amp;gt;
&lt;br&gt;---
&lt;br&gt;&amp;nbsp;fs/ext3/namei.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; 20 +++++++++++---------
&lt;br&gt;&amp;nbsp;fs/ext3/super.c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp;1 +
&lt;br&gt;&amp;nbsp;include/linux/ext3_fs_sb.h | &amp;nbsp; &amp;nbsp;1 +
&lt;br&gt;&amp;nbsp;3 files changed, 13 insertions(+), 9 deletions(-)
&lt;br&gt;&lt;br&gt;diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
&lt;br&gt;index aad6400..76d4c58 100644
&lt;br&gt;--- a/fs/ext3/namei.c
&lt;br&gt;+++ b/fs/ext3/namei.c
&lt;br&gt;@@ -1920,7 +1920,7 @@ int ext3_orphan_add(handle_t *handle, struct inode *inode)
&lt;br&gt;&amp;nbsp;	struct ext3_iloc iloc;
&lt;br&gt;&amp;nbsp;	int err = 0, rc;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	lock_super(sb);
&lt;br&gt;+	mutex_lock(&amp;EXT3_SB(sb)-&amp;gt;s_orphan_lock);
&lt;br&gt;&amp;nbsp;	if (!list_empty(&amp;EXT3_I(inode)-&amp;gt;i_orphan))
&lt;br&gt;&amp;nbsp;		goto out_unlock;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;@@ -1929,9 +1929,13 @@ int ext3_orphan_add(handle_t *handle, struct inode *inode)
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	/* @@@ FIXME: Observation from aviro:
&lt;br&gt;&amp;nbsp;	 * I think I can trigger J_ASSERT in ext3_orphan_add(). &amp;nbsp;We block
&lt;br&gt;-	 * here (on lock_super()), so race with ext3_link() which might bump
&lt;br&gt;+	 * here (on s_orphan_lock), so race with ext3_link() which might bump
&lt;br&gt;&amp;nbsp;	 * -&amp;gt;i_nlink. For, say it, character device. Not a regular file,
&lt;br&gt;&amp;nbsp;	 * not a directory, not a symlink and -&amp;gt;i_nlink &amp;gt; 0.
&lt;br&gt;+	 *
&lt;br&gt;+	 * tytso, 4/25/2009: I'm not sure how that could happen;
&lt;br&gt;+	 * shouldn't the fs core protect us from these sort of
&lt;br&gt;+	 * unlink()/link() races?
&lt;br&gt;&amp;nbsp;	 */
&lt;br&gt;&amp;nbsp;	J_ASSERT ((S_ISREG(inode-&amp;gt;i_mode) || S_ISDIR(inode-&amp;gt;i_mode) ||
&lt;br&gt;&amp;nbsp;		S_ISLNK(inode-&amp;gt;i_mode)) || inode-&amp;gt;i_nlink == 0);
&lt;br&gt;@@ -1968,7 +1972,7 @@ int ext3_orphan_add(handle_t *handle, struct inode *inode)
&lt;br&gt;&amp;nbsp;	jbd_debug(4, &amp;quot;orphan inode %lu will point to %d\n&amp;quot;,
&lt;br&gt;&amp;nbsp;			inode-&amp;gt;i_ino, NEXT_ORPHAN(inode));
&lt;br&gt;&amp;nbsp;out_unlock:
&lt;br&gt;-	unlock_super(sb);
&lt;br&gt;+	mutex_unlock(&amp;EXT3_SB(sb)-&amp;gt;s_orphan_lock);
&lt;br&gt;&amp;nbsp;	ext3_std_error(inode-&amp;gt;i_sb, err);
&lt;br&gt;&amp;nbsp;	return err;
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;@@ -1986,11 +1990,9 @@ int ext3_orphan_del(handle_t *handle, struct inode *inode)
&lt;br&gt;&amp;nbsp;	struct ext3_iloc iloc;
&lt;br&gt;&amp;nbsp;	int err = 0;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	lock_super(inode-&amp;gt;i_sb);
&lt;br&gt;-	if (list_empty(&amp;ei-&amp;gt;i_orphan)) {
&lt;br&gt;-		unlock_super(inode-&amp;gt;i_sb);
&lt;br&gt;-		return 0;
&lt;br&gt;-	}
&lt;br&gt;+	mutex_lock(&amp;EXT3_SB(inode-&amp;gt;i_sb)-&amp;gt;s_orphan_lock);
&lt;br&gt;+	if (list_empty(&amp;ei-&amp;gt;i_orphan))
&lt;br&gt;+		goto out;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	ino_next = NEXT_ORPHAN(inode);
&lt;br&gt;&amp;nbsp;	prev = ei-&amp;gt;i_orphan.prev;
&lt;br&gt;@@ -2040,7 +2042,7 @@ int ext3_orphan_del(handle_t *handle, struct inode *inode)
&lt;br&gt;&amp;nbsp;out_err:
&lt;br&gt;&amp;nbsp;	ext3_std_error(inode-&amp;gt;i_sb, err);
&lt;br&gt;&amp;nbsp;out:
&lt;br&gt;-	unlock_super(inode-&amp;gt;i_sb);
&lt;br&gt;+	mutex_unlock(&amp;EXT3_SB(inode-&amp;gt;i_sb)-&amp;gt;s_orphan_lock);
&lt;br&gt;&amp;nbsp;	return err;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;out_brelse:
&lt;br&gt;diff --git a/fs/ext3/super.c b/fs/ext3/super.c
&lt;br&gt;index 602b308..534557c 100644
&lt;br&gt;--- a/fs/ext3/super.c
&lt;br&gt;+++ b/fs/ext3/super.c
&lt;br&gt;@@ -1890,6 +1890,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
&lt;br&gt;&amp;nbsp;	sb-&amp;gt;dq_op = &amp;ext3_quota_operations;
&lt;br&gt;&amp;nbsp;#endif
&lt;br&gt;&amp;nbsp;	INIT_LIST_HEAD(&amp;sbi-&amp;gt;s_orphan); /* unlinked but open files */
&lt;br&gt;+	mutex_init(&amp;sbi-&amp;gt;s_orphan_lock);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	sb-&amp;gt;s_root = NULL;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;diff --git a/include/linux/ext3_fs_sb.h b/include/linux/ext3_fs_sb.h
&lt;br&gt;index f07f34d..dd61d83 100644
&lt;br&gt;--- a/include/linux/ext3_fs_sb.h
&lt;br&gt;+++ b/include/linux/ext3_fs_sb.h
&lt;br&gt;@@ -72,6 +72,7 @@ struct ext3_sb_info {
&lt;br&gt;&amp;nbsp;	struct inode * s_journal_inode;
&lt;br&gt;&amp;nbsp;	struct journal_s * s_journal;
&lt;br&gt;&amp;nbsp;	struct list_head s_orphan;
&lt;br&gt;+	struct mutex s_orphan_lock;
&lt;br&gt;&amp;nbsp;	unsigned long s_commit_interval;
&lt;br&gt;&amp;nbsp;	struct block_device *journal_bdev;
&lt;br&gt;&amp;nbsp;#ifdef CONFIG_JBD_DEBUG
&lt;br&gt;-- 1.6.0.6
&lt;br&gt;&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26782925&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH-0-4--ext3%3A-crossport-ext3-sb_lock-changes-tp26782848p26782925.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26782911</id>
	<title>[PATCH 2/4] ext3: ext3_mark_recovery_complete() doesn't need to use lock_super</title>
	<published>2009-12-14T10:59:59Z</published>
	<updated>2009-12-14T10:59:59Z</updated>
	<author>
		<name>Eric Sandeen-5</name>
	</author>
	<content type="html">From: Theodore Ts'o &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26782911&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;tytso@...&lt;/a&gt;&amp;gt;
&lt;br&gt;&lt;br&gt;The function ext3_mark_recovery_complete() is called from two call
&lt;br&gt;paths: either (a) while mounting the filesystem, in which case there's
&lt;br&gt;no danger of any other CPU calling write_super() until the mount is
&lt;br&gt;completed, and (b) while remounting the filesystem read-write, in
&lt;br&gt;which case the fs core has already locked the superblock. &amp;nbsp;This also
&lt;br&gt;allows us to take out a very vile unlock_super()/lock_super() pair in
&lt;br&gt;ext3_remount().
&lt;br&gt;&lt;br&gt;Crossport of a63c9eb2ce6f5028da90f282798232c4f398ceb8
&lt;br&gt;&lt;br&gt;Signed-off-by: Eric Sandeen &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26782911&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;sandeen@...&lt;/a&gt;&amp;gt;
&lt;br&gt;---
&lt;br&gt;&amp;nbsp;fs/ext3/super.c | &amp;nbsp; &amp;nbsp;8 --------
&lt;br&gt;&amp;nbsp;1 files changed, 0 insertions(+), 8 deletions(-)
&lt;br&gt;&lt;br&gt;diff --git a/fs/ext3/super.c b/fs/ext3/super.c
&lt;br&gt;index bed624c..602b308 100644
&lt;br&gt;--- a/fs/ext3/super.c
&lt;br&gt;+++ b/fs/ext3/super.c
&lt;br&gt;@@ -2352,13 +2352,11 @@ static void ext3_mark_recovery_complete(struct super_block * sb,
&lt;br&gt;&amp;nbsp;	if (journal_flush(journal) &amp;lt; 0)
&lt;br&gt;&amp;nbsp;		goto out;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-	lock_super(sb);
&lt;br&gt;&amp;nbsp;	if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER) &amp;&amp;
&lt;br&gt;&amp;nbsp;	 &amp;nbsp; &amp;nbsp;sb-&amp;gt;s_flags &amp; MS_RDONLY) {
&lt;br&gt;&amp;nbsp;		EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
&lt;br&gt;&amp;nbsp;		ext3_commit_super(sb, es, 1);
&lt;br&gt;&amp;nbsp;	}
&lt;br&gt;-	unlock_super(sb);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;out:
&lt;br&gt;&amp;nbsp;	journal_unlock_updates(journal);
&lt;br&gt;@@ -2550,13 +2548,7 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
&lt;br&gt;&amp;nbsp;			 &amp;nbsp; &amp;nbsp;(sbi-&amp;gt;s_mount_state &amp; EXT3_VALID_FS))
&lt;br&gt;&amp;nbsp;				es-&amp;gt;s_state = cpu_to_le16(sbi-&amp;gt;s_mount_state);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-			/*
&lt;br&gt;-			 * We have to unlock super so that we can wait for
&lt;br&gt;-			 * transactions.
&lt;br&gt;-			 */
&lt;br&gt;-			unlock_super(sb);
&lt;br&gt;&amp;nbsp;			ext3_mark_recovery_complete(sb, es);
&lt;br&gt;-			lock_super(sb);
&lt;br&gt;&amp;nbsp;		} else {
&lt;br&gt;&amp;nbsp;			__le32 ret;
&lt;br&gt;&amp;nbsp;			if ((ret = EXT3_HAS_RO_COMPAT_FEATURE(sb,
&lt;br&gt;-- 1.6.0.6
&lt;br&gt;&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26782911&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH-0-4--ext3%3A-crossport-ext3-sb_lock-changes-tp26782848p26782911.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26782909</id>
	<title>[PATCH 1/4] ext3: Remove outdated comment about lock_super()</title>
	<published>2009-12-14T10:59:18Z</published>
	<updated>2009-12-14T10:59:18Z</updated>
	<author>
		<name>Eric Sandeen-5</name>
	</author>
	<content type="html">From: Theodore Ts'o &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26782909&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;tytso@...&lt;/a&gt;&amp;gt;
&lt;br&gt;&lt;br&gt;ext3_fill_super() is no longer called by read_super(), and it is no
&lt;br&gt;longer called with the superblock locked. &amp;nbsp;The
&lt;br&gt;unlock_super()/lock_super() is no longer present, so this comment is
&lt;br&gt;entirely superfluous.
&lt;br&gt;&lt;br&gt;Crossport of 32ed5058ce90024efcd811254b4b1de0468099df
&lt;br&gt;&lt;br&gt;Signed-off-by: Eric Sandeen &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26782909&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;sandeen@...&lt;/a&gt;&amp;gt;
&lt;br&gt;---
&lt;br&gt;&amp;nbsp;fs/ext3/super.c | &amp;nbsp; &amp;nbsp;9 +--------
&lt;br&gt;&amp;nbsp;1 files changed, 1 insertions(+), 8 deletions(-)
&lt;br&gt;&lt;br&gt;diff --git a/fs/ext3/super.c b/fs/ext3/super.c
&lt;br&gt;index 427496c..bed624c 100644
&lt;br&gt;--- a/fs/ext3/super.c
&lt;br&gt;+++ b/fs/ext3/super.c
&lt;br&gt;@@ -1974,14 +1974,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
&lt;br&gt;&amp;nbsp;	}
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;	ext3_setup_super (sb, es, sb-&amp;gt;s_flags &amp; MS_RDONLY);
&lt;br&gt;-	/*
&lt;br&gt;-	 * akpm: core read_super() calls in here with the superblock locked.
&lt;br&gt;-	 * That deadlocks, because orphan cleanup needs to lock the superblock
&lt;br&gt;-	 * in numerous places. &amp;nbsp;Here we just pop the lock - it's relatively
&lt;br&gt;-	 * harmless, because we are now ready to accept write_super() requests,
&lt;br&gt;-	 * and aviro says that's the only reason for hanging onto the
&lt;br&gt;-	 * superblock lock.
&lt;br&gt;-	 */
&lt;br&gt;+
&lt;br&gt;&amp;nbsp;	EXT3_SB(sb)-&amp;gt;s_mount_state |= EXT3_ORPHAN_FS;
&lt;br&gt;&amp;nbsp;	ext3_orphan_cleanup(sb, es);
&lt;br&gt;&amp;nbsp;	EXT3_SB(sb)-&amp;gt;s_mount_state &amp;= ~EXT3_ORPHAN_FS;
&lt;br&gt;-- 1.6.0.6
&lt;br&gt;&lt;br&gt;--
&lt;br&gt;To unsubscribe from this list: send the line &amp;quot;unsubscribe linux-ext4&amp;quot; in
&lt;br&gt;the body of a message to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26782909&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;majordomo@...&lt;/a&gt;
&lt;br&gt;More majordomo info at &amp;nbsp;&lt;a href=&quot;http://vger.kernel.org/majordomo-info.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH-0-4--ext3%3A-crossport-ext3-sb_lock-changes-tp26782848p26782909.html" />
</entry>

</feed>
