Commit a647034f authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull NFS client updates from Trond Myklebust:
 "Highlights include:

  Stable fixes:

   - Add validation of the UDP retrans parameter to prevent shift
     out-of-bounds

   - Don't discard pNFS layout segments that are marked for return

  Bugfixes:

   - Fix a NULL dereference crash in xprt_complete_bc_request() when the
     NFSv4.1 server misbehaves.

   - Fix the handling of NFS READDIR cookie verifiers

   - Sundry fixes to ensure attribute revalidation works correctly when
     the server does not return post-op attributes.

   - nfs4_bitmask_adjust() must not change the server global bitmasks

   - Fix major timeout handling in the RPC code.

   - NFSv4.2 fallocate() fixes.

   - Fix the NFSv4.2 SEEK_HOLE/SEEK_DATA end-of-file handling

   - Copy offload attribute revalidation fixes

   - Fix an incorrect filehandle size check in the pNFS flexfiles driver

   - Fix several RDMA transport setup/teardown races

   - Fix several RDMA queue wrapping issues

   - Fix a misplaced memory read barrier in sunrpc's call_decode()

  Features:

   - Micro optimisation of the TCP transmission queue using TCP_CORK

   - statx() performance improvements by further splitting up the
     tracking of invalid cached file metadata.

   - Support the NFSv4.2 'change_attr_type' attribute and use it to
     optimise handling of change attribute updates"

* tag 'nfs-for-5.13-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (85 commits)
  xprtrdma: Fix a NULL dereference in frwr_unmap_sync()
  sunrpc: Fix misplaced barrier in call_decode
  NFSv4.2: Remove ifdef CONFIG_NFSD from NFSv4.2 client SSC code.
  xprtrdma: Move fr_mr field to struct rpcrdma_mr
  xprtrdma: Move the Work Request union to struct rpcrdma_mr
  xprtrdma: Move fr_linv_done field to struct rpcrdma_mr
  xprtrdma: Move cqe to struct rpcrdma_mr
  xprtrdma: Move fr_cid to struct rpcrdma_mr
  xprtrdma: Remove the RPC/RDMA QP event handler
  xprtrdma: Don't display r_xprt memory addresses in tracepoints
  xprtrdma: Add an rpcrdma_mr_completion_class
  xprtrdma: Add tracepoints showing FastReg WRs and remote invalidation
  xprtrdma: Avoid Send Queue wrapping
  xprtrdma: Do not wake RPC consumer on a failed LocalInv
  xprtrdma: Do not recycle MR after FastReg/LocalInv flushes
  xprtrdma: Clarify use of barrier in frwr_wc_localinv_done()
  xprtrdma: Rename frwr_release_mr()
  xprtrdma: rpcrdma_mr_pop() already does list_del_init()
  xprtrdma: Delete rpcrdma_recv_buffer_put()
  xprtrdma: Fix cwnd update ordering
  ...
parents e22e9832 9e895cd9
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -338,8 +338,8 @@ config NFS_COMMON
	default y

config NFS_V4_2_SSC_HELPER
	tristate
	default y if NFS_V4=y || NFS_FS=y
	bool
	default y if NFS_V4_2

