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

  Features:

   - NFSv3: Add emulation of lookupp() to improve open_by_filehandle()
     support

   - A series of patches to improve readdir performance, particularly
     with large directories

   - Basic support for using NFS/RDMA with the pNFS files and flexfiles
     drivers

   - Micro-optimisations for RDMA

   - RDMA tracing improvements

  Bugfixes:

   - Fix a long standing bug with xs_read_xdr_buf() when receiving
     partial pages (Dan Aloni)

   - Various fixes for getxattr and listxattr, when used over non-TCP
     transports

   - Fixes for containerised NFS from Sargun Dhillon

   - switch nfsiod to be an UNBOUND workqueue (Neil Brown)

   - READDIR should not ask for security label information if there is
     no LSM policy (Olga Kornievskaia)

   - Avoid using interval-based rebinding with TCP in lockd (Calum
     Mackay)

   - A series of RPC and NFS layer fixes to support the NFSv4.2
     READ_PLUS code

   - A couple of fixes for pnfs/flexfiles read failover

  Cleanups:

   - Various cleanups for the SUNRPC xdr code in conjunction with the
     READ_PLUS fixes"

* tag 'nfs-for-5.11-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (90 commits)
  NFS/pNFS: Fix a typo in ff_layout_resend_pnfs_read()
  pNFS/flexfiles: Avoid spurious layout returns in ff_layout_choose_ds_for_read
  NFSv4/pnfs: Add tracing for the deviceid cache
  fs/lockd: convert comma to semicolon
  NFSv4.2: fix error return on memory allocation failure
  NFSv4.2/pnfs: Don't use READ_PLUS with pNFS yet
  NFSv4.2: Deal with potential READ_PLUS data extent buffer overflow
  NFSv4.2: Don't error when exiting early on a READ_PLUS buffer overflow
  NFSv4.2: Handle hole lengths that exceed the READ_PLUS read buffer
  NFSv4.2: decode_read_plus_hole() needs to check the extent offset
  NFSv4.2: decode_read_plus_data() must skip padding after data segment
  NFSv4.2: Ensure we always reset the result->count in decode_read_plus()
  SUNRPC: When expanding the buffer, we may need grow the sparse pages
  SUNRPC: Cleanup - constify a number of xdr_buf helpers
  SUNRPC: Clean up open coded setting of the xdr_stream 'nwords' field
  SUNRPC: _copy_to/from_pages() now check for zero length
  SUNRPC: Cleanup xdr_shrink_bufhead()
  SUNRPC: Fix xdr_expand_hole()
  SUNRPC: Fixes for xdr_align_data()
  SUNRPC: _shift_data_left/right_pages should check the shift length
  ...
