Skip to content

Commit

Permalink
Merge tag 'nfsd-6.15' 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:
 "Neil Brown contributed more scalability improvements to NFSD's open
  file cache, and Jeff Layton contributed a menagerie of repairs to
  NFSD's NFSv4 callback / backchannel implementation.

  Mike Snitzer contributed a change to NFS re-export support that
  disables support for file locking on a re-exported NFSv4 mount. This
  is because NFSv4 state recovery is currently difficult if not
  impossible for re-exported NFS mounts. The change aims to prevent data
  integrity exposures after the re-export server crashes.

  Work continues on the evolving NFSD netlink administrative API.

  Many thanks to the contributors, reviewers, testers, and bug reporters
  who participated during the v6.15 development cycle"

* tag 'nfsd-6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux: (45 commits)
  NFSD: Add a Kconfig setting to enable delegated timestamps
  sysctl: Fixes nsm_local_state bounds
  nfsd: use a long for the count in nfsd4_state_shrinker_count()
  nfsd: remove obsolete comment from nfs4_alloc_stid
  nfsd: remove unneeded forward declaration of nfsd4_mark_cb_fault()
  nfsd: reorganize struct nfs4_delegation for better packing
  nfsd: handle errors from rpc_call_async()
  nfsd: move cb_need_restart flag into cb_flags
  nfsd: replace CB_GETATTR_BUSY with NFSD4_CALLBACK_RUNNING
  nfsd: eliminate cl_ra_cblist and NFSD4_CLIENT_CB_RECALL_ANY
  nfsd: prevent callback tasks running concurrently
  nfsd: disallow file locking and delegations for NFSv4 reexport
  nfsd: filecache: drop the list_lru lock during lock gc scans
  nfsd: filecache: don't repeatedly add/remove files on the lru list
  nfsd: filecache: introduce NFSD_FILE_RECENT
  nfsd: filecache: use list_lru_walk_node() in nfsd_file_gc()
  nfsd: filecache: use nfsd_file_dispose_list() in nfsd_file_close_inode_sync()
  NFSD: Re-organize nfsd_file_gc_worker()
  nfsd: filecache: remove race handling.
  fs: nfs: acl: Avoid -Wflex-array-member-not-at-end warning
  ...
  • Loading branch information
Linus Torvalds committed Apr 1, 2025
2 parents 1e7857b + 26a8076 commit b6dde1e
Show file tree
Hide file tree
Showing 29 changed files with 684 additions and 404 deletions.
10 changes: 7 additions & 3 deletions Documentation/filesystems/nfs/reexport.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,13 @@ Reboot recovery
---------------

The NFS protocol's normal reboot recovery mechanisms don't work for the
case when the reexport server reboots. Clients will lose any locks
they held before the reboot, and further IO will result in errors.
Closing and reopening files should clear the errors.
case when the reexport server reboots because the source server has not
rebooted, and so it is not in grace. Since the source server is not in
grace, it cannot offer any guarantees that the file won't have been
changed between the locks getting lost and any attempt to recover them.
The same applies to delegations and any associated locks. Clients are
not allowed to get file locks or delegations from a reexport server, any
attempts will fail with operation not supported.

Filehandle limits
-----------------
Expand Down
45 changes: 45 additions & 0 deletions Documentation/netlink/specs/lockd.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)

name: lockd
protocol: genetlink
uapi-header: linux/lockd_netlink.h

doc: lockd configuration over generic netlink

attribute-sets:
-
name: server
attributes:
-
name: gracetime
type: u32
-
name: tcp-port
type: u16
-
name: udp-port
type: u16

