Skip to content

Commit 8d3ca33

Browse files
author
Trond Myklebust
committed
NFS: Don't allow waiting for exiting tasks
Once a task calls exit_signals() it can no longer be signalled. So do not allow it to do killable waits. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
1 parent 14e41b1 commit 8d3ca33

File tree

4 files changed

+15
-3
lines changed

4 files changed

+15
-3
lines changed

fs/nfs/inode.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ nfs_fattr_to_ino_t(struct nfs_fattr *fattr)
7474

7575
int nfs_wait_bit_killable(struct wait_bit_key *key, int mode)
7676
{
77+
if (unlikely(nfs_current_task_exiting()))
78+
return -EINTR;
7779
schedule();
7880
if (signal_pending_state(mode, current))
7981
return -ERESTARTSYS;

fs/nfs/internal.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -912,6 +912,11 @@ static inline u32 nfs_stateid_hash(nfs4_stateid *stateid)
912912
}
913913
#endif
914914

915+
static inline bool nfs_current_task_exiting(void)
916+
{
917+
return (current->flags & PF_EXITING) != 0;
918+
}
919+
915920
static inline bool nfs_error_is_fatal(int err)
916921
{
917922
switch (err) {

fs/nfs/nfs3proc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
3939
__set_current_state(TASK_KILLABLE|TASK_FREEZABLE_UNSAFE);
4040
schedule_timeout(NFS_JUKEBOX_RETRY_TIME);
4141
res = -ERESTARTSYS;
42-
} while (!fatal_signal_pending(current));
42+
} while (!fatal_signal_pending(current) && !nfs_current_task_exiting());
4343
return res;
4444
}
4545

fs/nfs/nfs4proc.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,8 @@ static int nfs4_delay_killable(long *timeout)
446446
{
447447
might_sleep();
448448

449+
if (unlikely(nfs_current_task_exiting()))
450+
return -EINTR;
449451
__set_current_state(TASK_KILLABLE|TASK_FREEZABLE_UNSAFE);
450452
schedule_timeout(nfs4_update_delay(timeout));
451453
if (!__fatal_signal_pending(current))
@@ -457,6 +459,8 @@ static int nfs4_delay_interruptible(long *timeout)
457459
{
458460
might_sleep();
459461

462+
if (unlikely(nfs_current_task_exiting()))
463+
return -EINTR;
460464
__set_current_state(TASK_INTERRUPTIBLE|TASK_FREEZABLE_UNSAFE);
461465
schedule_timeout(nfs4_update_delay(timeout));
462466
if (!signal_pending(current))
@@ -1777,7 +1781,8 @@ static void nfs_set_open_stateid_locked(struct nfs4_state *state,
17771781
rcu_read_unlock();
17781782
trace_nfs4_open_stateid_update_wait(state->inode, stateid, 0);
17791783

1780-
if (!fatal_signal_pending(current)) {
1784+
if (!fatal_signal_pending(current) &&
1785+
!nfs_current_task_exiting()) {
17811786
if (schedule_timeout(5*HZ) == 0)
17821787
status = -EAGAIN;
17831788
else
@@ -3581,7 +3586,7 @@ static bool nfs4_refresh_open_old_stateid(nfs4_stateid *dst,
35813586
write_sequnlock(&state->seqlock);
35823587
trace_nfs4_close_stateid_update_wait(state->inode, dst, 0);
35833588

3584-
if (fatal_signal_pending(current))
3589+
if (fatal_signal_pending(current) || nfs_current_task_exiting())
35853590
status = -EINTR;
35863591
else
35873592
if (schedule_timeout(5*HZ) != 0)

0 commit comments

Comments
 (0)