lockd_nl_server_set_doit() required LOCKD_A_SERVER_GRACETIME via
GENL_REQ_ATTR_CHECK(), but all three attributes are optional in
lockd.yaml and each is applied independently below. The effect was that
the tcp and udp ports could not be set on their own.
nfsdctl hits this: with a [lockd] section that sets "port" but no
"grace-time", it sends SERVER_SET with only the two port attributes, and
"nfsdctl autostart" aborts with EINVAL before configuring anything.
Drop the check, along with the now-redundant outer test for "any
attribute present". The gracetime range check is unaffected.
Fixes: 9a28ac1762a7 ("lockd: add netlink control interface")
Assisted-by: LLM
Reported-by: Scott Mayhew <[email protected]>
Signed-off-by: Jeff Layton <[email protected]>
---
fs/lockd/svc.c | 50 ++++++++++++++++++++++----------------------------
1 file changed, 22 insertions(+), 28 deletions(-)
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index f0e1a58c9106..8e1b1735acaf 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -704,7 +704,8 @@ static struct svc_program nlmsvc_program = {
* @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.
+ * namespace, also update the "legacy" global values. Every attribute is
+ * optional; only the ones present in @info are changed.
*
* Return 0 on success or a negative errno.
*/
@@ -714,38 +715,31 @@ int lockd_nl_server_set_doit(struct sk_buff *skb, struct
genl_info *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;
+ attr = info->attrs[LOCKD_A_SERVER_GRACETIME];
+ if (attr) {
+ u32 gracetime = nla_get_u32(attr);
- 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;
- if (gracetime > nlm_grace_period_max)
- return -EINVAL;
+ ln->gracetime = gracetime;
- ln->gracetime = gracetime;
-
- if (net == &init_net)
- nlm_grace_period = 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_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;
- }
+ 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;
}
--
2.55.0