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

+287 -20
+10 -6
fs/nfs/file.c
··· 208 * fall back to doing a synchronous write. 209 */ 210 static int 211 - nfs_file_fsync_commit(struct file *file, loff_t start, loff_t end, int datasync) 212 { 213 struct nfs_open_context *ctx = nfs_file_open_context(file); 214 struct inode *inode = file_inode(file); 215 - int have_error, do_resend, status; 216 int ret = 0; 217 218 dprintk("NFS: fsync file(%pD2) datasync %d\n", file, datasync); 219 220 nfs_inc_stats(inode, NFSIOS_VFSFSYNC); 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); 224 - have_error |= test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags); 225 - if (have_error) { 226 ret = xchg(&ctx->error, 0); 227 if (ret) 228 goto out; ··· 245 trace_nfs_fsync_enter(inode); 246 247 do { 248 ret = filemap_write_and_wait_range(inode->i_mapping, start, end); 249 if (ret != 0) 250 break; 251 - ret = nfs_file_fsync_commit(file, start, end, datasync); 252 if (!ret) 253 ret = pnfs_sync_inode(inode, !!datasync); 254 /*
··· 208 * fall back to doing a synchronous write. 209 */ 210 static int 211 + nfs_file_fsync_commit(struct file *file, int datasync) 212 { 213 struct nfs_open_context *ctx = nfs_file_open_context(file); 214 struct inode *inode = file_inode(file); 215 + int do_resend, status; 216 int ret = 0; 217 218 dprintk("NFS: fsync file(%pD2) datasync %d\n", file, datasync); 219 220 nfs_inc_stats(inode, NFSIOS_VFSFSYNC); 221 do_resend = test_and_clear_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags); 222 status = nfs_commit_inode(inode, FLUSH_SYNC); 223 + if (test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags)) { 224 ret = xchg(&ctx->error, 0); 225 if (ret) 226 goto out; ··· 247 trace_nfs_fsync_enter(inode); 248 249 do { 250 + struct nfs_open_context *ctx = nfs_file_open_context(file); 251 ret = filemap_write_and_wait_range(inode->i_mapping, start, end); 252 + if (test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags)) { 253 + int ret2 = xchg(&ctx->error, 0); 254 + if (ret2) 255 + ret = ret2; 256 + } 257 if (ret != 0) 258 break; 259 + ret = nfs_file_fsync_commit(file, datasync); 260 if (!ret) 261 ret = pnfs_sync_inode(inode, !!datasync); 262 /*
+7
fs/nfs/internal.h
··· 768 return false; 769 } 770 }
··· 768 return false; 769 } 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 + }
+248
fs/nfs/nfstrace.h
··· 719 __get_str(name) 720 ) 721 ); 722 #endif /* _TRACE_NFS_H */ 723 724 #undef TRACE_INCLUDE_PATH
··· 719 __get_str(name) 720 ) 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 + 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 + 894 + TRACE_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 + 930 + TRACE_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 + 970 #endif /* _TRACE_NFS_H */ 971 972 #undef TRACE_INCLUDE_PATH
+2 -2
fs/nfs/pagelist.c
··· 1170 1171 /* remember fatal errors */ 1172 if (nfs_error_is_fatal(desc->pg_error)) 1173 - mapping_set_error(desc->pg_inode->i_mapping, 1174 - desc->pg_error); 1175 1176 func = desc->pg_completion_ops->error_cleanup; 1177 for (midx = 0; midx < desc->pg_mirror_count; midx++) {
··· 1170 1171 /* remember fatal errors */ 1172 if (nfs_error_is_fatal(desc->pg_error)) 1173 + nfs_context_set_write_error(req->wb_context, 1174 + desc->pg_error); 1175 1176 func = desc->pg_completion_ops->error_cleanup; 1177 for (midx = 0; midx < desc->pg_mirror_count; midx++) {
+9 -5
fs/nfs/pnfs.c
··· 1664 .offset = pos, 1665 .length = count, 1666 }; 1667 - unsigned pg_offset, seq; 1668 struct nfs_server *server = NFS_SERVER(ino); 1669 struct nfs_client *clp = server->nfs_client; 1670 struct pnfs_layout_hdr *lo = NULL; ··· 1754 } 1755 1756 first = true; 1757 - do { 1758 - seq = read_seqbegin(&ctx->state->seqlock); 1759 - nfs4_stateid_copy(&stateid, &ctx->state->stateid); 1760 - } while (read_seqretry(&ctx->state->seqlock, seq)); 1761 } else { 1762 nfs4_stateid_copy(&stateid, &lo->plh_stateid); 1763 }
··· 1664 .offset = pos, 1665 .length = count, 1666 }; 1667 + unsigned pg_offset; 1668 struct nfs_server *server = NFS_SERVER(ino); 1669 struct nfs_client *clp = server->nfs_client; 1670 struct pnfs_layout_hdr *lo = NULL; ··· 1754 } 1755 1756 first = true; 1757 + if (nfs4_select_rw_stateid(ctx->state, 1758 + iomode == IOMODE_RW ? FMODE_WRITE : FMODE_READ, 1759 + NULL, &stateid, NULL) != 0) { 1760 + trace_pnfs_update_layout(ino, pos, count, 1761 + iomode, lo, lseg, 1762 + PNFS_UPDATE_LAYOUT_INVALID_OPEN); 1763 + goto out_unlock; 1764 + } 1765 } else { 1766 nfs4_stateid_copy(&stateid, &lo->plh_stateid); 1767 }
+4
fs/nfs/read.c
··· 25 #include "iostat.h" 26 #include "fscache.h" 27 #include "pnfs.h" 28 29 #define NFSDBG_FACILITY NFSDBG_PAGECACHE 30 ··· 201 202 task_setup_data->flags |= swap_flags; 203 rpc_ops->read_setup(hdr, msg); 204 } 205 206 static void ··· 234 return status; 235 236 nfs_add_stats(inode, NFSIOS_SERVERREADBYTES, hdr->res.count); 237 238 if (task->tk_status == -ESTALE) { 239 set_bit(NFS_INO_STALE, &NFS_I(inode)->flags);
··· 25 #include "iostat.h" 26 #include "fscache.h" 27 #include "pnfs.h" 28 + #include "nfstrace.h" 29 30 #define NFSDBG_FACILITY NFSDBG_PAGECACHE 31 ··· 200 201 task_setup_data->flags |= swap_flags; 202 rpc_ops->read_setup(hdr, msg); 203 + trace_nfs_initiate_read(inode, hdr->io_start, hdr->good_bytes); 204 } 205 206 static void ··· 232 return status; 233 234 nfs_add_stats(inode, NFSIOS_SERVERREADBYTES, hdr->res.count); 235 + trace_nfs_readpage_done(inode, task->tk_status, 236 + hdr->args.offset, hdr->res.eof); 237 238 if (task->tk_status == -ESTALE) { 239 set_bit(NFS_INO_STALE, &NFS_I(inode)->flags);
+7 -7
fs/nfs/write.c
··· 145 kref_put(&ioc->refcount, nfs_io_completion_release); 146 } 147 148 - static 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 - 155 static struct nfs_page * 156 nfs_page_private_request(struct page *page) 157 { ··· 1376 1377 task_setup_data->priority = priority; 1378 rpc_ops->write_setup(hdr, msg); 1379 1380 nfs4_state_protect_write(NFS_SERVER(hdr->inode)->nfs_client, 1381 &task_setup_data->rpc_client, msg, hdr); ··· 1535 status = NFS_PROTO(inode)->write_done(task, hdr); 1536 if (status != 0) 1537 return status; 1538 nfs_add_stats(inode, NFSIOS_SERVERWRITTENBYTES, hdr->res.count); 1539 1540 if (hdr->res.verf->committed < hdr->args.stable && 1541 task->tk_status >= 0) { ··· 1667 }; 1668 /* Set up the initial task struct. */ 1669 nfs_ops->commit_setup(data, &msg); 1670 1671 dprintk("NFS: initiated commit call\n"); 1672 ··· 1792 1793 /* Call the NFS version-specific code */ 1794 NFS_PROTO(data->inode)->commit_done(task, data); 1795 } 1796 1797 static void nfs_commit_release_pages(struct nfs_commit_data *data)
··· 145 kref_put(&ioc->refcount, nfs_io_completion_release); 146 } 147 148 static struct nfs_page * 149 nfs_page_private_request(struct page *page) 150 { ··· 1383 1384 task_setup_data->priority = priority; 1385 rpc_ops->write_setup(hdr, msg); 1386 + trace_nfs_initiate_write(hdr->inode, hdr->io_start, hdr->good_bytes, 1387 + hdr->args.stable); 1388 1389 nfs4_state_protect_write(NFS_SERVER(hdr->inode)->nfs_client, 1390 &task_setup_data->rpc_client, msg, hdr); ··· 1540 status = NFS_PROTO(inode)->write_done(task, hdr); 1541 if (status != 0) 1542 return status; 1543 + 1544 nfs_add_stats(inode, NFSIOS_SERVERWRITTENBYTES, hdr->res.count); 1545 + trace_nfs_writeback_done(inode, task->tk_status, 1546 + hdr->args.offset, hdr->res.verf); 1547 1548 if (hdr->res.verf->committed < hdr->args.stable && 1549 task->tk_status >= 0) { ··· 1669 }; 1670 /* Set up the initial task struct. */ 1671 nfs_ops->commit_setup(data, &msg); 1672 + trace_nfs_initiate_commit(data); 1673 1674 dprintk("NFS: initiated commit call\n"); 1675 ··· 1793 1794 /* Call the NFS version-specific code */ 1795 NFS_PROTO(data->inode)->commit_done(task, data); 1796 + trace_nfs_commit_done(data); 1797 } 1798 1799 static void nfs_commit_release_pages(struct nfs_commit_data *data)