Commit 66b83455 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull NFS client updates from Anna Schumaker:
 "New Features:
   - Add NFSv4.2 xattr tracepoints
   - Replace xprtiod WQ in rpcrdma
   - Flexfiles cancels I/O on layout recall or revoke

  Bugfixes and Cleanups:
   - Directly use ida_alloc() / ida_free()
   - Don't open-code max_t()
   - Prefer using strscpy over strlcpy
   - Remove unused forward declarations
   - Always return layout states on flexfiles layout return
   - Have LISTXATTR treat NFS4ERR_NOXATTR as an empty reply instead of
     error
   - Allow more xprtrdma memory allocations to fail without triggering a
     reclaim
   - Various other xprtrdma clean ups
   - Fix rpc_killall_tasks() races"

* tag 'nfs-for-6.1-1' of git://git.linux-nfs.org/projects/anna/linux-nfs: (27 commits)
  NFSv4/flexfiles: Cancel I/O if the layout is recalled or revoked
  SUNRPC: Add API to force the client to disconnect
  SUNRPC: Add a helper to allow pNFS drivers to selectively cancel RPC calls
  SUNRPC: Fix races with rpc_killall_tasks()
  xprtrdma: Fix uninitialized variable
  xprtrdma: Prevent memory allocations from driving a reclaim
  xprtrdma: Memory allocation should be allowed to fail during connect
  xprtrdma: MR-related memory allocation should be allowed to fail
  xprtrdma: Clean up synopsis of rpcrdma_regbuf_alloc()
  xprtrdma: Clean up synopsis of rpcrdma_req_create()
  svcrdma: Clean up RPCRDMA_DEF_GFP
  SUNRPC: Replace the use of the xprtiod WQ in rpcrdma
  NFSv4.2: Add a tracepoint for listxattr
  NFSv4.2: Add tracepoints for getxattr, setxattr, and removexattr
  NFSv4.2: Move TRACE_DEFINE_ENUM(NFS4_CONTENT_*) under CONFIG_NFS_V4_2
  NFSv4.2: Add special handling for LISTXATTR receiving NFS4ERR_NOXATTR
  nfs: remove nfs_wait_atomic_killable() and nfs_write_prepare() declaration
  NFSv4: remove nfs4_renewd_prepare_shutdown() declaration
  fs/nfs/pnfs_nfs.c: fix spelling typo and syntax error in comment
  NFSv4/pNFS: Always return layout stats on layout return for flexfiles
  ...
parents 531d3b5f b739a5bd
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -656,7 +656,7 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
			goto out;
	}
	if (mntflags & NFS_MOUNT_WRITE_WAIT) {
		result = filemap_fdatawait_range(file->f_mapping,
		filemap_fdatawait_range(file->f_mapping,
					iocb->ki_pos - written,
					iocb->ki_pos - 1);
	}
+99 −10
Original line number Diff line number Diff line
@@ -30,14 +30,20 @@
#define FF_LAYOUT_POLL_RETRY_MAX     (15*HZ)
#define FF_LAYOUTRETURN_MAXERR 20

enum nfs4_ff_op_type {
	NFS4_FF_OP_LAYOUTSTATS,
	NFS4_FF_OP_LAYOUTRETURN,
};

static unsigned short io_maxretrans;

static const struct pnfs_commit_ops ff_layout_commit_ops;
static void ff_layout_read_record_layoutstats_done(struct rpc_task *task,
		struct nfs_pgio_header *hdr);
static int ff_layout_mirror_prepare_stats(struct pnfs_layout_hdr *lo,
static int
ff_layout_mirror_prepare_stats(struct pnfs_layout_hdr *lo,
			       struct nfs42_layoutstat_devinfo *devinfo,
			       int dev_limit);
			       int dev_limit, enum nfs4_ff_op_type type);
static void ff_layout_encode_ff_layoutupdate(struct xdr_stream *xdr,
			      const struct nfs42_layoutstat_devinfo *devinfo,
			      struct nfs4_ff_layout_mirror *mirror);
@@ -1373,6 +1379,11 @@ static int ff_layout_read_prepare_common(struct rpc_task *task,
		return -EIO;
	}

	if (!pnfs_is_valid_lseg(hdr->lseg)) {
		rpc_exit(task, -EAGAIN);
		return -EAGAIN;
	}

	ff_layout_read_record_layoutstats_start(task, hdr);
	return 0;
}
@@ -1553,6 +1564,11 @@ static int ff_layout_write_prepare_common(struct rpc_task *task,
		return -EIO;
	}

	if (!pnfs_is_valid_lseg(hdr->lseg)) {
		rpc_exit(task, -EAGAIN);
		return -EAGAIN;
	}

	ff_layout_write_record_layoutstats_start(task, hdr);
	return 0;
}
@@ -1645,15 +1661,23 @@ static void ff_layout_commit_record_layoutstats_done(struct rpc_task *task,
	set_bit(NFS_LSEG_LAYOUTRETURN, &cdata->lseg->pls_flags);
}

