Skip to content

Commit

Permalink
Merge tag 'nfs-for-5.6-1' of git://git.linux-nfs.org/projects/anna/li…
Browse files Browse the repository at this point in the history
…nux-nfs

Puyll NFS client updates from Anna Schumaker:
 "Stable bugfixes:
   - Fix memory leaks and corruption in readdir # v2.6.37+
   - Directory page cache needs to be locked when read # v2.6.37+

  New features:
   - Convert NFS to use the new mount API
   - Add "softreval" mount option to let clients use cache if server goes down
   - Add a config option to compile without UDP support
   - Limit the number of inactive delegations the client can cache at once
   - Improved readdir concurrency using iterate_shared()

  Other bugfixes and cleanups:
   - More 64-bit time conversions
   - Add additional diagnostic tracepoints
   - Check for holes in swapfiles, and add dependency on CONFIG_SWAP
   - Various xprtrdma cleanups to prepare for 5.7's changes
   - Several fixes for NFS writeback and commit handling
   - Fix acls over krb5i/krb5p mounts
   - Recover from premature loss of openstateids
   - Fix NFS v3 chacl and chmod bug
   - Compare creds using cred_fscmp()
   - Use kmemdup_nul() in more places
   - Optimize readdir cache page invalidation
   - Lease renewal and recovery fixes"

* tag 'nfs-for-5.6-1' of git://git.linux-nfs.org/projects/anna/linux-nfs: (93 commits)
  NFSv4.0: nfs4_do_fsinfo() should not do implicit lease renewals
  NFSv4: try lease recovery on NFS4ERR_EXPIRED
  NFS: Fix memory leaks
  nfs: optimise readdir cache page invalidation
  NFS: Switch readdir to using iterate_shared()
  NFS: Use kmemdup_nul() in nfs_readdir_make_qstr()
  NFS: Directory page cache pages need to be locked when read
  NFS: Fix memory leaks and corruption in readdir
  SUNRPC: Use kmemdup_nul() in rpc_parse_scope_id()
  NFS: Replace various occurrences of kstrndup() with kmemdup_nul()
  NFSv4: Limit the total number of cached delegations
  NFSv4: Add accounting for the number of active delegations held
  NFSv4: Try to return the delegation immediately when marked for return on close
  NFS: Clear NFS_DELEGATION_RETURN_IF_CLOSED when the delegation is returned
  NFSv4: nfs_inode_evict_delegation() should set NFS_DELEGATION_RETURNING
  NFS: nfs_find_open_context() should use cred_fscmp()
  NFS: nfs_access_get_cached_rcu() should use cred_fscmp()
  NFSv4: pnfs_roc() must use cred_fscmp() to compare creds
  NFS: remove unused macros
  nfs: Return EINVAL rather than ERANGE for mount parse errors
  ...
  • Loading branch information
Linus Torvalds committed Feb 8, 2020
2 parents 41dcd67 + 7dc2993 commit f43574d
Showing 63 changed files with 3,348 additions and 3,032 deletions.
11 changes: 10 additions & 1 deletion fs/nfs/Kconfig
Original file line number Diff line number Diff line change
@@ -90,7 +90,7 @@ config NFS_V4
config NFS_SWAP
bool "Provide swap over NFS support"
default n
depends on NFS_FS
depends on NFS_FS && SWAP
select SUNRPC_SWAP
help
This option enables swapon to work on files located on NFS mounts.
@@ -196,3 +196,12 @@ config NFS_DEBUG
depends on NFS_FS && SUNRPC_DEBUG
select CRC32
default y

