Skip to content

Commit adcffc1

Browse files
committed
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
2 parents bce58da + a3d0562 commit adcffc1

File tree

5 files changed

+54
-10
lines changed

5 files changed

+54
-10
lines changed

fs/nfs/nfs4proc.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,14 @@ static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dent
363363
kunmap_atomic(start);
364364
}
365365

366+
static void nfs4_fattr_set_prechange(struct nfs_fattr *fattr, u64 version)
367+
{
368+
if (!(fattr->valid & NFS_ATTR_FATTR_PRECHANGE)) {
369+
fattr->pre_change_attr = version;
370+
fattr->valid |= NFS_ATTR_FATTR_PRECHANGE;
371+
}
372+
}
373+
366374
static void nfs4_test_and_free_stateid(struct nfs_server *server,
367375
nfs4_stateid *stateid,
368376
const struct cred *cred)
@@ -6553,7 +6561,9 @@ static void nfs4_delegreturn_release(void *calldata)
65536561
pnfs_roc_release(&data->lr.arg, &data->lr.res,
65546562
data->res.lr_ret);
65556563
if (inode) {
6556-
nfs_post_op_update_inode_force_wcc(inode, &data->fattr);
6564+
nfs4_fattr_set_prechange(&data->fattr,
6565+
inode_peek_iversion_raw(inode));
6566+
nfs_refresh_inode(inode, &data->fattr);
65576567
nfs_iput_and_deactive(inode);
65586568
}
65596569
kfree(calldata);

include/linux/sunrpc/clnt.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ struct rpc_add_xprt_test {
160160
#define RPC_CLNT_CREATE_NO_RETRANS_TIMEOUT (1UL << 9)
161161
#define RPC_CLNT_CREATE_SOFTERR (1UL << 10)
162162
#define RPC_CLNT_CREATE_REUSEPORT (1UL << 11)
163+
#define RPC_CLNT_CREATE_IGNORE_NULL_UNAVAIL (1UL << 12)
163164

164165
struct rpc_clnt *rpc_create(struct rpc_create_args *args);
165166
struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *,

net/sunrpc/auth_gss/gss_rpc_upcall.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ static int gssp_rpc_create(struct net *net, struct rpc_clnt **_clnt)
9797
* timeout, which would result in reconnections being
9898
* done without the correct namespace:
9999
*/
100-
.flags = RPC_CLNT_CREATE_NOPING |
100+
.flags = RPC_CLNT_CREATE_IGNORE_NULL_UNAVAIL |
101101
RPC_CLNT_CREATE_NO_IDLE_TIMEOUT
102102
};
103103
struct rpc_clnt *clnt;

net/sunrpc/clnt.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,9 @@ static struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args,
479479

480480
if (!(args->flags & RPC_CLNT_CREATE_NOPING)) {
481481
int err = rpc_ping(clnt);
482+
if ((args->flags & RPC_CLNT_CREATE_IGNORE_NULL_UNAVAIL) &&
483+
err == -EOPNOTSUPP)
484+
err = 0;
482485
if (err != 0) {
483486
rpc_shutdown_client(clnt);
484487
return ERR_PTR(err);
@@ -1065,10 +1068,13 @@ rpc_task_get_next_xprt(struct rpc_clnt *clnt)
10651068
static
10661069
void rpc_task_set_transport(struct rpc_task *task, struct rpc_clnt *clnt)
10671070
{
1068-
if (task->tk_xprt &&
1069-
!(test_bit(XPRT_OFFLINE, &task->tk_xprt->state) &&
1070-
(task->tk_flags & RPC_TASK_MOVEABLE)))
1071-
return;
1071+
if (task->tk_xprt) {
1072+
if (!(test_bit(XPRT_OFFLINE, &task->tk_xprt->state) &&
1073+
(task->tk_flags & RPC_TASK_MOVEABLE)))
1074+
return;
1075+
xprt_release(task);
1076+
xprt_put(task->tk_xprt);
1077+
}
10721078
if (task->tk_flags & RPC_TASK_NO_ROUND_ROBIN)
10731079
task->tk_xprt = rpc_task_get_first_xprt(clnt);
10741080
else

net/sunrpc/xprtsock.c

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,6 +1418,26 @@ static size_t xs_tcp_bc_maxpayload(struct rpc_xprt *xprt)
14181418
}
14191419
#endif /* CONFIG_SUNRPC_BACKCHANNEL */
14201420

1421+
/**
1422+
* xs_local_state_change - callback to handle AF_LOCAL socket state changes
1423+
* @sk: socket whose state has changed
1424+
*
1425+
*/
1426+
static void xs_local_state_change(struct sock *sk)
1427+
{
1428+
struct rpc_xprt *xprt;
1429+
struct sock_xprt *transport;
1430+
1431+
if (!(xprt = xprt_from_sock(sk)))
1432+
return;
1433+
transport = container_of(xprt, struct sock_xprt, xprt);
1434+
if (sk->sk_shutdown & SHUTDOWN_MASK) {
1435+
clear_bit(XPRT_CONNECTED, &xprt->state);
1436+
/* Trigger the socket release */
1437+
xs_run_error_worker(transport, XPRT_SOCK_WAKE_DISCONNECT);
1438+
}
1439+
}
1440+
14211441
/**
14221442
* xs_tcp_state_change - callback to handle TCP socket state changes
14231443
* @sk: socket whose state has changed
@@ -1866,6 +1886,7 @@ static int xs_local_finish_connecting(struct rpc_xprt *xprt,
18661886
sk->sk_user_data = xprt;
18671887
sk->sk_data_ready = xs_data_ready;
18681888
sk->sk_write_space = xs_udp_write_space;
1889+
sk->sk_state_change = xs_local_state_change;
18691890
sk->sk_error_report = xs_error_report;
18701891

18711892
xprt_clear_connected(xprt);
@@ -1950,6 +1971,9 @@ static void xs_local_connect(struct rpc_xprt *xprt, struct rpc_task *task)
19501971
struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
19511972
int ret;
19521973

1974+
if (transport->file)
1975+
goto force_disconnect;
1976+
19531977
if (RPC_IS_ASYNC(task)) {
19541978
/*
19551979
* 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)
19621986
*/
19631987
task->tk_rpc_status = -ENOTCONN;
19641988
rpc_exit(task, -ENOTCONN);
1965-
return;
1989+
goto out_wake;
19661990
}
19671991
ret = xs_local_setup_socket(transport);
19681992
if (ret && !RPC_IS_SOFTCONN(task))
19691993
msleep_interruptible(15000);
1994+
return;
1995+
force_disconnect:
1996+
xprt_force_disconnect(xprt);
1997+
out_wake:
1998+
xprt_clear_connecting(xprt);
1999+
xprt_wake_pending_tasks(xprt, -ENOTCONN);
19702000
}
19712001

19722002
#if IS_ENABLED(CONFIG_SUNRPC_SWAP)
@@ -2845,9 +2875,6 @@ static struct rpc_xprt *xs_setup_local(struct xprt_create *args)
28452875
}
28462876
xprt_set_bound(xprt);
28472877
xs_format_peer_addresses(xprt, "local", RPCBIND_NETID_LOCAL);
2848-
ret = ERR_PTR(xs_local_setup_socket(transport));
2849-
if (ret)
2850-
goto out_err;
28512878
break;
28522879
default:
28532880
ret = ERR_PTR(-EAFNOSUPPORT);

0 commit comments

Comments
 (0)