summaryrefslogtreecommitdiff
path: root/include/linux/lockd
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-02-15 00:53:04 +0300
committerLinus Torvalds <torvalds@g5.osdl.org>2006-02-15 03:09:34 +0300
commit5ac5f9d1ce8492163dbde5d357dc5d03becf7e36 (patch)
tree3ce7f36c074e37dd565b91490582c4a4902f2b18 /include/linux/lockd
parent7c8903f6373f9abecf060bad53ca36bc4ac037f2 (diff)
downloadlinux-5ac5f9d1ce8492163dbde5d357dc5d03becf7e36.tar.xz
[PATCH] NLM: Fix the NLM_GRANTED callback checks
If 2 threads attached to the same process are blocking on different locks on different files (maybe even on different servers) but have the same lock arguments (i.e. same offset+length - actually quite common, since most processes try to lock the entire file) then the first GRANTED call that wakes one up will also wake the other. Currently when the NLM_GRANTED callback comes in, lockd walks the list of blocked locks in search of a match to the lock that the NLM server has granted. Although it checks the lock pid, start and end, it fails to check the filehandle and the server address. By checking the filehandle and server IP address, we ensure that this only happens if the locks truly are referencing the same file. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/linux/lockd')
-rw-r--r--include/linux/lockd/lockd.h6
1 files changed, 3 insertions, 3 deletions
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index 920766cea79c..ef21ed296039 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -149,7 +149,7 @@ struct nlm_rqst * nlmclnt_alloc_call(void);
int nlmclnt_prepare_block(struct nlm_rqst *req, struct nlm_host *host, struct file_lock *fl);
void nlmclnt_finish_block(struct nlm_rqst *req);
long nlmclnt_block(struct nlm_rqst *req, long timeout);
-u32 nlmclnt_grant(struct nlm_lock *);
+u32 nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *);
void nlmclnt_recovery(struct nlm_host *, u32);
int nlmclnt_reclaim(struct nlm_host *, struct file_lock *);
int nlmclnt_setgrantargs(struct nlm_rqst *, struct nlm_lock *);
@@ -204,7 +204,7 @@ nlmsvc_file_inode(struct nlm_file *file)
* Compare two host addresses (needs modifying for ipv6)
*/
static __inline__ int
-nlm_cmp_addr(struct sockaddr_in *sin1, struct sockaddr_in *sin2)
+nlm_cmp_addr(const struct sockaddr_in *sin1, const struct sockaddr_in *sin2)
{
return sin1->sin_addr.s_addr == sin2->sin_addr.s_addr;
}
@@ -214,7 +214,7 @@ nlm_cmp_addr(struct sockaddr_in *sin1, struct sockaddr_in *sin2)
* When the second lock is of type F_UNLCK, this acts like a wildcard.
*/
static __inline__ int
-nlm_compare_locks(struct file_lock *fl1, struct file_lock *fl2)
+nlm_compare_locks(const struct file_lock *fl1, const struct file_lock *fl2)
{
return fl1->fl_pid == fl2->fl_pid
&& fl1->fl_start == fl2->fl_start