<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux.git/fs/f2fs/node.c, branch v4.6</title>
<subtitle>Linux kernel source tree</subtitle>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/'/>
<entry>
<title>mm, fs: get rid of PAGE_CACHE_* and page_cache_{get,release} macros</title>
<updated>2016-04-04T17:41:08+00:00</updated>
<author>
<name>Kirill A. Shutemov</name>
<email>kirill.shutemov@linux.intel.com</email>
</author>
<published>2016-04-01T12:29:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=09cbfeaf1a5a67bfb3201e0c83c810cecb2efa5a'/>
<id>09cbfeaf1a5a67bfb3201e0c83c810cecb2efa5a</id>
<content type='text'>
PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} macros were introduced *long* time
ago with promise that one day it will be possible to implement page
cache with bigger chunks than PAGE_SIZE.

This promise never materialized.  And unlikely will.

We have many places where PAGE_CACHE_SIZE assumed to be equal to
PAGE_SIZE.  And it's constant source of confusion on whether
PAGE_CACHE_* or PAGE_* constant should be used in a particular case,
especially on the border between fs and mm.

Global switching to PAGE_CACHE_SIZE != PAGE_SIZE would cause to much
breakage to be doable.

Let's stop pretending that pages in page cache are special.  They are
not.

The changes are pretty straight-forward:

 - &lt;foo&gt; &lt;&lt; (PAGE_CACHE_SHIFT - PAGE_SHIFT) -&gt; &lt;foo&gt;;

 - &lt;foo&gt; &gt;&gt; (PAGE_CACHE_SHIFT - PAGE_SHIFT) -&gt; &lt;foo&gt;;

 - PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} -&gt; PAGE_{SIZE,SHIFT,MASK,ALIGN};

 - page_cache_get() -&gt; get_page();

 - page_cache_release() -&gt; put_page();

This patch contains automated changes generated with coccinelle using
script below.  For some reason, coccinelle doesn't patch header files.
I've called spatch for them manually.

The only adjustment after coccinelle is revert of changes to
PAGE_CAHCE_ALIGN definition: we are going to drop it later.

There are few places in the code where coccinelle didn't reach.  I'll
fix them manually in a separate patch.  Comments and documentation also
will be addressed with the separate patch.

virtual patch

@@
expression E;
@@
- E &lt;&lt; (PAGE_CACHE_SHIFT - PAGE_SHIFT)
+ E

@@
expression E;
@@
- E &gt;&gt; (PAGE_CACHE_SHIFT - PAGE_SHIFT)
+ E

@@
@@
- PAGE_CACHE_SHIFT
+ PAGE_SHIFT

@@
@@
- PAGE_CACHE_SIZE
+ PAGE_SIZE

@@
@@
- PAGE_CACHE_MASK
+ PAGE_MASK

@@
expression E;
@@
- PAGE_CACHE_ALIGN(E)
+ PAGE_ALIGN(E)

@@
expression E;
@@
- page_cache_get(E)
+ get_page(E)

@@
expression E;
@@
- page_cache_release(E)
+ put_page(E)

Signed-off-by: Kirill A. Shutemov &lt;kirill.shutemov@linux.intel.com&gt;
Acked-by: Michal Hocko &lt;mhocko@suse.com&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} macros were introduced *long* time
ago with promise that one day it will be possible to implement page
cache with bigger chunks than PAGE_SIZE.

This promise never materialized.  And unlikely will.

We have many places where PAGE_CACHE_SIZE assumed to be equal to
PAGE_SIZE.  And it's constant source of confusion on whether
PAGE_CACHE_* or PAGE_* constant should be used in a particular case,
especially on the border between fs and mm.

Global switching to PAGE_CACHE_SIZE != PAGE_SIZE would cause to much
breakage to be doable.

Let's stop pretending that pages in page cache are special.  They are
not.

