Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci-2.6.23
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci-2.6.23
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 @@ cleanup:
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