linux/fs/afs
David Howells 5a039c3227 afs: Make afs_write_begin() avoid writing to a page that's being stored
Make afs_write_begin() wait for a page that's marked PG_writeback because:

 (1) We need to avoid interference with the data being stored so that the
     data on the server ends up in a defined state.

 (2) page->private is used to track the window of dirty data within a page,
     but it's also used by the storage code to track what's being written,
     being cleared by the completion notification.  Ownership can't be
     relinquished by the storage code until completion because it a store
     fails, the data must be remarked dirty.

Tracing shows something like the following (edited):

 x86_64-linux-gn-15940 [1] afs_page_dirty: vn=ffff8800bef33800 9c75 begin 0-125
    kworker/u8:3-114   [2] afs_page_dirty: vn=ffff8800bef33800 9c75 store+ 0-125
 x86_64-linux-gn-15940 [1] afs_page_dirty: vn=ffff8800bef33800 9c75 begin 0-2052
    kworker/u8:3-114   [2] afs_page_dirty: vn=ffff8800bef33800 9c75 clear 0-2052
    kworker/u8:3-114   [2] afs_page_dirty: vn=ffff8800bef33800 9c75 store 0-0
    kworker/u8:3-114   [2] afs_page_dirty: vn=ffff8800bef33800 9c75 WARN 0-0

The clear (completion) corresponding to the store+ (store continuation from
a previous page) happens between the second begin (afs_write_begin) and the
store corresponding to that.  This results in the second store not seeing
any data to write back, leading to the following warning:

WARNING: CPU: 2 PID: 114 at ../fs/afs/write.c:403 afs_write_back_from_locked_page+0x19d/0x76c [kafs]
Modules linked in: kafs(E)
CPU: 2 PID: 114 Comm: kworker/u8:3 Tainted: G            E   4.14.0-fscache+ #242
Hardware name: ASUS All Series/H97-PLUS, BIOS 2306 10/09/2014
Workqueue: writeback wb_workfn (flush-afs-2)
task: ffff8800cad72600 task.stack: ffff8800cad44000
RIP: 0010:afs_write_back_from_locked_page+0x19d/0x76c [kafs]
RSP: 0018:ffff8800cad47aa0 EFLAGS: 00010246
RAX: 0000000000000001 RBX: ffff8800bef33a20 RCX: 0000000000000000
RDX: 000000000000000f RSI: ffffffff81c5d0e0 RDI: ffff8800cad72e78
RBP: ffff8800d31ea1e8 R08: ffff8800c1358000 R09: ffff8800ca00e400
R10: ffff8800cad47a38 R11: ffff8800c5d9e400 R12: 0000000000000000
R13: ffffea0002d9df00 R14: ffffffffa0023c1c R15: 0000000000007fdf
FS:  0000000000000000(0000) GS:ffff8800ca700000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f85ac6c4000 CR3: 0000000001c10001 CR4: 00000000001606e0
Call Trace:
 ? clear_page_dirty_for_io+0x23a/0x267
 afs_writepages_region+0x1be/0x286 [kafs]
 afs_writepages+0x60/0x127 [kafs]
 do_writepages+0x36/0x70
 __writeback_single_inode+0x12f/0x635
 writeback_sb_inodes+0x2cc/0x452
 __writeback_inodes_wb+0x68/0x9f
 wb_writeback+0x208/0x470
 ? wb_workfn+0x22b/0x565
 wb_workfn+0x22b/0x565
 ? worker_thread+0x230/0x2ac
 process_one_work+0x2cc/0x517
 ? worker_thread+0x230/0x2ac
 worker_thread+0x1d4/0x2ac
 ? rescuer_thread+0x29b/0x29b
 kthread+0x15d/0x165
 ? kthread_create_on_node+0x3f/0x3f
 ? call_usermodehelper_exec_async+0x118/0x11f
 ret_from_fork+0x24/0x30

Signed-off-by: David Howells <dhowells@redhat.com>
2017-11-24 10:56:51 +00:00
..
addr_list.c afs: Make use of the YFS service upgrade to fully support IPv6 2017-11-13 15:38:19 +00:00
afs_cm.h afs: support the CB.ProbeUuid RPC op 2008-04-29 08:06:26 -07:00
afs_fs.h afs: Overhaul volume and server record caching and fileserver rotation 2017-11-13 15:38:19 +00:00
afs_vl.h afs: Make use of the YFS service upgrade to fully support IPv6 2017-11-13 15:38:19 +00:00
afs.h afs: Overhaul permit caching 2017-11-13 15:38:18 +00:00
cache.c afs: Update the cache index structure 2017-11-13 15:38:17 +00:00
callback.c afs: Overhaul volume and server record caching and fileserver rotation 2017-11-13 15:38:19 +00:00
cell.c afs: Overhaul volume and server record caching and fileserver rotation 2017-11-13 15:38:19 +00:00
cmservice.c afs: Protect call->state changes against signals 2017-11-13 15:38:21 +00:00
dir.c afs: Introduce a file-private data record 2017-11-13 15:38:20 +00:00
file.c afs: Trace page dirty/clean 2017-11-13 15:38:21 +00:00
flock.c afs: Fix file locking 2017-11-17 10:06:13 +00:00
fsclient.c afs: Get rid of the afs_writeback record 2017-11-13 15:38:20 +00:00
inode.c afs: Get rid of the afs_writeback record 2017-11-13 15:38:20 +00:00
internal.h afs: Fix file locking 2017-11-17 10:06:13 +00:00
Kconfig fs/afs: remove depends on CONFIG_EXPERIMENTAL 2013-01-21 14:39:04 -08:00
main.c afs: Overhaul volume and server record caching and fileserver rotation 2017-11-13 15:38:19 +00:00
Makefile afs: Overhaul volume and server record caching and fileserver rotation 2017-11-13 15:38:19 +00:00
misc.c afs: Consolidate abort_to_error translators 2017-11-13 15:38:17 +00:00
mntpt.c afs: Add metadata xattrs 2017-07-09 14:40:12 -07:00
netdevices.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
proc.c afs: Overhaul volume and server record caching and fileserver rotation 2017-11-13 15:38:19 +00:00
rotate.c afs: Fix file locking 2017-11-17 10:06:13 +00:00
rxrpc.c afs: Protect call->state changes against signals 2017-11-13 15:38:21 +00:00
security.c afs: Fix file locking 2017-11-17 10:06:13 +00:00
server_list.c afs: Fix file locking 2017-11-17 10:06:13 +00:00
server.c afs: Make use of the YFS service upgrade to fully support IPv6 2017-11-13 15:38:19 +00:00
super.c afs: Get rid of the afs_writeback record 2017-11-13 15:38:20 +00:00
vlclient.c afs: Trace the initiation and completion of client calls 2017-11-13 15:38:19 +00:00
volume.c afs: Make use of the YFS service upgrade to fully support IPv6 2017-11-13 15:38:19 +00:00
write.c afs: Make afs_write_begin() avoid writing to a page that's being stored 2017-11-24 10:56:51 +00:00
xattr.c afs: Overhaul volume and server record caching and fileserver rotation 2017-11-13 15:38:19 +00:00