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
5d28dc82
Commit
5d28dc82
authored
Jun 26, 2007
by
Trond Myklebust
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
SUNRPC: Convert gss_ctx_lock to an RCU lock
Signed-off-by:
Trond Myklebust
<
Trond.Myklebust@netapp.com
>
parent
f5c2187c
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
37 additions
and
17 deletions
+37
-17
include/linux/sunrpc/auth_gss.h
include/linux/sunrpc/auth_gss.h
+1
-0
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/auth_gss/auth_gss.c
+36
-17
No files found.
include/linux/sunrpc/auth_gss.h
View file @
5d28dc82
...
@@ -75,6 +75,7 @@ struct gss_cl_ctx {
...
@@ -75,6 +75,7 @@ struct gss_cl_ctx {
struct
xdr_netobj
gc_wire_ctx
;
struct
xdr_netobj
gc_wire_ctx
;
u32
gc_win
;
u32
gc_win
;
unsigned
long
gc_expiry
;
unsigned
long
gc_expiry
;
struct
rcu_head
gc_rcu
;
};
};
struct
gss_upcall_msg
;
struct
gss_upcall_msg
;
...
...
net/sunrpc/auth_gss/auth_gss.c
View file @
5d28dc82
...
@@ -78,8 +78,6 @@ static const struct rpc_credops gss_credops;
...
@@ -78,8 +78,6 @@ static const struct rpc_credops gss_credops;
/* dump the buffer in `emacs-hexl' style */
/* dump the buffer in `emacs-hexl' style */
#define isprint(c) ((c > 0x1f) && (c < 0x7f))
#define isprint(c) ((c > 0x1f) && (c < 0x7f))
static
DEFINE_RWLOCK
(
gss_ctx_lock
);
struct
gss_auth
{
struct
gss_auth
{
struct
rpc_auth
rpc_auth
;
struct
rpc_auth
rpc_auth
;
struct
gss_api_mech
*
mech
;
struct
gss_api_mech
*
mech
;
...
@@ -88,7 +86,7 @@ struct gss_auth {
...
@@ -88,7 +86,7 @@ struct gss_auth {
struct
dentry
*
dentry
;
struct
dentry
*
dentry
;
};
};
static
void
gss_
destroy
_ctx
(
struct
gss_cl_ctx
*
);
static
void
gss_
free
_ctx
(
struct
gss_cl_ctx
*
);
static
struct
rpc_pipe_ops
gss_upcall_ops
;
static
struct
rpc_pipe_ops
gss_upcall_ops
;
static
inline
struct
gss_cl_ctx
*
static
inline
struct
gss_cl_ctx
*
...
@@ -102,20 +100,24 @@ static inline void
...
@@ -102,20 +100,24 @@ static inline void
gss_put_ctx
(
struct
gss_cl_ctx
*
ctx
)
gss_put_ctx
(
struct
gss_cl_ctx
*
ctx
)
{
{
if
(
atomic_dec_and_test
(
&
ctx
->
count
))
if
(
atomic_dec_and_test
(
&
ctx
->
count
))
gss_
destroy
_ctx
(
ctx
);
gss_
free
_ctx
(
ctx
);
}
}
/* gss_cred_set_ctx:
* called by gss_upcall_callback and gss_create_upcall in order
* to set the gss context. The actual exchange of an old context
* and a new one is protected by the inode->i_lock.
*/
static
void
static
void
gss_cred_set_ctx
(
struct
rpc_cred
*
cred
,
struct
gss_cl_ctx
*
ctx
)
gss_cred_set_ctx
(
struct
rpc_cred
*
cred
,
struct
gss_cl_ctx
*
ctx
)
{
{
struct
gss_cred
*
gss_cred
=
container_of
(
cred
,
struct
gss_cred
,
gc_base
);
struct
gss_cred
*
gss_cred
=
container_of
(
cred
,
struct
gss_cred
,
gc_base
);
struct
gss_cl_ctx
*
old
;
struct
gss_cl_ctx
*
old
;
write_lock
(
&
gss_ctx_lock
);
old
=
gss_cred
->
gc_ctx
;
old
=
gss_cred
->
gc_ctx
;
gss_cred
->
gc_ctx
=
ctx
;
rcu_assign_pointer
(
gss_cred
->
gc_ctx
,
ctx
)
;
set_bit
(
RPCAUTH_CRED_UPTODATE
,
&
cred
->
cr_flags
);
set_bit
(
RPCAUTH_CRED_UPTODATE
,
&
cred
->
cr_flags
);
clear_bit
(
RPCAUTH_CRED_NEW
,
&
cred
->
cr_flags
);
clear_bit
(
RPCAUTH_CRED_NEW
,
&
cred
->
cr_flags
);
write_unlock
(
&
gss_ctx_lock
);
if
(
old
)
if
(
old
)
gss_put_ctx
(
old
);
gss_put_ctx
(
old
);
}
}
...
@@ -126,10 +128,10 @@ gss_cred_is_uptodate_ctx(struct rpc_cred *cred)
...
@@ -126,10 +128,10 @@ gss_cred_is_uptodate_ctx(struct rpc_cred *cred)
struct
gss_cred
*
gss_cred
=
container_of
(
cred
,
struct
gss_cred
,
gc_base
);
struct
gss_cred
*
gss_cred
=
container_of
(
cred
,
struct
gss_cred
,
gc_base
);
int
res
=
0
;
int
res
=
0
;
r
ead_lock
(
&
gss_ctx_lock
);
r
cu_read_lock
(
);
if
(
test_bit
(
RPCAUTH_CRED_UPTODATE
,
&
cred
->
cr_flags
)
&&
gss_cred
->
gc_ctx
)
if
(
test_bit
(
RPCAUTH_CRED_UPTODATE
,
&
cred
->
cr_flags
)
&&
gss_cred
->
gc_ctx
)
res
=
1
;
res
=
1
;
r
ead_unlock
(
&
gss_ctx_lock
);
r
cu_read_unlock
(
);
return
res
;
return
res
;
}
}
...
@@ -168,10 +170,10 @@ gss_cred_get_ctx(struct rpc_cred *cred)
...
@@ -168,10 +170,10 @@ gss_cred_get_ctx(struct rpc_cred *cred)
struct
gss_cred
*
gss_cred
=
container_of
(
cred
,
struct
gss_cred
,
gc_base
);
struct
gss_cred
*
gss_cred
=
container_of
(
cred
,
struct
gss_cred
,
gc_base
);
struct
gss_cl_ctx
*
ctx
=
NULL
;
struct
gss_cl_ctx
*
ctx
=
NULL
;
r
ead_lock
(
&
gss_ctx_lock
);
r
cu_read_lock
(
);
if
(
gss_cred
->
gc_ctx
)
if
(
gss_cred
->
gc_ctx
)
ctx
=
gss_get_ctx
(
gss_cred
->
gc_ctx
);
ctx
=
gss_get_ctx
(
gss_cred
->
gc_ctx
);
r
ead_unlock
(
&
gss_ctx_lock
);
r
cu_read_unlock
(
);
return
ctx
;
return
ctx
;
}
}
...
@@ -333,11 +335,11 @@ gss_upcall_callback(struct rpc_task *task)
...
@@ -333,11 +335,11 @@ gss_upcall_callback(struct rpc_task *task)
struct
gss_upcall_msg
*
gss_msg
=
gss_cred
->
gc_upcall
;
struct
gss_upcall_msg
*
gss_msg
=
gss_cred
->
gc_upcall
;
struct
inode
*
inode
=
gss_msg
->
auth
->
dentry
->
d_inode
;
struct
inode
*
inode
=
gss_msg
->
auth
->
dentry
->
d_inode
;
spin_lock
(
&
inode
->
i_lock
);
if
(
gss_msg
->
ctx
)
if
(
gss_msg
->
ctx
)
gss_cred_set_ctx
(
task
->
tk_msg
.
rpc_cred
,
gss_get_ctx
(
gss_msg
->
ctx
));
gss_cred_set_ctx
(
task
->
tk_msg
.
rpc_cred
,
gss_get_ctx
(
gss_msg
->
ctx
));
else
else
task
->
tk_status
=
gss_msg
->
msg
.
errno
;
task
->
tk_status
=
gss_msg
->
msg
.
errno
;
spin_lock
(
&
inode
->
i_lock
);
gss_cred
->
gc_upcall
=
NULL
;
gss_cred
->
gc_upcall
=
NULL
;
rpc_wake_up_status
(
&
gss_msg
->
rpc_waitqueue
,
gss_msg
->
msg
.
errno
);
rpc_wake_up_status
(
&
gss_msg
->
rpc_waitqueue
,
gss_msg
->
msg
.
errno
);
spin_unlock
(
&
inode
->
i_lock
);
spin_unlock
(
&
inode
->
i_lock
);
...
@@ -440,7 +442,6 @@ gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
...
@@ -440,7 +442,6 @@ gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
prepare_to_wait
(
&
gss_msg
->
waitqueue
,
&
wait
,
TASK_INTERRUPTIBLE
);
prepare_to_wait
(
&
gss_msg
->
waitqueue
,
&
wait
,
TASK_INTERRUPTIBLE
);
spin_lock
(
&
inode
->
i_lock
);
spin_lock
(
&
inode
->
i_lock
);
if
(
gss_msg
->
ctx
!=
NULL
||
gss_msg
->
msg
.
errno
<
0
)
{
if
(
gss_msg
->
ctx
!=
NULL
||
gss_msg
->
msg
.
errno
<
0
)
{
spin_unlock
(
&
inode
->
i_lock
);
break
;
break
;
}
}
spin_unlock
(
&
inode
->
i_lock
);
spin_unlock
(
&
inode
->
i_lock
);
...
@@ -454,6 +455,7 @@ gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
...
@@ -454,6 +455,7 @@ gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
gss_cred_set_ctx
(
cred
,
gss_get_ctx
(
gss_msg
->
ctx
));
gss_cred_set_ctx
(
cred
,
gss_get_ctx
(
gss_msg
->
ctx
));
else
else
err
=
gss_msg
->
msg
.
errno
;
err
=
gss_msg
->
msg
.
errno
;
spin_unlock
(
&
inode
->
i_lock
);
out_intr:
out_intr:
finish_wait
(
&
gss_msg
->
waitqueue
,
&
wait
);
finish_wait
(
&
gss_msg
->
waitqueue
,
&
wait
);
gss_release_msg
(
gss_msg
);
gss_release_msg
(
gss_msg
);
...
@@ -681,9 +683,9 @@ gss_destroy(struct rpc_auth *auth)
...
@@ -681,9 +683,9 @@ gss_destroy(struct rpc_auth *auth)
* to create a new cred or context, so they check that things have been
* to create a new cred or context, so they check that things have been
* allocated before freeing them. */
* allocated before freeing them. */
static
void
static
void
gss_d
estroy
_ctx
(
struct
gss_cl_ctx
*
ctx
)
gss_d
o_free
_ctx
(
struct
gss_cl_ctx
*
ctx
)
{
{
dprintk
(
"RPC: gss_
destroy
_ctx
\n
"
);
dprintk
(
"RPC: gss_
free
_ctx
\n
"
);
if
(
ctx
->
gc_gss_ctx
)
if
(
ctx
->
gc_gss_ctx
)
gss_delete_sec_context
(
&
ctx
->
gc_gss_ctx
);
gss_delete_sec_context
(
&
ctx
->
gc_gss_ctx
);
...
@@ -692,12 +694,23 @@ gss_destroy_ctx(struct gss_cl_ctx *ctx)
...
@@ -692,12 +694,23 @@ gss_destroy_ctx(struct gss_cl_ctx *ctx)
kfree
(
ctx
);
kfree
(
ctx
);
}
}
static
void
gss_free_ctx_callback
(
struct
rcu_head
*
head
)
{
struct
gss_cl_ctx
*
ctx
=
container_of
(
head
,
struct
gss_cl_ctx
,
gc_rcu
);
gss_do_free_ctx
(
ctx
);
}
static
void
gss_free_ctx
(
struct
gss_cl_ctx
*
ctx
)
{
call_rcu
(
&
ctx
->
gc_rcu
,
gss_free_ctx_callback
);
}
static
void
static
void
gss_free_cred
(
struct
gss_cred
*
gss_cred
)
gss_free_cred
(
struct
gss_cred
*
gss_cred
)
{
{
dprintk
(
"RPC: gss_free_cred %p
\n
"
,
gss_cred
);
dprintk
(
"RPC: gss_free_cred %p
\n
"
,
gss_cred
);
if
(
gss_cred
->
gc_ctx
)
gss_put_ctx
(
gss_cred
->
gc_ctx
);
kfree
(
gss_cred
);
kfree
(
gss_cred
);
}
}
...
@@ -711,7 +724,13 @@ gss_free_cred_callback(struct rcu_head *head)
...
@@ -711,7 +724,13 @@ gss_free_cred_callback(struct rcu_head *head)
static
void
static
void
gss_destroy_cred
(
struct
rpc_cred
*
cred
)
gss_destroy_cred
(
struct
rpc_cred
*
cred
)
{
{
struct
gss_cred
*
gss_cred
=
container_of
(
cred
,
struct
gss_cred
,
gc_base
);
struct
gss_cl_ctx
*
ctx
=
gss_cred
->
gc_ctx
;
rcu_assign_pointer
(
gss_cred
->
gc_ctx
,
NULL
);
call_rcu
(
&
cred
->
cr_rcu
,
gss_free_cred_callback
);
call_rcu
(
&
cred
->
cr_rcu
,
gss_free_cred_callback
);
if
(
ctx
)
gss_put_ctx
(
ctx
);
}
}
/*
/*
...
...
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