operations:
list:
-
name: server-set
doc: set the lockd server parameters
attribute-set: server
flags: [ admin-perm ]
do:
request:
attributes:
- gracetime
- tcp-port
- udp-port
-
name: server-get
doc: get the lockd server parameters
attribute-set: server
do:
reply:
attributes:
- gracetime
- tcp-port
- udp-port
2 changes: 1 addition & 1 deletion fs/lockd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ ccflags-y += -I$(src) # needed for trace events
obj-$(CONFIG_LOCKD) += lockd.o

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
svcshare.o svcproc.o svcsubs.o mon.o trace.o xdr.o netlink.o
lockd-$(CONFIG_LOCKD_V4) += clnt4xdr.o xdr4.o svc4proc.o
lockd-$(CONFIG_PROC_FS) += procfs.o
44 changes: 44 additions & 0 deletions fs/lockd/netlink.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
/* Do not edit directly, auto-generated from: */
/* Documentation/netlink/specs/lockd.yaml */
/* YNL-GEN kernel source */

#include <net/netlink.h>
#include <net/genetlink.h>

#include "netlink.h"

#include <uapi/linux/lockd_netlink.h>

/* LOCKD_CMD_SERVER_SET - do */
static const struct nla_policy lockd_server_set_nl_policy[LOCKD_A_SERVER_UDP_PORT + 1] = {
[LOCKD_A_SERVER_GRACETIME] = { .type = NLA_U32, },
[LOCKD_A_SERVER_TCP_PORT] = { .type = NLA_U16, },
[LOCKD_A_SERVER_UDP_PORT] = { .type = NLA_U16, },
};

/* Ops table for lockd */
static const struct genl_split_ops lockd_nl_ops[] = {
{
.cmd = LOCKD_CMD_SERVER_SET,
.doit = lockd_nl_server_set_doit,
.policy = lockd_server_set_nl_policy,
.maxattr = LOCKD_A_SERVER_UDP_PORT,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
.cmd = LOCKD_CMD_SERVER_GET,
.doit = lockd_nl_server_get_doit,
.flags = GENL_CMD_CAP_DO,
},
};

struct genl_family lockd_nl_family __ro_after_init = {
.name = LOCKD_FAMILY_NAME,
.version = LOCKD_FAMILY_VERSION,
.netnsok = true,
.parallel_ops = true,
.module = THIS_MODULE,
.split_ops = lockd_nl_ops,
.n_split_ops = ARRAY_SIZE(lockd_nl_ops),
};
19 changes: 19 additions & 0 deletions fs/lockd/netlink.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
/* Do not edit directly, auto-generated from: */
/* Documentation/netlink/specs/lockd.yaml */
/* YNL-GEN kernel header */

#ifndef _LINUX_LOCKD_GEN_H
#define _LINUX_LOCKD_GEN_H

#include <net/netlink.h>
#include <net/genetlink.h>

#include <uapi/linux/lockd_netlink.h>

int lockd_nl_server_set_doit(struct sk_buff *skb, struct genl_info *info);
int lockd_nl_server_get_doit(struct sk_buff *skb, struct genl_info *info);

extern struct genl_family lockd_nl_family;

