aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-09-14 23:04:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-09-14 23:04:32 -0400
commit6ed0529fef09f50ef41d396cb55c5519e4936b16 (patch)
tree09d83956d0c386fc62440243c903ca889f34ab2c
parent9e0ce554b039e3df288d83189ecf226c16da04af (diff)
parentbf4b49059718b2217339eb15c60f8753d5b0da99 (diff)
Merge tag 'nfs-for-4.14-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull more NFS client updates from Trond Myklebust: "Hightlights include: Bugfixes: - Various changes relating to reporting IO errors. - pnfs: Use the standard I/O stateid when calling LAYOUTGET Features: - Add static NFS I/O tracepoints for debugging" * tag 'nfs-for-4.14-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: NFS: various changes relating to reporting IO errors. NFS: Add static NFS I/O tracepoints pNFS: Use the standard I/O stateid when calling LAYOUTGET
-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 TP_STRUCT__entry(
859 __field(int, status)
860 __field(loff_t, offset)
861 __field(enum nfs3_stable_how, stable)
862 __field(unsigned long long, verifier)
863 __field(dev_t, dev)
864 __field(u32, fhandle)
865 __field(u64, fileid)
866 ),
867
868 TP_fast_assign(
869 const struct nfs_inode *nfsi = NFS_I(inode);
870
871 __entry->status = status;
872 __entry->offset = offset;
873 __entry->stable = writeverf->committed;
874 memcpy(&__entry->verifier, &writeverf->verifier,
875 sizeof(__entry->verifier));
876 __entry->dev = inode->i_sb->s_dev;
877 __entry->fileid = nfsi->fileid;
878 __entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
879 ),
880
881 TP_printk(
882 "fileid=%02x:%02x:%llu fhandle=0x%08x "
883 "offset=%lld status=%d stable=%d%s "
884 "verifier 0x%016llx",
885 MAJOR(__entry->dev), MINOR(__entry->dev),
886 (unsigned long long)__entry->fileid,
887 __entry->fhandle,
888 __entry->offset, __entry->status,
889 __entry->stable, nfs_show_stable(__entry->stable),
890 __entry->verifier
891 )
892);
893
894TRACE_EVENT(nfs_initiate_commit,
895 TP_PROTO(
896 const struct nfs_commit_data *data
897 ),
898
899 TP_ARGS(data),
900
901 TP_STRUCT__entry(
902 __field(loff_t, offset)
903 __field(unsigned long, count)
904 __field(dev_t, dev)
905 __field(u32, fhandle)
906 __field(u64, fileid)
907 ),
908
909 TP_fast_assign(
910 const struct inode *inode = data->inode;
911 const struct nfs_inode *nfsi = NFS_I(inode);
912
913 __entry->offset = data->args.offset;
914 __entry->count = data->args.count;
915 __entry->dev = inode->i_sb->s_dev;
916 __entry->fileid = nfsi->fileid;
917 __entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
918 ),
919
920 TP_printk(
921 "fileid=%02x:%02x:%llu fhandle=0x%08x "
922 "offset=%lld count=%lu",
923 MAJOR(__entry->dev), MINOR(__entry->dev),
924 (unsigned long long)__entry->fileid,
925 __entry->fhandle,
926 __entry->offset, __entry->count
927 )
928);
929
930TRACE_EVENT(nfs_commit_done,
931 TP_PROTO(
932 const struct nfs_commit_data *data
933 ),
934
935 TP_ARGS(data),
936
937 TP_STRUCT__entry(
938 __field(int, status)
939 __field(loff_t, offset)
940 __field(unsigned long long, verifier)
941 __field(dev_t, dev)
942 __field(u32, fhandle)
943 __field(u64, fileid)
944 ),
945
946 TP_fast_assign(
947 const struct inode *inode = data->inode;
948 const struct nfs_inode *nfsi = NFS_I(inode);
949
950 __entry->status = data->res.op_status;
951 __entry->offset = data->args.offset;
952 memcpy(&__entry->verifier, &data->verf.verifier,
953 sizeof(__entry->verifier));
954 __entry->dev = inode->i_sb->s_dev;
955 __entry->fileid = nfsi->fileid;
956 __entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
957 ),
958
959 TP_printk(
960 "fileid=%02x:%02x:%llu fhandle=0x%08x "
961 "offset=%lld status=%d verifier 0x%016llx",
962 MAJOR(__entry->dev), MINOR(__entry->dev),
963 (unsigned long long)__entry->fileid,
964 __entry->fhandle,
965 __entry->offset, __entry->status,
966 __entry->verifier
967 )
968);
969
722#endif /* _TRACE_NFS_H */ 970#endif /* _TRACE_NFS_H */
723 971
724#undef TRACE_INCLUDE_PATH 972#undef TRACE_INCLUDE_PATH
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index bec120ec1967..d0543e19098a 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -1170,8 +1170,8 @@ out_failed:
1170 1170
1171 /* remember fatal errors */ 1171 /* remember fatal errors */
1172 if (nfs_error_is_fatal(desc->pg_error)) 1172 if (nfs_error_is_fatal(desc->pg_error))
1173 mapping_set_error(desc->pg_inode->i_mapping, 1173 nfs_context_set_write_error(req->wb_context,
1174 desc->pg_error); 1174 desc->pg_error);
1175 1175
1176 func = desc->pg_completion_ops->error_cleanup; 1176 func = desc->pg_completion_ops->error_cleanup;
1177 for (midx = 0; midx < desc->pg_mirror_count; midx++) { 1177 for (midx = 0; midx < desc->pg_mirror_count; midx++) {
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 7879ed8ceb76..3bcd669a3152 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1664,7 +1664,7 @@ pnfs_update_layout(struct inode *ino,
1664 .offset = pos, 1664 .offset = pos,
1665 .length = count, 1665 .length = count,
1666 }; 1666 };
1667 unsigned pg_offset, seq; 1667 unsigned pg_offset;
1668 struct nfs_server *server = NFS_SERVER(ino); 1668 struct nfs_server *server = NFS_SERVER(ino);
1669 struct nfs_client *clp = server->nfs_client; 1669 struct nfs_client *clp = server->nfs_client;
1670 struct pnfs_layout_hdr *lo = NULL; 1670 struct pnfs_layout_hdr *lo = NULL;
@@ -1754,10 +1754,14 @@ lookup_again:
1754 } 1754 }
1755 1755
1756 first = true; 1756 first = true;
1757 do { 1757 if (nfs4_select_rw_stateid(ctx->state,
1758 seq = read_seqbegin(&ctx->state->seqlock); 1758 iomode == IOMODE_RW ? FMODE_WRITE : FMODE_READ,
1759 nfs4_stateid_copy(&stateid, &ctx->state->stateid); 1759 NULL, &stateid, NULL) != 0) {
1760 } while (read_seqretry(&ctx->state->seqlock, seq)); 1760 trace_pnfs_update_layout(ino, pos, count,
1761 iomode, lo, lseg,
1762 PNFS_UPDATE_LAYOUT_INVALID_OPEN);
1763 goto out_unlock;
1764 }
1761 } else { 1765 } else {
1762 nfs4_stateid_copy(&stateid, &lo->plh_stateid); 1766 nfs4_stateid_copy(&stateid, &lo->plh_stateid);
1763 } 1767 }
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 0d42573d423d..48d7277c60a9 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -25,6 +25,7 @@
25#include "iostat.h" 25#include "iostat.h"
26#include "fscache.h" 26#include "fscache.h"
27#include "pnfs.h" 27#include "pnfs.h"
28#include "nfstrace.h"
28 29
29#define NFSDBG_FACILITY NFSDBG_PAGECACHE 30#define NFSDBG_FACILITY NFSDBG_PAGECACHE
30 31
@@ -200,6 +201,7 @@ static void nfs_initiate_read(struct nfs_pgio_header *hdr,
200 201
201 task_setup_data->flags |= swap_flags; 202 task_setup_data->flags |= swap_flags;
202 rpc_ops->read_setup(hdr, msg); 203 rpc_ops->read_setup(hdr, msg);
204 trace_nfs_initiate_read(inode, hdr->io_start, hdr->good_bytes);
203} 205}
204 206
205static void 207static void
@@ -232,6 +234,8 @@ static int nfs_readpage_done(struct rpc_task *task,
232 return status; 234 return status;
233 235
234 nfs_add_stats(inode, NFSIOS_SERVERREADBYTES, hdr->res.count); 236 nfs_add_stats(inode, NFSIOS_SERVERREADBYTES, hdr->res.count);
237 trace_nfs_readpage_done(inode, task->tk_status,
238 hdr->args.offset, hdr->res.eof);
235 239
236 if (task->tk_status == -ESTALE) { 240 if (task->tk_status == -ESTALE) {
237 set_bit(NFS_INO_STALE, &NFS_I(inode)->flags); 241 set_bit(NFS_INO_STALE, &NFS_I(inode)->flags);
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index f68083db63c8..babebbccae2a 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -145,13 +145,6 @@ static void nfs_io_completion_put(struct nfs_io_completion *ioc)
145 kref_put(&ioc->refcount, nfs_io_completion_release); 145 kref_put(&ioc->refcount, nfs_io_completion_release);
146} 146}
147 147
148static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error)
149{
150 ctx->error = error;
151 smp_wmb();
152 set_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
153}
154
155static struct nfs_page * 148static struct nfs_page *
156nfs_page_private_request(struct page *page) 149nfs_page_private_request(struct page *page)
157{ 150{
@@ -1383,6 +1376,8 @@ static void nfs_initiate_write(struct nfs_pgio_header *hdr,
1383 1376
1384 task_setup_data->priority = priority; 1377 task_setup_data->priority = priority;
1385 rpc_ops->write_setup(hdr, msg); 1378 rpc_ops->write_setup(hdr, msg);
1379 trace_nfs_initiate_write(hdr->inode, hdr->io_start, hdr->good_bytes,
1380 hdr->args.stable);
1386 1381
1387 nfs4_state_protect_write(NFS_SERVER(hdr->inode)->nfs_client, 1382 nfs4_state_protect_write(NFS_SERVER(hdr->inode)->nfs_client,
1388 &task_setup_data->rpc_client, msg, hdr); 1383 &task_setup_data->rpc_client, msg, hdr);
@@ -1540,7 +1535,10 @@ static int nfs_writeback_done(struct rpc_task *task,
1540 status = NFS_PROTO(inode)->write_done(task, hdr); 1535 status = NFS_PROTO(inode)->write_done(task, hdr);
1541 if (status != 0) 1536 if (status != 0)
1542 return status; 1537 return status;
1538
1543 nfs_add_stats(inode, NFSIOS_SERVERWRITTENBYTES, hdr->res.count); 1539 nfs_add_stats(inode, NFSIOS_SERVERWRITTENBYTES, hdr->res.count);
1540 trace_nfs_writeback_done(inode, task->tk_status,
1541 hdr->args.offset, hdr->res.verf);
1544 1542
1545 if (hdr->res.verf->committed < hdr->args.stable && 1543 if (hdr->res.verf->committed < hdr->args.stable &&
1546 task->tk_status >= 0) { 1544 task->tk_status >= 0) {
@@ -1669,6 +1667,7 @@ int nfs_initiate_commit(struct rpc_clnt *clnt, struct nfs_commit_data *data,
1669 }; 1667 };
1670 /* Set up the initial task struct. */ 1668 /* Set up the initial task struct. */
1671 nfs_ops->commit_setup(data, &msg); 1669 nfs_ops->commit_setup(data, &msg);
1670 trace_nfs_initiate_commit(data);
1672 1671
1673 dprintk("NFS: initiated commit call\n"); 1672 dprintk("NFS: initiated commit call\n");
1674 1673
@@ -1793,6 +1792,7 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata)
1793 1792
1794 /* Call the NFS version-specific code */ 1793 /* Call the NFS version-specific code */
1795 NFS_PROTO(data->inode)->commit_done(task, data); 1794 NFS_PROTO(data->inode)->commit_done(task, data);
1795 trace_nfs_commit_done(data);
1796} 1796}
1797 1797
1798static void nfs_commit_release_pages(struct nfs_commit_data *data) 1798static void nfs_commit_release_pages(struct nfs_commit_data *data)