From 176d1b96436dee996f5bd7b36429e6068a848478 Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Thu, 30 Jul 2015 18:49:55 -0400 Subject: [PATCH] staging/lustre/llite: Don't set page writeback on non-dirty page New writeback changes in 4.2-RC1 have exposed that we incorrectly set page_writeback on a page that is being written synchronously, which aside from this new crash (dereference of NULL inode->i_wb from set_page_writeback) likely threw off some related page statistics in the past. BUG: unable to handle kernel NULL pointer dereference at 0000000000000138 IP: [] __percpu_counter_add+0x1a/0x80 PGD 0 Oops: 0000 [#1] SMP DEBUG_PAGEALLOC Modules linked in: osc(C) lmv(C) fld(C) mgc(C) lustre(C) mdc(C) fid(C) lov(C) ksocklnd(C) ptlrpc(C) obdclass(C) lnet(C) libcfs(C) loop sha512_generic crc32 rpcsec_gss_krb5 microcode joydev i2c_piix4 acpi_cpufreq pcspkr nfsd syscopyarea sysfillrect sysimgblt drm_kms_helper ttm drm serio_raw virtio_blk [last unloaded: libcfs] CPU: 0 PID: 13328 Comm: cvs Tainted: G C 4.2.0-rc1-vm-nfs+ #30 Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 task: ffff8800cc98a400 ti: ffff8801157e8000 task.ti: ffff8801157e8000 RIP: 0010:[] [] __percpu_counter_add+0x1a/0x80 RSP: 0018:ffff8801157eb698 EFLAGS: 00010086 RAX: 0000000000000003 RBX: ffffea0002b91cc0 RCX: 000000000000001a RDX: 0000000000000020 RSI: 0000000000000001 RDI: 00000000000000e8 RBP: ffff8801157eb6b8 R08: 0000000000000001 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: 00000000000000e8 R13: 0000000000000001 R14: ffff8800673587a8 R15: ffff8800673589b0 FS: 00007f6718b89800(0000) GS:ffff88011f400000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000138 CR3: 000000009d51c000 CR4: 00000000000007f0 Stack: ffffffff811919e2 ffffea0002b91cc0 ffff880067358998 ffff880119419800 ffff8801157eb718 ffffffff81191a58 ffff8801157eb788 0000000000000282 ffff8800ce5ce920 0000000000000000 ffff8800a525af80 ffff880053f68f10 Call Trace: [] ? __test_set_page_writeback+0x72/0x240 [] __test_set_page_writeback+0xe8/0x240 [] vvp_page_prep_write+0x33/0xb0 [lustre] [] cl_page_invoke+0x57/0x90 [obdclass] [] cl_page_prep+0x2d/0x180 [obdclass] [] osc_io_submit+0x134/0x4a0 [osc] [] cl_io_submit_rw+0x53/0xb0 [obdclass] [] lov_io_submit+0x3a5/0x570 [lov] [] ? lockdep_init_map+0x5b/0x6d0 [] cl_io_submit_rw+0x53/0xb0 [obdclass] [] cl_io_submit_sync+0xed/0x1c0 [obdclass] [] vvp_page_sync_io.isra.15+0x4d/0x100 [lustre] [] ? cl_page_clip+0xff/0x130 [obdclass] [] vvp_io_commit_write+0x448/0x500 [lustre] [] cl_io_commit_write+0x9a/0x130 [obdclass] [] ll_commit_write+0xc2/0x230 [lustre] [] ll_write_end+0x2a/0x50 [lustre] [] generic_perform_write+0xfa/0x1b0 [] ? dentry_needs_remove_privs.part.16+0x1e/0x30 [] __generic_file_write_iter+0x190/0x1f0 [] generic_file_write_iter+0xea/0x1e0 [] vvp_io_write_start+0xa0/0x1e0 [lustre] [] cl_io_start+0x49/0x80 [obdclass] [] cl_io_loop+0x73/0xd0 [obdclass] [] ll_file_io_generic+0x45f/0x4b0 [lustre] [] ll_file_write_iter+0x6c/0xc0 [lustre] [] __vfs_write+0xaa/0xe0 [] vfs_write+0xa9/0x190 [] SyS_write+0x49/0xa0 [] entry_SYSCALL_64_fastpath+0x16/0x7a Code: 5b 41 5c 41 5d 41 5e 5d c3 0f 1f 84 00 00 00 00 00 55 48 89 e5 41 55 41 54 53 49 89 fc 49 89 f5 48 83 ec 08 65 ff 05 8e d1 bf 7e <48> 8b 47 50 48 63 ca 65 8b 18 48 63 db 48 01 f3 48 39 cb 7d 0a Signed-off-by: Jinshan Xiong Signed-off-by: Oleg Drokin Reviewed-on: http://review.whamcloud.com/15610 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6854 Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/lustre/llite/vvp_page.c | 27 ++++++++++++------- .../staging/lustre/lustre/obdclass/cl_page.c | 3 --- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/vvp_page.c b/drivers/staging/lustre/lustre/llite/vvp_page.c index 954ed08c6af2..a3cf5ad20c60 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_page.c +++ b/drivers/staging/lustre/lustre/llite/vvp_page.c @@ -227,11 +227,16 @@ static int vvp_page_prep_write(const struct lu_env *env, struct cl_io *unused) { struct page *vmpage = cl2vm_page(slice); + struct cl_page *pg = slice->cpl_page; LASSERT(PageLocked(vmpage)); LASSERT(!PageDirty(vmpage)); - set_page_writeback(vmpage); + /* ll_writepage path is not a sync write, so need to set page writeback + * flag */ + if (!pg->cp_sync_io) + set_page_writeback(vmpage); + vvp_write_pending(cl2ccc(slice->cpl_obj), cl2ccc_page(slice)); return 0; @@ -298,9 +303,6 @@ static void vvp_page_completion_write(const struct lu_env *env, struct cl_page *pg = slice->cpl_page; struct page *vmpage = cp->cpg_page; - LASSERT(ergo(pg->cp_sync_io != NULL, PageLocked(vmpage))); - LASSERT(PageWriteback(vmpage)); - CL_PAGE_HEADER(D_PAGE, env, pg, "completing WRITE with %d\n", ioret); /* @@ -316,14 +318,19 @@ static void vvp_page_completion_write(const struct lu_env *env, cp->cpg_write_queued = 0; vvp_write_complete(cl2ccc(slice->cpl_obj), cp); - /* - * Only mark the page error only when it's an async write because - * applications won't wait for IO to finish. - */ - if (pg->cp_sync_io == NULL) + if (pg->cp_sync_io != NULL) { + LASSERT(PageLocked(vmpage)); + LASSERT(!PageWriteback(vmpage)); + } else { + LASSERT(PageWriteback(vmpage)); + /* + * Only mark the page error only when it's an async write + * because applications won't wait for IO to finish. + */ vvp_vmpage_error(ccc_object_inode(pg->cp_obj), vmpage, ioret); - end_page_writeback(vmpage); + end_page_writeback(vmpage); + } } /** diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c index 0f3417159fc1..d5fb81f84cd4 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_page.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c @@ -1192,9 +1192,6 @@ int cl_page_prep(const struct lu_env *env, struct cl_io *io, if (result == 0) cl_page_io_start(env, pg, crt); - KLASSERT(ergo(crt == CRT_WRITE && pg->cp_type == CPT_CACHEABLE, - equi(result == 0, - PageWriteback(cl_page_vmpage(env, pg))))); CL_PAGE_HEADER(D_TRACE, env, pg, "%d %d\n", crt, result); return result; } -- 2.30.2