diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 145393188f6a..227cddc12983 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -329,6 +329,7 @@ int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc)
 	struct nfs_cache_array *array;
 	int status;
 
+	trace_nfs_readdir_search_array_enter(desc);
 	array = kmap(desc->page);
 
 	if (*desc->dir_cookie == 0)
@@ -342,6 +343,7 @@ int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc)
 		desc->page_index++;
 	}
 	kunmap(desc->page);
+	trace_nfs_readdir_search_array_exit(desc, status);
 	return status;
 }
 
@@ -762,6 +764,7 @@ int readdir_search_pagecache(nfs_readdir_descriptor_t *desc)
 {
 	int res;
 
+	trace_nfs_readdir_search_pagecache_enter(desc);
 	if (desc->page_index == 0) {
 		desc->current_index = 0;
 		desc->prev_index = 0;
@@ -770,6 +773,7 @@ int readdir_search_pagecache(nfs_readdir_descriptor_t *desc)
 	do {
 		res = find_and_lock_cache_page(desc);
 	} while (res == -EAGAIN);
+	trace_nfs_readdir_search_pagecache_exit(desc, res);
 	return res;
 }
 
@@ -835,8 +839,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc)
 	struct inode *inode = file_inode(desc->file);
 	struct nfs_open_dir_context *ctx = desc->file->private_data;
 
-	dfprintk(DIRCACHE, "NFS: uncached_readdir() searching for cookie %Lu\n",
-			(unsigned long long)*desc->dir_cookie);
+	trace_nfs_uncached_readdir_enter(desc);
 
 	page = alloc_page(GFP_HIGHUSER);
 	if (!page) {
@@ -859,8 +862,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc)
 	nfs_readdir_clear_array(desc->page);
 	cache_page_release(desc);
  out:
-	dfprintk(DIRCACHE, "NFS: %s: returns %d\n",
-			__func__, status);
+	trace_nfs_uncached_readdir_exit(desc, status);
 	return status;
 }
 
diff --git a/fs/nfs/nfstrace.h b/fs/nfs/nfstrace.h
index 6bbe0aa221f2..e6a946b83330 100644
--- a/fs/nfs/nfstrace.h
+++ b/fs/nfs/nfstrace.h
@@ -752,6 +752,108 @@
 		)
 );
 
+DECLARE_EVENT_CLASS(nfs_readdir_descriptor_event_enter,
+		TP_PROTO(
+				const nfs_readdir_descriptor_t *desc
+			),
+
+		TP_ARGS(desc),
+
+		TP_STRUCT__entry(
+			__field(dev_t, dev)
+			__field(u64, fileid)
+			__field(u32, fhandle)
+			__field(u64, dir_cookie)
+			__field(u64, page_index)
+			__field(u64, last_cookie)
+			__field(u64, current_index)
+			__field(u64, prev_index)
+		),
+
+		TP_fast_assign(
+			__entry->dev = file_inode(desc->file)->i_sb->s_dev;
+			__entry->fileid = NFS_FILEID(file_inode(desc->file));
+			__entry->fhandle = nfs_fhandle_hash(NFS_FH(file_inode(desc->file)));
+			__entry->dir_cookie = *desc->dir_cookie;
+			__entry->page_index = desc->page_index;
+			__entry->last_cookie = desc->last_cookie;
+			__entry->current_index = desc->current_index;
+			__entry->prev_index = desc->prev_index;
+		),
+
+		TP_printk(
+			"fileid=%02x:%02x:%llu fhandle=0x%08x dir_cookie=0x%08llx last_cookie=0x%08llx page_index=0x%08llx current_index=0x%08llu prev_index=0x%08llu",
+			MAJOR(__entry->dev), MINOR(__entry->dev),
+			(unsigned long long)__entry->fileid, __entry->fhandle,
+			__entry->dir_cookie, __entry->last_cookie, __entry->page_index,
+			__entry->current_index, __entry->prev_index
+		)
+);
+
+#define DEFINE_NFS_READDIR_DESCRIPTOR_EVENT(name) \
+	DEFINE_EVENT(nfs_readdir_descriptor_event_enter, name, \
+			TP_PROTO( \
+				const nfs_readdir_descriptor_t *desc \
+			), \
+			TP_ARGS(desc))
+
+DECLARE_EVENT_CLASS(nfs_readdir_descriptor_event_exit,
+		TP_PROTO(
+				const nfs_readdir_descriptor_t *desc,
+				int error
+			),
+
+		TP_ARGS(desc, error),
+
+		TP_STRUCT__entry(
+			__field(dev_t, dev)
+			__field(u64, fileid)
+			__field(u32, fhandle)
+			__field(u64, dir_cookie)
+			__field(unsigned long, error)
+			__field(u64, page_index)
+			__field(u64, last_cookie)
+			__field(u64, current_index)
+			__field(u64, prev_index)
+		),
+
+		TP_fast_assign(
+			__entry->dev = file_inode(desc->file)->i_sb->s_dev;
+			__entry->fileid = NFS_FILEID(file_inode(desc->file));
+			__entry->fhandle = nfs_fhandle_hash(NFS_FH(file_inode(desc->file)));
+			__entry->dir_cookie = *desc->dir_cookie;
+			__entry->error = error;
+			__entry->page_index = desc->page_index;
+			__entry->last_cookie = desc->last_cookie;
+			__entry->current_index = desc->current_index;
+			__entry->prev_index = desc->prev_index;
+		),
+
+		TP_printk(
+			"error=%ld fileid=%02x:%02x:%llu fhandle=0x%08x dir_cookie=0x%08llx last_cookie=0x%08llx page_index=0x%08llx current_index=0x%08llu prev_index=0x%08llu",
+			__entry->error,
+			MAJOR(__entry->dev), MINOR(__entry->dev),
+			(unsigned long long)__entry->fileid, __entry->fhandle,
+			__entry->dir_cookie, __entry->last_cookie, __entry->page_index,
+			__entry->current_index, __entry->prev_index
+		)
+);
+
+#define DEFINE_NFS_READDIR_DESCRIPTOR_EVENT_EXIT(name) \
+	DEFINE_EVENT(nfs_readdir_descriptor_event_exit, name, \
+			TP_PROTO( \
+				const nfs_readdir_descriptor_t *desc, \
+				int error \
+			), \
+			TP_ARGS(desc, error))
+
+DEFINE_NFS_READDIR_DESCRIPTOR_EVENT(nfs_uncached_readdir_enter);
+DEFINE_NFS_READDIR_DESCRIPTOR_EVENT_EXIT(nfs_uncached_readdir_exit);
+DEFINE_NFS_READDIR_DESCRIPTOR_EVENT(nfs_readdir_search_pagecache_enter);
+DEFINE_NFS_READDIR_DESCRIPTOR_EVENT_EXIT(nfs_readdir_search_pagecache_exit);
+DEFINE_NFS_READDIR_DESCRIPTOR_EVENT(nfs_readdir_search_array_enter);
+DEFINE_NFS_READDIR_DESCRIPTOR_EVENT_EXIT(nfs_readdir_search_array_exit);
+
 TRACE_EVENT(nfs_link_enter,
 		TP_PROTO(
 			const struct inode *inode,