The changes are pretty straight-forward:

 - &lt;foo&gt; &lt;&lt; (PAGE_CACHE_SHIFT - PAGE_SHIFT) -&gt; &lt;foo&gt;;

 - &lt;foo&gt; &gt;&gt; (PAGE_CACHE_SHIFT - PAGE_SHIFT) -&gt; &lt;foo&gt;;

 - PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} -&gt; PAGE_{SIZE,SHIFT,MASK,ALIGN};

 - page_cache_get() -&gt; get_page();

 - page_cache_release() -&gt; put_page();

This patch contains automated changes generated with coccinelle using
script below.  For some reason, coccinelle doesn't patch header files.
I've called spatch for them manually.

The only adjustment after coccinelle is revert of changes to
PAGE_CAHCE_ALIGN definition: we are going to drop it later.

There are few places in the code where coccinelle didn't reach.  I'll
fix them manually in a separate patch.  Comments and documentation also
will be addressed with the separate patch.

virtual patch

@@
expression E;
@@
- E &lt;&lt; (PAGE_CACHE_SHIFT - PAGE_SHIFT)
+ E

@@
expression E;
@@
- E &gt;&gt; (PAGE_CACHE_SHIFT - PAGE_SHIFT)
+ E

@@
@@
- PAGE_CACHE_SHIFT
+ PAGE_SHIFT

@@
@@
- PAGE_CACHE_SIZE
+ PAGE_SIZE

@@
@@
- PAGE_CACHE_MASK
+ PAGE_MASK

@@
expression E;
@@
- PAGE_CACHE_ALIGN(E)
+ PAGE_ALIGN(E)

@@
expression E;
@@
- page_cache_get(E)
+ get_page(E)

@@
expression E;
@@
- page_cache_release(E)
+ put_page(E)

Signed-off-by: Kirill A. Shutemov &lt;kirill.shutemov@linux.intel.com&gt;
Acked-by: Michal Hocko &lt;mhocko@suse.com&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>f2fs: submit node page write bios when really required</title>
<updated>2016-03-18T04:19:47+00:00</updated>
<author>
<name>Jaegeuk Kim</name>
<email>jaegeuk@kernel.org</email>
</author>
<published>2016-03-11T23:33:22+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=12bb0a8fd47e6020a7b52dc283a2d855f03d6ef5'/>
<id>12bb0a8fd47e6020a7b52dc283a2d855f03d6ef5</id>
<content type='text'>
If many threads calls fsync with data writes, we don't need to flush every
bios having node page writes.
The f2fs_wait_on_page_writeback will flush its bios when the page is really
needed.

Signed-off-by: Jaegeuk Kim &lt;jaegeuk@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
If many threads calls fsync with data writes, we don't need to flush every
bios having node page writes.
The f2fs_wait_on_page_writeback will flush its bios when the page is really
needed.

Signed-off-by: Jaegeuk Kim &lt;jaegeuk@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>f2fs: declare static functions</title>
<updated>2016-03-18T04:19:44+00:00</updated>
<author>
<name>Jaegeuk Kim</name>
<email>jaegeuk@kernel.org</email>
</author>
<published>2016-03-08T17:04:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=17a0ee552c4a4310b351b281098454a00e0e8034'/>
<id>17a0ee552c4a4310b351b281098454a00e0e8034</id>
<content type='text'>
Just to avoid sparse warnings.

Signed-off-by: Jaegeuk Kim &lt;jaegeuk@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Just to avoid sparse warnings.

Signed-off-by: Jaegeuk Kim &lt;jaegeuk@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>f2fs: modify the readahead method in ra_node_page()</title>
<updated>2016-03-18T04:19:43+00:00</updated>
<author>
<name>Fan Li</name>
<email>fanofcode.li@samsung.com</email>
</author>
<published>2016-02-29T06:29:51+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=999270de31138f1ae41743a856911f8e5e114264'/>
<id>999270de31138f1ae41743a856911f8e5e114264</id>
<content type='text'>
ra_node_page() is used to read ahead one node page. Comparing to regular
read, it's faster because it doesn't wait for IO completion.
But if it is called twice for reading the same block, and the IO request
from the first call hasn't been completed before the second call, the second
call will have to wait until the read is over.

