aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorBenny Halevy <bhalevy@tonian.com>2013-02-24 09:55:57 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2013-02-24 10:07:36 -0500
commit78f33277f96430ea001c39e952f6b8200b2ab850 (patch)
tree4aebf68f67ac716d0d63bb3b025fbf394ac8bb88 /fs/nfs
parenta9a6b52ee1baa865283a91eb8d443ee91adfca56 (diff)
pnfs: fix resend_to_mds for directio
Pass the directio request on pageio_init to clean up the API. Percolate pg_dreq from original nfs_pageio_descriptor to the pnfs_{read,write}_done_resend_to_mds and use it on respective call to nfs_pageio_init_{read,write} on the newly created nfs_pageio_descriptor. Reproduced by command: mount -o vers=4.1 server:/ /mnt dd bs=128k count=8 if=/dev/zero of=/mnt/dd.out oflag=direct BUG: unable to handle kernel NULL pointer dereference at 0000000000000028 IP: [<ffffffffa021a3a8>] atomic_inc+0x4/0x9 [nfs] PGD 34786067 PUD 34794067 PMD 0 Oops: 0002 [#1] SMP Modules linked in: nfs_layout_nfsv41_files nfsv4 nfs nfsd lockd nfs_acl auth_rpcgss exportfs sunrpc btrfs zlib_deflate libcrc32c ipv6 autofs4 CPU 1 Pid: 259, comm: kworker/1:2 Not tainted 3.8.0-rc6 #2 Bochs Bochs RIP: 0010:[<ffffffffa021a3a8>] [<ffffffffa021a3a8>] atomic_inc+0x4/0x9 [nfs] RSP: 0018:ffff880038f8fa68 EFLAGS: 00010206 RAX: ffffffffa021a6a9 RBX: ffff880038f8fb48 RCX: 00000000000a0000 RDX: ffffffffa021e616 RSI: ffff8800385e9a40 RDI: 0000000000000028 RBP: ffff880038f8fa68 R08: ffffffff81ad6720 R09: ffff8800385e9510 R10: ffffffffa0228450 R11: ffff880038e87418 R12: ffff8800385e9a40 R13: ffff8800385e9a70 R14: ffff880038f8fb38 R15: ffffffffa0148878 FS: 0000000000000000(0000) GS:ffff88003e400000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 0000000000000028 CR3: 0000000034789000 CR4: 00000000000006e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process kworker/1:2 (pid: 259, threadinfo ffff880038f8e000, task ffff880038302480) Stack: ffff880038f8fa78 ffffffffa021a6bf ffff880038f8fa88 ffffffffa021bb82 ffff880038f8fae8 ffffffffa021f454 ffff880038f8fae8 ffffffff8109689d ffff880038f8fab8 ffffffff00000006 0000000000000000 ffff880038f8fb48 Call Trace: [<ffffffffa021a6bf>] nfs_direct_pgio_init+0x16/0x18 [nfs] [<ffffffffa021bb82>] nfs_pgheader_init+0x6a/0x6c [nfs] [<ffffffffa021f454>] nfs_generic_pg_writepages+0x51/0xf8 [nfs] [<ffffffff8109689d>] ? mark_held_locks+0x71/0x99 [<ffffffffa0148878>] ? rpc_release_resources_task+0x37/0x37 [sunrpc] [<ffffffffa021bc25>] nfs_pageio_doio+0x1a/0x43 [nfs] [<ffffffffa021be7c>] nfs_pageio_complete+0x16/0x2c [nfs] [<ffffffffa02608be>] pnfs_write_done_resend_to_mds+0x95/0xc5 [nfsv4] [<ffffffffa0148878>] ? rpc_release_resources_task+0x37/0x37 [sunrpc] [<ffffffffa028e27f>] filelayout_reset_write+0x8c/0x99 [nfs_layout_nfsv41_files] [<ffffffffa028e5f9>] filelayout_write_done_cb+0x4d/0xc1 [nfs_layout_nfsv41_files] [<ffffffffa024587a>] nfs4_write_done+0x36/0x49 [nfsv4] [<ffffffffa021f996>] nfs_writeback_done+0x53/0x1cc [nfs] [<ffffffffa021fb1d>] nfs_writeback_done_common+0xe/0x10 [nfs] [<ffffffffa028e03d>] filelayout_write_call_done+0x28/0x2a [nfs_layout_nfsv41_files] [<ffffffffa01488a1>] rpc_exit_task+0x29/0x87 [sunrpc] [<ffffffffa014a0c9>] __rpc_execute+0x11d/0x3cc [sunrpc] [<ffffffff810969dc>] ? trace_hardirqs_on_caller+0x117/0x173 [<ffffffffa014a39f>] rpc_async_schedule+0x27/0x32 [sunrpc] [<ffffffffa014a378>] ? __rpc_execute+0x3cc/0x3cc [sunrpc] [<ffffffff8105f8c1>] process_one_work+0x226/0x422 [<ffffffff8105f7f4>] ? process_one_work+0x159/0x422 [<ffffffff81094757>] ? lock_acquired+0x210/0x249 [<ffffffffa014a378>] ? __rpc_execute+0x3cc/0x3cc [sunrpc] [<ffffffff810600d8>] worker_thread+0x126/0x1c4 [<ffffffff8105ffb2>] ? manage_workers+0x240/0x240 [<ffffffff81064ef8>] kthread+0xb1/0xb9 [<ffffffff81064e47>] ? __kthread_parkme+0x65/0x65 [<ffffffff815206ec>] ret_from_fork+0x7c/0xb0 [<ffffffff81064e47>] ? __kthread_parkme+0x65/0x65 Code: 00 83 38 02 74 12 48 81 4b 50 00 00 01 00 c7 83 60 07 00 00 01 00 00 00 48 89 df e8 55 fe ff ff 5b 41 5c 5d c3 66 90 55 48 89 e5 <f0> ff 07 5d c3 55 48 89 e5 f0 ff 0f 0f 94 c0 84 c0 0f 95 c0 0f RIP [<ffffffffa021a3a8>] atomic_inc+0x4/0x9 [nfs] RSP <ffff880038f8fa68> CR2: 0000000000000028 Signed-off-by: Benny Halevy <bhalevy@tonian.com> Cc: stable@kernel.org [>= 3.6] Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/nfs4filelayout.c6
-rw-r--r--fs/nfs/pnfs.c14
-rw-r--r--fs/nfs/pnfs.h6
3 files changed, 18 insertions, 8 deletions
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index 194c48410336..49eeb044c109 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -99,7 +99,8 @@ static void filelayout_reset_write(struct nfs_write_data *data)
99 99
100 task->tk_status = pnfs_write_done_resend_to_mds(hdr->inode, 100 task->tk_status = pnfs_write_done_resend_to_mds(hdr->inode,
101 &hdr->pages, 101 &hdr->pages,
102 hdr->completion_ops); 102 hdr->completion_ops,
103 hdr->dreq);
103 } 104 }
104} 105}
105 106
@@ -119,7 +120,8 @@ static void filelayout_reset_read(struct nfs_read_data *data)
119 120
120 task->tk_status = pnfs_read_done_resend_to_mds(hdr->inode, 121 task->tk_status = pnfs_read_done_resend_to_mds(hdr->inode,
121 &hdr->pages, 122 &hdr->pages,
122 hdr->completion_ops); 123 hdr->completion_ops,
124 hdr->dreq);
123 } 125 }
124} 126}
125 127
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 6be70f622b62..97767c8683f9 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1422,13 +1422,15 @@ EXPORT_SYMBOL_GPL(pnfs_generic_pg_test);
1422 1422
1423int pnfs_write_done_resend_to_mds(struct inode *inode, 1423int pnfs_write_done_resend_to_mds(struct inode *inode,
1424 struct list_head *head, 1424 struct list_head *head,
1425 const struct nfs_pgio_completion_ops *compl_ops) 1425 const struct nfs_pgio_completion_ops *compl_ops,
1426 struct nfs_direct_req *dreq)
1426{ 1427{
1427 struct nfs_pageio_descriptor pgio; 1428 struct nfs_pageio_descriptor pgio;
1428 LIST_HEAD(failed); 1429 LIST_HEAD(failed);
1429 1430
1430 /* Resend all requests through the MDS */ 1431 /* Resend all requests through the MDS */
1431 nfs_pageio_init_write(&pgio, inode, FLUSH_STABLE, compl_ops); 1432 nfs_pageio_init_write(&pgio, inode, FLUSH_STABLE, compl_ops);
1433 pgio.pg_dreq = dreq;
1432 while (!list_empty(head)) { 1434 while (!list_empty(head)) {
1433 struct nfs_page *req = nfs_list_entry(head->next); 1435 struct nfs_page *req = nfs_list_entry(head->next);
1434 1436
@@ -1463,7 +1465,8 @@ static void pnfs_ld_handle_write_error(struct nfs_write_data *data)
1463 if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) 1465 if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags))
1464 data->task.tk_status = pnfs_write_done_resend_to_mds(hdr->inode, 1466 data->task.tk_status = pnfs_write_done_resend_to_mds(hdr->inode,
1465 &hdr->pages, 1467 &hdr->pages,
1466 hdr->completion_ops); 1468 hdr->completion_ops,
1469 hdr->dreq);
1467} 1470}
1468 1471
1469/* 1472/*
@@ -1578,13 +1581,15 @@ EXPORT_SYMBOL_GPL(pnfs_generic_pg_writepages);
1578 1581
1579int pnfs_read_done_resend_to_mds(struct inode *inode, 1582int pnfs_read_done_resend_to_mds(struct inode *inode,
1580 struct list_head *head, 1583 struct list_head *head,
1581 const struct nfs_pgio_completion_ops *compl_ops) 1584 const struct nfs_pgio_completion_ops *compl_ops,
1585 struct nfs_direct_req *dreq)
1582{ 1586{
1583 struct nfs_pageio_descriptor pgio; 1587 struct nfs_pageio_descriptor pgio;
1584 LIST_HEAD(failed); 1588 LIST_HEAD(failed);
1585 1589
1586 /* Resend all requests through the MDS */ 1590 /* Resend all requests through the MDS */
1587 nfs_pageio_init_read(&pgio, inode, compl_ops); 1591 nfs_pageio_init_read(&pgio, inode, compl_ops);
1592 pgio.pg_dreq = dreq;
1588 while (!list_empty(head)) { 1593 while (!list_empty(head)) {
1589 struct nfs_page *req = nfs_list_entry(head->next); 1594 struct nfs_page *req = nfs_list_entry(head->next);
1590 1595
@@ -1615,7 +1620,8 @@ static void pnfs_ld_handle_read_error(struct nfs_read_data *data)
1615 if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) 1620 if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags))
1616 data->task.tk_status = pnfs_read_done_resend_to_mds(hdr->inode, 1621 data->task.tk_status = pnfs_read_done_resend_to_mds(hdr->inode,
1617 &hdr->pages, 1622 &hdr->pages,
1618 hdr->completion_ops); 1623 hdr->completion_ops,
1624 hdr->dreq);
1619} 1625}
1620 1626
1621/* 1627/*
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index 97cb358bb882..94ba80417748 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -230,9 +230,11 @@ struct pnfs_layout_segment *pnfs_update_layout(struct inode *ino,
230 230
231void nfs4_deviceid_mark_client_invalid(struct nfs_client *clp); 231void nfs4_deviceid_mark_client_invalid(struct nfs_client *clp);
232int pnfs_read_done_resend_to_mds(struct inode *inode, struct list_head *head, 232int pnfs_read_done_resend_to_mds(struct inode *inode, struct list_head *head,
233 const struct nfs_pgio_completion_ops *compl_ops); 233 const struct nfs_pgio_completion_ops *compl_ops,
234 struct nfs_direct_req *dreq);
234int pnfs_write_done_resend_to_mds(struct inode *inode, struct list_head *head, 235int pnfs_write_done_resend_to_mds(struct inode *inode, struct list_head *head,
235 const struct nfs_pgio_completion_ops *compl_ops); 236 const struct nfs_pgio_completion_ops *compl_ops,
237 struct nfs_direct_req *dreq);
236struct nfs4_threshold *pnfs_mdsthreshold_alloc(void); 238struct nfs4_threshold *pnfs_mdsthreshold_alloc(void);
237 239
238/* nfs4_deviceid_flags */ 240/* nfs4_deviceid_flags */