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
72dbac37
Commit
72dbac37
authored
Jul 05, 2006
by
Trond Myklebust
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'locks'
parents
4e0641a7
01c3b861
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
80 additions
and
44 deletions
+80
-44
fs/lockd/clntproc.c
fs/lockd/clntproc.c
+17
-9
fs/locks.c
fs/locks.c
+21
-2
fs/nfs/nfs4proc.c
fs/nfs/nfs4proc.c
+41
-33
include/linux/fs.h
include/linux/fs.h
+1
-0
No files found.
fs/lockd/clntproc.c
View file @
72dbac37
...
...
@@ -454,7 +454,7 @@ static void nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *ho
fl
->
fl_ops
=
&
nlmclnt_lock_ops
;
}
static
void
do_vfs_lock
(
struct
file_lock
*
fl
)
static
int
do_vfs_lock
(
struct
file_lock
*
fl
)
{
int
res
=
0
;
switch
(
fl
->
fl_flags
&
(
FL_POSIX
|
FL_FLOCK
))
{
...
...
@@ -467,9 +467,7 @@ static void do_vfs_lock(struct file_lock *fl)
default:
BUG
();
}
if
(
res
<
0
)
printk
(
KERN_WARNING
"%s: VFS is out of sync with lock manager!
\n
"
,
__FUNCTION__
);
return
res
;
}
/*
...
...
@@ -498,6 +496,7 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
struct
nlm_host
*
host
=
req
->
a_host
;
struct
nlm_res
*
resp
=
&
req
->
a_res
;
struct
nlm_wait
*
block
=
NULL
;
unsigned
char
fl_flags
=
fl
->
fl_flags
;
int
status
=
-
ENOLCK
;
if
(
!
host
->
h_monitored
&&
nsm_monitor
(
host
)
<
0
)
{
...
...
@@ -505,6 +504,10 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
host
->
h_name
);
goto
out
;
}
fl
->
fl_flags
|=
FL_ACCESS
;
status
=
do_vfs_lock
(
fl
);
if
(
status
<
0
)
goto
out
;
block
=
nlmclnt_prepare_block
(
host
,
fl
);
again:
...
...
@@ -539,9 +542,10 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
up_read
(
&
host
->
h_rwsem
);
goto
again
;
}
fl
->
fl_flags
|=
FL_SLEEP
;
/* Ensure the resulting lock will get added to granted list */
do_vfs_lock
(
fl
);
fl
->
fl_flags
=
fl_flags
|
FL_SLEEP
;
if
(
do_vfs_lock
(
fl
)
<
0
)
printk
(
KERN_WARNING
"%s: VFS is out of sync with lock manager!
\n
"
,
__FUNCTION__
);
up_read
(
&
host
->
h_rwsem
);
}
status
=
nlm_stat_to_errno
(
resp
->
status
);
...
...
@@ -552,6 +556,7 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
nlmclnt_cancel
(
host
,
req
->
a_args
.
block
,
fl
);
out:
nlm_release_call
(
req
);
fl
->
fl_flags
=
fl_flags
;
return
status
;
}
...
...
@@ -606,15 +611,19 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl)
{
struct
nlm_host
*
host
=
req
->
a_host
;
struct
nlm_res
*
resp
=
&
req
->
a_res
;
int
status
;
int
status
=
0
;
/*
* Note: the server is supposed to either grant us the unlock
* request, or to deny it with NLM_LCK_DENIED_GRACE_PERIOD. In either
* case, we want to unlock.
*/
fl
->
fl_flags
|=
FL_EXISTS
;
down_read
(
&
host
->
h_rwsem
);
do_vfs_lock
(
fl
);
if
(
do_vfs_lock
(
fl
)
==
-
ENOENT
)
{
up_read
(
&
host
->
h_rwsem
);
goto
out
;
}
up_read
(
&
host
->
h_rwsem
);
if
(
req
->
a_flags
&
RPC_TASK_ASYNC
)
...
...
@@ -624,7 +633,6 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl)
if
(
status
<
0
)
goto
out
;
status
=
0
;
if
(
resp
->
status
==
NLM_LCK_GRANTED
)
goto
out
;
...
...
fs/locks.c
View file @
72dbac37
...
...
@@ -725,6 +725,10 @@ static int posix_locks_deadlock(struct file_lock *caller_fl,
/* Try to create a FLOCK lock on filp. We always insert new FLOCK locks
* at the head of the list, but that's secret knowledge known only to
* flock_lock_file and posix_lock_file.
*
* Note that if called with an FL_EXISTS argument, the caller may determine
* whether or not a lock was successfully freed by testing the return
* value for -ENOENT.
*/
static
int
flock_lock_file
(
struct
file
*
filp
,
struct
file_lock
*
request
)
{
...
...
@@ -735,6 +739,8 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
int
found
=
0
;
lock_kernel
();
if
(
request
->
fl_flags
&
FL_ACCESS
)
goto
find_conflict
;
for_each_lock
(
inode
,
before
)
{
struct
file_lock
*
fl
=
*
before
;
if
(
IS_POSIX
(
fl
))
...
...
@@ -750,8 +756,11 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
break
;
}
if
(
request
->
fl_type
==
F_UNLCK
)
if
(
request
->
fl_type
==
F_UNLCK
)
{
if
((
request
->
fl_flags
&
FL_EXISTS
)
&&
!
found
)
error
=
-
ENOENT
;
goto
out
;
}
error
=
-
ENOMEM
;
new_fl
=
locks_alloc_lock
();
...
...
@@ -764,6 +773,7 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
if
(
found
)
cond_resched
();
find_conflict:
for_each_lock
(
inode
,
before
)
{
struct
file_lock
*
fl
=
*
before
;
if
(
IS_POSIX
(
fl
))
...
...
@@ -777,6 +787,8 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
locks_insert_block
(
fl
,
request
);
goto
out
;
}
if
(
request
->
fl_flags
&
FL_ACCESS
)
goto
out
;
locks_copy_lock
(
new_fl
,
request
);
locks_insert_lock
(
&
inode
->
i_flock
,
new_fl
);
new_fl
=
NULL
;
...
...
@@ -948,8 +960,11 @@ static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request
error
=
0
;
if
(
!
added
)
{
if
(
request
->
fl_type
==
F_UNLCK
)
if
(
request
->
fl_type
==
F_UNLCK
)
{
if
(
request
->
fl_flags
&
FL_EXISTS
)
error
=
-
ENOENT
;
goto
out
;
}
if
(
!
new_fl
)
{
error
=
-
ENOLCK
;
...
...
@@ -996,6 +1011,10 @@ static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request
* Add a POSIX style lock to a file.
* We merge adjacent & overlapping locks whenever possible.
* POSIX locks are sorted by owner task, then by starting address
*
* Note that if called with an FL_EXISTS argument, the caller may determine
* whether or not a lock was successfully freed by testing the return
* value for -ENOENT.
*/
int
posix_lock_file
(
struct
file
*
filp
,
struct
file_lock
*
fl
)
{
...
...
fs/nfs/nfs4proc.c
View file @
72dbac37
...
...
@@ -3144,9 +3144,6 @@ static int do_vfs_lock(struct file *file, struct file_lock *fl)
default:
BUG
();
}
if
(
res
<
0
)
printk
(
KERN_WARNING
"%s: VFS is out of sync with lock manager!
\n
"
,
__FUNCTION__
);
return
res
;
}
...
...
@@ -3258,8 +3255,6 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl,
return
ERR_PTR
(
-
ENOMEM
);
}
/* Unlock _before_ we do the RPC call */
do_vfs_lock
(
fl
->
fl_file
,
fl
);
return
rpc_run_task
(
NFS_CLIENT
(
lsp
->
ls_state
->
inode
),
RPC_TASK_ASYNC
,
&
nfs4_locku_ops
,
data
);
}
...
...
@@ -3270,30 +3265,28 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *
struct
rpc_task
*
task
;
int
status
=
0
;
/* Is this a delegated lock? */
if
(
test_bit
(
NFS_DELEGATED_STATE
,
&
state
->
flags
))
goto
out_unlock
;
/* Is this open_owner holding any locks on the server? */
if
(
test_bit
(
LK_STATE_IN_USE
,
&
state
->
flags
)
==
0
)
goto
out_unlock
;
status
=
nfs4_set_lock_state
(
state
,
request
);
/* Unlock _before_ we do the RPC call */
request
->
fl_flags
|=
FL_EXISTS
;
if
(
do_vfs_lock
(
request
->
fl_file
,
request
)
==
-
ENOENT
)
goto
out
;
if
(
status
!=
0
)
goto
out_unlock
;
goto
out
;
/* Is this a delegated lock? */
if
(
test_bit
(
NFS_DELEGATED_STATE
,
&
state
->
flags
))
goto
out
;
lsp
=
request
->
fl_u
.
nfs4_fl
.
owner
;
status
=
-
ENOMEM
;
seqid
=
nfs_alloc_seqid
(
&
lsp
->
ls_seqid
);
status
=
-
ENOMEM
;
if
(
seqid
==
NULL
)
goto
out
_unlock
;
goto
out
;
task
=
nfs4_do_unlck
(
request
,
request
->
fl_file
->
private_data
,
lsp
,
seqid
);
status
=
PTR_ERR
(
task
);
if
(
IS_ERR
(
task
))
goto
out
_unlock
;
goto
out
;
status
=
nfs4_wait_for_completion_rpc_task
(
task
);
rpc_release_task
(
task
);
return
status
;
out_unlock:
do_vfs_lock
(
request
->
fl_file
,
request
);
out:
return
status
;
}
...
...
@@ -3461,10 +3454,10 @@ static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request
struct
nfs4_exception
exception
=
{
};
int
err
;
/* Cache the lock if possible... */
if
(
test_bit
(
NFS_DELEGATED_STATE
,
&
state
->
flags
))
return
0
;
do
{
/* Cache the lock if possible... */
if
(
test_bit
(
NFS_DELEGATED_STATE
,
&
state
->
flags
)
!=
0
)
return
0
;
err
=
_nfs4_do_setlk
(
state
,
F_SETLK
,
request
,
1
);
if
(
err
!=
-
NFS4ERR_DELAY
)
break
;
...
...
@@ -3483,6 +3476,8 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request
if
(
err
!=
0
)
return
err
;
do
{
if
(
test_bit
(
NFS_DELEGATED_STATE
,
&
state
->
flags
)
!=
0
)
return
0
;
err
=
_nfs4_do_setlk
(
state
,
F_SETLK
,
request
,
0
);
if
(
err
!=
-
NFS4ERR_DELAY
)
break
;
...
...
@@ -3494,29 +3489,42 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request
static
int
_nfs4_proc_setlk
(
struct
nfs4_state
*
state
,
int
cmd
,
struct
file_lock
*
request
)
{
struct
nfs4_client
*
clp
=
state
->
owner
->
so_client
;
unsigned
char
fl_flags
=
request
->
fl_flags
;
int
status
;
/* Is this a delegated open? */
if
(
NFS_I
(
state
->
inode
)
->
delegation_state
!=
0
)
{
/* Yes: cache locks! */
status
=
do_vfs_lock
(
request
->
fl_file
,
request
);
/* ...but avoid races with delegation recall... */
if
(
status
<
0
||
test_bit
(
NFS_DELEGATED_STATE
,
&
state
->
flags
))
return
status
;
}
down_read
(
&
clp
->
cl_sem
);
status
=
nfs4_set_lock_state
(
state
,
request
);
if
(
status
!=
0
)
goto
out
;
request
->
fl_flags
|=
FL_ACCESS
;
status
=
do_vfs_lock
(
request
->
fl_file
,
request
);
if
(
status
<
0
)
goto
out
;
down_read
(
&
clp
->
cl_sem
);
if
(
test_bit
(
NFS_DELEGATED_STATE
,
&
state
->
flags
))
{
struct
nfs_inode
*
nfsi
=
NFS_I
(
state
->
inode
);
/* Yes: cache locks! */
down_read
(
&
nfsi
->
rwsem
);
/* ...but avoid races with delegation recall... */
if
(
test_bit
(
NFS_DELEGATED_STATE
,
&
state
->
flags
))
{
request
->
fl_flags
=
fl_flags
&
~
FL_SLEEP
;
status
=
do_vfs_lock
(
request
->
fl_file
,
request
);
up_read
(
&
nfsi
->
rwsem
);
goto
out_unlock
;
}
up_read
(
&
nfsi
->
rwsem
);
}
status
=
_nfs4_do_setlk
(
state
,
cmd
,
request
,
0
);
if
(
status
!=
0
)
goto
out
;
goto
out
_unlock
;
/* Note: we always want to sleep here! */
request
->
fl_flags
|=
FL_SLEEP
;
request
->
fl_flags
=
fl_flags
|
FL_SLEEP
;
if
(
do_vfs_lock
(
request
->
fl_file
,
request
)
<
0
)
printk
(
KERN_WARNING
"%s: VFS is out of sync with lock manager!
\n
"
,
__FUNCTION__
);
out:
out
_unlock
:
up_read
(
&
clp
->
cl_sem
);
out:
request
->
fl_flags
=
fl_flags
;
return
status
;
}
...
...
include/linux/fs.h
View file @
72dbac37
...
...
@@ -716,6 +716,7 @@ extern spinlock_t files_lock;
#define FL_POSIX 1
#define FL_FLOCK 2
#define FL_ACCESS 8
/* not trying to lock, just looking */
#define FL_EXISTS 16
/* when unlocking, test for existence */
#define FL_LEASE 32
/* lease held on this file */
#define FL_CLOSE 64
/* unlock on close */
#define FL_SLEEP 128
/* A blocking lock */
...
...
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