Here use the code in __do_page_cache_readahead() to solve this problem.
It does nothing when someone else already puts the page in mapping. The
status of page should be assured by whoever puts it there.
This implement also prevents alteration of page reference count.

Signed-off-by: Fan li &lt;fanofcode.li@samsung.com&gt;
Signed-off-by: Jaegeuk Kim &lt;jaegeuk@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
ra_node_page() is used to read ahead one node page. Comparing to regular
read, it's faster because it doesn't wait for IO completion.
But if it is called twice for reading the same block, and the IO request
from the first call hasn't been completed before the second call, the second
call will have to wait until the read is over.

Here use the code in __do_page_cache_readahead() to solve this problem.
It does nothing when someone else already puts the page in mapping. The
status of page should be assured by whoever puts it there.
This implement also prevents alteration of page reference count.

Signed-off-by: Fan li &lt;fanofcode.li@samsung.com&gt;
Signed-off-by: Jaegeuk Kim &lt;jaegeuk@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>f2fs: fix to avoid deadlock when merging inline data</title>
<updated>2016-02-26T19:52:03+00:00</updated>
<author>
<name>Chao Yu</name>
<email>chao2.yu@samsung.com</email>
</author>
<published>2016-02-26T01:33:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=19c7377b56a618c2a6ae1dfef1c22f19ad9d427c'/>
<id>19c7377b56a618c2a6ae1dfef1c22f19ad9d427c</id>
<content type='text'>
When testing with fsstress, kworker and user threads were both blocked:

INFO: task kworker/u16:1:16580 blocked for more than 120 seconds.
"echo 0 &gt; /proc/sys/kernel/hung_task_timeout_secs" disables this message.
kworker/u16:1   D ffff8803f2595390     0 16580      2 0x00000000
Workqueue: writeback bdi_writeback_workfn (flush-251:0)
 ffff8802730e5760 0000000000000046 ffff880274729fc0 0000000000012440
 ffff8802730e5fd8 ffff8802730e4010 0000000000012440 0000000000012440
 ffff8802730e5fd8 0000000000012440 ffff880274729fc0 ffff88026eb50000
Call Trace:
 [&lt;ffffffff816fe9d9&gt;] schedule+0x29/0x70
 [&lt;ffffffff816ff895&gt;] rwsem_down_read_failed+0xa5/0xf9
 [&lt;ffffffff81378584&gt;] call_rwsem_down_read_failed+0x14/0x30
 [&lt;ffffffffa0694feb&gt;] f2fs_write_data_page+0x31b/0x420 [f2fs]
 [&lt;ffffffffa0690f1a&gt;] __f2fs_writepage+0x1a/0x50 [f2fs]
 [&lt;ffffffffa06922a0&gt;] f2fs_write_data_pages+0xe0/0x290 [f2fs]
 [&lt;ffffffff811473b3&gt;] do_writepages+0x23/0x40
 [&lt;ffffffff811cc3ee&gt;] __writeback_single_inode+0x4e/0x250
 [&lt;ffffffff811cd4f1&gt;] writeback_sb_inodes+0x2c1/0x470
 [&lt;ffffffff811cd73e&gt;] __writeback_inodes_wb+0x9e/0xd0
 [&lt;ffffffff811cda0b&gt;] wb_writeback+0x1fb/0x2d0
 [&lt;ffffffff811cdb7c&gt;] wb_do_writeback+0x9c/0x220
 [&lt;ffffffff811ce232&gt;] bdi_writeback_workfn+0x72/0x1c0
 [&lt;ffffffff8106b74e&gt;] process_one_work+0x1de/0x5b0
 [&lt;ffffffff8106e78f&gt;] worker_thread+0x11f/0x3e0
 [&lt;ffffffff810750ce&gt;] kthread+0xde/0xf0
 [&lt;ffffffff817093f8&gt;] ret_from_fork+0x58/0x90

