diff options
| -rw-r--r-- | fs/nfs/file.c | 16 | ||||
| -rw-r--r-- | fs/nfs/internal.h | 7 | ||||
| -rw-r--r-- | fs/nfs/nfstrace.h | 248 | ||||
| -rw-r--r-- | fs/nfs/pagelist.c | 4 | ||||
| -rw-r--r-- | fs/nfs/pnfs.c | 14 | ||||
| -rw-r--r-- | fs/nfs/read.c | 4 | ||||
| -rw-r--r-- | fs/nfs/write.c | 14 |
7 files changed, 287 insertions, 20 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index a385d1c3f146..0214dd1e1060 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
| @@ -208,21 +208,19 @@ EXPORT_SYMBOL_GPL(nfs_file_mmap); | |||
| 208 | * fall back to doing a synchronous write. | 208 | * fall back to doing a synchronous write. |
| 209 | */ | 209 | */ |
| 210 | static int | 210 | static int |
| 211 | nfs_file_fsync_commit(struct file *file, loff_t start, loff_t end, int datasync) | 211 | nfs_file_fsync_commit(struct file *file, int datasync) |
| 212 | { | 212 | { |
| 213 | struct nfs_open_context *ctx = nfs_file_open_context(file); | 213 | struct nfs_open_context *ctx = nfs_file_open_context(file); |
| 214 | struct inode *inode = file_inode(file); | 214 | struct inode *inode = file_inode(file); |
| 215 | int have_error, do_resend, status; | 215 | int do_resend, status; |
| 216 | int ret = 0; | 216 | int ret = 0; |
| 217 | 217 | ||
| 218 | dprintk("NFS: fsync file(%pD2) datasync %d\n", file, datasync); | 218 | dprintk("NFS: fsync file(%pD2) datasync %d\n", file, datasync); |
| 219 | 219 | ||
| 220 | nfs_inc_stats(inode, NFSIOS_VFSFSYNC); | 220 | nfs_inc_stats(inode, NFSIOS_VFSFSYNC); |
| 221 | do_resend = test_and_clear_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags); | 221 | do_resend = test_and_clear_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags); |
| 222 | have_error = test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags); | ||
| 223 | status = nfs_commit_inode(inode, FLUSH_SYNC); | 222 | status = nfs_commit_inode(inode, FLUSH_SYNC); |
| 224 | have_error |= test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags); | 223 | if (test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags)) { |
| 225 | if (have_error) { | ||
| 226 | ret = xchg(&ctx->error, 0); | 224 | ret = xchg(&ctx->error, 0); |
| 227 | if (ret) | 225 | if (ret) |
| 228 | goto out; | 226 | goto out; |
| @@ -247,10 +245,16 @@ nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync) | |||
| 247 | trace_nfs_fsync_enter(inode); | 245 | trace_nfs_fsync_enter(inode); |
| 248 | 246 | ||
| 249 | do { | 247 | do { |
| 248 | struct nfs_open_context *ctx = nfs_file_open_context(file); | ||
| 250 | ret = filemap_write_and_wait_range(inode->i_mapping, start, end); | 249 | ret = filemap_write_and_wait_range(inode->i_mapping, start, end); |
| 250 | if (test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags)) { | ||
| 251 | int ret2 = xchg(&ctx->error, 0); | ||
| 252 | if (ret2) | ||
| 253 | ret = ret2; | ||
| 254 | } | ||
| 251 | if (ret != 0) | 255 | if (ret != 0) |
| 252 | break; | 256 | break; |
| 253 | ret = nfs_file_fsync_commit(file, start, end, datasync); | 257 | ret = nfs_file_fsync_commit(file, datasync); |
| 254 | if (!ret) | 258 | if (!ret) |
| 255 | ret = pnfs_sync_inode(inode, !!datasync); | 259 | ret = pnfs_sync_inode(inode, !!datasync); |
| 256 | /* | 260 | /* |
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 68cc22083639..5bdf952f414b 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
| @@ -768,3 +768,10 @@ static inline bool nfs_error_is_fatal(int err) | |||
| 768 | return false; | 768 | return false; |
| 769 | } | 769 | } |
| 770 | } | 770 | } |
| 771 | |||
| 772 | static inline void nfs_context_set_write_error(struct nfs_open_context *ctx, int error) | ||
| 773 | { | ||
| 774 | ctx->error = error; | ||
| 775 | smp_wmb(); | ||
| 776 | set_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags); | ||
| 777 | } | ||
diff --git a/fs/nfs/nfstrace.h b/fs/nfs/nfstrace.h index 2ca9167bc97d..551711042ba4 100644 --- a/fs/nfs/nfstrace.h +++ b/fs/nfs/nfstrace.h | |||
| @@ -719,6 +719,254 @@ TRACE_EVENT(nfs_sillyrename_unlink, | |||
| 719 | __get_str(name) | 719 | __get_str(name) |
| 720 | ) | 720 | ) |
| 721 | ); | 721 | ); |
| 722 | |||
| 723 | TRACE_EVENT(nfs_initiate_read, | ||
| 724 | TP_PROTO( | ||
| 725 | const struct inode *inode, | ||
| 726 | loff_t offset, unsigned long count | ||
| 727 | ), | ||
| 728 | |||
| 729 | TP_ARGS(inode, offset, count), | ||
| 730 | |||
| 731 | TP_STRUCT__entry( | ||
| 732 | __field(loff_t, offset) | ||
| 733 | __field(unsigned long, count) | ||
| 734 | __field(dev_t, dev) | ||
| 735 | __field(u32, fhandle) | ||
| 736 | __field(u64, fileid) | ||
| 737 | ), | ||
| 738 | |||
| 739 | TP_fast_assign( | ||
| 740 | const struct nfs_inode *nfsi = NFS_I(inode); | ||
| 741 | |||
| 742 | __entry->offset = offset; | ||
| 743 | __entry->count = count; | ||
| 744 | __entry->dev = inode->i_sb->s_dev; | ||
| 745 | __entry->fileid = nfsi->fileid; | ||
| 746 | __entry->fhandle = nfs_fhandle_hash(&nfsi->fh); | ||
| 747 | ), | ||
| 748 | |||
| 749 | TP_printk( | ||
| 750 | "fileid=%02x:%02x:%llu fhandle=0x%08x " | ||
| 751 | "offset=%lld count=%lu", | ||
| 752 | MAJOR(__entry->dev), MINOR(__entry->dev), | ||
| 753 | (unsigned long long)__entry->fileid, | ||
| 754 | __entry->fhandle, | ||
| 755 | __entry->offset, __entry->count | ||
| 756 | ) | ||
| 757 | ); | ||
| 758 | |||
| 759 | TRACE_EVENT(nfs_readpage_done, | ||
| 760 | TP_PROTO( | ||
| 761 | const struct inode *inode, | ||
| 762 | int status, loff_t offset, bool eof | ||
| 763 | ), | ||
| 764 | |||
| 765 | TP_ARGS(inode, status, offset, eof), | ||
| 766 | |||
| 767 | TP_STRUCT__entry( | ||
| 768 | __field(int, status) | ||
| 769 | __field(loff_t, offset) | ||
| 770 | __field(bool, eof) | ||
| 771 | __field(dev_t, dev) | ||
| 772 | __field(u32, fhandle) | ||
| 773 | __field(u64, fileid) | ||
| 774 | ), | ||
| 775 | |||
| 776 | TP_fast_assign( | ||
| 777 | const struct nfs_inode *nfsi = NFS_I(inode); | ||
| 778 | |||
| 779 | __entry->status = status; | ||
| 780 | __entry->offset = offset; | ||
| 781 | __entry->eof = eof; | ||
| 782 | __entry->dev = inode->i_sb->s_dev; | ||
| 783 | __entry->fileid = nfsi->fileid; | ||
| 784 | __entry->fhandle = nfs_fhandle_hash(&nfsi->fh); | ||
| 785 | ), | ||
| 786 | |||
| 787 | TP_printk( | ||
| 788 | "fileid=%02x:%02x:%llu fhandle=0x%08x " | ||
| 789 | "offset=%lld status=%d%s", | ||
| 790 | MAJOR(__entry->dev), MINOR(__entry->dev), | ||
| 791 | (unsigned long long)__entry->fileid, | ||
| 792 | __entry->fhandle, | ||
| 793 | __entry->offset, __entry->status, | ||
| 794 | __entry->eof ? " eof" : "" | ||
| 795 | ) | ||
| 796 | ); | ||
| 797 | |||
| 798 | /* | ||
| 799 | * XXX: I tried using NFS_UNSTABLE and friends in this table, but they | ||
| 800 | * all evaluate to 0 for some reason, even if I include linux/nfs.h. | ||
| 801 | */ | ||
| 802 | #define nfs_show_stable(stable) \ | ||
| 803 | __print_symbolic(stable, \ | ||
| 804 | { 0, " (UNSTABLE)" }, \ | ||
| 805 | { 1, " (DATA_SYNC)" }, \ | ||
| 806 | { 2, " (FILE_SYNC)" }) | ||
| 807 | |||
| 808 | TRACE_EVENT(nfs_initiate_write, | ||
| 809 | TP_PROTO( | ||
| 810 | const struct inode *inode, | ||
| 811 | loff_t offset, unsigned long count, | ||
| 812 | enum nfs3_stable_how stable | ||
| 813 | ), | ||
| 814 | |||
| 815 | TP_ARGS(inode, offset, count, stable), | ||
| 816 | |||
| 817 | TP_STRUCT__entry( | ||
| 818 | __field(loff_t, offset) | ||
| 819 | __field(unsigned long, count) | ||
| 820 | __field(enum nfs3_stable_how, stable) | ||
| 821 | __field(dev_t, dev) | ||
| 822 | __field(u32, fhandle) | ||
| 823 | __field(u64, fileid) | ||
| 824 | ), | ||
| 825 | |||
| 826 | TP_fast_assign( | ||
| 827 | const struct nfs_inode *nfsi = NFS_I(inode); | ||
| 828 | |||
| 829 | __entry->offset = offset; | ||
| 830 | __entry->count = count; | ||
| 831 | __entry->stable = stable; | ||
| 832 | __entry->dev = inode->i_sb->s_dev; | ||
| 833 | __entry->fileid = nfsi->fileid; | ||
| 834 | __entry->fhandle = nfs_fhandle_hash(&nfsi->fh); | ||
| 835 | ), | ||
| 836 | |||
| 837 | TP_printk( | ||
| 838 | "fileid=%02x:%02x:%llu fhandle=0x%08x " | ||
| 839 | "offset=%lld count=%lu stable=%d%s", | ||
| 840 | MAJOR(__entry->dev), MINOR(__entry->dev), | ||
| 841 | (unsigned long long)__entry->fileid, | ||
| 842 | __entry->fhandle, | ||
| 843 | __entry->offset, __entry->count, | ||
| 844 | __entry->stable, nfs_show_stable(__entry->stable) | ||
| 845 | ) | ||
| 846 | ); | ||
| 847 | |||
| 848 | TRACE_EVENT(nfs_writeback_done, | ||
| 849 | TP_PROTO( | ||
| 850 | const struct inode *inode, | ||
| 851 | int status, | ||
| 852 | loff_t offset, | ||
| 853 | struct nfs_writeverf *writeverf | ||
| 854 | ), | ||
| 855 | |||
| 856 | TP_ARGS(inode, status, offset, writeverf), | ||
| 857 | |||
| 858 | T | ||
