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

Commit 8f03cf50 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'nfs-for-4.11-1' of git://git.linux-nfs.org/projects/anna/linux-nfs

Pull NFS client updates from Anna Schumaker:
 "Highlights include:

  Stable bugfixes:
   - NFSv4: Fix memory and state leak in _nfs4_open_and_get_state
   - xprtrdma: Fix Read chunk padding
   - xprtrdma: Per-connection pad optimization
   - xprtrdma: Disable pad optimization by default
   - xprtrdma: Reduce required number of send SGEs
   - nlm: Ensure callback code also checks that the files match
   - pNFS/flexfiles: If the layout is invalid, it must be updated before
     retrying
   - NFSv4: Fix reboot recovery in copy offload
   - Revert "NFSv4.1: Handle NFS4ERR_BADSESSION/NFS4ERR_DEADSESSION
     replies to OP_SEQUENCE"
   - NFSv4: fix getacl head length estimation
   - NFSv4: fix getacl ERANGE for sum ACL buffer sizes

  Features:
   - Add and use dprintk_cont macros
   - Various cleanups to NFS v4.x to reduce code duplication and
     complexity
   - Remove unused cr_magic related code
   - Improvements to sunrpc "read from buffer" code
   - Clean up sunrpc timeout code and allow changing TCP timeout
     parameters
   - Remove duplicate mw_list management code in xprtrdma
   - Add generic functions for encoding and decoding xdr streams

  Bugfixes:
   - Clean up nfs_show_mountd_netid
   - Make layoutreturn_ops static and use NULL instead of 0 to fix
     sparse warnings
   - Properly handle -ERESTARTSYS in nfs_rename()
   - Check if register_shrinker() failed during rpcauth_init()
   - Properly clean up procfs/pipefs entries
   - Various NFS over RDMA related fixes
   - Silence unititialized variable warning in sunrpc"

* tag 'nfs-for-4.11-1' of git://git.linux-nfs.org/projects/anna/linux-nfs: (64 commits)
  NFSv4: fix getacl ERANGE for some ACL buffer sizes
  NFSv4: fix getacl head length estimation
  Revert "NFSv4.1: Handle NFS4ERR_BADSESSION/NFS4ERR_DEADSESSION replies to OP_SEQUENCE"
  NFSv4: Fix reboot recovery in copy offload
  pNFS/flexfiles: If the layout is invalid, it must be updated before retrying
  NFSv4: Clean up owner/group attribute decode
  SUNRPC: Add a helper function xdr_stream_decode_string_dup()
  NFSv4: Remove bogus "struct nfs_client" argument from decode_ace()
  NFSv4: Fix the underestimation of delegation XDR space reservation
  NFSv4: Replace callback string decode function with a generic
  NFSv4: Replace the open coded decode_opaque_inline() with the new generic
  NFSv4: Replace ad-hoc xdr encode/decode helpers with xdr_stream_* generics
  SUNRPC: Add generic helpers for xdr_stream encode/decode
  sunrpc: silence uninitialized variable warning
  nlm: Ensure callback code also checks that the files match
  sunrpc: Allow xprt->ops->timer method to sleep
  xprtrdma: Refactor management of mw_list field
  xprtrdma: Handle stale connection rejection
  xprtrdma: Properly recover FRWRs with in-flight FASTREG WRs
  xprtrdma: Shrink send SGEs array
  ...
parents 25c4e6c3 ed92d8c1
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -141,7 +141,6 @@ int nfs_cache_register_net(struct net *net, struct cache_detail *cd)

void nfs_cache_unregister_sb(struct super_block *sb, struct cache_detail *cd)
{
	if (cd->u.pipefs.dir)
	sunrpc_cache_unregister_pipefs(cd);
}

+10 −28
Original line number Diff line number Diff line
@@ -83,23 +83,15 @@ static __be32 *read_buf(struct xdr_stream *xdr, size_t nbytes)
	return p;
}

static __be32 decode_string(struct xdr_stream *xdr, unsigned int *len, const char **str)
static __be32 decode_string(struct xdr_stream *xdr, unsigned int *len,
		const char **str, size_t maxlen)
{
	__be32 *p;

	p = read_buf(xdr, 4);
	if (unlikely(p == NULL))
		return htonl(NFS4ERR_RESOURCE);
	*len = ntohl(*p);

	if (*len != 0) {
		p = read_buf(xdr, *len);
		if (unlikely(p == NULL))
			return htonl(NFS4ERR_RESOURCE);
		*str = (const char *)p;
	} else
		*str = NULL;
	ssize_t err;

	err = xdr_stream_decode_opaque_inline(xdr, (void **)str, maxlen);
	if (err < 0)
		return cpu_to_be32(NFS4ERR_RESOURCE);
	*len = err;
	return 0;
}