#endif /* _LINUX_LOCKD_GEN_H */
3 changes: 3 additions & 0 deletions fs/lockd/netns.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ struct lockd_net {
unsigned int nlmsvc_users;
unsigned long next_gc;
unsigned long nrhosts;
u32 gracetime;
u16 tcp_port;
u16 udp_port;

struct delayed_work grace_period_end;
struct lock_manager lockd_manager;
Expand Down
123 changes: 115 additions & 8 deletions fs/lockd/svc.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@

#include "netns.h"
#include "procfs.h"
#include "netlink.h"

#define NLMDBG_FACILITY NLMDBG_SVC
#define LOCKD_BUFSIZE (1024 + NLMSVC_XDRSIZE)
Expand Down Expand Up @@ -83,8 +84,14 @@ static const int nlm_port_min = 0, nlm_port_max = 65535;
static struct ctl_table_header * nlm_sysctl_table;
#endif

static unsigned long get_lockd_grace_period(void)
static unsigned long get_lockd_grace_period(struct net *net)
{
struct lockd_net *ln = net_generic(net, lockd_net_id);

/* Return the net-ns specific grace period, if there is one */
if (ln->gracetime)
return ln->gracetime * HZ;

/* Note: nlm_timeout should always be nonzero */
if (nlm_grace_period)
return roundup(nlm_grace_period, nlm_timeout) * HZ;
Expand All @@ -103,7 +110,7 @@ static void grace_ender(struct work_struct *grace)

static void set_grace_period(struct net *net)
{
unsigned long grace_period = get_lockd_grace_period();
unsigned long grace_period = get_lockd_grace_period(net);
struct lockd_net *ln = net_generic(net, lockd_net_id);

locks_start_grace(net, &ln->lockd_manager);
Expand Down Expand Up @@ -166,15 +173,16 @@ static int create_lockd_listener(struct svc_serv *serv, const char *name,
static int create_lockd_family(struct svc_serv *serv, struct net *net,
const int family, const struct cred *cred)
{
struct lockd_net *ln = net_generic(net, lockd_net_id);
int err;

err = create_lockd_listener(serv, "udp", net, family, nlm_udpport,
cred);
err = create_lockd_listener(serv, "udp", net, family,
ln->udp_port ? ln->udp_port : nlm_udpport, cred);
if (err < 0)
return err;

return create_lockd_listener(serv, "tcp", net, family, nlm_tcpport,
cred);
return create_lockd_listener(serv, "tcp", net, family,
ln->tcp_port ? ln->tcp_port : nlm_tcpport, cred);
}

/*
Expand Down Expand Up @@ -459,9 +467,10 @@ static const struct ctl_table nlm_sysctls[] = {
{
.procname = "nsm_local_state",
.data = &nsm_local_state,
.maxlen = sizeof(int),
.maxlen = sizeof(nsm_local_state),
.mode = 0644,
.proc_handler = proc_dointvec,
.proc_handler = proc_douintvec,
.extra1 = SYSCTL_ZERO,
},
};

Expand Down Expand Up @@ -588,13 +597,19 @@ static int __init init_nlm(void)
if (err)
goto err_pernet;

err = genl_register_family(&lockd_nl_family);
if (err)
goto err_netlink;

err = lockd_create_procfs();
if (err)
goto err_procfs;

return 0;

err_procfs:
genl_unregister_family(&lockd_nl_family);
err_netlink:
unregister_pernet_subsys(&lockd_net_ops);
err_pernet:
#ifdef CONFIG_SYSCTL
Expand All @@ -608,6 +623,7 @@ static void __exit exit_nlm(void)
{
/* FIXME: delete all NLM clients */
nlm_shutdown_hosts();
genl_unregister_family(&lockd_nl_family);
lockd_remove_procfs();
unregister_pernet_subsys(&lockd_net_ops);
#ifdef CONFIG_SYSCTL
Expand Down Expand Up @@ -710,3 +726,94 @@ static struct svc_program nlmsvc_program = {
.pg_init_request = svc_generic_init_request,
.pg_rpcbind_set = svc_generic_rpcbind_set,
};

/**
* lockd_nl_server_set_doit - set the lockd server parameters via netlink
* @skb: reply buffer
* @info: netlink metadata and command arguments
*
* This updates the per-net values. When updating the values in the init_net
* namespace, also update the "legacy" global values.
*
* Return 0 on success or a negative errno.
*/
int lockd_nl_server_set_doit(struct sk_buff *skb, struct genl_info *info)
{
struct net *net = genl_info_net(info);
struct lockd_net *ln = net_generic(net, lockd_net_id);
const struct nlattr *attr;

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

if (info->attrs[LOCKD_A_SERVER_GRACETIME] ||
info->attrs[LOCKD_A_SERVER_TCP_PORT] ||
info->attrs[LOCKD_A_SERVER_UDP_PORT]) {
attr = info->attrs[LOCKD_A_SERVER_GRACETIME];
if (attr) {
u32 gracetime = nla_get_u32(attr);

if (gracetime > nlm_grace_period_max)
return -EINVAL;

ln->gracetime = gracetime;

if (net == &init_net)
nlm_grace_period = gracetime;
}

attr = info->attrs[LOCKD_A_SERVER_TCP_PORT];
if (attr) {
ln->tcp_port = nla_get_u16(attr);
if (net == &init_net)
nlm_tcpport = ln->tcp_port;
}

attr = info->attrs[LOCKD_A_SERVER_UDP_PORT];
if (attr) {
ln->udp_port = nla_get_u16(attr);
if (net == &init_net)
nlm_udpport = ln->udp_port;
}
}
return 0;
}

/**
* lockd_nl_server_get_doit - get lockd server parameters via netlink
* @skb: reply buffer
* @info: netlink metadata and command arguments
*
* Return 0 on success or a negative errno.
*/
int lockd_nl_server_get_doit(struct sk_buff *skb, struct genl_info *info)
{
struct net *net = genl_info_net(info);
struct lockd_net *ln = net_generic(net, lockd_net_id);
void *hdr;
int err;

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

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

err = nla_put_u32(skb, LOCKD_A_SERVER_GRACETIME, ln->gracetime) ||
nla_put_u16(skb, LOCKD_A_SERVER_TCP_PORT, ln->tcp_port) ||
nla_put_u16(skb, LOCKD_A_SERVER_UDP_PORT, ln->udp_port);
if (err)
goto err_free_msg;

genlmsg_end(skb, hdr);

return genlmsg_reply(skb, info);
err_free_msg:
nlmsg_free(skb);

return err;
}
3 changes: 2 additions & 1 deletion fs/nfs/export.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,5 +154,6 @@ const struct export_operations nfs_export_ops = {
EXPORT_OP_CLOSE_BEFORE_UNLINK |
EXPORT_OP_REMOTE_FS |
EXPORT_OP_NOATOMIC_ATTR |
EXPORT_OP_FLUSH_ON_CLOSE,
EXPORT_OP_FLUSH_ON_CLOSE |
EXPORT_OP_NOLOCKS,
};
8 changes: 5 additions & 3 deletions fs/nfs_common/nfsacl.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ struct nfsacl_encode_desc {
};

struct nfsacl_simple_acl {
struct posix_acl acl;
struct posix_acl_hdr acl;
struct posix_acl_entry ace[4];
};

Expand Down Expand Up @@ -112,7 +112,8 @@ int nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode,
xdr_encode_word(buf, base, entries))
return -EINVAL;
if (encode_entries && acl && acl->a_count == 3) {
struct posix_acl *acl2 = &aclbuf.acl;
struct posix_acl *acl2 =
container_of(&aclbuf.acl, struct posix_acl, hdr);

/* Avoid the use of posix_acl_alloc(). nfsacl_encode() is
* invoked in contexts where a memory allocation failure is
Expand Down Expand Up @@ -177,7 +178,8 @@ bool nfs_stream_encode_acl(struct xdr_stream *xdr, struct inode *inode,
return false;

if (encode_entries && acl && acl->a_count == 3) {
struct posix_acl *acl2 = &aclbuf.acl;
struct posix_acl *acl2 =
container_of(&aclbuf.acl, struct posix_acl, hdr);

/* Avoid the use of posix_acl_alloc(). nfsacl_encode() is
* invoked in contexts where a memory allocation failure is
Expand Down
12 changes: 11 additions & 1 deletion fs/nfsd/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,16 @@ config NFSD_LEGACY_CLIENT_TRACKING
recoverydir, or spawn a process directly using a usermodehelper
upcall.

These legacy client tracking methods have proven to be probelmatic
These legacy client tracking methods have proven to be problematic
and will be removed in the future. Say Y here if you need support
for them in the interim.

config NFSD_V4_DELEG_TIMESTAMPS
bool "Support delegated timestamps"
depends on NFSD_V4
default n
help
NFSD implements delegated timestamps according to
draft-ietf-nfsv4-delstid-08 "Extending the Opening of Files". This
is currently an experimental feature and is therefore left disabled
by default.
Loading

0 comments on commit b6dde1e

Please sign in to comment.