diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-08-21 12:08:45 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-08-22 08:58:19 -0400 |
commit | 70ded2017072ae16aeaa7fb2a15a879a475161a6 (patch) | |
tree | 8eb125f0b56f2c55d529211def630c46b74c2267 | |
parent | 1ca42382afd67bf58523d36b00fb4ff487d8173b (diff) |
NFS: Add tracepoints for debugging NFS rename and sillyrename issues
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | fs/nfs/dir.c | 3 | ||||
-rw-r--r-- | fs/nfs/nfstrace.h | 138 | ||||
-rw-r--r-- | fs/nfs/unlink.c | 5 |
3 files changed, 146 insertions, 0 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index e41dec5cfbc9..dca7deb1609b 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -1909,6 +1909,7 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1909 | new_dentry->d_parent->d_name.name, new_dentry->d_name.name, | 1909 | new_dentry->d_parent->d_name.name, new_dentry->d_name.name, |
1910 | d_count(new_dentry)); | 1910 | d_count(new_dentry)); |
1911 | 1911 | ||
1912 | trace_nfs_rename_enter(old_dir, old_dentry, new_dir, new_dentry); | ||
1912 | /* | 1913 | /* |
1913 | * For non-directories, check whether the target is busy and if so, | 1914 | * For non-directories, check whether the target is busy and if so, |
1914 | * make a copy of the dentry and then do a silly-rename. If the | 1915 | * make a copy of the dentry and then do a silly-rename. If the |
@@ -1955,6 +1956,8 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1955 | out: | 1956 | out: |
1956 | if (rehash) | 1957 | if (rehash) |
1957 | d_rehash(rehash); | 1958 | d_rehash(rehash); |
1959 | trace_nfs_rename_exit(old_dir, old_dentry, | ||
1960 | new_dir, new_dentry, error); | ||
1958 | if (!error) { | 1961 | if (!error) { |
1959 | if (new_inode != NULL) | 1962 | if (new_inode != NULL) |
1960 | nfs_drop_nlink(new_inode); | 1963 | nfs_drop_nlink(new_inode); |
diff --git a/fs/nfs/nfstrace.h b/fs/nfs/nfstrace.h index 58279063b9a1..a20f0d147cf2 100644 --- a/fs/nfs/nfstrace.h +++ b/fs/nfs/nfstrace.h | |||
@@ -512,6 +512,144 @@ DEFINE_NFS_DIRECTORY_EVENT_DONE(nfs_unlink_exit); | |||
512 | DEFINE_NFS_DIRECTORY_EVENT(nfs_symlink_enter); | 512 | DEFINE_NFS_DIRECTORY_EVENT(nfs_symlink_enter); |
513 | DEFINE_NFS_DIRECTORY_EVENT_DONE(nfs_symlink_exit); | 513 | DEFINE_NFS_DIRECTORY_EVENT_DONE(nfs_symlink_exit); |
514 | 514 | ||
515 | DECLARE_EVENT_CLASS(nfs_rename_event, | ||
516 | TP_PROTO( | ||
517 | const struct inode *old_dir, | ||
518 | const struct dentry *old_dentry, | ||
519 | const struct inode *new_dir, | ||
520 | const struct dentry *new_dentry | ||
521 | ), | ||
522 | |||
523 | TP_ARGS(old_dir, old_dentry, new_dir, new_dentry), | ||
524 | |||
525 | TP_STRUCT__entry( | ||
526 | __field(dev_t, dev) | ||
527 | __field(u64, old_dir) | ||
528 | __field(u64, new_dir) | ||
529 | __string(old_name, old_dentry->d_name.name) | ||
530 | __string(new_name, new_dentry->d_name.name) | ||
531 | ), | ||
532 | |||
533 | TP_fast_assign( | ||
534 | __entry->dev = old_dir->i_sb->s_dev; | ||
535 | __entry->old_dir = NFS_FILEID(old_dir); | ||
536 | __entry->new_dir = NFS_FILEID(new_dir); | ||
537 | __assign_str(old_name, old_dentry->d_name.name); | ||
538 | __assign_str(new_name, new_dentry->d_name.name); | ||
539 | ), | ||
540 | |||
541 | TP_printk( | ||
542 | "old_name=%02x:%02x:%llu/%s new_name=%02x:%02x:%llu/%s", | ||
543 | MAJOR(__entry->dev), MINOR(__entry->dev), | ||
544 | (unsigned long long)__entry->old_dir, | ||
545 | __get_str(old_name), | ||
546 | MAJOR(__entry->dev), MINOR(__entry->dev), | ||
547 | (unsigned long long)__entry->new_dir, | ||
548 | __get_str(new_name) | ||
549 | ) | ||
550 | ); | ||
551 | #define DEFINE_NFS_RENAME_EVENT(name) \ | ||
552 | DEFINE_EVENT(nfs_rename_event, name, \ | ||
553 | TP_PROTO( \ | ||
554 | const struct inode *old_dir, \ | ||
555 | const struct dentry *old_dentry, \ | ||
556 | const struct inode *new_dir, \ | ||
557 | const struct dentry *new_dentry \ | ||
558 | ), \ | ||
559 | TP_ARGS(old_dir, old_dentry, new_dir, new_dentry)) | ||
560 | |||
561 | DECLARE_EVENT_CLASS(nfs_rename_event_done, | ||
562 | TP_PROTO( | ||
563 | const struct inode *old_dir, | ||
564 | const struct dentry *old_dentry, | ||
565 | const struct inode *new_dir, | ||
566 | const struct dentry *new_dentry, | ||
567 | int error | ||
568 | ), | ||
569 | |||
570 | TP_ARGS(old_dir, old_dentry, new_dir, new_dentry, error), | ||
571 | |||
572 | TP_STRUCT__entry( | ||
573 | __field(dev_t, dev) | ||
574 | __field(int, error) | ||
575 | __field(u64, old_dir) | ||
576 | __string(old_name, old_dentry->d_name.name) | ||
577 | __field(u64, new_dir) | ||
578 | __string(new_name, new_dentry->d_name.name) | ||
579 | ), | ||
580 | |||
581 | TP_fast_assign( | ||
582 | __entry->dev = old_dir->i_sb->s_dev; | ||
583 | __entry->old_dir = NFS_FILEID(old_dir); | ||
584 | __entry->new_dir = NFS_FILEID(new_dir); | ||
585 | __entry->error = error; | ||
586 | __assign_str(old_name, old_dentry->d_name.name); | ||
587 | __assign_str(new_name, new_dentry->d_name.name); | ||
588 | ), | ||
589 | |||
590 | TP_printk( | ||
591 | "error=%d old_name=%02x:%02x:%llu/%s " | ||
592 | "new_name=%02x:%02x:%llu/%s", | ||
593 | __entry->error, | ||
594 | MAJOR(__entry->dev), MINOR(__entry->dev), | ||
595 | (unsigned long long)__entry->old_dir, | ||
596 | __get_str(old_name), | ||
597 | MAJOR(__entry->dev), MINOR(__entry->dev), | ||
598 | (unsigned long long)__entry->new_dir, | ||
599 | __get_str(new_name) | ||
600 | ) | ||
601 | ); | ||
602 | #define DEFINE_NFS_RENAME_EVENT_DONE(name) \ | ||
603 | DEFINE_EVENT(nfs_rename_event_done, name, \ | ||
604 | TP_PROTO( \ | ||
605 | const struct inode *old_dir, \ | ||
606 | const struct dentry *old_dentry, \ | ||
607 | const struct inode *new_dir, \ | ||
608 | const struct dentry *new_dentry, \ | ||
609 | int error \ | ||
610 | ), \ | ||
611 | TP_ARGS(old_dir, old_dentry, new_dir, \ | ||
612 | new_dentry, error)) | ||
613 | |||
614 | DEFINE_NFS_RENAME_EVENT(nfs_rename_enter); | ||
615 | DEFINE_NFS_RENAME_EVENT_DONE(nfs_rename_exit); | ||
616 | |||
617 | DEFINE_NFS_RENAME_EVENT_DONE(nfs_sillyrename_rename); | ||
618 | |||
619 | TRACE_EVENT(nfs_sillyrename_unlink, | ||
620 | TP_PROTO( | ||
621 | const struct nfs_unlinkdata *data, | ||
622 | int error | ||
623 | ), | ||
624 | |||
625 | TP_ARGS(data, error), | ||
626 | |||
627 | TP_STRUCT__entry( | ||
628 | __field(dev_t, dev) | ||
629 | __field(int, error) | ||
630 | __field(u64, dir) | ||
631 | __dynamic_array(char, name, data->args.name.len + 1) | ||
632 | ), | ||
633 | |||
634 | TP_fast_assign( | ||
635 | struct inode *dir = data->dir; | ||
636 | size_t len = data->args.name.len; | ||
637 | __entry->dev = dir->i_sb->s_dev; | ||
638 | __entry->dir = NFS_FILEID(dir); | ||
639 | __entry->error = error; | ||
640 | memcpy(__get_dynamic_array(name), | ||
641 | data->args.name.name, len); | ||
642 | ((char *)__get_dynamic_array(name))[len] = 0; | ||
643 | ), | ||
644 | |||
645 | TP_printk( | ||
646 | "error=%d name=%02x:%02x:%llu/%s", | ||
647 | __entry->error, | ||
648 | MAJOR(__entry->dev), MINOR(__entry->dev), | ||
649 | (unsigned long long)__entry->dir, | ||
650 | __get_str(name) | ||
651 | ) | ||
652 | ); | ||
515 | #endif /* _TRACE_NFS_H */ | 653 | #endif /* _TRACE_NFS_H */ |
516 | 654 | ||
517 | #undef TRACE_INCLUDE_PATH | 655 | #undef TRACE_INCLUDE_PATH |
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c index 488fd162f75b..2c1485d18419 100644 --- a/fs/nfs/unlink.c +++ b/fs/nfs/unlink.c | |||
@@ -20,6 +20,8 @@ | |||
20 | #include "iostat.h" | 20 | #include "iostat.h" |
21 | #include "delegation.h" | 21 | #include "delegation.h" |
22 | 22 | ||
23 | #include "nfstrace.h" | ||
24 | |||
23 | /** | 25 | /** |
24 | * nfs_free_unlinkdata - release data from a sillydelete operation. | 26 | * nfs_free_unlinkdata - release data from a sillydelete operation. |
25 | * @data: pointer to unlink structure. | 27 | * @data: pointer to unlink structure. |
@@ -77,6 +79,7 @@ static void nfs_async_unlink_done(struct rpc_task *task, void *calldata) | |||
77 | struct nfs_unlinkdata *data = calldata; | 79 | struct nfs_unlinkdata *data = calldata; |
78 | struct inode *dir = data->dir; | 80 | struct inode *dir = data->dir; |
79 | 81 | ||
82 | trace_nfs_sillyrename_unlink(data, task->tk_status); | ||
80 | if (!NFS_PROTO(dir)->unlink_done(task, dir)) | 83 | if (!NFS_PROTO(dir)->unlink_done(task, dir)) |
81 | rpc_restart_call_prepare(task); | 84 | rpc_restart_call_prepare(task); |
82 | } | 85 | } |
@@ -336,6 +339,8 @@ static void nfs_async_rename_done(struct rpc_task *task, void *calldata) | |||
336 | struct inode *new_dir = data->new_dir; | 339 | struct inode *new_dir = data->new_dir; |
337 | struct dentry *old_dentry = data->old_dentry; | 340 | struct dentry *old_dentry = data->old_dentry; |
338 | 341 | ||
342 | trace_nfs_sillyrename_rename(old_dir, old_dentry, | ||
343 | new_dir, data->new_dentry, task->tk_status); | ||
339 | if (!NFS_PROTO(old_dir)->rename_done(task, old_dir, new_dir)) { | 344 | if (!NFS_PROTO(old_dir)->rename_done(task, old_dir, new_dir)) { |
340 | rpc_restart_call_prepare(task); | 345 | rpc_restart_call_prepare(task); |
341 | return; | 346 | return; |