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
09c7938c
Commit
09c7938c
authored
Mar 20, 2006
by
Trond Myklebust
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lockd: Fix server-side lock blocking code
Signed-off-by:
Trond Myklebust
<
Trond.Myklebust@netapp.com
>
parent
0996905f
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
40 additions
and
33 deletions
+40
-33
fs/lockd/svclock.c
fs/lockd/svclock.c
+40
-33
No files found.
fs/lockd/svclock.c
View file @
09c7938c
...
...
@@ -193,6 +193,7 @@ nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_file *file,
goto
failed_free
;
/* Set notifier function for VFS, and init args */
block
->
b_call
.
a_args
.
lock
.
fl
.
fl_flags
|=
FL_SLEEP
;
block
->
b_call
.
a_args
.
lock
.
fl
.
fl_lmops
=
&
nlmsvc_lock_operations
;
block
->
b_call
.
a_args
.
cookie
=
*
cookie
;
/* see above */
...
...
@@ -228,19 +229,18 @@ nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_file *file,
* can be closed hereafter.
*/
static
int
nlmsvc_delete_block
(
struct
nlm_block
*
block
,
int
unlock
)
nlmsvc_delete_block
(
struct
nlm_block
*
block
)
{
struct
file_lock
*
fl
=
&
block
->
b_call
.
a_args
.
lock
.
fl
;
struct
nlm_file
*
file
=
block
->
b_file
;
struct
nlm_block
**
bp
;
int
status
=
0
;
int
status
;
dprintk
(
"lockd: deleting block %p...
\n
"
,
block
);
/* Remove block from list */
nlmsvc_remove_block
(
block
);
if
(
unlock
)
status
=
posix_unblock_lock
(
file
->
f_file
,
fl
);
status
=
posix_unblock_lock
(
file
->
f_file
,
fl
);
/* If the block is in the middle of a GRANT callback,
* don't kill it yet. */
...
...
@@ -282,7 +282,7 @@ nlmsvc_traverse_blocks(struct nlm_host *host, struct nlm_file *file, int action)
block
->
b_host
->
h_inuse
=
1
;
else
if
(
action
==
NLM_ACT_UNLOCK
)
{
if
(
host
==
NULL
||
host
==
block
->
b_host
)
nlmsvc_delete_block
(
block
,
1
);
nlmsvc_delete_block
(
block
);
}
}
up
(
&
file
->
f_sema
);
...
...
@@ -297,7 +297,7 @@ u32
nlmsvc_lock
(
struct
svc_rqst
*
rqstp
,
struct
nlm_file
*
file
,
struct
nlm_lock
*
lock
,
int
wait
,
struct
nlm_cookie
*
cookie
)
{
struct
nlm_block
*
block
;
struct
nlm_block
*
block
,
*
newblock
=
NULL
;
int
error
;
u32
ret
;
...
...
@@ -310,59 +310,65 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
wait
);
/* Get existing block (in case client is busy-waiting) */
block
=
nlmsvc_lookup_block
(
file
,
lock
,
0
);
lock
->
fl
.
fl_flags
&=
~
FL_SLEEP
;
again:
/* Lock file against concurrent access */
down
(
&
file
->
f_sema
);
/* Get existing block (in case client is busy-waiting) */
block
=
nlmsvc_lookup_block
(
file
,
lock
,
0
);
if
(
block
==
NULL
)
{
if
(
newblock
!=
NULL
)
lock
=
&
newblock
->
b_call
.
a_args
.
lock
.
fl
;
}
else
lock
=
&
block
->
b_call
.
a_args
.
lock
.
fl
;
error
=
posix_lock_file
(
file
->
f_file
,
&
lock
->
fl
);
lock
->
fl
.
fl_flags
&=
~
FL_SLEEP
;
dprintk
(
"lockd: posix_lock_file returned %d
\n
"
,
error
);
if
(
error
!=
-
EAGAIN
)
{
if
(
block
)
nlmsvc_delete_block
(
block
,
0
);
up
(
&
file
->
f_sema
);
switch
(
-
error
)
{
switch
(
error
)
{
case
0
:
ret
=
nlm_granted
;
goto
out
;
case
EDEADLK
:
case
-
EAGAIN
:
break
;
case
-
EDEADLK
:
ret
=
nlm_deadlock
;
goto
out
;
default:
/* includes ENOLCK */
ret
=
nlm_lck_denied_nolocks
;
goto
out
;
}
}
if
(
!
wait
)
{
ret
=
nlm_lck_denied
;
goto
out_unlock
;
}
ret
=
nlm_lck_denied
;
if
(
!
wait
)
goto
out
;
ret
=
nlm_lck_blocked
;
if
(
block
!=
NULL
)
goto
out
;
/* If we don't have a block, create and initialize it. Then
* retry because we may have slept in kmalloc. */
/* We have to release f_sema as nlmsvc_create_block may try to
* to claim it while doing host garbage collection */
if
(
block
==
NULL
)
{
if
(
new
block
==
NULL
)
{
up
(
&
file
->
f_sema
);
dprintk
(
"lockd: blocking on this lock (allocating).
\n
"
);
if
(
!
(
block
=
nlmsvc_create_block
(
rqstp
,
file
,
lock
,
cookie
)))
if
(
!
(
new
block
=
nlmsvc_create_block
(
rqstp
,
file
,
lock
,
cookie
)))
return
nlm_lck_denied_nolocks
;
goto
again
;
}
/* Append to list of blocked */
nlmsvc_insert_block
(
block
,
NLM_NEVER
);
nlmsvc_insert_block
(
newblock
,
NLM_NEVER
);
newblock
=
NULL
;
ret
=
nlm_lck_blocked
;
out_unlock:
up
(
&
file
->
f_sema
);
out:
up
(
&
file
->
f_sema
);
if
(
newblock
!=
NULL
)
nlmsvc_delete_block
(
newblock
);
dprintk
(
"lockd: nlmsvc_lock returned %u
\n
"
,
ret
);
return
ret
;
}
...
...
@@ -445,7 +451,7 @@ nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock)
down
(
&
file
->
f_sema
);
if
((
block
=
nlmsvc_lookup_block
(
file
,
lock
,
1
))
!=
NULL
)
status
=
nlmsvc_delete_block
(
block
,
1
);
status
=
nlmsvc_delete_block
(
block
);
up
(
&
file
->
f_sema
);
return
status
?
nlm_lck_denied
:
nlm_granted
;
}
...
...
@@ -519,7 +525,11 @@ nlmsvc_grant_blocked(struct nlm_block *block)
}
/* Try the lock operation again */
posix_unblock_lock
(
file
->
f_file
,
&
lock
->
fl
);
lock
->
fl
.
fl_flags
|=
FL_SLEEP
;
error
=
posix_lock_file
(
file
->
f_file
,
&
lock
->
fl
);
lock
->
fl
.
fl_flags
&=
~
FL_SLEEP
;
switch
(
error
)
{
case
0
:
break
;
...
...
@@ -630,11 +640,8 @@ nlmsvc_grant_reply(struct svc_rqst *rqstp, struct nlm_cookie *cookie, u32 status
}
else
{
/* Lock is now held by client, or has been rejected.
* In both cases, the block should be removed. */
nlmsvc_delete_block
(
block
);
up
(
&
file
->
f_sema
);
if
(
status
==
NLM_LCK_GRANTED
)
nlmsvc_delete_block
(
block
,
0
);
else
nlmsvc_delete_block
(
block
,
1
);
}
}
nlm_release_file
(
file
);
...
...
@@ -661,7 +668,7 @@ nlmsvc_retry_blocked(void)
dprintk
(
"nlmsvc_retry_blocked(%p, when=%ld, done=%d)
\n
"
,
block
,
block
->
b_when
,
block
->
b_done
);
if
(
block
->
b_done
)
nlmsvc_delete_block
(
block
,
0
);
nlmsvc_delete_block
(
block
);
else
nlmsvc_grant_blocked
(
block
);
}
...
...
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