NFS client bugfixes for Linux 5.18
Highlights include: Stable fixes: - Fix a socket leak when setting up an AF_LOCAL RPC client - Ensure that knfsd connects to the gss-proxy daemon on setup Bugfixes: - Fix a refcount leak when migrating a task off an offlined transport - Don't gratuitously invalidate inode attributes on delegation return - Don't leak sockets in xs_local_connect() - Ensure timely close of disconnected AF_LOCAL sockets -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEESQctxSBg8JpV8KqEZwvnipYKAPIFAmJ1f3wACgkQZwvnipYK APKKIRAAmVUswcfRQ9wSz5wW6DCFU9hdsN9JD4pAcPvWAYGo8fqmn3I3qe/iaBCf rrJF38SfQVygtthmAY4CBBwOiVxm2fvqanML2lta+ZUU15MqoH2px3kMYemRyulJ 9/2yP25AUSgkmwdEmm69hIXJkEJa3dsjg+LajQZ5X01DgKSfpObS5s9t/upM9kve Wqz5QRr+aJnZuuYYJWxNmXZ4XQEkzHccg3aSswB6bEsEGNXKo8NnWryrSMnWTW1y rQCb0e+gxpoVFgV3ngP1r9xT2l2ISbJIIhTPoj5hSjSVlFvQlIEyHtGA2vuIEZH9 hPJAnaSc7Xb+QER6XfZkTxjW+jtMl5OmMKkWUcUmHiYv2KIM8dUAd3ANnbDBCUvw C5bGF907Qjqs5d2VdfsbisT9ikyn+xw6SFxcr9HYyH2T3dIsC1A8P9uUvn/afwUQ EPfQIsIEDeufo6O8KLfF+gCO9kbk9rdaP8Bv3B2H94aRs1yYde9bJpa7QABncGbA otWehkX/AbrIa4Zjp1ELzcVJxlIl+/AtxzCdGY2me1Ds388U/RKsyDWwXuGynLP6 98ycdtHWVyoJ48L5kZowuj8/3tEB998En5hh0HSuAd0DYkAuGxaSGb+iuwKi/M0H +D1wZxef49r2ggQkEOsllTEjJKSHcq1+vCVASZ8ITEbcVUSiO90= =LSoH -----END PGP SIGNATURE----- Merge tag 'nfs-for-5.18-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs Pull NFS client fixes from Trond Myklebust: "Highlights include: Stable fixes: - Fix a socket leak when setting up an AF_LOCAL RPC client - Ensure that knfsd connects to the gss-proxy daemon on setup Bugfixes: - Fix a refcount leak when migrating a task off an offlined transport - Don't gratuitously invalidate inode attributes on delegation return - Don't leak sockets in xs_local_connect() - Ensure timely close of disconnected AF_LOCAL sockets" * tag 'nfs-for-5.18-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: Revert "SUNRPC: attempt AF_LOCAL connect on setup" SUNRPC: Ensure gss-proxy connects on setup SUNRPC: Ensure timely close of disconnected AF_LOCAL sockets SUNRPC: Don't leak sockets in xs_local_connect() NFSv4: Don't invalidate inode attributes on delegation return SUNRPC release the transport of a relocated task with an assigned transport
This commit is contained in:
commit
adcffc1716
|
@ -363,6 +363,14 @@ static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dent
|
|||
kunmap_atomic(start);
|
||||
}
|
||||
|
||||
static void nfs4_fattr_set_prechange(struct nfs_fattr *fattr, u64 version)
|
||||
{
|
||||
if (!(fattr->valid & NFS_ATTR_FATTR_PRECHANGE)) {
|
||||
fattr->pre_change_attr = version;
|
||||
fattr->valid |= NFS_ATTR_FATTR_PRECHANGE;
|
||||
}
|
||||
}
|
||||
|
||||
static void nfs4_test_and_free_stateid(struct nfs_server *server,
|
||||
nfs4_stateid *stateid,
|
||||
const struct cred *cred)
|
||||
|
@ -6553,7 +6561,9 @@ static void nfs4_delegreturn_release(void *calldata)
|
|||
pnfs_roc_release(&data->lr.arg, &data->lr.res,
|
||||
data->res.lr_ret);
|
||||
if (inode) {
|
||||
nfs_post_op_update_inode_force_wcc(inode, &data->fattr);
|
||||
nfs4_fattr_set_prechange(&data->fattr,
|
||||
inode_peek_iversion_raw(inode));
|
||||
nfs_refresh_inode(inode, &data->fattr);
|
||||
nfs_iput_and_deactive(inode);
|
||||
}
|
||||
kfree(calldata);
|
||||
|
|
|
@ -160,6 +160,7 @@ struct rpc_add_xprt_test {
|
|||
#define RPC_CLNT_CREATE_NO_RETRANS_TIMEOUT (1UL << 9)
|
||||
#define RPC_CLNT_CREATE_SOFTERR (1UL << 10)
|
||||
#define RPC_CLNT_CREATE_REUSEPORT (1UL << 11)
|
||||
#define RPC_CLNT_CREATE_IGNORE_NULL_UNAVAIL (1UL << 12)
|
||||
|
||||
struct rpc_clnt *rpc_create(struct rpc_create_args *args);
|
||||
struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *,
|
||||
|
|
|
@ -97,7 +97,7 @@ static int gssp_rpc_create(struct net *net, struct rpc_clnt **_clnt)
|
|||
* timeout, which would result in reconnections being
|
||||
* done without the correct namespace:
|
||||
*/
|
||||
.flags = RPC_CLNT_CREATE_NOPING |
|
||||
.flags = RPC_CLNT_CREATE_IGNORE_NULL_UNAVAIL |
|
||||
RPC_CLNT_CREATE_NO_IDLE_TIMEOUT
|
||||
};
|
||||
struct rpc_clnt *clnt;
|
||||
|
|
|
@ -479,6 +479,9 @@ static struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args,
|
|||
|
||||
if (!(args->flags & RPC_CLNT_CREATE_NOPING)) {
|
||||
int err = rpc_ping(clnt);
|
||||
if ((args->flags & RPC_CLNT_CREATE_IGNORE_NULL_UNAVAIL) &&
|
||||
err == -EOPNOTSUPP)
|
||||
err = 0;
|
||||
if (err != 0) {
|
||||
rpc_shutdown_client(clnt);
|
||||
return ERR_PTR(err);
|
||||
|
@ -1065,10 +1068,13 @@ rpc_task_get_next_xprt(struct rpc_clnt *clnt)
|
|||
static
|
||||
void rpc_task_set_transport(struct rpc_task *task, struct rpc_clnt *clnt)
|
||||
{
|
||||
if (task->tk_xprt &&
|
||||
!(test_bit(XPRT_OFFLINE, &task->tk_xprt->state) &&
|
||||
(task->tk_flags & RPC_TASK_MOVEABLE)))
|
||||
return;
|
||||
if (task->tk_xprt) {
|
||||
if (!(test_bit(XPRT_OFFLINE, &task->tk_xprt->state) &&
|
||||
(task->tk_flags & RPC_TASK_MOVEABLE)))
|
||||
return;
|
||||
xprt_release(task);
|
||||
xprt_put(task->tk_xprt);
|
||||
}
|
||||
if (task->tk_flags & RPC_TASK_NO_ROUND_ROBIN)
|
||||
task->tk_xprt = rpc_task_get_first_xprt(clnt);
|
||||
else
|
||||
|
|
|
@ -1418,6 +1418,26 @@ static size_t xs_tcp_bc_maxpayload(struct rpc_xprt *xprt)
|
|||
}
|
||||
#endif /* CONFIG_SUNRPC_BACKCHANNEL */
|
||||
|
||||
/**
|
||||
* xs_local_state_change - callback to handle AF_LOCAL socket state changes
|
||||
* @sk: socket whose state has changed
|
||||
*
|
||||
*/
|
||||
static void xs_local_state_change(struct sock *sk)
|
||||
{
|
||||
struct rpc_xprt *xprt;
|
||||
struct sock_xprt *transport;
|
||||
|
||||
if (!(xprt = xprt_from_sock(sk)))
|
||||
return;
|
||||
transport = container_of(xprt, struct sock_xprt, xprt);
|
||||
if (sk->sk_shutdown & SHUTDOWN_MASK) {
|
||||
clear_bit(XPRT_CONNECTED, &xprt->state);
|
||||
/* Trigger the socket release */
|
||||
xs_run_error_worker(transport, XPRT_SOCK_WAKE_DISCONNECT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* xs_tcp_state_change - callback to handle TCP socket state changes
|
||||
* @sk: socket whose state has changed
|
||||
|
@ -1866,6 +1886,7 @@ static int xs_local_finish_connecting(struct rpc_xprt *xprt,
|
|||
sk->sk_user_data = xprt;
|
||||
sk->sk_data_ready = xs_data_ready;
|
||||
sk->sk_write_space = xs_udp_write_space;
|
||||
sk->sk_state_change = xs_local_state_change;
|
||||
sk->sk_error_report = xs_error_report;
|
||||
|
||||
xprt_clear_connected(xprt);
|
||||
|
@ -1950,6 +1971,9 @@ static void xs_local_connect(struct rpc_xprt *xprt, struct rpc_task *task)
|
|||
struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
|
||||
int ret;
|
||||
|
||||
if (transport->file)
|
||||
goto force_disconnect;
|
||||
|
||||
if (RPC_IS_ASYNC(task)) {
|
||||
/*
|
||||
* We want the AF_LOCAL connect to be resolved in the
|
||||
|
@ -1962,11 +1986,17 @@ static void xs_local_connect(struct rpc_xprt *xprt, struct rpc_task *task)
|
|||
*/
|
||||
task->tk_rpc_status = -ENOTCONN;
|
||||
rpc_exit(task, -ENOTCONN);
|
||||
return;
|
||||
goto out_wake;
|
||||
}
|
||||
ret = xs_local_setup_socket(transport);
|
||||
if (ret && !RPC_IS_SOFTCONN(task))
|
||||
msleep_interruptible(15000);
|
||||
return;
|
||||
force_disconnect:
|
||||
xprt_force_disconnect(xprt);
|
||||
out_wake:
|
||||
xprt_clear_connecting(xprt);
|
||||
xprt_wake_pending_tasks(xprt, -ENOTCONN);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_SUNRPC_SWAP)
|
||||
|
@ -2845,9 +2875,6 @@ static struct rpc_xprt *xs_setup_local(struct xprt_create *args)
|
|||
}
|
||||
xprt_set_bound(xprt);
|
||||
xs_format_peer_addresses(xprt, "local", RPCBIND_NETID_LOCAL);
|
||||
ret = ERR_PTR(xs_local_setup_socket(transport));
|
||||
if (ret)
|
||||
goto out_err;
|
||||
break;
|
||||
default:
|
||||
ret = ERR_PTR(-EAFNOSUPPORT);
|
||||
|
|
Loading…
Reference in New Issue