static void ff_layout_commit_prepare_common(struct rpc_task *task,
static int ff_layout_commit_prepare_common(struct rpc_task *task,
					   struct nfs_commit_data *cdata)
{
	if (!pnfs_is_valid_lseg(cdata->lseg)) {
		rpc_exit(task, -EAGAIN);
		return -EAGAIN;
	}

	ff_layout_commit_record_layoutstats_start(task, cdata);
	return 0;
}

static void ff_layout_commit_prepare_v3(struct rpc_task *task, void *data)
{
	ff_layout_commit_prepare_common(task, data);
	if (ff_layout_commit_prepare_common(task, data))
		return;

	rpc_call_start(task);
}

@@ -1949,6 +1973,65 @@ ff_layout_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
					    ff_layout_initiate_commit);
}

static bool ff_layout_match_rw(const struct rpc_task *task,
			       const struct nfs_pgio_header *hdr,
			       const struct pnfs_layout_segment *lseg)
{
	return hdr->lseg == lseg;
}

static bool ff_layout_match_commit(const struct rpc_task *task,
				   const struct nfs_commit_data *cdata,
				   const struct pnfs_layout_segment *lseg)
{
	return cdata->lseg == lseg;
}

static bool ff_layout_match_io(const struct rpc_task *task, const void *data)
{
	const struct rpc_call_ops *ops = task->tk_ops;

	if (ops == &ff_layout_read_call_ops_v3 ||
	    ops == &ff_layout_read_call_ops_v4 ||
	    ops == &ff_layout_write_call_ops_v3 ||
	    ops == &ff_layout_write_call_ops_v4)
		return ff_layout_match_rw(task, task->tk_calldata, data);
	if (ops == &ff_layout_commit_call_ops_v3 ||
	    ops == &ff_layout_commit_call_ops_v4)
		return ff_layout_match_commit(task, task->tk_calldata, data);
	return false;
}

static void ff_layout_cancel_io(struct pnfs_layout_segment *lseg)
{
	struct nfs4_ff_layout_segment *flseg = FF_LAYOUT_LSEG(lseg);
	struct nfs4_ff_layout_mirror *mirror;
	struct nfs4_ff_layout_ds *mirror_ds;
	struct nfs4_pnfs_ds *ds;
	struct nfs_client *ds_clp;
	struct rpc_clnt *clnt;
	u32 idx;

	for (idx = 0; idx < flseg->mirror_array_cnt; idx++) {
		mirror = flseg->mirror_array[idx];
		mirror_ds = mirror->mirror_ds;
		if (!mirror_ds)
			continue;
		ds = mirror->mirror_ds->ds;
		if (!ds)
			continue;
		ds_clp = ds->ds_clp;
		if (!ds_clp)
			continue;
		clnt = ds_clp->cl_rpcclient;
		if (!clnt)
			continue;
		if (!rpc_cancel_tasks(clnt, -EAGAIN, ff_layout_match_io, lseg))
			continue;
		rpc_clnt_disconnect(clnt);
	}
}

static struct pnfs_ds_commit_info *
ff_layout_get_ds_info(struct inode *inode)
{
@@ -2161,8 +2244,9 @@ ff_layout_prepare_layoutreturn(struct nfs4_layoutreturn_args *args)
			FF_LAYOUTRETURN_MAXERR);

	spin_lock(&args->inode->i_lock);
	ff_args->num_dev = ff_layout_mirror_prepare_stats(&ff_layout->generic_hdr,
			&ff_args->devinfo[0], ARRAY_SIZE(ff_args->devinfo));
	ff_args->num_dev = ff_layout_mirror_prepare_stats(
		&ff_layout->generic_hdr, &ff_args->devinfo[0],
		ARRAY_SIZE(ff_args->devinfo), NFS4_FF_OP_LAYOUTRETURN);
	spin_unlock(&args->inode->i_lock);

	args->ld_private->ops = &layoutreturn_ops;
