Commit c2fc9462 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull nfsd fixes from Chuck Lever:

 - Fix crashes triggered by administrative operations on the server

* tag 'nfsd-6.10-2' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux:
  NFSD: grab nfsd_mutex in nfsd_nl_rpc_status_get_dumpit()
  nfsd: fix oops when reading pool_stats before server is started
parents 563a5067 da2c8fef
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -123,8 +123,6 @@ operations:
      doc: dump pending nfsd rpc
      attribute-set: rpc-status
      dump:
        pre: nfsd-nl-rpc-status-get-start
        post: nfsd-nl-rpc-status-get-done
        reply:
          attributes:
            - xid
+0 −2
Original line number Diff line number Diff line
@@ -44,9 +44,7 @@ static const struct nla_policy nfsd_listener_set_nl_policy[NFSD_A_SERVER_SOCK_AD
static const struct genl_split_ops nfsd_nl_ops[] = {
	{
		.cmd	= NFSD_CMD_RPC_STATUS_GET,
		.start	= nfsd_nl_rpc_status_get_start,
		.dumpit	= nfsd_nl_rpc_status_get_dumpit,
		.done	= nfsd_nl_rpc_status_get_done,
		.flags	= GENL_CMD_CAP_DUMP,
	},
	{
+0 −3
Original line number Diff line number Diff line
@@ -15,9 +15,6 @@
extern const struct nla_policy nfsd_sock_nl_policy[NFSD_A_SOCK_TRANSPORT_NAME + 1];
extern const struct nla_policy nfsd_version_nl_policy[NFSD_A_VERSION_ENABLED + 1];

int nfsd_nl_rpc_status_get_start(struct netlink_callback *cb);
int nfsd_nl_rpc_status_get_done(struct netlink_callback *cb);

int nfsd_nl_rpc_status_get_dumpit(struct sk_buff *skb,
				  struct netlink_callback *cb);
int nfsd_nl_threads_set_doit(struct sk_buff *skb, struct genl_info *info);
+11 −37
Original line number Diff line number Diff line
@@ -1460,28 +1460,6 @@ static int create_proc_exports_entry(void)

unsigned int nfsd_net_id;

/**
 * nfsd_nl_rpc_status_get_start - Prepare rpc_status_get dumpit
 * @cb: netlink metadata and command arguments
 *
 * Return values:
 *   %0: The rpc_status_get command may proceed
 *   %-ENODEV: There is no NFSD running in this namespace
 */
int nfsd_nl_rpc_status_get_start(struct netlink_callback *cb)
{
	struct nfsd_net *nn = net_generic(sock_net(cb->skb->sk), nfsd_net_id);
	int ret = -ENODEV;

	mutex_lock(&nfsd_mutex);
	if (nn->nfsd_serv)
		ret = 0;
	else
		mutex_unlock(&nfsd_mutex);

	return ret;
}

static int nfsd_genl_rpc_status_compose_msg(struct sk_buff *skb,
					    struct netlink_callback *cb,
					    struct nfsd_genl_rqstp *rqstp)
@@ -1558,8 +1536,16 @@ static int nfsd_genl_rpc_status_compose_msg(struct sk_buff *skb,
int nfsd_nl_rpc_status_get_dumpit(struct sk_buff *skb,
				  struct netlink_callback *cb)
{
	struct nfsd_net *nn = net_generic(sock_net(skb->sk), nfsd_net_id);
	int i, ret, rqstp_index = 0;
	struct nfsd_net *nn;

	mutex_lock(&nfsd_mutex);

	nn = net_generic(sock_net(skb->sk), nfsd_net_id);
	if (!nn->nfsd_serv) {
		ret = -ENODEV;
		goto out_unlock;
	}

	rcu_read_lock();

@@ -1636,22 +1622,10 @@ int nfsd_nl_rpc_status_get_dumpit(struct sk_buff *skb,
	ret = skb->len;
out:
	rcu_read_unlock();

	return ret;
}

/**
 * nfsd_nl_rpc_status_get_done - rpc_status_get dumpit post-processing
 * @cb: netlink metadata and command arguments
 *
 * Return values:
 *   %0: Success
 */
int nfsd_nl_rpc_status_get_done(struct netlink_callback *cb)
{
out_unlock:
	mutex_unlock(&nfsd_mutex);

	return 0;
	return ret;
}

/**
+5 −3
Original line number Diff line number Diff line
@@ -1421,12 +1421,13 @@ static void *svc_pool_stats_start(struct seq_file *m, loff_t *pos)

	dprintk("svc_pool_stats_start, *pidx=%u\n", pidx);

	if (!si->serv)
		return NULL;

	mutex_lock(si->mutex);

	if (!pidx)
		return SEQ_START_TOKEN;
	if (!si->serv)
		return NULL;
	return pidx > si->serv->sv_nrpools ? NULL
		: &si->serv->sv_pools[pidx - 1];
}
@@ -1458,6 +1459,7 @@ static void svc_pool_stats_stop(struct seq_file *m, void *p)
{
	struct svc_info *si = m->private;

	if (si->serv)
		mutex_unlock(si->mutex);
}