@@ -162,15 +154,9 @@ static __be32 decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound
	__be32 *p;
	__be32 status;

	status = decode_string(xdr, &hdr->taglen, &hdr->tag);
	status = decode_string(xdr, &hdr->taglen, &hdr->tag, CB_OP_TAGLEN_MAXSZ);
	if (unlikely(status != 0))
		return status;
	/* We do not like overly long tags! */
	if (hdr->taglen > CB_OP_TAGLEN_MAXSZ) {
		printk("NFS: NFSv4 CALLBACK %s: client sent tag of length %u\n",
				__func__, hdr->taglen);
		return htonl(NFS4ERR_RESOURCE);
	}
	p = read_buf(xdr, 12);
	if (unlikely(p == NULL))
		return htonl(NFS4ERR_RESOURCE);
@@ -582,12 +568,8 @@ static __be32 decode_notify_lock_args(struct svc_rqst *rqstp, struct xdr_stream

static __be32 encode_string(struct xdr_stream *xdr, unsigned int len, const char *str)
{
	__be32 *p;

	p = xdr_reserve_space(xdr, 4 + len);
	if (unlikely(p == NULL))
		return htonl(NFS4ERR_RESOURCE);
	xdr_encode_opaque(p, str, len);
	if (unlikely(xdr_stream_encode_opaque(xdr, str, len) < 0))
		return cpu_to_be32(NFS4ERR_RESOURCE);
	return 0;
}

+25 −11
Original line number Diff line number Diff line
@@ -2002,6 +2002,29 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
}
EXPORT_SYMBOL_GPL(nfs_link);

static void
nfs_complete_rename(struct rpc_task *task, struct nfs_renamedata *data)
{
	struct dentry *old_dentry = data->old_dentry;
	struct dentry *new_dentry = data->new_dentry;
	struct inode *old_inode = d_inode(old_dentry);
	struct inode *new_inode = d_inode(new_dentry);

	nfs_mark_for_revalidate(old_inode);

	switch (task->tk_status) {
	case 0:
		if (new_inode != NULL)
			nfs_drop_nlink(new_inode);
		d_move(old_dentry, new_dentry);
		nfs_set_verifier(new_dentry,
					nfs_save_change_attribute(data->new_dir));
		break;
	case -ENOENT:
		nfs_dentry_handle_enoent(old_dentry);
	}
}

/*
 * RENAME
 * FIXME: Some nfsds, like the Linux user space nfsd, may generate a
@@ -2084,7 +2107,8 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
	if (new_inode != NULL)
		NFS_PROTO(new_inode)->return_delegation(new_inode);

	task = nfs_async_rename(old_dir, new_dir, old_dentry, new_dentry, NULL);
	task = nfs_async_rename(old_dir, new_dir, old_dentry, new_dentry,
					nfs_complete_rename);
	if (IS_ERR(task)) {
		error = PTR_ERR(task);
		goto out;
@@ -2094,21 +2118,11 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
	if (error == 0)
		error = task->tk_status;
	rpc_put_task(task);
	nfs_mark_for_revalidate(old_inode);
out:
	if (rehash)
		d_rehash(rehash);
	trace_nfs_rename_exit(old_dir, old_dentry,
			new_dir, new_dentry, error);
	if (!error) {
		if (new_inode != NULL)
			nfs_drop_nlink(new_inode);
		d_move(old_dentry, new_dentry);
		nfs_set_verifier(new_dentry,
					nfs_save_change_attribute(new_dir));
	} else if (error == -ENOENT)
		nfs_dentry_handle_enoent(old_dentry);

	/* new dentry created? */
	if (dentry)
		dput(dentry);