config NFS_DISABLE_UDP_SUPPORT
bool "NFS: Disable NFS UDP protocol support"
depends on NFS_FS
default y
help
Choose Y here to disable the use of NFS over UDP. NFS over UDP
on modern networks (1Gb+) can lead to data corruption caused by
fragmentation during high loads.
2 changes: 1 addition & 1 deletion fs/nfs/Makefile
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ CFLAGS_nfstrace.o += -I$(src)
nfs-y := client.o dir.o file.o getroot.o inode.o super.o \
io.o direct.o pagelist.o read.o symlink.o unlink.o \
write.o namespace.o mount_clnt.o nfstrace.o \
export.o sysfs.o
export.o sysfs.o fs_context.o
nfs-$(CONFIG_ROOT_NFS) += nfsroot.o
nfs-$(CONFIG_SYSCTL) += sysctl.o
nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o
11 changes: 8 additions & 3 deletions fs/nfs/callback_xdr.c
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@
#include "callback.h"
#include "internal.h"
#include "nfs4session.h"
#include "nfs4trace.h"

#define CB_OP_TAGLEN_MAXSZ (512)
#define CB_OP_HDR_RES_MAXSZ (2 * 4) // opcode, status
@@ -946,9 +947,13 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp)

if (hdr_arg.minorversion == 0) {
cps.clp = nfs4_find_client_ident(SVC_NET(rqstp), hdr_arg.cb_ident);
if (!cps.clp || !check_gss_callback_principal(cps.clp, rqstp)) {
if (cps.clp)
nfs_put_client(cps.clp);
if (!cps.clp) {
trace_nfs_cb_no_clp(rqstp->rq_xid, hdr_arg.cb_ident);
goto out_invalidcred;
}
if (!check_gss_callback_principal(cps.clp, rqstp)) {
trace_nfs_cb_badprinc(rqstp->rq_xid, hdr_arg.cb_ident);
nfs_put_client(cps.clp);
goto out_invalidcred;
}
}
84 changes: 44 additions & 40 deletions fs/nfs/client.c
Original file line number Diff line number Diff line change
@@ -474,6 +474,7 @@ 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;
@@ -484,6 +485,7 @@ 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();
}
@@ -580,8 +582,10 @@ static int nfs_start_lockd(struct nfs_server *server)
default:
nlm_init.protocol = IPPROTO_TCP;
break;
#ifndef CONFIG_NFS_DISABLE_UDP_SUPPORT
case XPRT_TRANSPORT_UDP:
nlm_init.protocol = IPPROTO_UDP;
#endif
}

host = nlmclnt_init(&nlm_init);
@@ -658,28 +662,28 @@ EXPORT_SYMBOL_GPL(nfs_init_client);
* Create a version 2 or 3 client
*/
static int nfs_init_server(struct nfs_server *server,
const struct nfs_parsed_mount_data *data,
struct nfs_subversion *nfs_mod)
const struct fs_context *fc)
{
const struct nfs_fs_context *ctx = nfs_fc2context(fc);
struct rpc_timeout timeparms;
struct nfs_client_initdata cl_init = {
.hostname = data->nfs_server.hostname,
.addr = (const struct sockaddr *)&data->nfs_server.address,
.addrlen = data->nfs_server.addrlen,
.nfs_mod = nfs_mod,
.proto = data->nfs_server.protocol,
.net = data->net,
.hostname = ctx->nfs_server.hostname,
.addr = (const struct sockaddr *)&ctx->nfs_server.address,
.addrlen = ctx->nfs_server.addrlen,
.nfs_mod = ctx->nfs_mod,
.proto = ctx->nfs_server.protocol,
.net = fc->net_ns,
.timeparms = &timeparms,
.cred = server->cred,
.nconnect = data->nfs_server.nconnect,
.nconnect = ctx->nfs_server.nconnect,
.init_flags = (1UL << NFS_CS_REUSEPORT),
};
struct nfs_client *clp;
int error;

nfs_init_timeout_values(&timeparms, data->nfs_server.protocol,
data->timeo, data->retrans);
if (data->flags & NFS_MOUNT_NORESVPORT)
nfs_init_timeout_values(&timeparms, ctx->nfs_server.protocol,
ctx->timeo, ctx->retrans);
if (ctx->flags & NFS_MOUNT_NORESVPORT)
set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);

/* Allocate or find a client reference we can use */
@@ -690,46 +694,46 @@ static int nfs_init_server(struct nfs_server *server,
server->nfs_client = clp;

/* Initialise the client representation from the mount data */
server->flags = data->flags;
server->options = data->options;
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;

if (data->rsize)
server->rsize = nfs_block_size(data->rsize, NULL);
if (data->wsize)
server->wsize = nfs_block_size(data->wsize, NULL);
if (ctx->rsize)
server->rsize = nfs_block_size(ctx->rsize, NULL);
if (ctx->wsize)
server->wsize = nfs_block_size(ctx->wsize, NULL);

server->acregmin = data->acregmin * HZ;
server->acregmax = data->acregmax * HZ;
server->acdirmin = data->acdirmin * HZ;
server->acdirmax = data->acdirmax * HZ;
server->acregmin = ctx->acregmin * HZ;
server->acregmax = ctx->acregmax * HZ;
server->acdirmin = ctx->acdirmin * HZ;
server->acdirmax = ctx->acdirmax * HZ;

/* Start lockd here, before we might error out */
error = nfs_start_lockd(server);
if (error < 0)
goto error;

server->port = data->nfs_server.port;
server->auth_info = data->auth_info;
server->port = ctx->nfs_server.port;
server->auth_info = ctx->auth_info;

error = nfs_init_server_rpcclient(server, &timeparms,
data->selected_flavor);
ctx->selected_flavor);
if (error < 0)
goto error;

/* Preserve the values of mount_server-related mount options */
if (data->mount_server.addrlen) {
memcpy(&server->mountd_address, &data->mount_server.address,
data->mount_server.addrlen);
server->mountd_addrlen = data->mount_server.addrlen;
if (ctx->mount_server.addrlen) {
memcpy(&server->mountd_address, &ctx->mount_server.address,
ctx->mount_server.addrlen);
server->mountd_addrlen = ctx->mount_server.addrlen;
}
server->mountd_version = data->mount_server.version;
server->mountd_port = data->mount_server.port;
server->mountd_protocol = data->mount_server.protocol;
server->mountd_version = ctx->mount_server.version;
server->mountd_port = ctx->mount_server.port;
server->mountd_protocol = ctx->mount_server.protocol;

server->namelen = data->namlen;
server->namelen = ctx->namlen;
return 0;

error:
@@ -951,9 +955,9 @@ EXPORT_SYMBOL_GPL(nfs_free_server);
* Create a version 2 or 3 volume record
* - keyed on server and FSID
*/
struct nfs_server *nfs_create_server(struct nfs_mount_info *mount_info,
struct nfs_subversion *nfs_mod)
struct nfs_server *nfs_create_server(struct fs_context *fc)
{
struct nfs_fs_context *ctx = nfs_fc2context(fc);
struct nfs_server *server;
struct nfs_fattr *fattr;
int error;
@@ -970,27 +974,27 @@ struct nfs_server *nfs_create_server(struct nfs_mount_info *mount_info,
goto error;

/* Get a client representation */
error = nfs_init_server(server, mount_info->parsed, nfs_mod);
error = nfs_init_server(server, fc);
if (error < 0)
goto error;

/* Probe the root fh to retrieve its FSID */
error = nfs_probe_fsinfo(server, mount_info->mntfh, fattr);
error = nfs_probe_fsinfo(server, ctx->mntfh, fattr);
if (error < 0)
goto error;
if (server->nfs_client->rpc_ops->version == 3) {
if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
server->namelen = NFS3_MAXNAMLEN;
if (!(mount_info->parsed->flags & NFS_MOUNT_NORDIRPLUS))
if (!(ctx->flags & NFS_MOUNT_NORDIRPLUS))
server->caps |= NFS_CAP_READDIRPLUS;
} else {
if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN)
server->namelen = NFS2_MAXNAMLEN;
}

if (!(fattr->valid & NFS_ATTR_FATTR)) {
error = nfs_mod->rpc_ops->getattr(server, mount_info->mntfh,
fattr, NULL, NULL);
error = ctx->nfs_mod->rpc_ops->getattr(server, ctx->mntfh,
fattr, NULL, NULL);
if (error < 0) {
dprintk("nfs_create_server: getattr error = %d\n", -error);
goto error;
Loading

0 comments on commit f43574d

Please sign in to comment.