aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/file.c16
-rw-r--r--fs/nfs/internal.h7
-rw-r--r--fs/nfs/nfstrace.h248
-rw-r--r--fs/nfs/pagelist.c4
-rw-r--r--fs/nfs/pnfs.c14
-rw-r--r--fs/nfs/read.c4
-rw-r--r--fs/nfs/write.c14
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 */
210static int 210static int
211nfs_file_fsync_commit(struct file *file, loff_t start, loff_t end, int datasync) 211nfs_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
772static 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
723TRACE_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
759TRACE_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
808TRACE_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
848TRACE_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