parents be695ee2 52104f27
Loading
Loading
Loading
Loading
+12 −10
Original line number Diff line number Diff line
@@ -163,7 +163,7 @@ static struct nlm_host *nlm_alloc_host(struct nlm_lookup_host_info *ni,
	host->h_nsmhandle  = nsm;
	host->h_addrbuf    = nsm->sm_addrbuf;
	host->net	   = ni->net;
	host->h_cred	   = get_cred(ni->cred),
	host->h_cred	   = get_cred(ni->cred);
	strlcpy(host->nodename, utsname()->nodename, sizeof(host->nodename));

out:
@@ -439,12 +439,7 @@ nlm_bind_host(struct nlm_host *host)
	 * RPC rebind is required
	 */
	if ((clnt = host->h_rpcclnt) != NULL) {
		if (time_after_eq(jiffies, host->h_nextrebind)) {
			rpc_force_rebind(clnt);
			host->h_nextrebind = jiffies + NLM_HOST_REBIND;
			dprintk("lockd: next rebind in %lu jiffies\n",
					host->h_nextrebind - jiffies);
		}
		nlm_rebind_host(host);
	} else {
		unsigned long increment = nlmsvc_timeout;
		struct rpc_timeout timeparms = {
@@ -494,13 +489,20 @@ nlm_bind_host(struct nlm_host *host)
	return clnt;
}

/*
 * Force a portmap lookup of the remote lockd port
/**
 * nlm_rebind_host - If needed, force a portmap lookup of the peer's lockd port
 * @host: NLM host handle for peer
 *
 * This is not needed when using a connection-oriented protocol, such as TCP.
 * The existing autobind mechanism is sufficient to force a rebind when
 * required, e.g. on connection state transitions.
 */
void
nlm_rebind_host(struct nlm_host *host)
{
	dprintk("lockd: rebind host %s\n", host->h_name);
	if (host->h_proto != IPPROTO_UDP)
		return;

	if (host->h_rpcclnt && time_after_eq(jiffies, host->h_nextrebind)) {
		rpc_force_rebind(host->h_rpcclnt);
		host->h_nextrebind = jiffies + NLM_HOST_REBIND;
+4 −4
Original line number Diff line number Diff line
@@ -571,7 +571,7 @@ static int nfs_start_lockd(struct nfs_server *server)
					1 : 0,
		.net		= clp->cl_net,
		.nlmclnt_ops 	= clp->cl_nfs_mod->rpc_ops->nlmclnt_ops,
		.cred		= current_cred(),
		.cred		= server->cred,
	};

	if (nlm_init.nfs_version > 3)
@@ -781,8 +781,8 @@ static void nfs_server_set_fsinfo(struct nfs_server *server,
	server->wtmult = nfs_block_bits(fsinfo->wtmult, NULL);

	server->dtsize = nfs_block_size(fsinfo->dtpref, NULL);
	if (server->dtsize > PAGE_SIZE * NFS_MAX_READDIR_PAGES)
		server->dtsize = PAGE_SIZE * NFS_MAX_READDIR_PAGES;
	if (server->dtsize > NFS_MAX_FILE_IO_SIZE)
		server->dtsize = NFS_MAX_FILE_IO_SIZE;
	if (server->dtsize > server->rsize)
		server->dtsize = server->rsize;

@@ -985,7 +985,7 @@ struct nfs_server *nfs_create_server(struct fs_context *fc)
	if (!server)
		return ERR_PTR(-ENOMEM);

	server->cred = get_cred(current_cred());
	server->cred = get_cred(fc->cred);

	error = -ENOMEM;
	fattr = nfs_alloc_fattr();
+459 −260

File changed.

Preview size limit exceeded, changes collapsed.

+4 −13
Original line number Diff line number Diff line
@@ -740,16 +740,12 @@ ff_layout_choose_ds_for_read(struct pnfs_layout_segment *lseg,
	struct nfs4_ff_layout_segment *fls = FF_LAYOUT_LSEG(lseg);
	struct nfs4_ff_layout_mirror *mirror;
	struct nfs4_pnfs_ds *ds;
	bool fail_return = false;
	u32 idx;

	/* mirrors are initially sorted by efficiency */
	for (idx = start_idx; idx < fls->mirror_array_cnt; idx++) {
		if (idx+1 == fls->mirror_array_cnt)
			fail_return = !check_device;

		mirror = FF_LAYOUT_COMP(lseg, idx);
		ds = nfs4_ff_layout_prepare_ds(lseg, mirror, fail_return);
		ds = nfs4_ff_layout_prepare_ds(lseg, mirror, false);
		if (!ds)
			continue;

@@ -1056,7 +1052,7 @@ static void ff_layout_resend_pnfs_read(struct nfs_pgio_header *hdr)
	u32 idx = hdr->pgio_mirror_idx + 1;
	u32 new_idx = 0;

	if (ff_layout_choose_any_ds_for_read(hdr->lseg, idx + 1, &new_idx))
	if (ff_layout_choose_any_ds_for_read(hdr->lseg, idx, &new_idx))
		ff_layout_send_layouterror(hdr->lseg);
	else
		pnfs_error_mark_layout_for_return(hdr->inode, hdr->lseg);
@@ -2284,7 +2280,6 @@ ff_layout_encode_netaddr(struct xdr_stream *xdr, struct nfs4_pnfs_ds_addr *da)
	struct sockaddr *sap = (struct sockaddr *)&da->da_addr;
	char portbuf[RPCBIND_MAXUADDRPLEN];
	char addrbuf[RPCBIND_MAXUADDRLEN];
	char *netid;
	unsigned short port;
	int len, netid_len;
	__be32 *p;
@@ -2294,18 +2289,13 @@ ff_layout_encode_netaddr(struct xdr_stream *xdr, struct nfs4_pnfs_ds_addr *da)
		if (ff_layout_ntop4(sap, addrbuf, sizeof(addrbuf)) == 0)
			return;
		port = ntohs(((struct sockaddr_in *)sap)->sin_port);
		netid = "tcp";
		netid_len = 3;
		break;
	case AF_INET6:
		if (ff_layout_ntop6_noscopeid(sap, addrbuf, sizeof(addrbuf)) == 0)
			return;
		port = ntohs(((struct sockaddr_in6 *)sap)->sin6_port);
		netid = "tcp6";
		netid_len = 4;
		break;
	default:
		/* we only support tcp and tcp6 */
		WARN_ON_ONCE(1);
		return;
	}
@@ -2313,8 +2303,9 @@ ff_layout_encode_netaddr(struct xdr_stream *xdr, struct nfs4_pnfs_ds_addr *da)
	snprintf(portbuf, sizeof(portbuf), ".%u.%u", port >> 8, port & 0xff);
	len = strlcat(addrbuf, portbuf, sizeof(addrbuf));

	netid_len = strlen(da->da_netid);
	p = xdr_reserve_space(xdr, 4 + netid_len);
	xdr_encode_opaque(p, netid, netid_len);
	xdr_encode_opaque(p, da->da_netid, netid_len);

	p = xdr_reserve_space(xdr, 4 + len);
	xdr_encode_opaque(p, addrbuf, len);
+12 −9
Original line number Diff line number Diff line
@@ -510,13 +510,12 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
		ctx->nfs_server.protocol = XPRT_TRANSPORT_UDP;
		break;
	case Opt_tcp:
		ctx->flags |= NFS_MOUNT_TCP;
		ctx->nfs_server.protocol = XPRT_TRANSPORT_TCP;
		break;
	case Opt_rdma:
		ctx->flags |= NFS_MOUNT_TCP; /* for side protocols */
		ctx->nfs_server.protocol = XPRT_TRANSPORT_RDMA;
		xprt_load_transport(param->key);
		ret = xprt_find_transport_ident(param->key);
		if (ret < 0)
			goto out_bad_transport;
		ctx->nfs_server.protocol = ret;
		break;
	case Opt_acl:
		if (result.negated)
@@ -670,11 +669,13 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
		case Opt_xprt_rdma:
			/* vector side protocols to TCP */
			ctx->flags |= NFS_MOUNT_TCP;
			ctx->nfs_server.protocol = XPRT_TRANSPORT_RDMA;
			xprt_load_transport(param->string);
			ret = xprt_find_transport_ident(param->string);
			if (ret < 0)
				goto out_bad_transport;
			ctx->nfs_server.protocol = ret;
			break;
		default:
			return nfs_invalf(fc, "NFS: Unrecognized transport protocol");
			goto out_bad_transport;
		}

		ctx->protofamily = protofamily;
@@ -697,7 +698,7 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
			break;
		case Opt_xprt_rdma: /* not used for side protocols */
		default:
			return nfs_invalf(fc, "NFS: Unrecognized transport protocol");
			goto out_bad_transport;
		}
		ctx->mountfamily = mountfamily;
		break;
@@ -787,6 +788,8 @@ out_invalid_address:
	return nfs_invalf(fc, "NFS: Bad IP address specified");
out_of_bounds:
	return nfs_invalf(fc, "NFS: Value for '%s' out of range", param->key);
out_bad_transport:
	return nfs_invalf(fc, "NFS: Unrecognized transport protocol");
}

/*
Loading