mirror of
https://github.com/torvalds/linux.git
synced 2026-06-08 14:42:37 +02:00
sunrpc: Fix potential race conditions in rpc_sysfs_xprt_state_change()
[ Upstream commit 1a48db3fef ]
We need to use test_and_set_bit() when changing xprt state flags to
avoid potentially getting xps->xps_nactive out of sync.
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
4b22aa42bd
commit
4403233b87
|
|
@ -305,25 +305,28 @@ static ssize_t rpc_sysfs_xprt_state_change(struct kobject *kobj,
|
|||
goto release_tasks;
|
||||
}
|
||||
if (offline) {
|
||||
set_bit(XPRT_OFFLINE, &xprt->state);
|
||||
spin_lock(&xps->xps_lock);
|
||||
xps->xps_nactive--;
|
||||
spin_unlock(&xps->xps_lock);
|
||||
if (!test_and_set_bit(XPRT_OFFLINE, &xprt->state)) {
|
||||
spin_lock(&xps->xps_lock);
|
||||
xps->xps_nactive--;
|
||||
spin_unlock(&xps->xps_lock);
|
||||
}
|
||||
} else if (online) {
|
||||
clear_bit(XPRT_OFFLINE, &xprt->state);
|
||||
spin_lock(&xps->xps_lock);
|
||||
xps->xps_nactive++;
|
||||
spin_unlock(&xps->xps_lock);
|
||||
if (test_and_clear_bit(XPRT_OFFLINE, &xprt->state)) {
|
||||
spin_lock(&xps->xps_lock);
|
||||
xps->xps_nactive++;
|
||||
spin_unlock(&xps->xps_lock);
|
||||
}
|
||||
} else if (remove) {
|
||||
if (test_bit(XPRT_OFFLINE, &xprt->state)) {
|
||||
set_bit(XPRT_REMOVE, &xprt->state);
|
||||
xprt_force_disconnect(xprt);
|
||||
if (test_bit(XPRT_CONNECTED, &xprt->state)) {
|
||||
if (!xprt->sending.qlen &&
|
||||
!xprt->pending.qlen &&
|
||||
!xprt->backlog.qlen &&
|
||||
!atomic_long_read(&xprt->queuelen))
|
||||
rpc_xprt_switch_remove_xprt(xps, xprt);
|
||||
if (!test_and_set_bit(XPRT_REMOVE, &xprt->state)) {
|
||||
xprt_force_disconnect(xprt);
|
||||
if (test_bit(XPRT_CONNECTED, &xprt->state)) {
|
||||
if (!xprt->sending.qlen &&
|
||||
!xprt->pending.qlen &&
|
||||
!xprt->backlog.qlen &&
|
||||
!atomic_long_read(&xprt->queuelen))
|
||||
rpc_xprt_switch_remove_xprt(xps, xprt);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
count = -EINVAL;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user