fsstress thread stack:
 [&lt;ffffffff81139f0e&gt;] sleep_on_page+0xe/0x20
 [&lt;ffffffff81139ef7&gt;] __lock_page+0x67/0x70
 [&lt;ffffffff8113b100&gt;] find_lock_page+0x50/0x80
 [&lt;ffffffff8113b24f&gt;] find_or_create_page+0x3f/0xb0
 [&lt;ffffffffa06983a9&gt;] sync_node_pages+0x259/0x810 [f2fs]
 [&lt;ffffffffa068d874&gt;] write_checkpoint+0x1a4/0xce0 [f2fs]
 [&lt;ffffffffa0686b0c&gt;] f2fs_sync_fs+0x7c/0xd0 [f2fs]
 [&lt;ffffffffa067c813&gt;] f2fs_sync_file+0x143/0x5f0 [f2fs]
 [&lt;ffffffff811d301b&gt;] vfs_fsync_range+0x2b/0x40
 [&lt;ffffffff811d304c&gt;] vfs_fsync+0x1c/0x20
 [&lt;ffffffff811d3291&gt;] do_fsync+0x41/0x70
 [&lt;ffffffff811d32d3&gt;] SyS_fdatasync+0x13/0x20
 [&lt;ffffffff817094a2&gt;] system_call_fastpath+0x16/0x1b
 [&lt;ffffffffffffffff&gt;] 0xffffffffffffffff

The reason of this issue is:
CPU0:					CPU1:
 - f2fs_write_data_pages
					 - f2fs_sync_fs
					  - write_checkpoint
					   - block_operations
					    - f2fs_lock_all
					     - down_write(sbi-&gt;cp_rwsem)
  - lock_page(page)
  - f2fs_write_data_page
					    - sync_node_pages
					     - flush_inline_data
					      - pagecache_get_page(page, GFP_LOCK)
   - f2fs_lock_op
    - down_read(sbi-&gt;cp_rwsem)

This patch alters to use trylock_page in flush_inline_data to fix this ABBA
deadlock issue.

Signed-off-by: Chao Yu &lt;chao2.yu@samsung.com&gt;
Signed-off-by: Jaegeuk Kim &lt;jaegeuk@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When testing with fsstress, kworker and user threads were both blocked:

INFO: task kworker/u16:1:16580 blocked for more than 120 seconds.
"echo 0 &gt; /proc/sys/kernel/hung_task_timeout_secs" disables this message.
kworker/u16:1   D ffff8803f2595390     0 16580      2 0x00000000
Workqueue: writeback bdi_writeback_workfn (flush-251:0)
 ffff8802730e5760 0000000000000046 ffff880274729fc0 0000000000012440
 ffff8802730e5fd8 ffff8802730e4010 0000000000012440 0000000000012440
 ffff8802730e5fd8 0000000000012440 ffff880274729fc0 ffff88026eb50000
Call Trace:
 [&lt;ffffffff816fe9d9&gt;] schedule+0x29/0x70
 [&lt;ffffffff816ff895&gt;] rwsem_down_read_failed+0xa5/0xf9
 [&lt;ffffffff81378584&gt;] call_rwsem_down_read_failed+0x14/0x30
 [&lt;ffffffffa0694feb&gt;] f2fs_write_data_page+0x31b/0x420 [f2fs]
 [&lt;ffffffffa0690f1a&gt;] __f2fs_writepage+0x1a/0x50 [f2fs]
 [&lt;ffffffffa06922a0&gt;] f2fs_write_data_pages+0xe0/0x290 [f2fs]
 [&lt;ffffffff811473b3&gt;] do_writepages+0x23/0x40
 [&lt;ffffffff811cc3ee&gt;] __writeback_single_inode+0x4e/0x250
 [&lt;ffffffff811cd4f1&gt;] writeback_sb_inodes+0x2c1/0x470
 [&lt;ffffffff811cd73e&gt;] __writeback_inodes_wb+0x9e/0xd0
 [&lt;ffffffff811cda0b&gt;] wb_writeback+0x1fb/0x2d0
 [&lt;ffffffff811cdb7c&gt;] wb_do_writeback+0x9c/0x220
 [&lt;ffffffff811ce232&gt;] bdi_writeback_workfn+0x72/0x1c0
 [&lt;ffffffff8106b74e&gt;] process_one_work+0x1de/0x5b0
 [&lt;ffffffff8106e78f&gt;] worker_thread+0x11f/0x3e0
 [&lt;ffffffff810750ce&gt;] kthread+0xde/0xf0
 [&lt;ffffffff817093f8&gt;] ret_from_fork+0x58/0x90

