Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
e6b3c4db
Commit
e6b3c4db
authored
Nov 11, 2006
by
Trond Myklebust
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix a second potential rpc_wakeup race...
Signed-off-by:
Trond Myklebust
<
Trond.Myklebust@netapp.com
>
parent
cc4dc59e
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
65 additions
and
57 deletions
+65
-57
fs/nfs/nfs4proc.c
fs/nfs/nfs4proc.c
+6
-6
include/linux/sunrpc/sched.h
include/linux/sunrpc/sched.h
+1
-7
net/sunrpc/clnt.c
net/sunrpc/clnt.c
+10
-9
net/sunrpc/pmap_clnt.c
net/sunrpc/pmap_clnt.c
+1
-1
net/sunrpc/sched.c
net/sunrpc/sched.c
+47
-33
net/sunrpc/sunrpc_syms.c
net/sunrpc/sunrpc_syms.c
+0
-1
No files found.
fs/nfs/nfs4proc.c
View file @
e6b3c4db
...
...
@@ -636,7 +636,7 @@ static int _nfs4_proc_open_confirm(struct nfs4_opendata *data)
smp_wmb
();
}
else
status
=
data
->
rpc_status
;
rpc_
release
_task
(
task
);
rpc_
put
_task
(
task
);
return
status
;
}
...
...
@@ -742,7 +742,7 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
smp_wmb
();
}
else
status
=
data
->
rpc_status
;
rpc_
release
_task
(
task
);
rpc_
put
_task
(
task
);
if
(
status
!=
0
)
return
status
;
...
...
@@ -3067,7 +3067,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
if
(
status
==
0
)
nfs_post_op_update_inode
(
inode
,
&
data
->
fattr
);
}
rpc_
release
_task
(
task
);
rpc_
put
_task
(
task
);
return
status
;
}
...
...
@@ -3314,7 +3314,7 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *
if
(
IS_ERR
(
task
))
goto
out
;
status
=
nfs4_wait_for_completion_rpc_task
(
task
);
rpc_
release
_task
(
task
);
rpc_
put
_task
(
task
);
out:
return
status
;
}
...
...
@@ -3430,7 +3430,7 @@ static void nfs4_lock_release(void *calldata)
task
=
nfs4_do_unlck
(
&
data
->
fl
,
data
->
ctx
,
data
->
lsp
,
data
->
arg
.
lock_seqid
);
if
(
!
IS_ERR
(
task
))
rpc_
release
_task
(
task
);
rpc_
put
_task
(
task
);
dprintk
(
"%s: cancelling lock!
\n
"
,
__FUNCTION__
);
}
else
nfs_free_seqid
(
data
->
arg
.
lock_seqid
);
...
...
@@ -3472,7 +3472,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
ret
=
-
EAGAIN
;
}
else
data
->
cancelled
=
1
;
rpc_
release
_task
(
task
);
rpc_
put
_task
(
task
);
dprintk
(
"%s: done, ret = %d!
\n
"
,
__FUNCTION__
,
ret
);
return
ret
;
}
...
...
include/linux/sunrpc/sched.h
View file @
e6b3c4db
...
...
@@ -178,13 +178,6 @@ struct rpc_call_ops {
} while (0)
#define RPC_IS_ACTIVATED(t) (test_bit(RPC_TASK_ACTIVE, &(t)->tk_runstate))
#define rpc_set_active(t) (set_bit(RPC_TASK_ACTIVE, &(t)->tk_runstate))
#define rpc_clear_active(t) \
do { \
smp_mb__before_clear_bit(); \
clear_bit(RPC_TASK_ACTIVE, &(t)->tk_runstate); \
smp_mb__after_clear_bit(); \
} while(0)
/*
* Task priorities.
...
...
@@ -254,6 +247,7 @@ struct rpc_task *rpc_run_task(struct rpc_clnt *clnt, int flags,
void
rpc_init_task
(
struct
rpc_task
*
task
,
struct
rpc_clnt
*
clnt
,
int
flags
,
const
struct
rpc_call_ops
*
ops
,
void
*
data
);
void
rpc_put_task
(
struct
rpc_task
*
);
void
rpc_release_task
(
struct
rpc_task
*
);
void
rpc_exit_task
(
struct
rpc_task
*
);
void
rpc_killall_tasks
(
struct
rpc_clnt
*
);
...
...
net/sunrpc/clnt.c
View file @
e6b3c4db
...
...
@@ -466,10 +466,9 @@ int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
BUG_ON
(
flags
&
RPC_TASK_ASYNC
);
status
=
-
ENOMEM
;
task
=
rpc_new_task
(
clnt
,
flags
,
&
rpc_default_ops
,
NULL
);
if
(
task
==
NULL
)
goto
out
;
return
-
ENOMEM
;
/* Mask signals on RPC calls _and_ GSS_AUTH upcalls */
rpc_task_sigmask
(
task
,
&
oldset
);
...
...
@@ -478,15 +477,17 @@ int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
/* Set up the call info struct and execute the task */
status
=
task
->
tk_status
;
if
(
status
==
0
)
{
atomic_inc
(
&
task
->
tk_count
);
status
=
rpc_execute
(
task
);
if
(
status
==
0
)
status
=
task
->
tk_status
;
if
(
status
!=
0
)
{
rpc_release_task
(
task
);
goto
out
;
}
rpc_restore_sigmask
(
&
oldset
);
rpc_release_task
(
task
);
atomic_inc
(
&
task
->
tk_count
);
status
=
rpc_execute
(
task
);
if
(
status
==
0
)
status
=
task
->
tk_status
;
rpc_put_task
(
task
);
out:
rpc_restore_sigmask
(
&
oldset
);
return
status
;
}
...
...
net/sunrpc/pmap_clnt.c
View file @
e6b3c4db
...
...
@@ -134,7 +134,7 @@ void rpc_getport(struct rpc_task *task)
child
=
rpc_run_task
(
pmap_clnt
,
RPC_TASK_ASYNC
,
&
pmap_getport_ops
,
map
);
if
(
IS_ERR
(
child
))
goto
bailout
;
rpc_
release
_task
(
child
);
rpc_
put
_task
(
child
);
task
->
tk_xprt
->
stat
.
bind_count
++
;
return
;
...
...
net/sunrpc/sched.c
View file @
e6b3c4db
...
...
@@ -266,12 +266,28 @@ static int rpc_wait_bit_interruptible(void *word)
return
0
;
}
static
void
rpc_set_active
(
struct
rpc_task
*
task
)
{
if
(
test_and_set_bit
(
RPC_TASK_ACTIVE
,
&
task
->
tk_runstate
)
!=
0
)
return
;
spin_lock
(
&
rpc_sched_lock
);
#ifdef RPC_DEBUG
task
->
tk_magic
=
RPC_TASK_MAGIC_ID
;
task
->
tk_pid
=
rpc_task_id
++
;
#endif
/* Add to global list of all tasks */
list_add_tail
(
&
task
->
tk_task
,
&
all_tasks
);
spin_unlock
(
&
rpc_sched_lock
);
}
/*
* Mark an RPC call as having completed by clearing the 'active' bit
*/
static
inline
void
rpc_mark_complete_task
(
struct
rpc_task
*
task
)
static
void
rpc_mark_complete_task
(
struct
rpc_task
*
task
)
{
rpc_clear_active
(
task
);
smp_mb__before_clear_bit
();
clear_bit
(
RPC_TASK_ACTIVE
,
&
task
->
tk_runstate
);
smp_mb__after_clear_bit
();
wake_up_bit
(
&
task
->
tk_runstate
,
RPC_TASK_ACTIVE
);
}
...
...
@@ -335,9 +351,6 @@ static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
return
;
}
/* Mark the task as being activated if so needed */
rpc_set_active
(
task
);
__rpc_add_wait_queue
(
q
,
task
);
BUG_ON
(
task
->
tk_callback
!=
NULL
);
...
...
@@ -348,6 +361,9 @@ static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
void
rpc_sleep_on
(
struct
rpc_wait_queue
*
q
,
struct
rpc_task
*
task
,
rpc_action
action
,
rpc_action
timer
)
{
/* Mark the task as being activated if so needed */
rpc_set_active
(
task
);
/*
* Protect the queue operations.
*/
...
...
@@ -673,8 +689,6 @@ static int __rpc_execute(struct rpc_task *task)
}
dprintk
(
"RPC: %4d, return %d, status %d
\n
"
,
task
->
tk_pid
,
status
,
task
->
tk_status
);
/* Wake up anyone who is waiting for task completion */
rpc_mark_complete_task
(
task
);
/* Release all resources associated with the task */
rpc_release_task
(
task
);
return
status
;
...
...
@@ -788,15 +802,6 @@ void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, int flags, cons
task
->
tk_flags
|=
RPC_TASK_NOINTR
;
}
#ifdef RPC_DEBUG
task
->
tk_magic
=
RPC_TASK_MAGIC_ID
;
task
->
tk_pid
=
rpc_task_id
++
;
#endif
/* Add to global list of all tasks */
spin_lock
(
&
rpc_sched_lock
);
list_add_tail
(
&
task
->
tk_task
,
&
all_tasks
);
spin_unlock
(
&
rpc_sched_lock
);
BUG_ON
(
task
->
tk_ops
==
NULL
);
/* starting timestamp */
...
...
@@ -849,16 +854,35 @@ struct rpc_task *rpc_new_task(struct rpc_clnt *clnt, int flags, const struct rpc
goto
out
;
}
void
rpc_release_task
(
struct
rpc_task
*
task
)
void
rpc_put_task
(
struct
rpc_task
*
task
)
{
const
struct
rpc_call_ops
*
tk_ops
=
task
->
tk_ops
;
void
*
calldata
=
task
->
tk_calldata
;
if
(
!
atomic_dec_and_test
(
&
task
->
tk_count
))
return
;
/* Release resources */
if
(
task
->
tk_rqstp
)
xprt_release
(
task
);
if
(
task
->
tk_msg
.
rpc_cred
)
rpcauth_unbindcred
(
task
);
if
(
task
->
tk_client
)
{
rpc_release_client
(
task
->
tk_client
);
task
->
tk_client
=
NULL
;
}
if
(
task
->
tk_flags
&
RPC_TASK_DYNAMIC
)
rpc_free_task
(
task
);
if
(
tk_ops
->
rpc_release
)
tk_ops
->
rpc_release
(
calldata
);
}
EXPORT_SYMBOL
(
rpc_put_task
);
void
rpc_release_task
(
struct
rpc_task
*
task
)
{
#ifdef RPC_DEBUG
BUG_ON
(
task
->
tk_magic
!=
RPC_TASK_MAGIC_ID
);
#endif
if
(
!
atomic_dec_and_test
(
&
task
->
tk_count
))
return
;
dprintk
(
"RPC: %4d release task
\n
"
,
task
->
tk_pid
);
/* Remove from global task list */
...
...
@@ -871,23 +895,13 @@ void rpc_release_task(struct rpc_task *task)
/* Synchronously delete any running timer */
rpc_delete_timer
(
task
);
/* Release resources */
if
(
task
->
tk_rqstp
)
xprt_release
(
task
);
if
(
task
->
tk_msg
.
rpc_cred
)
rpcauth_unbindcred
(
task
);
if
(
task
->
tk_client
)
{
rpc_release_client
(
task
->
tk_client
);
task
->
tk_client
=
NULL
;
}
#ifdef RPC_DEBUG
task
->
tk_magic
=
0
;
#endif
if
(
task
->
tk_flags
&
RPC_TASK_DYNAMIC
)
rpc_fre
e_task
(
task
);
if
(
tk_ops
->
rpc_release
)
tk_ops
->
rpc_release
(
calldata
);
/* Wake up anyone who is waiting for task completion */
rpc_mark_complet
e_task
(
task
);
rpc_put_task
(
task
);
}
/**
...
...
net/sunrpc/sunrpc_syms.c
View file @
e6b3c4db
...
...
@@ -33,7 +33,6 @@ EXPORT_SYMBOL(rpciod_down);
EXPORT_SYMBOL
(
rpciod_up
);
EXPORT_SYMBOL
(
rpc_new_task
);
EXPORT_SYMBOL
(
rpc_wake_up_status
);
EXPORT_SYMBOL
(
rpc_release_task
);
/* RPC client functions */
EXPORT_SYMBOL
(
rpc_clone_client
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment