Skip to content

Commit

Permalink
Merge tag 'nfsd-6.11' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/cel/linux

Pull nfsd updates from Chuck Lever:
 "This is a light release containing optimizations, code clean-ups, and
  minor bug fixes.

  This development cycle focused on work outside of upstream kernel
  development:

   - Continuing to build upstream CI for NFSD based on kdevops

   - Continuing to focus on the quality of NFSD in LTS kernels

   - Participation in IETF nfsv4 WG discussions about NFSv4 ACLs,
     directory delegation, and NFSv4.2 COPY offload

  Notable features for v6.11 that do not come through the NFSD tree
  include NFS server-side support for the new pNFS NVMe layout type
  [RFC9561]. Functional testing for pNFS block layouts like this one has
  been introduced to our kdevops CI harness. Work on improving the
  resolution of file attribute time stamps in local filesystems is also
  ongoing tree-wide.

  As always I am grateful to NFSD contributors, reviewers, testers, and
  bug reporters who participated during this cycle"

* tag 'nfsd-6.11' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux:
  nfsd: nfsd_file_lease_notifier_call gets a file_lease as an argument
  gss_krb5: Fix the error handling path for crypto_sync_skcipher_setkey
  MAINTAINERS: Add a bugzilla link for NFSD
  nfsd: new netlink ops to get/set server pool_mode
  sunrpc: refactor pool_mode setting code
  nfsd: allow passing in array of thread counts via netlink
  nfsd: make nfsd_svc take an array of thread counts
  sunrpc: fix up the special handling of sv_nrpools == 1
  SUNRPC: Add a trace point in svc_xprt_deferred_close
  NFSD: Support write delegations in LAYOUTGET
  lockd: Use *-y instead of *-objs in Makefile
  NFSD: Fix nfsdcld warning
  svcrdma: Handle ADDR_CHANGE CM event properly
  svcrdma: Refactor the creation of listener CMA ID
  NFSD: remove unused structs 'nfsd3_voidargs'
  NFSD: harden svcxdr_dupstr() and svcxdr_tmpalloc() against integer overflows
  • Loading branch information
torvalds committed Jul 17, 2024
2 parents 48f8bfd + 769d200 commit 586a7a8
Show file tree
Hide file tree
Showing 21 changed files with 337 additions and 127 deletions.
27 changes: 27 additions & 0 deletions Documentation/netlink/specs/nfsd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,15 @@ attribute-sets:
type: nest
nested-attributes: sock
multi-attr: true
-
name: pool-mode
attributes:
-
name: mode
type: string
-
name: npools
type: u32

operations:
list:
Expand Down Expand Up @@ -195,3 +204,21 @@ operations:
reply:
attributes:
- addr
-
name: pool-mode-set
doc: set the current server pool-mode
attribute-set: pool-mode
flags: [ admin-perm ]
do:
request:
attributes:
- mode
-
name: pool-mode-get
doc: get info about server pool-mode
attribute-set: pool-mode
do:
reply:
attributes:
- mode
- npools
2 changes: 1 addition & 1 deletion MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -12065,7 +12065,7 @@ R: Dai Ngo <[email protected]>
R: Tom Talpey <[email protected]>
L: [email protected]
S: Supported
W: http://nfs.sourceforge.net/
B: https://bugzilla.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux.git
F: Documentation/filesystems/nfs/
F: fs/lockd/
Expand Down
9 changes: 4 additions & 5 deletions fs/lockd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ ccflags-y += -I$(src) # needed for trace events

obj-$(CONFIG_LOCKD) += lockd.o

lockd-objs-y += clntlock.o clntproc.o clntxdr.o host.o svc.o svclock.o \
svcshare.o svcproc.o svcsubs.o mon.o trace.o xdr.o
lockd-objs-$(CONFIG_LOCKD_V4) += clnt4xdr.o xdr4.o svc4proc.o
lockd-objs-$(CONFIG_PROC_FS) += procfs.o
lockd-objs := $(lockd-objs-y)
lockd-y := clntlock.o clntproc.o clntxdr.o host.o svc.o svclock.o \
svcshare.o svcproc.o svcsubs.o mon.o trace.o xdr.o
lockd-$(CONFIG_LOCKD_V4) += clnt4xdr.o xdr4.o svc4proc.o
lockd-$(CONFIG_PROC_FS) += procfs.o
2 changes: 1 addition & 1 deletion fs/nfsd/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ config NFSD_V4_SECURITY_LABEL
config NFSD_LEGACY_CLIENT_TRACKING
bool "Support legacy NFSv4 client tracking methods (DEPRECATED)"
depends on NFSD_V4
default n
default y
help
The NFSv4 server needs to store a small amount of information on
stable storage in order to handle state recovery after reboot. Most
Expand Down
2 changes: 1 addition & 1 deletion fs/nfsd/filecache.c
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,7 @@ static int
nfsd_file_lease_notifier_call(struct notifier_block *nb, unsigned long arg,
void *data)
{
struct file_lock *fl = data;
struct file_lease *fl = data;

/* Only close files for F_SETLEASE leases */
if (fl->c.flc_flags & FL_LEASE)
Expand Down
17 changes: 17 additions & 0 deletions fs/nfsd/netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ static const struct nla_policy nfsd_listener_set_nl_policy[NFSD_A_SERVER_SOCK_AD
[NFSD_A_SERVER_SOCK_ADDR] = NLA_POLICY_NESTED(nfsd_sock_nl_policy),
};

/* NFSD_CMD_POOL_MODE_SET - do */
static const struct nla_policy nfsd_pool_mode_set_nl_policy[NFSD_A_POOL_MODE_MODE + 1] = {
[NFSD_A_POOL_MODE_MODE] = { .type = NLA_NUL_STRING, },
};

/* Ops table for nfsd */
static const struct genl_split_ops nfsd_nl_ops[] = {
{
Expand Down Expand Up @@ -83,6 +88,18 @@ static const struct genl_split_ops nfsd_nl_ops[] = {
.doit = nfsd_nl_listener_get_doit,
.flags = GENL_CMD_CAP_DO,
},
{
.cmd = NFSD_CMD_POOL_MODE_SET,
.doit = nfsd_nl_pool_mode_set_doit,
.policy = nfsd_pool_mode_set_nl_policy,
.maxattr = NFSD_A_POOL_MODE_MODE,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
.cmd = NFSD_CMD_POOL_MODE_GET,
.doit = nfsd_nl_pool_mode_get_doit,
.flags = GENL_CMD_CAP_DO,
},
};

struct genl_family nfsd_nl_family __ro_after_init = {
Expand Down
2 changes: 2 additions & 0 deletions fs/nfsd/netlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ int nfsd_nl_version_set_doit(struct sk_buff *skb, struct genl_info *info);
int nfsd_nl_version_get_doit(struct sk_buff *skb, struct genl_info *info);
int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info);
int nfsd_nl_listener_get_doit(struct sk_buff *skb, struct genl_info *info);
int nfsd_nl_pool_mode_set_doit(struct sk_buff *skb, struct genl_info *info);
int nfsd_nl_pool_mode_get_doit(struct sk_buff *skb, struct genl_info *info);

extern struct genl_family nfsd_nl_family;

Expand Down
2 changes: 0 additions & 2 deletions fs/nfsd/nfs2acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,8 +308,6 @@ static void nfsaclsvc_release_access(struct svc_rqst *rqstp)
fh_put(&resp->fh);
}

struct nfsd3_voidargs { int dummy; };

#define ST 1 /* status*/
#define AT 21 /* attributes */
#define pAT (1+AT) /* post attributes - conditional */
Expand Down
2 changes: 0 additions & 2 deletions fs/nfsd/nfs3acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,6 @@ static void nfs3svc_release_getacl(struct svc_rqst *rqstp)
posix_acl_release(resp->acl_default);
}

struct nfsd3_voidargs { int dummy; };

#define ST 1 /* status*/
#define AT 21 /* attributes */
#define pAT (1+AT) /* post attributes - conditional */
Expand Down
5 changes: 3 additions & 2 deletions fs/nfsd/nfs4proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2269,7 +2269,7 @@ nfsd4_layoutget(struct svc_rqst *rqstp,
const struct nfsd4_layout_ops *ops;
struct nfs4_layout_stateid *ls;
__be32 nfserr;
int accmode = NFSD_MAY_READ_IF_EXEC;
int accmode = NFSD_MAY_READ_IF_EXEC | NFSD_MAY_OWNER_OVERRIDE;

switch (lgp->lg_seg.iomode) {
case IOMODE_READ:
Expand Down Expand Up @@ -2359,7 +2359,8 @@ nfsd4_layoutcommit(struct svc_rqst *rqstp,
struct nfs4_layout_stateid *ls;
__be32 nfserr;

nfserr = fh_verify(rqstp, current_fh, 0, NFSD_MAY_WRITE);
nfserr = fh_verify(rqstp, current_fh, 0,
NFSD_MAY_WRITE | NFSD_MAY_OWNER_OVERRIDE);
if (nfserr)
goto out;

Expand Down
4 changes: 2 additions & 2 deletions fs/nfsd/nfs4recover.c
Original file line number Diff line number Diff line change
Expand Up @@ -2086,8 +2086,8 @@ nfsd4_client_tracking_init(struct net *net)
status = nn->client_tracking_ops->init(net);
out:
if (status) {
printk(KERN_WARNING "NFSD: Unable to initialize client "
"recovery tracking! (%d)\n", status);
pr_warn("NFSD: Unable to initialize client recovery tracking! (%d)\n", status);
pr_warn("NFSD: Is nfsdcld running? If not, enable CONFIG_NFSD_LEGACY_CLIENT_TRACKING.\n");
nn->client_tracking_ops = NULL;
}
return status;
Expand Down
12 changes: 6 additions & 6 deletions fs/nfsd/nfs4xdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,11 @@ static int zero_clientid(clientid_t *clid)
* operation described in @argp finishes.
*/
static void *
svcxdr_tmpalloc(struct nfsd4_compoundargs *argp, u32 len)
svcxdr_tmpalloc(struct nfsd4_compoundargs *argp, size_t len)
{
struct svcxdr_tmpbuf *tb;

tb = kmalloc(sizeof(*tb) + len, GFP_KERNEL);
tb = kmalloc(struct_size(tb, buf, len), GFP_KERNEL);
if (!tb)
return NULL;
tb->next = argp->to_free;
Expand All @@ -138,9 +138,9 @@ svcxdr_tmpalloc(struct nfsd4_compoundargs *argp, u32 len)
* buffer might end on a page boundary.
*/
static char *
svcxdr_dupstr(struct nfsd4_compoundargs *argp, void *buf, u32 len)
svcxdr_dupstr(struct nfsd4_compoundargs *argp, void *buf, size_t len)
{
char *p = svcxdr_tmpalloc(argp, len + 1);
char *p = svcxdr_tmpalloc(argp, size_add(len, 1));

if (!p)
return NULL;
Expand All @@ -150,7 +150,7 @@ svcxdr_dupstr(struct nfsd4_compoundargs *argp, void *buf, u32 len)
}

static void *
svcxdr_savemem(struct nfsd4_compoundargs *argp, __be32 *p, u32 len)
svcxdr_savemem(struct nfsd4_compoundargs *argp, __be32 *p, size_t len)
{
__be32 *tmp;

Expand Down Expand Up @@ -2146,7 +2146,7 @@ nfsd4_decode_clone(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u)
*/
static __be32
nfsd4_vbuf_from_vector(struct nfsd4_compoundargs *argp, struct xdr_buf *xdr,
char **bufp, u32 buflen)
char **bufp, size_t buflen)
{
struct page **pages = xdr->pages;
struct kvec *head = xdr->head;
Expand Down
99 changes: 86 additions & 13 deletions fs/nfsd/nfsctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size)
return -EINVAL;
trace_nfsd_ctl_threads(net, newthreads);
mutex_lock(&nfsd_mutex);
rv = nfsd_svc(newthreads, net, file->f_cred, NULL);
rv = nfsd_svc(1, &newthreads, net, file->f_cred, NULL);
mutex_unlock(&nfsd_mutex);
if (rv < 0)
return rv;
Expand Down Expand Up @@ -481,6 +481,14 @@ static ssize_t write_pool_threads(struct file *file, char *buf, size_t size)
goto out_free;
trace_nfsd_ctl_pool_threads(net, i, nthreads[i]);
}

/*
* There must always be a thread in pool 0; the admin
* can't shut down NFS completely using pool_threads.
*/
if (nthreads[0] == 0)
nthreads[0] = 1;

rv = nfsd_set_nrthreads(i, nthreads, net);
if (rv)
goto out_free;
Expand Down Expand Up @@ -1637,7 +1645,7 @@ int nfsd_nl_rpc_status_get_dumpit(struct sk_buff *skb,
*/
int nfsd_nl_threads_set_doit(struct sk_buff *skb, struct genl_info *info)
{
int nthreads = 0, count = 0, nrpools, ret = -EOPNOTSUPP, rem;
int *nthreads, count = 0, nrpools, i, ret = -EOPNOTSUPP, rem;
struct net *net = genl_info_net(info);
struct nfsd_net *nn = net_generic(net, nfsd_net_id);
const struct nlattr *attr;
Expand All @@ -1654,15 +1662,22 @@ int nfsd_nl_threads_set_doit(struct sk_buff *skb, struct genl_info *info)

mutex_lock(&nfsd_mutex);

nrpools = nfsd_nrpools(net);
if (nrpools && count > nrpools)
count = nrpools;

/* XXX: make this handle non-global pool-modes */
if (count > 1)
nrpools = max(count, nfsd_nrpools(net));
nthreads = kcalloc(nrpools, sizeof(int), GFP_KERNEL);
if (!nthreads) {
ret = -ENOMEM;
goto out_unlock;
}

i = 0;
nlmsg_for_each_attr(attr, info->nlhdr, GENL_HDRLEN, rem) {
if (nla_type(attr) == NFSD_A_SERVER_THREADS) {
nthreads[i++] = nla_get_u32(attr);
if (i >= nrpools)
break;
}
}

nthreads = nla_get_u32(info->attrs[NFSD_A_SERVER_THREADS]);
if (info->attrs[NFSD_A_SERVER_GRACETIME] ||
info->attrs[NFSD_A_SERVER_LEASETIME] ||
info->attrs[NFSD_A_SERVER_SCOPE]) {
Expand Down Expand Up @@ -1696,12 +1711,13 @@ int nfsd_nl_threads_set_doit(struct sk_buff *skb, struct genl_info *info)
scope = nla_data(attr);
}

ret = nfsd_svc(nthreads, net, get_current_cred(), scope);

ret = nfsd_svc(nrpools, nthreads, net, get_current_cred(), scope);
if (ret > 0)
ret = 0;
out_unlock:
mutex_unlock(&nfsd_mutex);

return ret == nthreads ? 0 : ret;
kfree(nthreads);
return ret;
}

/**
Expand Down Expand Up @@ -2140,6 +2156,63 @@ int nfsd_nl_listener_get_doit(struct sk_buff *skb, struct genl_info *info)
return err;
}

/**
* nfsd_nl_pool_mode_set_doit - set the number of running threads
* @skb: reply buffer
* @info: netlink metadata and command arguments
*
* Return 0 on success or a negative errno.
*/
int nfsd_nl_pool_mode_set_doit(struct sk_buff *skb, struct genl_info *info)
{
const struct nlattr *attr;

if (GENL_REQ_ATTR_CHECK(info, NFSD_A_POOL_MODE_MODE))
return -EINVAL;

attr = info->attrs[NFSD_A_POOL_MODE_MODE];
return sunrpc_set_pool_mode(nla_data(attr));
}

/**
* nfsd_nl_pool_mode_get_doit - get info about pool_mode
* @skb: reply buffer
* @info: netlink metadata and command arguments
*
* Return 0 on success or a negative errno.
*/
int nfsd_nl_pool_mode_get_doit(struct sk_buff *skb, struct genl_info *info)
{
struct net *net = genl_info_net(info);
char buf[16];
void *hdr;
int err;

if (sunrpc_get_pool_mode(buf, ARRAY_SIZE(buf)) >= ARRAY_SIZE(buf))
return -ERANGE;

skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!skb)
return -ENOMEM;

err = -EMSGSIZE;
hdr = genlmsg_iput(skb, info);
if (!hdr)
goto err_free_msg;

err = nla_put_string(skb, NFSD_A_POOL_MODE_MODE, buf) |
nla_put_u32(skb, NFSD_A_POOL_MODE_NPOOLS, nfsd_nrpools(net));
if (err)
goto err_free_msg;

genlmsg_end(skb, hdr);
return genlmsg_reply(skb, info);

err_free_msg:
nlmsg_free(skb);
return err;
}

/**
* nfsd_net_init - Prepare the nfsd_net portion of a new net namespace
* @net: a freshly-created network namespace
Expand Down
3 changes: 2 additions & 1 deletion fs/nfsd/nfsd.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ bool nfssvc_encode_voidres(struct svc_rqst *rqstp,
/*
* Function prototypes.
*/
int nfsd_svc(int nrservs, struct net *net, const struct cred *cred, const char *scope);
int nfsd_svc(int n, int *nservers, struct net *net,
const struct cred *cred, const char *scope);
int nfsd_dispatch(struct svc_rqst *rqstp);

int nfsd_nrthreads(struct net *);
Expand Down
Loading

0 comments on commit 586a7a8

Please sign in to comment.