fsstress thread stack:
 [&lt;ffffffff81139f0e&gt;] sleep_on_page+0xe/0x20
 [&lt;ffffffff81139ef7&gt;] __lock_page+0x67/0x70
 [&lt;ffffffff8113b100&gt;] find_lock_page+0x50/0x80
 [&lt;ffffffff8113b24f&gt;] find_or_create_page+0x3f/0xb0
 [&lt;ffffffffa06983a9&gt;] sync_node_pages+0x259/0x810 [f2fs]
 [&lt;ffffffffa068d874&gt;] write_checkpoint+0x1a4/0xce0 [f2fs]
 [&lt;ffffffffa0686b0c&gt;] f2fs_sync_fs+0x7c/0xd0 [f2fs]
 [&lt;ffffffffa067c813&gt;] f2fs_sync_file+0x143/0x5f0 [f2fs]
 [&lt;ffffffff811d301b&gt;] vfs_fsync_range+0x2b/0x40
 [&lt;ffffffff811d304c&gt;] vfs_fsync+0x1c/0x20
 [&lt;ffffffff811d3291&gt;] do_fsync+0x41/0x70
 [&lt;ffffffff811d32d3&gt;] SyS_fdatasync+0x13/0x20
 [&lt;ffffffff817094a2&gt;] system_call_fastpath+0x16/0x1b
 [&lt;ffffffffffffffff&gt;] 0xffffffffffffffff

The reason of this issue is:
CPU0:					CPU1:
 - f2fs_write_data_pages
					 - f2fs_sync_fs
					  - write_checkpoint
					   - block_operations
					    - f2fs_lock_all
					     - down_write(sbi-&gt;cp_rwsem)
  - lock_page(page)
  - f2fs_write_data_page
					    - sync_node_pages
					     - flush_inline_data
					      - pagecache_get_page(page, GFP_LOCK)
   - f2fs_lock_op
    - down_read(sbi-&gt;cp_rwsem)

This patch alters to use trylock_page in flush_inline_data to fix this ABBA
deadlock issue.

Signed-off-by: Chao Yu &lt;chao2.yu@samsung.com&gt;
Signed-off-by: Jaegeuk Kim &lt;jaegeuk@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>f2fs: fix incorrect upper bound when iterating inode mapping tree</title>
<updated>2016-02-26T01:27:03+00:00</updated>
<author>
<name>Chao Yu</name>
<email>chao2.yu@samsung.com</email>
</author>
<published>2016-02-24T09:20:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=80dd9c0e9db220697301e76b7b61f580ad9e8ecd'/>
<id>80dd9c0e9db220697301e76b7b61f580ad9e8ecd</id>
<content type='text'>
1. Inode mapping tree can index page in range of [0, ULONG_MAX], however,
in some places, f2fs only search or iterate page in ragne of [0, LONG_MAX],
result in miss hitting in page cache.

2. filemap_fdatawait_range accepts range parameters in unit of bytes, so
the max range it covers should be [0, LLONG_MAX], if we use [0, LONG_MAX]
as range for waiting on writeback, big number of pages will not be covered.

This patch corrects above two issues.