source "net/sunrpc/Kconfig"
source "fs/ceph/Kconfig"
+9 −8
Original line number Diff line number Diff line
@@ -137,12 +137,12 @@ static struct inode *nfs_layout_find_inode_by_stateid(struct nfs_client *clp,
		list_for_each_entry_rcu(lo, &server->layouts, plh_layouts) {
			if (!pnfs_layout_is_valid(lo))
				continue;
			if (stateid != NULL &&
			    !nfs4_stateid_match_other(stateid, &lo->plh_stateid))
				continue;
			if (!nfs_sb_active(server->super))
			if (!nfs4_stateid_match_other(stateid, &lo->plh_stateid))
				continue;
			if (nfs_sb_active(server->super))
				inode = igrab(lo->plh_inode);
			else
				inode = ERR_PTR(-EAGAIN);
			rcu_read_unlock();
			if (inode)
				return inode;
@@ -176,9 +176,10 @@ static struct inode *nfs_layout_find_inode_by_fh(struct nfs_client *clp,
				continue;
			if (nfsi->layout != lo)
				continue;
			if (!nfs_sb_active(server->super))
				continue;
			if (nfs_sb_active(server->super))
				inode = igrab(lo->plh_inode);
			else
				inode = ERR_PTR(-EAGAIN);
			rcu_read_unlock();
			if (inode)
				return inode;
+15 −5
Original line number Diff line number Diff line
@@ -476,7 +476,6 @@ void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
			to->to_maxval = to->to_initval;
		to->to_exponential = 0;
		break;
#ifndef CONFIG_NFS_DISABLE_UDP_SUPPORT
	case XPRT_TRANSPORT_UDP:
		if (retrans == NFS_UNSPEC_RETRANS)
			to->to_retries = NFS_DEF_UDP_RETRANS;
@@ -487,7 +486,6 @@ void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
		to->to_maxval = NFS_MAX_UDP_TIMEOUT;
		to->to_exponential = 1;
		break;
#endif
	default:
		BUG();
	}
@@ -698,9 +696,18 @@ static int nfs_init_server(struct nfs_server *server,
	/* Initialise the client representation from the mount data */
	server->flags = ctx->flags;
	server->options = ctx->options;
	server->caps |= NFS_CAP_HARDLINKS|NFS_CAP_SYMLINKS|NFS_CAP_FILEID|
		NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER|NFS_CAP_OWNER_GROUP|
		NFS_CAP_ATIME|NFS_CAP_CTIME|NFS_CAP_MTIME;
	server->caps |= NFS_CAP_HARDLINKS | NFS_CAP_SYMLINKS;

	switch (clp->rpc_ops->version) {
	case 2:
		server->fattr_valid = NFS_ATTR_FATTR_V2;
		break;
	case 3:
		server->fattr_valid = NFS_ATTR_FATTR_V3;
		break;
	default:
		server->fattr_valid = NFS_ATTR_FATTR_V4;
	}

	if (ctx->rsize)
		server->rsize = nfs_block_size(ctx->rsize, NULL);
@@ -794,6 +801,7 @@ static void nfs_server_set_fsinfo(struct nfs_server *server,
	server->maxfilesize = fsinfo->maxfilesize;

	server->time_delta = fsinfo->time_delta;
	server->change_attr_type = fsinfo->change_attr_type;

	server->clone_blksize = fsinfo->clone_blksize;
	/* We're airborne Set socket buffersize */
@@ -935,6 +943,8 @@ struct nfs_server *nfs_alloc_server(void)
		return NULL;
	}

	server->change_attr_type = NFS4_CHANGE_TYPE_IS_UNDEFINED;

	ida_init(&server->openowner_id);
	ida_init(&server->lockowner_id);
	pnfs_init_server(server);
+20 −9
Original line number Diff line number Diff line
@@ -114,7 +114,7 @@ nfs4_do_check_delegation(struct inode *inode, fmode_t flags, bool mark)
	return ret;
}
/**
 * nfs_have_delegation - check if inode has a delegation, mark it
 * nfs4_have_delegation - check if inode has a delegation, mark it
 * NFS_DELEGATION_REFERENCED if there is one.
 * @inode: inode to check
 * @flags: delegation types to check for
@@ -481,6 +481,22 @@ int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred,
	if (freeme == NULL)
		goto out;
add_new:
	/*
	 * If we didn't revalidate the change attribute before setting
	 * the delegation, then pre-emptively ask for a full attribute
	 * cache revalidation.
	 */
	spin_lock(&inode->i_lock);
	if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_CHANGE)
		nfs_set_cache_invalid(inode,
			NFS_INO_INVALID_ATIME | NFS_INO_INVALID_CTIME |
			NFS_INO_INVALID_MTIME | NFS_INO_INVALID_SIZE |
			NFS_INO_INVALID_BLOCKS | NFS_INO_INVALID_NLINK |
			NFS_INO_INVALID_OTHER | NFS_INO_INVALID_DATA |
			NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL |
			NFS_INO_INVALID_XATTR);
	spin_unlock(&inode->i_lock);

	list_add_tail_rcu(&delegation->super_list, &server->delegations);
	rcu_assign_pointer(nfsi->delegation, delegation);
	delegation = NULL;
@@ -488,11 +504,6 @@ int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred,
	atomic_long_inc(&nfs_active_delegations);

	trace_nfs4_set_delegation(inode, type);

	spin_lock(&inode->i_lock);
	if (NFS_I(inode)->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME))
		NFS_I(inode)->cache_validity |= NFS_INO_REVAL_FORCED;
	spin_unlock(&inode->i_lock);
out:
	spin_unlock(&clp->cl_lock);
	if (delegation != NULL)
@@ -674,7 +685,7 @@ void nfs_inode_evict_delegation(struct inode *inode)
}

/**
 * nfs_inode_return_delegation - synchronously return a delegation
 * nfs4_inode_return_delegation - synchronously return a delegation
 * @inode: inode to process
 *
 * This routine will always flush any dirty data to disk on the
@@ -697,7 +708,7 @@ int nfs4_inode_return_delegation(struct inode *inode)
}

/**
 * nfs_inode_return_delegation_on_close - asynchronously return a delegation
 * nfs4_inode_return_delegation_on_close - asynchronously return a delegation
 * @inode: inode to process
 *
 * This routine is called on file close in order to determine if the
@@ -811,7 +822,7 @@ void nfs_expire_all_delegations(struct nfs_client *clp)
}

/**
 * nfs_super_return_all_delegations - return delegations for one superblock
 * nfs_server_return_all_delegations - return delegations for one superblock
 * @server: pointer to nfs_server to process
 *
 */
+1 −2
Original line number Diff line number Diff line
@@ -84,8 +84,7 @@ int nfs4_inode_make_writeable(struct inode *inode);

static inline int nfs_have_delegated_attributes(struct inode *inode)
{
	return NFS_PROTO(inode)->have_delegation(inode, FMODE_READ) &&
		!(NFS_I(inode)->cache_validity & NFS_INO_REVAL_FORCED);
	return NFS_PROTO(inode)->have_delegation(inode, FMODE_READ);
}

#endif
Loading