linux/fs/nfs
Dave Kleikamp ad3cba223a nfs: don't dirty kernel pages read by direct-io
When we use direct_IO with an NFS backing store, we can trigger a
WARNING in __set_page_dirty(), as below, since we're dirtying the page
unnecessarily in nfs_direct_read_completion().

To fix, replicate the logic in commit 53cbf3b157 ("fs: direct-io:
don't dirtying pages for ITER_BVEC/ITER_KVEC direct read").

Other filesystems that implement direct_IO handle this; most use
blockdev_direct_IO(). ceph and cifs have similar logic.

mount 127.0.0.1:/export /nfs
dd if=/dev/zero of=/nfs/image bs=1M count=200
losetup --direct-io=on -f /nfs/image
mkfs.btrfs /dev/loop0
mount -t btrfs /dev/loop0 /mnt/

kernel: WARNING: CPU: 0 PID: 8067 at fs/buffer.c:580 __set_page_dirty+0xaf/0xd0
kernel: Modules linked in: loop(E) nfsv3(E) rpcsec_gss_krb5(E) nfsv4(E) dns_resolver(E) nfs(E) fscache(E) nfsd(E) auth_rpcgss(E) nfs_acl(E) lockd(E) grace(E) fuse(E) tun(E) ip6t_rpfilter(E) ipt_REJECT(E) nf_
kernel:  snd_seq(E) snd_seq_device(E) snd_pcm(E) video(E) snd_timer(E) snd(E) soundcore(E) ip_tables(E) xfs(E) libcrc32c(E) sd_mod(E) sr_mod(E) cdrom(E) ata_generic(E) pata_acpi(E) crc32c_intel(E) ahci(E) li
kernel: CPU: 0 PID: 8067 Comm: kworker/0:2 Tainted: G            E     4.20.0-rc1.master.20181111.ol7.x86_64 #1
kernel: Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
kernel: Workqueue: nfsiod rpc_async_release [sunrpc]
kernel: RIP: 0010:__set_page_dirty+0xaf/0xd0
kernel: Code: c3 48 8b 02 f6 c4 04 74 d4 48 89 df e8 ba 05 f7 ff 48 89 c6 eb cb 48 8b 43 08 a8 01 75 1f 48 89 d8 48 8b 00 a8 04 74 02 eb 87 <0f> 0b eb 83 48 83 e8 01 eb 9f 48 83 ea 01 0f 1f 00 eb 8b 48 83 e8
kernel: RSP: 0000:ffffc1c8825b7d78 EFLAGS: 00013046
kernel: RAX: 000fffffc0020089 RBX: fffff2b603308b80 RCX: 0000000000000001
kernel: RDX: 0000000000000001 RSI: ffff9d11478115c8 RDI: ffff9d11478115d0
kernel: RBP: ffffc1c8825b7da0 R08: 0000646f6973666e R09: 8080808080808080
kernel: R10: 0000000000000001 R11: 0000000000000000 R12: ffff9d11478115d0
kernel: R13: ffff9d11478115c8 R14: 0000000000003246 R15: 0000000000000001
kernel: FS:  0000000000000000(0000) GS:ffff9d115ba00000(0000) knlGS:0000000000000000
kernel: CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
kernel: CR2: 00007f408686f640 CR3: 0000000104d8e004 CR4: 00000000000606f0
kernel: DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
kernel: DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
kernel: Call Trace:
kernel:  __set_page_dirty_buffers+0xb6/0x110
kernel:  set_page_dirty+0x52/0xb0
kernel:  nfs_direct_read_completion+0xc4/0x120 [nfs]
kernel:  nfs_pgio_release+0x10/0x20 [nfs]
kernel:  rpc_free_task+0x30/0x70 [sunrpc]
kernel:  rpc_async_release+0x12/0x20 [sunrpc]
kernel:  process_one_work+0x174/0x390
kernel:  worker_thread+0x4f/0x3e0
kernel:  kthread+0x102/0x140
kernel:  ? drain_workqueue+0x130/0x130
kernel:  ? kthread_stop+0x110/0x110
kernel:  ret_from_fork+0x35/0x40
kernel: ---[ end trace 01341980905412c9 ]---

Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>

[forward-ported to v4.20]
Signed-off-by: Calum Mackay <calum.mackay@oracle.com>
Reviewed-by: Dave Kleikamp <dave.kleikamp@oracle.com>
Reviewed-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2018-12-02 09:43:56 -05:00
..
blocklayout page cache: Convert hole search to XArray 2018-10-21 10:46:33 -04:00
filelayout pNFS: Don't allocate more pages than we need to fit a layoutget response 2018-09-30 15:35:16 -04:00
flexfilelayout flexfiles: enforce per-mirror stateid only for v4 DSes 2018-12-02 09:43:56 -05:00
cache_lib.c
cache_lib.h
callback_proc.c NFSv4.2 copy do not allocate memory under the lock 2018-11-22 13:54:46 -05:00
callback_xdr.c NFS CB_OFFLOAD xdr 2018-08-09 12:56:38 -04:00
callback.c
callback.h NFS CB_OFFLOAD xdr 2018-08-09 12:56:38 -04:00
client.c NFS add support for asynchronous COPY 2018-08-09 12:56:39 -04:00
delegation.c NFSv4: Fix an Oops during delegation callbacks 2018-11-13 17:15:17 -05:00
delegation.h NFSv4: Fix the nfs_inode_set_delegation() arguments 2018-04-10 16:06:22 -04:00
dir.c NFSv4: Fix lookup revalidate of regular files 2018-09-30 15:35:18 -04:00
direct.c nfs: don't dirty kernel pages read by direct-io 2018-12-02 09:43:56 -05:00
dns_resolve.c NFS: Fix up a typo in nfs_dns_ent_put 2018-10-29 16:58:04 -04:00
dns_resolve.h
export.c NFS: Pass the inode down to the getattr() callback 2018-06-04 12:07:07 -04:00
file.c fs: nfs: Adding new return type vm_fault_t 2018-07-30 13:19:40 -04:00
fscache-index.c vfs: change inode times to use struct timespec64 2018-06-05 16:57:31 -07:00
fscache.c vfs: change inode times to use struct timespec64 2018-06-05 16:57:31 -07:00
fscache.h fscache: Pass object size in rather than calling back for it 2018-04-06 14:05:14 +01:00
getroot.c
inode.c NFS: Convert lookups of the open context to RCU 2018-09-30 15:35:17 -04:00
internal.h
io.c
iostat.h
Kconfig
Makefile
mount_clnt.c
namespace.c
netns.h
nfs2super.c
nfs2xdr.c vfs: change inode times to use struct timespec64 2018-06-05 16:57:31 -07:00
nfs3_fs.h
nfs3acl.c NFS: Mark expected switch fall-throughs 2018-08-08 16:50:02 -04:00
nfs3client.c
nfs3proc.c NFSv3: Improve NFSv3 performance when server returns no post-op attributes 2018-09-30 15:35:17 -04:00
nfs3super.c
nfs3xdr.c NFSv3: Improve NFSv3 performance when server returns no post-op attributes 2018-09-30 15:35:17 -04:00
nfs4_fs.h NFSv4: Fix a NFSv4 state manager deadlock 2018-11-19 20:11:45 -05:00
nfs4client.c NFSv4.1: Fix the r/wsize checking 2018-09-30 15:35:17 -04:00
nfs4file.c vfs: make remap_file_range functions take and return bytes completed 2018-10-30 10:41:49 +11:00
nfs4getroot.c
nfs4idmap.c NFS: Mark expected switch fall-throughs 2018-08-08 16:50:02 -04:00
nfs4idmap.h
nfs4namespace.c
nfs4proc.c NFS: fix spelling mistake, EACCESS -> EACCES 2018-11-01 14:07:06 -04:00
nfs4renewd.c
nfs4session.c
nfs4session.h
nfs4state.c NFSv4: Fix a NFSv4 state manager deadlock 2018-11-19 20:11:45 -05:00
nfs4super.c
nfs4sysctl.c
nfs4trace.c
nfs4trace.h NFSv4: Fix a tracepoint Oops in initiate_file_draining() 2018-09-14 16:24:08 -04:00
nfs4xdr.c NFS: change sign of nfs_fh length 2018-10-23 12:22:21 -04:00
nfs42.h
nfs42proc.c NFSv4.2 copy do not allocate memory under the lock 2018-11-22 13:54:46 -05:00
nfs42xdr.c NFS add support for asynchronous COPY 2018-08-09 12:56:39 -04:00
nfs.h
nfsroot.c
nfstrace.c
nfstrace.h
pagelist.c nfs: remove redundant call to nfs_context_set_write_error() 2018-10-18 17:20:57 -04:00
pnfs_dev.c
pnfs_nfs.c NFSv4: Fix locking in pnfs_generic_recover_commit_reqs 2018-08-15 11:43:38 -04:00
pnfs.c NFS: Convert lookups of the open context to RCU 2018-09-30 15:35:17 -04:00
pnfs.h pNFS: Don't allocate more pages than we need to fit a layoutget response 2018-09-30 15:35:16 -04:00
proc.c NFS: Pass the inode down to the getattr() callback 2018-06-04 12:07:07 -04:00
read.c NFS: Remove private spinlock in struct nfs_pgio_header 2018-09-30 15:35:17 -04:00
super.c NFS: silence a harmless uninitialized variable warning 2018-07-31 12:53:40 -04:00
symlink.c
sysctl.c
unlink.c NFS: Fix up sillyrename() 2018-05-31 15:02:16 -04:00
write.c NFS: Ensure we immediately start writeback on rescheduled writes 2018-07-26 16:25:25 -04:00