+3 −3
Original line number Diff line number Diff line
@@ -305,7 +305,7 @@ static void filelayout_read_prepare(struct rpc_task *task, void *data)
	}
	hdr->pgio_done_cb = filelayout_read_done_cb;

	if (nfs41_setup_sequence(hdr->ds_clp->cl_session,
	if (nfs4_setup_sequence(hdr->ds_clp,
			&hdr->args.seq_args,
			&hdr->res.seq_res,
			task))
@@ -403,7 +403,7 @@ static void filelayout_write_prepare(struct rpc_task *task, void *data)
		rpc_exit(task, 0);
		return;
	}
	if (nfs41_setup_sequence(hdr->ds_clp->cl_session,
	if (nfs4_setup_sequence(hdr->ds_clp,
			&hdr->args.seq_args,
			&hdr->res.seq_res,
			task))
@@ -438,7 +438,7 @@ static void filelayout_commit_prepare(struct rpc_task *task, void *data)
{
	struct nfs_commit_data *wdata = data;

	nfs41_setup_sequence(wdata->ds_clp->cl_session,
	nfs4_setup_sequence(wdata->ds_clp,
			&wdata->args.seq_args,
			&wdata->res.seq_res,
			task);
+21 −39
Original line number Diff line number Diff line
@@ -1053,9 +1053,6 @@ static int ff_layout_async_handle_error_v4(struct rpc_task *task,
	struct nfs_client *mds_client = mds_server->nfs_client;
	struct nfs4_slot_table *tbl = &clp->cl_session->fc_slot_table;

	if (task->tk_status >= 0)
		return 0;

	switch (task->tk_status) {
	/* MDS state errors */
	case -NFS4ERR_DELEG_REVOKED:
@@ -1157,9 +1154,6 @@ static int ff_layout_async_handle_error_v3(struct rpc_task *task,
{
	struct nfs4_deviceid_node *devid = FF_LAYOUT_DEVID_NODE(lseg, idx);

	if (task->tk_status >= 0)
		return 0;

	switch (task->tk_status) {
	/* File access problems. Don't mark the device as unavailable */
	case -EACCES:
@@ -1195,6 +1189,13 @@ static int ff_layout_async_handle_error(struct rpc_task *task,
{
	int vers = clp->cl_nfs_mod->rpc_vers->number;

	if (task->tk_status >= 0)
		return 0;

	/* Handle the case of an invalid layout segment */
	if (!pnfs_is_valid_lseg(lseg))
		return -NFS4ERR_RESET_TO_PNFS;

	switch (vers) {
	case 3:
		return ff_layout_async_handle_error_v3(task, lseg, idx);
@@ -1384,27 +1385,11 @@ static void ff_layout_read_prepare_v3(struct rpc_task *task, void *data)
	rpc_call_start(task);
}

static int ff_layout_setup_sequence(struct nfs_client *ds_clp,
				    struct nfs4_sequence_args *args,
				    struct nfs4_sequence_res *res,
				    struct rpc_task *task)
{
	if (ds_clp->cl_session)
		return nfs41_setup_sequence(ds_clp->cl_session,
					   args,
					   res,
					   task);
	return nfs40_setup_sequence(ds_clp->cl_slot_tbl,
				   args,
				   res,
				   task);
}

static void ff_layout_read_prepare_v4(struct rpc_task *task, void *data)
{
	struct nfs_pgio_header *hdr = data;

	if (ff_layout_setup_sequence(hdr->ds_clp,
	if (nfs4_setup_sequence(hdr->ds_clp,
				&hdr->args.seq_args,
				&hdr->res.seq_res,
				task))
@@ -1578,7 +1563,7 @@ static void ff_layout_write_prepare_v4(struct rpc_task *task, void *data)
{
	struct nfs_pgio_header *hdr = data;

	if (ff_layout_setup_sequence(hdr->ds_clp,
	if (nfs4_setup_sequence(hdr->ds_clp,
				&hdr->args.seq_args,
				&hdr->res.seq_res,
				task))
@@ -1667,7 +1652,7 @@ static void ff_layout_commit_prepare_v4(struct rpc_task *task, void *data)
{
	struct nfs_commit_data *wdata = data;

	if (ff_layout_setup_sequence(wdata->ds_clp,
	if (nfs4_setup_sequence(wdata->ds_clp,
				&wdata->args.seq_args,
				&wdata->res.seq_res,
				task))
@@ -1965,10 +1950,7 @@ static int ff_layout_encode_ioerr(struct xdr_stream *xdr,
static void
encode_opaque_fixed(struct xdr_stream *xdr, const void *buf, size_t len)
{
	__be32 *p;

	p = xdr_reserve_space(xdr, len);
	xdr_encode_opaque_fixed(p, buf, len);
	WARN_ON_ONCE(xdr_stream_encode_opaque_fixed(xdr, buf, len) < 0);
}

static void
@@ -2092,7 +2074,7 @@ ff_layout_free_layoutreturn(struct nfs4_xdr_opaque_data *args)
	kfree(ff_args);
}

const struct nfs4_xdr_opaque_ops layoutreturn_ops = {
static const struct nfs4_xdr_opaque_ops layoutreturn_ops = {
	.encode = ff_layout_encode_layoutreturn,
	.free = ff_layout_free_layoutreturn,
};
Loading