Signed-off-by: Chao Yu &lt;chao2.yu@samsung.com&gt;
Signed-off-by: Jaegeuk Kim &lt;jaegeuk@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
1. Inode mapping tree can index page in range of [0, ULONG_MAX], however,
in some places, f2fs only search or iterate page in ragne of [0, LONG_MAX],
result in miss hitting in page cache.

2. filemap_fdatawait_range accepts range parameters in unit of bytes, so
the max range it covers should be [0, LLONG_MAX], if we use [0, LONG_MAX]
as range for waiting on writeback, big number of pages will not be covered.

This patch corrects above two issues.

Signed-off-by: Chao Yu &lt;chao2.yu@samsung.com&gt;
Signed-off-by: Jaegeuk Kim &lt;jaegeuk@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>f2fs: trace old block address for CoWed page</title>
<updated>2016-02-23T05:40:02+00:00</updated>
<author>
<name>Chao Yu</name>
<email>chao2.yu@samsung.com</email>
</author>
<published>2016-02-22T10:36:38+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=7a9d75481b85d59204d76097d41a28db663a7a43'/>
<id>7a9d75481b85d59204d76097d41a28db663a7a43</id>
<content type='text'>
This patch enables to trace old block address of CoWed page for better
debugging.

f2fs_submit_page_mbio: dev = (1,0), ino = 1, page_index = 0x1d4f0, oldaddr = 0xfe8ab, newaddr = 0xfee90 rw = WRITE_SYNC, type = NODE
f2fs_submit_page_mbio: dev = (1,0), ino = 1, page_index = 0x1d4f8, oldaddr = 0xfe8b0, newaddr = 0xfee91 rw = WRITE_SYNC, type = NODE
f2fs_submit_page_mbio: dev = (1,0), ino = 1, page_index = 0x1d4fa, oldaddr = 0xfe8ae, newaddr = 0xfee92 rw = WRITE_SYNC, type = NODE

f2fs_submit_page_mbio: dev = (1,0), ino = 134824, page_index = 0x96, oldaddr = 0xf049b, newaddr = 0x2bbe rw = WRITE, type = DATA
f2fs_submit_page_mbio: dev = (1,0), ino = 134824, page_index = 0x97, oldaddr = 0xf049c, newaddr = 0x2bbf rw = WRITE, type = DATA
f2fs_submit_page_mbio: dev = (1,0), ino = 134824, page_index = 0x98, oldaddr = 0xf049d, newaddr = 0x2bc0 rw = WRITE, type = DATA

f2fs_submit_page_mbio: dev = (1,0), ino = 135260, page_index = 0x47, oldaddr = 0xffffffff, newaddr = 0xf2631 rw = WRITE, type = DATA
f2fs_submit_page_mbio: dev = (1,0), ino = 135260, page_index = 0x48, oldaddr = 0xffffffff, newaddr = 0xf2632 rw = WRITE, type = DATA
f2fs_submit_page_mbio: dev = (1,0), ino = 135260, page_index = 0x49, oldaddr = 0xffffffff, newaddr = 0xf2633 rw = WRITE, type = DATA

Signed-off-by: Chao Yu &lt;chao2.yu@samsung.com&gt;
Signed-off-by: Jaegeuk Kim &lt;jaegeuk@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This patch enables to trace old block address of CoWed page for better
debugging.

f2fs_submit_page_mbio: dev = (1,0), ino = 1, page_index = 0x1d4f0, oldaddr = 0xfe8ab, newaddr = 0xfee90 rw = WRITE_SYNC, type = NODE
f2fs_submit_page_mbio: dev = (1,0), ino = 1, page_index = 0x1d4f8, oldaddr = 0xfe8b0, newaddr = 0xfee91 rw = WRITE_SYNC, type = NODE
f2fs_submit_page_mbio: dev = (1,0), ino = 1, page_index = 0x1d4fa, oldaddr = 0xfe8ae, newaddr = 0xfee92 rw = WRITE_SYNC, type = NODE

