diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-08-21 12:36:04 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-08-22 08:58:19 -0400 |
commit | 1ca42382afd67bf58523d36b00fb4ff487d8173b (patch) | |
tree | ac285dda99b3a9227a7dc75fe6abcc7dac4b4b3b /fs/nfs | |
parent | 8b0ad3d489cb107804bd8c78695532794eec73d5 (diff) |
NFS: Add tracepoints for debugging directory changes
Add tracepoints for mknod, mkdir, rmdir, remove (unlink) and symlink.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/dir.c | 15 | ||||
-rw-r--r-- | fs/nfs/nfstrace.h | 90 |
2 files changed, 104 insertions, 1 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 9c0781265425..e41dec5cfbc9 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -1642,7 +1642,9 @@ nfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev) | |||
1642 | attr.ia_mode = mode; | 1642 | attr.ia_mode = mode; |
1643 | attr.ia_valid = ATTR_MODE; | 1643 | attr.ia_valid = ATTR_MODE; |
1644 | 1644 | ||
1645 | trace_nfs_mknod_enter(dir, dentry); | ||
1645 | status = NFS_PROTO(dir)->mknod(dir, dentry, &attr, rdev); | 1646 | status = NFS_PROTO(dir)->mknod(dir, dentry, &attr, rdev); |
1647 | trace_nfs_mknod_exit(dir, dentry, status); | ||
1646 | if (status != 0) | 1648 | if (status != 0) |
1647 | goto out_err; | 1649 | goto out_err; |
1648 | return 0; | 1650 | return 0; |
@@ -1666,7 +1668,9 @@ int nfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
1666 | attr.ia_valid = ATTR_MODE; | 1668 | attr.ia_valid = ATTR_MODE; |
1667 | attr.ia_mode = mode | S_IFDIR; | 1669 | attr.ia_mode = mode | S_IFDIR; |
1668 | 1670 | ||
1671 | trace_nfs_mkdir_enter(dir, dentry); | ||
1669 | error = NFS_PROTO(dir)->mkdir(dir, dentry, &attr); | 1672 | error = NFS_PROTO(dir)->mkdir(dir, dentry, &attr); |
1673 | trace_nfs_mkdir_exit(dir, dentry, error); | ||
1670 | if (error != 0) | 1674 | if (error != 0) |
1671 | goto out_err; | 1675 | goto out_err; |
1672 | return 0; | 1676 | return 0; |
@@ -1689,12 +1693,14 @@ int nfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
1689 | dfprintk(VFS, "NFS: rmdir(%s/%ld), %s\n", | 1693 | dfprintk(VFS, "NFS: rmdir(%s/%ld), %s\n", |
1690 | dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); | 1694 | dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); |
1691 | 1695 | ||
1696 | trace_nfs_rmdir_enter(dir, dentry); | ||
1692 | error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name); | 1697 | error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name); |
1693 | /* Ensure the VFS deletes this inode */ | 1698 | /* Ensure the VFS deletes this inode */ |
1694 | if (error == 0 && dentry->d_inode != NULL) | 1699 | if (error == 0 && dentry->d_inode != NULL) |
1695 | clear_nlink(dentry->d_inode); | 1700 | clear_nlink(dentry->d_inode); |
1696 | else if (error == -ENOENT) | 1701 | else if (error == -ENOENT) |
1697 | nfs_dentry_handle_enoent(dentry); | 1702 | nfs_dentry_handle_enoent(dentry); |
1703 | trace_nfs_rmdir_exit(dir, dentry, error); | ||
1698 | 1704 | ||
1699 | return error; | 1705 | return error; |
1700 | } | 1706 | } |
@@ -1722,6 +1728,7 @@ static int nfs_safe_remove(struct dentry *dentry) | |||
1722 | goto out; | 1728 | goto out; |
1723 | } | 1729 | } |
1724 | 1730 | ||
1731 | trace_nfs_remove_enter(dir, dentry); | ||
1725 | if (inode != NULL) { | 1732 | if (inode != NULL) { |
1726 | NFS_PROTO(inode)->return_delegation(inode); | 1733 | NFS_PROTO(inode)->return_delegation(inode); |
1727 | error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); | 1734 | error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); |
@@ -1731,6 +1738,7 @@ static int nfs_safe_remove(struct dentry *dentry) | |||
1731 | error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); | 1738 | error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); |
1732 | if (error == -ENOENT) | 1739 | if (error == -ENOENT) |
1733 | nfs_dentry_handle_enoent(dentry); | 1740 | nfs_dentry_handle_enoent(dentry); |
1741 | trace_nfs_remove_exit(dir, dentry, error); | ||
1734 | out: | 1742 | out: |
1735 | return error; | 1743 | return error; |
1736 | } | 1744 | } |
@@ -1748,13 +1756,14 @@ int nfs_unlink(struct inode *dir, struct dentry *dentry) | |||
1748 | dfprintk(VFS, "NFS: unlink(%s/%ld, %s)\n", dir->i_sb->s_id, | 1756 | dfprintk(VFS, "NFS: unlink(%s/%ld, %s)\n", dir->i_sb->s_id, |
1749 | dir->i_ino, dentry->d_name.name); | 1757 | dir->i_ino, dentry->d_name.name); |
1750 | 1758 | ||
1759 | trace_nfs_unlink_enter(dir, dentry); | ||
1751 | spin_lock(&dentry->d_lock); | 1760 | spin_lock(&dentry->d_lock); |
1752 | if (d_count(dentry) > 1) { | 1761 | if (d_count(dentry) > 1) { |
1753 | spin_unlock(&dentry->d_lock); | 1762 | spin_unlock(&dentry->d_lock); |
1754 | /* Start asynchronous writeout of the inode */ | 1763 | /* Start asynchronous writeout of the inode */ |
1755 | write_inode_now(dentry->d_inode, 0); | 1764 | write_inode_now(dentry->d_inode, 0); |
1756 | error = nfs_sillyrename(dir, dentry); | 1765 | error = nfs_sillyrename(dir, dentry); |
1757 | return error; | 1766 | goto out; |
1758 | } | 1767 | } |
1759 | if (!d_unhashed(dentry)) { | 1768 | if (!d_unhashed(dentry)) { |
1760 | __d_drop(dentry); | 1769 | __d_drop(dentry); |
@@ -1766,6 +1775,8 @@ int nfs_unlink(struct inode *dir, struct dentry *dentry) | |||
1766 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); | 1775 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); |
1767 | } else if (need_rehash) | 1776 | } else if (need_rehash) |
1768 | d_rehash(dentry); | 1777 | d_rehash(dentry); |
1778 | out: | ||
1779 | trace_nfs_unlink_exit(dir, dentry, error); | ||
1769 | return error; | 1780 | return error; |
1770 | } | 1781 | } |
1771 | EXPORT_SYMBOL_GPL(nfs_unlink); | 1782 | EXPORT_SYMBOL_GPL(nfs_unlink); |
@@ -1812,7 +1823,9 @@ int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) | |||
1812 | memset(kaddr + pathlen, 0, PAGE_SIZE - pathlen); | 1823 | memset(kaddr + pathlen, 0, PAGE_SIZE - pathlen); |
1813 | kunmap_atomic(kaddr); | 1824 | kunmap_atomic(kaddr); |
1814 | 1825 | ||
1826 | trace_nfs_symlink_enter(dir, dentry); | ||
1815 | error = NFS_PROTO(dir)->symlink(dir, dentry, page, pathlen, &attr); | 1827 | error = NFS_PROTO(dir)->symlink(dir, dentry, page, pathlen, &attr); |
1828 | trace_nfs_symlink_exit(dir, dentry, error); | ||
1816 | if (error != 0) { | 1829 | if (error != 0) { |
1817 | dfprintk(VFS, "NFS: symlink(%s/%ld, %s, %s) error %d\n", | 1830 | dfprintk(VFS, "NFS: symlink(%s/%ld, %s, %s) error %d\n", |
1818 | dir->i_sb->s_id, dir->i_ino, | 1831 | dir->i_sb->s_id, dir->i_ino, |
diff --git a/fs/nfs/nfstrace.h b/fs/nfs/nfstrace.h index 2963a050ceff..58279063b9a1 100644 --- a/fs/nfs/nfstrace.h +++ b/fs/nfs/nfstrace.h | |||
@@ -422,6 +422,96 @@ TRACE_EVENT(nfs_create_exit, | |||
422 | ) | 422 | ) |
423 | ); | 423 | ); |
424 | 424 | ||
425 | DECLARE_EVENT_CLASS(nfs_directory_event, | ||
426 | TP_PROTO( | ||
427 | const struct inode *dir, | ||
428 | const struct dentry *dentry | ||
429 | ), | ||
430 | |||
431 | TP_ARGS(dir, dentry), | ||
432 | |||
433 | TP_STRUCT__entry( | ||
434 | __field(dev_t, dev) | ||
435 | __field(u64, dir) | ||
436 | __string(name, dentry->d_name.name) | ||
437 | ), | ||
438 | |||
439 | TP_fast_assign( | ||
440 | __entry->dev = dir->i_sb->s_dev; | ||
441 | __entry->dir = NFS_FILEID(dir); | ||
442 | __assign_str(name, dentry->d_name.name); | ||
443 | ), | ||
444 | |||
445 | TP_printk( | ||
446 | "name=%02x:%02x:%llu/%s", | ||
447 | MAJOR(__entry->dev), MINOR(__entry->dev), | ||
448 | (unsigned long long)__entry->dir, | ||
449 | __get_str(name) | ||
450 | ) | ||
451 | ); | ||
452 | |||
453 | #define DEFINE_NFS_DIRECTORY_EVENT(name) \ | ||
454 | DEFINE_EVENT(nfs_directory_event, name, \ | ||
455 | TP_PROTO( \ | ||
456 | const struct inode *dir, \ | ||
457 | const struct dentry *dentry \ | ||
458 | ), \ | ||
459 | TP_ARGS(dir, dentry)) | ||
460 | |||
461 | DECLARE_EVENT_CLASS(nfs_directory_event_done, | ||
462 | TP_PROTO( | ||
463 | const struct inode *dir, | ||
464 | const struct dentry *dentry, | ||
465 | int error | ||
466 | ), | ||
467 | |||
468 | TP_ARGS(dir, dentry, error), | ||
469 | |||
470 | TP_STRUCT__entry( | ||
471 | __field(int, error) | ||
472 | __field(dev_t, dev) | ||
473 | __field(u64, dir) | ||
474 | __string(name, dentry->d_name.name) | ||
475 | ), | ||
476 | |||
477 | TP_fast_assign( | ||
478 | __entry->dev = dir->i_sb->s_dev; | ||
479 | __entry->dir = NFS_FILEID(dir); | ||
480 | __entry->error = error; | ||
481 | __assign_str(name, dentry->d_name.name); | ||
482 | ), | ||
483 | |||
484 | TP_printk( | ||
485 | "error=%d name=%02x:%02x:%llu/%s", | ||
486 | __entry->error, | ||
487 | MAJOR(__entry->dev), MINOR(__entry->dev), | ||
488 | (unsigned long long)__entry->dir, | ||
489 | __get_str(name) | ||
490 | ) | ||
491 | ); | ||
492 | |||
493 | #define DEFINE_NFS_DIRECTORY_EVENT_DONE(name) \ | ||
494 | DEFINE_EVENT(nfs_directory_event_done, name, \ | ||
495 | TP_PROTO( \ | ||
496 | const struct inode *dir, \ | ||
497 | const struct dentry *dentry, \ | ||
498 | int error \ | ||
499 | ), \ | ||
500 | TP_ARGS(dir, dentry, error)) | ||
501 | |||
502 | DEFINE_NFS_DIRECTORY_EVENT(nfs_mknod_enter); | ||
503 | DEFINE_NFS_DIRECTORY_EVENT_DONE(nfs_mknod_exit); | ||
504 | DEFINE_NFS_DIRECTORY_EVENT(nfs_mkdir_enter); | ||
505 | DEFINE_NFS_DIRECTORY_EVENT_DONE(nfs_mkdir_exit); | ||
506 | DEFINE_NFS_DIRECTORY_EVENT(nfs_rmdir_enter); | ||
507 | DEFINE_NFS_DIRECTORY_EVENT_DONE(nfs_rmdir_exit); | ||
508 | DEFINE_NFS_DIRECTORY_EVENT(nfs_remove_enter); | ||
509 | DEFINE_NFS_DIRECTORY_EVENT_DONE(nfs_remove_exit); | ||
510 | DEFINE_NFS_DIRECTORY_EVENT(nfs_unlink_enter); | ||
511 | DEFINE_NFS_DIRECTORY_EVENT_DONE(nfs_unlink_exit); | ||
512 | DEFINE_NFS_DIRECTORY_EVENT(nfs_symlink_enter); | ||
513 | DEFINE_NFS_DIRECTORY_EVENT_DONE(nfs_symlink_exit); | ||
514 | |||
425 | #endif /* _TRACE_NFS_H */ | 515 | #endif /* _TRACE_NFS_H */ |
426 | 516 | ||
427 | #undef TRACE_INCLUDE_PATH | 517 | #undef TRACE_INCLUDE_PATH |