Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6ed0529f authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents 9e0ce554 bf4b4905
Loading
Loading
Loading
Loading
+10 −6
Original line number Diff line number Diff line
@@ -208,21 +208,19 @@ EXPORT_SYMBOL_GPL(nfs_file_mmap);
 * fall back to doing a synchronous write.
 */
static int
nfs_file_fsync_commit(struct file *file, loff_t start, loff_t end, int datasync)
nfs_file_fsync_commit(struct file *file, int datasync)
{
	struct nfs_open_context *ctx = nfs_file_open_context(file);
	struct inode *inode = file_inode(file);
	int have_error, do_resend, status;
	int do_resend, status;
	int ret = 0;

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

	nfs_inc_stats(inode, NFSIOS_VFSFSYNC);
	do_resend = test_and_clear_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags);
	have_error = test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
	status = nfs_commit_inode(inode, FLUSH_SYNC);
	have_error |= test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
	if (have_error) {
	if (test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags)) {
		ret = xchg(&ctx->error, 0);
		if (ret)
			goto out;
@@ -247,10 +245,16 @@ nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
	trace_nfs_fsync_enter(inode);

	do {
		struct nfs_open_context *ctx = nfs_file_open_context(file);
		ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
		if (test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags)) {
			int ret2 = xchg(&ctx->error, 0);
			if (ret2)
				ret = ret2;
		}
		if (ret != 0)
			break;
		ret = nfs_file_fsync_commit(file, start, end, datasync);
		ret = nfs_file_fsync_commit(file, datasync);
		if (!ret)
			ret = pnfs_sync_inode(inode, !!datasync);
		/*
+7 −0
Original line number Diff line number Diff line
@@ -768,3 +768,10 @@ static inline bool nfs_error_is_fatal(int err)
		return false;
	}
}

static inline void nfs_context_set_write_error(struct nfs_open_context *ctx, int error)
{
	ctx->error = error;
	smp_wmb();
	set_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
}
+248 −0
Original line number Diff line number Diff line
@@ -719,6 +719,254 @@ TRACE_EVENT(nfs_sillyrename_unlink,
			__get_str(name)
		)
);

TRACE_EVENT(nfs_initiate_read,
		TP_PROTO(
			const struct inode *inode,
			loff_t offset, unsigned long count
		),

		TP_ARGS(inode, offset, count),

		TP_STRUCT__entry(
			__field(loff_t, offset)
			__field(unsigned long, count)
			__field(dev_t, dev)
			__field(u32, fhandle)
			__field(u64, fileid)
		),

		TP_fast_assign(
			const struct nfs_inode *nfsi = NFS_I(inode);

			__entry->offset = offset;
			__entry->count = count;
			__entry->dev = inode->i_sb->s_dev;
			__entry->fileid = nfsi->fileid;
			__entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
		),

		TP_printk(
			"fileid=%02x:%02x:%llu fhandle=0x%08x "
			"offset=%lld count=%lu",
			MAJOR(__entry->dev), MINOR(__entry->dev),
			(unsigned long long)__entry->fileid,
			__entry->fhandle,
			__entry->offset, __entry->count
		)
);

TRACE_EVENT(nfs_readpage_done,
		TP_PROTO(
			const struct inode *inode,
			int status, loff_t offset, bool eof
		),

		TP_ARGS(inode, status, offset, eof),

		TP_STRUCT__entry(
			__field(int, status)
			__field(loff_t, offset)
			__field(bool, eof)
			__field(dev_t, dev)
			__field(u32, fhandle)
			__field(u64, fileid)
		),

		TP_fast_assign(
			const struct nfs_inode *nfsi = NFS_I(inode);

			__entry->status = status;
			__entry->offset = offset;
			__entry->eof = eof;
			__entry->dev = inode->i_sb->s_dev;
			__entry->fileid = nfsi->fileid;
			__entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
		),

		TP_printk(
			"fileid=%02x:%02x:%llu fhandle=0x%08x "
			"offset=%lld status=%d%s",
			MAJOR(__entry->dev), MINOR(__entry->dev),
			(unsigned long long)__entry->fileid,
			__entry->fhandle,
			__entry->offset, __entry->status,
			__entry->eof ? " eof" : ""
		)
);

/*
 * XXX: I tried using NFS_UNSTABLE and friends in this table, but they
 * all evaluate to 0 for some reason, even if I include linux/nfs.h.
 */
#define nfs_show_stable(stable) \
	__print_symbolic(stable, \
			{ 0, " (UNSTABLE)" }, \
			{ 1, " (DATA_SYNC)" }, \
			{ 2, " (FILE_SYNC)" })

TRACE_EVENT(nfs_initiate_write,
		TP_PROTO(
			const struct inode *inode,
			loff_t offset, unsigned long count,
			enum nfs3_stable_how stable
		),

		TP_ARGS(inode, offset, count, stable),

		TP_STRUCT__entry(
			__field(loff_t, offset)
			__field(unsigned long, count)
			__field(enum nfs3_stable_how, stable)
			__field(dev_t, dev)
			__field(u32, fhandle)
			__field(u64, fileid)
		),

		TP_fast_assign(
			const struct nfs_inode *nfsi = NFS_I(inode);

			__entry->offset = offset;
			__entry->count = count;
			__entry->stable = stable;
			__entry->dev = inode->i_sb->s_dev;
			__entry->fileid = nfsi->fileid;
			__entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
		),

		TP_printk(
			"fileid=%02x:%02x:%llu fhandle=0x%08x "
			"offset=%lld count=%lu stable=%d%s",
			MAJOR(__entry->dev), MINOR(__entry->dev),
			(unsigned long long)__entry->fileid,
			__entry->fhandle,
			__entry->offset, __entry->count,
			__entry->stable, nfs_show_stable(__entry->stable)
		)
);

TRACE_EVENT(nfs_writeback_done,
		TP_PROTO(
			const struct inode *inode,
			int status,
			loff_t offset,
			struct nfs_writeverf *writeverf
		),

		TP_ARGS(inode, status, offset, writeverf),

		TP_STRUCT__entry(
			__field(int, status)
			__field(loff_t, offset)
			__field(enum nfs3_stable_how, stable)
			__field(unsigned long long, verifier)
			__field(dev_t, dev)
			__field(u32, fhandle)
			__field(u64, fileid)
		),

		TP_fast_assign(
			const struct nfs_inode *nfsi = NFS_I(inode);

			__entry->status = status;
			__entry->offset = offset;
			__entry->stable = writeverf->committed;
			memcpy(&__entry->verifier, &writeverf->verifier,
			       sizeof(__entry->verifier));
			__entry->dev = inode->i_sb->s_dev;
			__entry->fileid = nfsi->fileid;
			__entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
		),

		TP_printk(
			"fileid=%02x:%02x:%llu fhandle=0x%08x "
			"offset=%lld status=%d stable=%d%s "
			"verifier 0x%016llx",
			MAJOR(__entry->dev), MINOR(__entry->dev),
			(unsigned long long)__entry->fileid,
			__entry->fhandle,
			__entry->offset, __entry->status,
			__entry->stable, nfs_show_stable(__entry->stable),
			__entry->verifier
		)
);

TRACE_EVENT(nfs_initiate_commit,
		TP_PROTO(
			const struct nfs_commit_data *data
		),

		TP_ARGS(data),

		TP_STRUCT__entry(
			__field(loff_t, offset)
			__field(unsigned long, count)
			__field(dev_t, dev)
			__field(u32, fhandle)
			__field(u64, fileid)
		),

		TP_fast_assign(
			const struct inode *inode = data->inode;
			const struct nfs_inode *nfsi = NFS_I(inode);

			__entry->offset = data->args.offset;
			__entry->count = data->args.count;
			__entry->dev = inode->i_sb->s_dev;
			__entry->fileid = nfsi->fileid;
			__entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
		),

		TP_printk(
			"fileid=%02x:%02x:%llu fhandle=0x%08x "
			"offset=%lld count=%lu",
			MAJOR(__entry->dev), MINOR(__entry->dev),
			(unsigned long long)__entry->fileid,
			__entry->fhandle,
			__entry->offset, __entry->count
		)
);

TRACE_EVENT(nfs_commit_done,
		TP_PROTO(
			const struct nfs_commit_data *data
		),

		TP_ARGS(data),

		TP_STRUCT__entry(
			__field(int, status)
			__field(loff_t, offset)
			__field(unsigned long long, verifier)
			__field(dev_t, dev)
			__field(u32, fhandle)
			__field(u64, fileid)
		),

		TP_fast_assign(
			const struct inode *inode = data->inode;
			const struct nfs_inode *nfsi = NFS_I(inode);

			__entry->status = data->res.op_status;
			__entry->offset = data->args.offset;
			memcpy(&__entry->verifier, &data->verf.verifier,
			       sizeof(__entry->verifier));
			__entry->dev = inode->i_sb->s_dev;
			__entry->fileid = nfsi->fileid;
			__entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
		),

		TP_printk(
			"fileid=%02x:%02x:%llu fhandle=0x%08x "
			"offset=%lld status=%d verifier 0x%016llx",
			MAJOR(__entry->dev), MINOR(__entry->dev),
			(unsigned long long)__entry->fileid,
			__entry->fhandle,
			__entry->offset, __entry->status,
			__entry->verifier
		)
);

#endif /* _TRACE_NFS_H */

#undef TRACE_INCLUDE_PATH
+2 −2
Original line number Diff line number Diff line
@@ -1170,7 +1170,7 @@ int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,

		/* remember fatal errors */
		if (nfs_error_is_fatal(desc->pg_error))
			mapping_set_error(desc->pg_inode->i_mapping,
			nfs_context_set_write_error(req->wb_context,
						    desc->pg_error);

		func = desc->pg_completion_ops->error_cleanup;
+9 −5
Original line number Diff line number Diff line
@@ -1664,7 +1664,7 @@ pnfs_update_layout(struct inode *ino,
		.offset = pos,
		.length = count,
	};
	unsigned pg_offset, seq;
	unsigned pg_offset;
	struct nfs_server *server = NFS_SERVER(ino);
	struct nfs_client *clp = server->nfs_client;
	struct pnfs_layout_hdr *lo = NULL;
@@ -1754,10 +1754,14 @@ pnfs_update_layout(struct inode *ino,
		}

		first = true;
		do {
			seq = read_seqbegin(&ctx->state->seqlock);
			nfs4_stateid_copy(&stateid, &ctx->state->stateid);
		} while (read_seqretry(&ctx->state->seqlock, seq));
		if (nfs4_select_rw_stateid(ctx->state,
					iomode == IOMODE_RW ? FMODE_WRITE : FMODE_READ,
					NULL, &stateid, NULL) != 0) {
			trace_pnfs_update_layout(ino, pos, count,
					iomode, lo, lseg,
					PNFS_UPDATE_LAYOUT_INVALID_OPEN);
			goto out_unlock;
		}
	} else {
		nfs4_stateid_copy(&stateid, &lo->plh_stateid);
	}
Loading