Skip to content

Commit 6282adb

Browse files
author
Jaegeuk Kim
committed
f2fs: call set_page_dirty to attach i_wb for cgroup
The cgroup attaches inode->i_wb via mark_inode_dirty and when set_page_writeback is called, __inc_wb_stat() updates i_wb's stat. So, we need to explicitly call set_page_dirty->__mark_inode_dirty in prior to any writebacking pages. This patch should resolve the following kernel panic reported by Andreas Reis. https://bugzilla.kernel.org/show_bug.cgi?id=101801 --- Comment foss-for-synopsys-dwc-arc-processors#2 from Andreas Reis <andreas.reis@gmail.com> --- BUG: unable to handle kernel NULL pointer dereference at 00000000000000a8 IP: [<ffffffff8149deea>] __percpu_counter_add+0x1a/0x90 PGD 2951ff067 PUD 2df43f067 PMD 0 Oops: 0000 [foss-for-synopsys-dwc-arc-processors#1] PREEMPT SMP Modules linked in: CPU: 7 PID: 10356 Comm: gcc Tainted: G W 4.2.0-1-cu foss-for-synopsys-dwc-arc-processors#1 Hardware name: Gigabyte Technology Co., Ltd. G1.Sniper M5/G1.Sniper M5, BIOS T01 02/03/2015 task: ffff880295044f80 ti: ffff880295140000 task.ti: ffff880295140000 RIP: 0010:[<ffffffff8149deea>] [<ffffffff8149deea>] __percpu_counter_add+0x1a/0x90 RSP: 0018:ffff880295143ac8 EFLAGS: 00010082 RAX: 0000000000000003 RBX: ffffea000a526d40 RCX: 0000000000000001 RDX: 0000000000000020 RSI: 0000000000000001 RDI: 0000000000000088 RBP: ffff880295143ae8 R08: 0000000000000000 R09: ffff88008f69bb30 R10: 00000000fffffffa R11: 0000000000000000 R12: 0000000000000088 R13: 0000000000000001 R14: ffff88041d099000 R15: ffff880084a205d0 FS: 00007f8549374700(0000) GS:ffff88042f3c0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000000000000a8 CR3: 000000033e1d5000 CR4: 00000000001406e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Stack: 0000000000000000 ffffea000a526d40 ffff880084a20738 ffff880084a20750 ffff880295143b48 ffffffff811cc91e ffff880000000000 0000000000000296 0000000000000000 ffff880417090198 0000000000000000 ffffea000a526d40 Call Trace: [<ffffffff811cc91e>] __test_set_page_writeback+0xde/0x1d0 [<ffffffff813fee87>] do_write_data_page+0xe7/0x3a0 [<ffffffff813faeea>] gc_data_segment+0x5aa/0x640 [<ffffffff813fb0b8>] do_garbage_collect+0x138/0x150 [<ffffffff813fb3fe>] f2fs_gc+0x1be/0x3e0 [<ffffffff81405541>] f2fs_balance_fs+0x81/0x90 [<ffffffff813ee357>] f2fs_unlink+0x47/0x1d0 [<ffffffff81239329>] vfs_unlink+0x109/0x1b0 [<ffffffff8123e3d7>] do_unlinkat+0x287/0x2c0 [<ffffffff8123ebc6>] SyS_unlink+0x16/0x20 [<ffffffff81942e2e>] entry_SYSCALL_64_fastpath+0x12/0x71 Code: 41 5e 5d c3 0f 1f 00 66 2e 0f 1f 84 00 00 00 00 00 55 48 89 e5 41 55 49 89 f5 41 54 49 89 fc 53 48 83 ec 08 65 ff 05 e6 d9 b6 7e <48> 8b 47 20 48 63 ca 65 8b 18 48 63 db 48 01 f3 48 39 cb 7d 0a RIP [<ffffffff8149deea>] __percpu_counter_add+0x1a/0x90 RSP <ffff880295143ac8> CR2: 00000000000000a8 ---[ end trace 5132449a58ed93a3 ]--- note: gcc[10356] exited with preempt_count 2 Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
1 parent 548aeda commit 6282adb

File tree

5 files changed

+13
-6
lines changed

5 files changed

+13
-6
lines changed

fs/f2fs/data.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2072,8 +2072,6 @@ static int f2fs_set_data_page_dirty(struct page *page)
20722072
return 1;
20732073
}
20742074

2075-
mark_inode_dirty(inode);
2076-
20772075
if (!PageDirty(page)) {
20782076
__set_page_dirty_nobuffers(page);
20792077
update_dirty_page(inode, page);

fs/f2fs/file.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,12 +1331,13 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp)
13311331
if (ret)
13321332
return ret;
13331333

1334-
if (f2fs_is_atomic_file(inode))
1334+
if (f2fs_is_atomic_file(inode)) {
1335+
clear_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE);
13351336
commit_inmem_pages(inode, false);
1337+
}
13361338

13371339
ret = f2fs_sync_file(filp, 0, LONG_MAX, 0);
13381340
mnt_drop_write_file(filp);
1339-
clear_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE);
13401341
return ret;
13411342
}
13421343

@@ -1387,8 +1388,8 @@ static int f2fs_ioc_abort_volatile_write(struct file *filp)
13871388
f2fs_balance_fs(F2FS_I_SB(inode));
13881389

13891390
if (f2fs_is_atomic_file(inode)) {
1390-
commit_inmem_pages(inode, false);
13911391
clear_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE);
1392+
commit_inmem_pages(inode, false);
13921393
}
13931394

13941395
if (f2fs_is_volatile_file(inode))

fs/f2fs/gc.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,11 @@ static void move_encrypted_block(struct inode *inode, block_t bidx)
568568
if (unlikely(fio.encrypted_page->mapping != META_MAPPING(fio.sbi)))
569569
goto put_page_out;
570570

571+
set_page_dirty(fio.encrypted_page);
572+
f2fs_wait_on_page_writeback(fio.encrypted_page, META);
573+
if (clear_page_dirty_for_io(fio.encrypted_page))
574+
dec_page_count(fio.sbi, F2FS_DIRTY_META);
575+
571576
set_page_writeback(fio.encrypted_page);
572577

573578
/* allocate block address */
@@ -612,8 +617,8 @@ static void move_data_page(struct inode *inode, block_t bidx, int gc_type)
612617
.page = page,
613618
.encrypted_page = NULL,
614619
};
620+
set_page_dirty(page);
615621
f2fs_wait_on_page_writeback(page, DATA);
616-
617622
if (clear_page_dirty_for_io(page))
618623
inode_dec_dirty_pages(inode);
619624
set_cold_data(page);

fs/f2fs/inline.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page)
141141
kunmap_atomic(dst_addr);
142142
SetPageUptodate(page);
143143
no_update:
144+
set_page_dirty(page);
145+
144146
/* clear dirty state */
145147
dirty = clear_page_dirty_for_io(page);
146148

fs/f2fs/segment.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ void commit_inmem_pages(struct inode *inode, bool abort)
257257
if (!abort) {
258258
lock_page(cur->page);
259259
if (cur->page->mapping == inode->i_mapping) {
260+
set_page_dirty(cur->page);
260261
f2fs_wait_on_page_writeback(cur->page, DATA);
261262
if (clear_page_dirty_for_io(cur->page))
262263
inode_dec_dirty_pages(inode);

0 commit comments

Comments
 (0)