Skip to content

Commit a47970f

Browse files
westonandrosadamsonTrond Myklebust
authored and
Trond Myklebust
committed
NFSv4.1: Hold reference to layout hdr in layoutget
This fixes an oops where a LAYOUTGET is in still in the rpciod queue, but the requesting processes has been killed. Without this, killing the process does the final pnfs_put_layout_hdr() and sets NFS_I(inode)->layout to NULL while the LAYOUTGET rpc task still references it. Example oops: BUG: unable to handle kernel NULL pointer dereference at 0000000000000080 IP: [<ffffffffa01bd586>] pnfs_choose_layoutget_stateid+0x37/0xef [nfsv4] PGD 7365b067 PUD 7365d067 PMD 0 Oops: 0000 [#1] SMP DEBUG_PAGEALLOC Modules linked in: nfs_layout_nfsv41_files nfsv4 auth_rpcgss nfs lockd sunrpc ipt_MASQUERADE ip6table_mangle ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 iptable_nat nf_nat_ipv4 nf_nat iptable_mangle ip6table_filter ip6_tables ppdev e1000 i2c_piix4 i2c_core shpchp parport_pc parport crc32c_intel aesni_intel xts aes_x86_64 lrw gf128mul ablk_helper cryptd mptspi scsi_transport_spi mptscsih mptbase floppy autofs4 CPU 0 Pid: 27, comm: kworker/0:1 Not tainted 3.8.0-dros_cthon2013+ raspberrypi#4 VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform RIP: 0010:[<ffffffffa01bd586>] [<ffffffffa01bd586>] pnfs_choose_layoutget_stateid+0x37/0xef [nfsv4] RSP: 0018:ffff88007b0c1c88 EFLAGS: 00010246 RAX: ffff88006ed36678 RBX: 0000000000000000 RCX: 0000000ea877e3bc RDX: ffff88007a729da8 RSI: 0000000000000000 RDI: ffff88007a72b958 RBP: ffff88007b0c1ca8 R08: 0000000000000002 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: ffff88007a72b958 R13: ffff88007a729da8 R14: 0000000000000000 R15: ffffffffa011077e FS: 0000000000000000(0000) GS:ffff88007f600000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000080 CR3: 00000000735f8000 CR4: 00000000001407f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process kworker/0:1 (pid: 27, threadinfo ffff88007b0c0000, task ffff88007c2fa0c0) Stack: ffff88006fc05388 ffff88007a72b908 ffff88007b240900 ffff88006fc05388 ffff88007b0c1cd8 ffffffffa01a2170 ffff88007b240900 ffff88007b240900 ffff88007b240970 ffffffffa011077e ffff88007b0c1ce8 ffffffffa0110791 Call Trace: [<ffffffffa01a2170>] nfs4_layoutget_prepare+0x7b/0x92 [nfsv4] [<ffffffffa011077e>] ? __rpc_atrun+0x15/0x15 [sunrpc] [<ffffffffa0110791>] rpc_prepare_task+0x13/0x15 [sunrpc] Reported-by: Tigran Mkrtchyan <[email protected]> Signed-off-by: Weston Andros Adamson <[email protected]> Cc: [email protected] Signed-off-by: Trond Myklebust <[email protected]>
1 parent 78f3327 commit a47970f

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

fs/nfs/nfs4proc.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6129,11 +6129,13 @@ static struct page **nfs4_alloc_pages(size_t size, gfp_t gfp_flags)
61296129
static void nfs4_layoutget_release(void *calldata)
61306130
{
61316131
struct nfs4_layoutget *lgp = calldata;
6132-
struct nfs_server *server = NFS_SERVER(lgp->args.inode);
6132+
struct inode *inode = lgp->args.inode;
6133+
struct nfs_server *server = NFS_SERVER(inode);
61336134
size_t max_pages = max_response_pages(server);
61346135

61356136
dprintk("--> %s\n", __func__);
61366137
nfs4_free_pages(lgp->args.layout.pages, max_pages);
6138+
pnfs_put_layout_hdr(NFS_I(inode)->layout);
61376139
put_nfs_open_context(lgp->args.ctx);
61386140
kfree(calldata);
61396141
dprintk("<-- %s\n", __func__);
@@ -6148,7 +6150,8 @@ static const struct rpc_call_ops nfs4_layoutget_call_ops = {
61486150
struct pnfs_layout_segment *
61496151
nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
61506152
{
6151-
struct nfs_server *server = NFS_SERVER(lgp->args.inode);
6153+
struct inode *inode = lgp->args.inode;
6154+
struct nfs_server *server = NFS_SERVER(inode);
61526155
size_t max_pages = max_response_pages(server);
61536156
struct rpc_task *task;
61546157
struct rpc_message msg = {
@@ -6178,6 +6181,10 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
61786181
lgp->res.layoutp = &lgp->args.layout;
61796182
lgp->res.seq_res.sr_slot = NULL;
61806183
nfs41_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0);
6184+
6185+
/* nfs4_layoutget_release calls pnfs_put_layout_hdr */
6186+
pnfs_get_layout_hdr(NFS_I(inode)->layout);
6187+
61816188
task = rpc_run_task(&task_setup_data);
61826189
if (IS_ERR(task))
61836190
return ERR_CAST(task);

0 commit comments

Comments
 (0)