f2fs_submit_page_mbio: dev = (1,0), ino = 134824, page_index = 0x96, oldaddr = 0xf049b, newaddr = 0x2bbe rw = WRITE, type = DATA
f2fs_submit_page_mbio: dev = (1,0), ino = 134824, page_index = 0x97, oldaddr = 0xf049c, newaddr = 0x2bbf rw = WRITE, type = DATA
f2fs_submit_page_mbio: dev = (1,0), ino = 134824, page_index = 0x98, oldaddr = 0xf049d, newaddr = 0x2bc0 rw = WRITE, type = DATA

f2fs_submit_page_mbio: dev = (1,0), ino = 135260, page_index = 0x47, oldaddr = 0xffffffff, newaddr = 0xf2631 rw = WRITE, type = DATA
f2fs_submit_page_mbio: dev = (1,0), ino = 135260, page_index = 0x48, oldaddr = 0xffffffff, newaddr = 0xf2632 rw = WRITE, type = DATA
f2fs_submit_page_mbio: dev = (1,0), ino = 135260, page_index = 0x49, oldaddr = 0xffffffff, newaddr = 0xf2633 rw = WRITE, type = DATA

Signed-off-by: Chao Yu &lt;chao2.yu@samsung.com&gt;
Signed-off-by: Jaegeuk Kim &lt;jaegeuk@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>f2fs: try to flush inode after merging inline data</title>
<updated>2016-02-23T05:40:02+00:00</updated>
<author>
<name>Chao Yu</name>
<email>chao2.yu@samsung.com</email>
</author>
<published>2016-02-22T10:35:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=9a4cbc9e5318608740e3e3e44d4d565e19ad5e74'/>
<id>9a4cbc9e5318608740e3e3e44d4d565e19ad5e74</id>
<content type='text'>
When flushing node pages, if current node page is an inline inode page, we
will try to merge inline data from data page into inline inode page, then
skip flushing current node page, it will decrease the number of nodes to
be flushed in batch in this round, which may lead to worse performance.

This patch gives a chance to flush just merged inline inode pages for
performance.

Signed-off-by: Chao Yu &lt;chao2.yu@samsung.com&gt;
Signed-off-by: Jaegeuk Kim &lt;jaegeuk@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When flushing node pages, if current node page is an inline inode page, we
will try to merge inline data from data page into inline inode page, then
skip flushing current node page, it will decrease the number of nodes to
be flushed in batch in this round, which may lead to worse performance.

This patch gives a chance to flush just merged inline inode pages for
performance.

Signed-off-by: Chao Yu &lt;chao2.yu@samsung.com&gt;
Signed-off-by: Jaegeuk Kim &lt;jaegeuk@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>f2fs: reorder nat cache lock in cache_nat_entry</title>
<updated>2016-02-23T05:39:55+00:00</updated>
<author>
<name>Chao Yu</name>
<email>chao2.yu@samsung.com</email>
</author>
<published>2016-02-19T10:12:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=1515aef0130845c6a5c72a3710df362f79eb9fb1'/>
<id>1515aef0130845c6a5c72a3710df362f79eb9fb1</id>
<content type='text'>
When lookuping nat entry in cache_nat_entry, if we fail to hit nat cache,
we try to load nat entries a) from journal of current segment cache or b)
from NAT pages for updating, during the process, write lock of
nat_tree_lock will be held to avoid inconsistent condition in between
nid cache and nat cache caused by racing among nat entry shrinker,
checkpointer, nat entry updater.

But this way may cause low efficient when updating nat cache, because it
serializes accessing in journal cache or reading NAT pages.

Here, we reorder lock and update flow as below to enhance accessing
concurrency:

 - get_node_info
  - down_read(nat_tree_lock)
  - lookup nat cache --- hit -&gt; unlock &amp; return
  - lookup journal cache --- hit -&gt; unlock &amp; goto update
  - up_read(nat_tree_lock)
update:
  - down_write(nat_tree_lock)
  - cache_nat_entry
   - lookup nat cache --- nohit -&gt; update
  - up_write(nat_tree_lock)