@@ -2396,7 +2480,7 @@ static const struct nfs4_xdr_opaque_ops layoutstat_ops = {
static int
ff_layout_mirror_prepare_stats(struct pnfs_layout_hdr *lo,
			       struct nfs42_layoutstat_devinfo *devinfo,
			       int dev_limit)
			       int dev_limit, enum nfs4_ff_op_type type)
{
	struct nfs4_flexfile_layout *ff_layout = FF_LAYOUT_FROM_HDR(lo);
	struct nfs4_ff_layout_mirror *mirror;
@@ -2408,7 +2492,9 @@ ff_layout_mirror_prepare_stats(struct pnfs_layout_hdr *lo,
			break;
		if (IS_ERR_OR_NULL(mirror->mirror_ds))
			continue;
		if (!test_and_clear_bit(NFS4_FF_MIRROR_STAT_AVAIL, &mirror->flags))
		if (!test_and_clear_bit(NFS4_FF_MIRROR_STAT_AVAIL,
					&mirror->flags) &&
		    type != NFS4_FF_OP_LAYOUTRETURN)
			continue;
		/* mirror refcount put in cleanup_layoutstats */
		if (!refcount_inc_not_zero(&mirror->ref))
@@ -2448,7 +2534,9 @@ ff_layout_prepare_layoutstats(struct nfs42_layoutstat_args *args)
	spin_lock(&args->inode->i_lock);
	ff_layout = FF_LAYOUT_FROM_HDR(NFS_I(args->inode)->layout);
	args->num_dev = ff_layout_mirror_prepare_stats(&ff_layout->generic_hdr,
			&args->devinfo[0], dev_count);
						       &args->devinfo[0],
						       dev_count,
						       NFS4_FF_OP_LAYOUTSTATS);
	spin_unlock(&args->inode->i_lock);
	if (!args->num_dev) {
		kfree(args->devinfo);
@@ -2501,6 +2589,7 @@ static struct pnfs_layoutdriver_type flexfilelayout_type = {
	.prepare_layoutreturn   = ff_layout_prepare_layoutreturn,
	.sync			= pnfs_nfs_generic_sync,
	.prepare_layoutstats	= ff_layout_prepare_layoutstats,
	.cancel_io		= ff_layout_cancel_io,
};

static int __init nfs4flexfilelayout_init(void)
+3 −3
Original line number Diff line number Diff line
@@ -313,7 +313,7 @@ struct nfs_find_desc {
static int
nfs_find_actor(struct inode *inode, void *opaque)
{
	struct nfs_find_desc	*desc = (struct nfs_find_desc *)opaque;
	struct nfs_find_desc	*desc = opaque;
	struct nfs_fh		*fh = desc->fh;
	struct nfs_fattr	*fattr = desc->fattr;

@@ -331,7 +331,7 @@ nfs_find_actor(struct inode *inode, void *opaque)
static int
nfs_init_locked(struct inode *inode, void *opaque)
{
	struct nfs_find_desc	*desc = (struct nfs_find_desc *)opaque;
	struct nfs_find_desc	*desc = opaque;
	struct nfs_fattr	*fattr = desc->fattr;

	set_nfs_fileid(inode, fattr->fileid);
@@ -2267,7 +2267,7 @@ static inline void nfs4_init_once(struct nfs_inode *nfsi)

static void init_once(void *foo)
{
	struct nfs_inode *nfsi = (struct nfs_inode *) foo;
	struct nfs_inode *nfsi = foo;

	inode_init_once(&nfsi->vfs_inode);
	INIT_LIST_HEAD(&nfsi->open_files);
+0 −2
Original line number Diff line number Diff line
@@ -435,7 +435,6 @@ extern void nfs_zap_acl_cache(struct inode *inode);
extern void nfs_set_cache_invalid(struct inode *inode, unsigned long flags);
extern bool nfs_check_cache_invalid(struct inode *, unsigned long);
extern int nfs_wait_bit_killable(struct wait_bit_key *key, int mode);
extern int nfs_wait_atomic_killable(atomic_t *p, unsigned int mode);

/* super.c */
extern const struct super_operations nfs_sops;
@@ -503,7 +502,6 @@ extern void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
			const struct nfs_pgio_completion_ops *compl_ops);
extern void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio);
extern void nfs_commit_free(struct nfs_commit_data *p);
extern void nfs_write_prepare(struct rpc_task *task, void *calldata);
extern void nfs_commit_prepare(struct rpc_task *task, void *calldata);
extern int nfs_initiate_commit(struct rpc_clnt *clnt,
			       struct nfs_commit_data *data,
+4 −0
Original line number Diff line number Diff line
@@ -1175,6 +1175,7 @@ static int _nfs42_proc_removexattr(struct inode *inode, const char *name)

	ret = nfs4_call_sync(server->client, server, &msg, &args.seq_args,
	    &res.seq_res, 1);
	trace_nfs4_removexattr(inode, name, ret);
	if (!ret)
		nfs4_update_changeattr(inode, &res.cinfo, timestamp, 0);

@@ -1214,6 +1215,7 @@ static int _nfs42_proc_setxattr(struct inode *inode, const char *name,

	ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args,
	    &res.seq_res, 1);
	trace_nfs4_setxattr(inode, name, ret);

	for (; np > 0; np--)
		put_page(pages[np - 1]);
@@ -1246,6 +1248,7 @@ static ssize_t _nfs42_proc_getxattr(struct inode *inode, const char *name,

	ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args,
	    &res.seq_res, 0);
	trace_nfs4_getxattr(inode, name, ret);
	if (ret < 0)
		return ret;

@@ -1317,6 +1320,7 @@ static ssize_t _nfs42_proc_listxattrs(struct inode *inode, void *buf,

	ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args,
	    &res.seq_res, 0);
	trace_nfs4_listxattr(inode, ret);

	if (ret >= 0) {
		ret = res.copied;
Loading