Skip to content

Commit 6ed0529

Browse files
committed
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
2 parents 9e0ce55 + bf4b490 commit 6ed0529

File tree

7 files changed

+287
-20
lines changed

7 files changed

+287
-20
lines changed

fs/nfs/file.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -208,21 +208,19 @@ EXPORT_SYMBOL_GPL(nfs_file_mmap);
208208
* fall back to doing a synchronous write.
209209
*/
210210
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)
212212
{
213213
struct nfs_open_context *ctx = nfs_file_open_context(file);
214214
struct inode *inode = file_inode(file);
215-
int have_error, do_resend, status;
215+
int do_resend, status;
216216
int ret = 0;
217217

218218
dprintk("NFS: fsync file(%pD2) datasync %d\n", file, datasync);
219219

220220
nfs_inc_stats(inode, NFSIOS_VFSFSYNC);
221221
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);
223222
status = nfs_commit_inode(inode, FLUSH_SYNC);
224-
have_error |= test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
225-
if (have_error) {
223+
if (test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags)) {
226224
ret = xchg(&ctx->error, 0);
227225
if (ret)
228226
goto out;
@@ -247,10 +245,16 @@ nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
247245
trace_nfs_fsync_enter(inode);
248246

249247
do {
248+
struct nfs_open_context *ctx = nfs_file_open_context(file);
250249
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+
}
251255
if (ret != 0)
252256
break;
253-
ret = nfs_file_fsync_commit(file, start, end, datasync);
257+
ret = nfs_file_fsync_commit(file, datasync);
254258
if (!ret)
255259
ret = pnfs_sync_inode(inode, !!datasync);
256260
/*

fs/nfs/internal.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -768,3 +768,10 @@ static inline bool nfs_error_is_fatal(int err)
768768
return false;
769769
}
770770
}
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+
}

fs/nfs/nfstrace.h

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,254 @@ TRACE_EVENT(nfs_sillyrename_unlink,
719719
__get_str(name)
720720
)
721721
);
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+
722970
#endif /* _TRACE_NFS_H */
723971

724972
#undef TRACE_INCLUDE_PATH

fs/nfs/pagelist.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,8 +1170,8 @@ int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
11701170

11711171
/* remember fatal errors */
11721172
if (nfs_error_is_fatal(desc->pg_error))
1173-
mapping_set_error(desc->pg_inode->i_mapping,
1174-
desc->pg_error);
1173+
nfs_context_set_write_error(req->wb_context,
1174+
desc->pg_error);
11751175

11761176
func = desc->pg_completion_ops->error_cleanup;
11771177
for (midx = 0; midx < desc->pg_mirror_count; midx++) {

fs/nfs/pnfs.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1664,7 +1664,7 @@ pnfs_update_layout(struct inode *ino,
16641664
.offset = pos,
16651665
.length = count,
16661666
};
1667-
unsigned pg_offset, seq;
1667+
unsigned pg_offset;
16681668
struct nfs_server *server = NFS_SERVER(ino);
16691669
struct nfs_client *clp = server->nfs_client;
16701670
struct pnfs_layout_hdr *lo = NULL;
@@ -1754,10 +1754,14 @@ pnfs_update_layout(struct inode *ino,
17541754
}
17551755

17561756
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));
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+
}
17611765
} else {
17621766
nfs4_stateid_copy(&stateid, &lo->plh_stateid);
17631767
}

fs/nfs/read.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "iostat.h"
2626
#include "fscache.h"
2727
#include "pnfs.h"
28+
#include "nfstrace.h"
2829

2930
#define NFSDBG_FACILITY NFSDBG_PAGECACHE
3031

@@ -200,6 +201,7 @@ static void nfs_initiate_read(struct nfs_pgio_header *hdr,
200201

201202
task_setup_data->flags |= swap_flags;
202203
rpc_ops->read_setup(hdr, msg);
204+
trace_nfs_initiate_read(inode, hdr->io_start, hdr->good_bytes);
203205
}
204206

205207
static void
@@ -232,6 +234,8 @@ static int nfs_readpage_done(struct rpc_task *task,
232234
return status;
233235

234236
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);
235239

236240
if (task->tk_status == -ESTALE) {
237241
set_bit(NFS_INO_STALE, &NFS_I(inode)->flags);

0 commit comments

Comments
 (0)