NFS: Introduce trace events triggered by page writeback errors
authorChuck Lever <chuck.lever@oracle.com>
Mon, 23 Dec 2019 15:28:33 +0000 (10:28 -0500)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Wed, 15 Jan 2020 15:54:31 +0000 (10:54 -0500)
Try to capture the reason for the writeback path tagging an error on
a page.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
fs/nfs/nfstrace.h
fs/nfs/write.c

index f64a33d2a1d15f36d258e8db1579f5ed3080a984..4d6eb1703943725506c81c757c316adac384348a 100644 (file)
@@ -989,6 +989,51 @@ TRACE_EVENT(nfs_writeback_done,
                )
 );
 
+DECLARE_EVENT_CLASS(nfs_page_error_class,
+               TP_PROTO(
+                       const struct nfs_page *req,
+                       int error
+               ),
+
+               TP_ARGS(req, error),
+
+               TP_STRUCT__entry(
+                       __field(const void *, req)
+                       __field(pgoff_t, index)
+                       __field(unsigned int, offset)
+                       __field(unsigned int, pgbase)
+                       __field(unsigned int, bytes)
+                       __field(int, error)
+               ),
+
+               TP_fast_assign(
+                       __entry->req = req;
+                       __entry->index = req->wb_index;
+                       __entry->offset = req->wb_offset;
+                       __entry->pgbase = req->wb_pgbase;
+                       __entry->bytes = req->wb_bytes;
+                       __entry->error = error;
+               ),
+
+               TP_printk(
+                       "req=%p index=%lu offset=%u pgbase=%u bytes=%u error=%d",
+                       __entry->req, __entry->index, __entry->offset,
+                       __entry->pgbase, __entry->bytes, __entry->error
+               )
+);
+
+#define DEFINE_NFS_PAGEERR_EVENT(name) \
+       DEFINE_EVENT(nfs_page_error_class, name, \
+                       TP_PROTO( \
+                               const struct nfs_page *req, \
+                               int error \
+                       ), \
+                       TP_ARGS(req, error))
+
+DEFINE_NFS_PAGEERR_EVENT(nfs_write_error);
+DEFINE_NFS_PAGEERR_EVENT(nfs_comp_error);
+DEFINE_NFS_PAGEERR_EVENT(nfs_commit_error);
+
 TRACE_EVENT(nfs_initiate_commit,
                TP_PROTO(
                        const struct nfs_commit_data *data
index 52cab65f91cf08460a926d45c1dddb40cc885a69..21787711e3524047ebd028c2c34e6bbb76e06f2d 100644 (file)
@@ -593,6 +593,7 @@ release_request:
 static void nfs_write_error(struct nfs_page *req, int error)
 {
        nfs_set_pageerror(page_file_mapping(req->wb_page));
+       trace_nfs_write_error(req, error);
        nfs_mapping_set_error(req->wb_page, error);
        nfs_inode_remove_request(req);
        nfs_end_page_writeback(req);
@@ -999,6 +1000,7 @@ static void nfs_write_completion(struct nfs_pgio_header *hdr)
                if (test_bit(NFS_IOHDR_ERROR, &hdr->flags) &&
                    (hdr->good_bytes < bytes)) {
                        nfs_set_pageerror(page_file_mapping(req->wb_page));
+                       trace_nfs_comp_error(req, hdr->error);
                        nfs_mapping_set_error(req->wb_page, hdr->error);
                        goto remove_req;
                }
@@ -1847,6 +1849,7 @@ static void nfs_commit_release_pages(struct nfs_commit_data *data)
                        (long long)req_offset(req));
                if (status < 0) {
                        if (req->wb_page) {
+                               trace_nfs_commit_error(req, status);
                                nfs_mapping_set_error(req->wb_page, status);
                                nfs_inode_remove_request(req);
                        }