Signed-off-by: Chao Yu &lt;chao2.yu@samsung.com&gt;
Signed-off-by: Jaegeuk Kim &lt;jaegeuk@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When lookuping nat entry in cache_nat_entry, if we fail to hit nat cache,
we try to load nat entries a) from journal of current segment cache or b)
from NAT pages for updating, during the process, write lock of
nat_tree_lock will be held to avoid inconsistent condition in between
nid cache and nat cache caused by racing among nat entry shrinker,
checkpointer, nat entry updater.

But this way may cause low efficient when updating nat cache, because it
serializes accessing in journal cache or reading NAT pages.

Here, we reorder lock and update flow as below to enhance accessing
concurrency:

 - get_node_info
  - down_read(nat_tree_lock)
  - lookup nat cache --- hit -&gt; unlock &amp; return
  - lookup journal cache --- hit -&gt; unlock &amp; goto update
  - up_read(nat_tree_lock)
update:
  - down_write(nat_tree_lock)
  - cache_nat_entry
   - lookup nat cache --- nohit -&gt; update
  - up_write(nat_tree_lock)

Signed-off-by: Chao Yu &lt;chao2.yu@samsung.com&gt;
Signed-off-by: Jaegeuk Kim &lt;jaegeuk@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>f2fs: split journal cache from curseg cache</title>
<updated>2016-02-23T05:39:54+00:00</updated>
<author>
<name>Chao Yu</name>
<email>chao2.yu@samsung.com</email>
</author>
<published>2016-02-19T10:08:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=b7ad7512b84b26f1c0ec823647a387627c138d32'/>
<id>b7ad7512b84b26f1c0ec823647a387627c138d32</id>
<content type='text'>
In curseg cache, f2fs caches two different parts:
 - datas of current summay block, i.e. summary entries, footer info.
 - journal info, i.e. sparse nat/sit entries or io stat info.

With this approach, 1) it may cause higher lock contention when we access
or update both of the parts of cache since we use the same mutex lock
curseg_mutex to protect the cache. 2) current summary block with last
journal info will be writebacked into device as a normal summary block
when flushing, however, we treat journal info as valid one only in current
summary, so most normal summary blocks contain junk journal data, it wastes
remaining space of summary block.

So, in order to fix above issues, we split curseg cache into two parts:
a) current summary block, protected by original mutex lock curseg_mutex
b) journal cache, protected by newly introduced r/w semaphore journal_rwsem

When loading curseg cache during -&gt;mount, we store summary info and
journal info into different caches; When doing checkpoint, we combine
datas of two cache into current summary block for persisting.

Signed-off-by: Chao Yu &lt;chao2.yu@samsung.com&gt;
Signed-off-by: Jaegeuk Kim &lt;jaegeuk@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
In curseg cache, f2fs caches two different parts:
 - datas of current summay block, i.e. summary entries, footer info.
 - journal info, i.e. sparse nat/sit entries or io stat info.

With this approach, 1) it may cause higher lock contention when we access
or update both of the parts of cache since we use the same mutex lock
curseg_mutex to protect the cache. 2) current summary block with last
journal info will be writebacked into device as a normal summary block
when flushing, however, we treat journal info as valid one only in current
summary, so most normal summary blocks contain junk journal data, it wastes
remaining space of summary block.

So, in order to fix above issues, we split curseg cache into two parts:
a) current summary block, protected by original mutex lock curseg_mutex
b) journal cache, protected by newly introduced r/w semaphore journal_rwsem

When loading curseg cache during -&gt;mount, we store summary info and
journal info into different caches; When doing checkpoint, we combine
datas of two cache into current summary block for persisting.

Signed-off-by: Chao Yu &lt;chao2.yu@samsung.com&gt;
Signed-off-by: Jaegeuk Kim &lt;jaegeuk@kernel.org&gt;
</pre>
</div>
</content>
</entry>
</feed>
