diff options
Diffstat (limited to 'fs/lockd')
-rw-r--r-- | fs/lockd/clntlock.c | 13 | ||||
-rw-r--r-- | fs/lockd/clntproc.c | 5 | ||||
-rw-r--r-- | fs/lockd/svc.c | 2 | ||||
-rw-r--r-- | fs/lockd/svclock.c | 18 | ||||
-rw-r--r-- | fs/lockd/svcsubs.c | 12 |
5 files changed, 36 insertions, 14 deletions
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index 01bfe7662751..41e491b8e5d7 100644 --- a/fs/lockd/clntlock.c +++ b/fs/lockd/clntlock.c | |||
@@ -64,12 +64,17 @@ struct nlm_host *nlmclnt_init(const struct nlmclnt_initdata *nlm_init) | |||
64 | nlm_init->protocol, nlm_version, | 64 | nlm_init->protocol, nlm_version, |
65 | nlm_init->hostname, nlm_init->noresvport, | 65 | nlm_init->hostname, nlm_init->noresvport, |
66 | nlm_init->net); | 66 | nlm_init->net); |
67 | if (host == NULL) { | 67 | if (host == NULL) |
68 | lockd_down(nlm_init->net); | 68 | goto out_nohost; |
69 | return ERR_PTR(-ENOLCK); | 69 | if (host->h_rpcclnt == NULL && nlm_bind_host(host) == NULL) |
70 | } | 70 | goto out_nobind; |
71 | 71 | ||
72 | return host; | 72 | return host; |
73 | out_nobind: | ||
74 | nlmclnt_release_host(host); | ||
75 | out_nohost: | ||
76 | lockd_down(nlm_init->net); | ||
77 | return ERR_PTR(-ENOLCK); | ||
73 | } | 78 | } |
74 | EXPORT_SYMBOL_GPL(nlmclnt_init); | 79 | EXPORT_SYMBOL_GPL(nlmclnt_init); |
75 | 80 | ||
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index 9760ecb9b60f..acd394716349 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c | |||
@@ -125,14 +125,15 @@ static void nlmclnt_setlockargs(struct nlm_rqst *req, struct file_lock *fl) | |||
125 | { | 125 | { |
126 | struct nlm_args *argp = &req->a_args; | 126 | struct nlm_args *argp = &req->a_args; |
127 | struct nlm_lock *lock = &argp->lock; | 127 | struct nlm_lock *lock = &argp->lock; |
128 | char *nodename = req->a_host->h_rpcclnt->cl_nodename; | ||
128 | 129 | ||
129 | nlmclnt_next_cookie(&argp->cookie); | 130 | nlmclnt_next_cookie(&argp->cookie); |
130 | memcpy(&lock->fh, NFS_FH(file_inode(fl->fl_file)), sizeof(struct nfs_fh)); | 131 | memcpy(&lock->fh, NFS_FH(file_inode(fl->fl_file)), sizeof(struct nfs_fh)); |
131 | lock->caller = utsname()->nodename; | 132 | lock->caller = nodename; |
132 | lock->oh.data = req->a_owner; | 133 | lock->oh.data = req->a_owner; |
133 | lock->oh.len = snprintf(req->a_owner, sizeof(req->a_owner), "%u@%s", | 134 | lock->oh.len = snprintf(req->a_owner, sizeof(req->a_owner), "%u@%s", |
134 | (unsigned int)fl->fl_u.nfs_fl.owner->pid, | 135 | (unsigned int)fl->fl_u.nfs_fl.owner->pid, |
135 | utsname()->nodename); | 136 | nodename); |
136 | lock->svid = fl->fl_u.nfs_fl.owner->pid; | 137 | lock->svid = fl->fl_u.nfs_fl.owner->pid; |
137 | lock->fl.fl_start = fl->fl_start; | 138 | lock->fl.fl_start = fl->fl_start; |
138 | lock->fl.fl_end = fl->fl_end; | 139 | lock->fl.fl_end = fl->fl_end; |
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index a2aa97d45670..10d6c41aecad 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c | |||
@@ -305,7 +305,7 @@ static int lockd_start_svc(struct svc_serv *serv) | |||
305 | svc_sock_update_bufs(serv); | 305 | svc_sock_update_bufs(serv); |
306 | serv->sv_maxconn = nlm_max_connections; | 306 | serv->sv_maxconn = nlm_max_connections; |
307 | 307 | ||
308 | nlmsvc_task = kthread_run(lockd, nlmsvc_rqst, serv->sv_name); | 308 | nlmsvc_task = kthread_run(lockd, nlmsvc_rqst, "%s", serv->sv_name); |
309 | if (IS_ERR(nlmsvc_task)) { | 309 | if (IS_ERR(nlmsvc_task)) { |
310 | error = PTR_ERR(nlmsvc_task); | 310 | error = PTR_ERR(nlmsvc_task); |
311 | printk(KERN_WARNING | 311 | printk(KERN_WARNING |
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index e703318c41df..e066a3902973 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c | |||
@@ -276,7 +276,7 @@ static int nlmsvc_unlink_block(struct nlm_block *block) | |||
276 | dprintk("lockd: unlinking block %p...\n", block); | 276 | dprintk("lockd: unlinking block %p...\n", block); |
277 | 277 | ||
278 | /* Remove block from list */ | 278 | /* Remove block from list */ |
279 | status = posix_unblock_lock(block->b_file->f_file, &block->b_call->a_args.lock.fl); | 279 | status = posix_unblock_lock(&block->b_call->a_args.lock.fl); |
280 | nlmsvc_remove_block(block); | 280 | nlmsvc_remove_block(block); |
281 | return status; | 281 | return status; |
282 | } | 282 | } |
@@ -744,8 +744,20 @@ static int nlmsvc_same_owner(struct file_lock *fl1, struct file_lock *fl2) | |||
744 | return fl1->fl_owner == fl2->fl_owner && fl1->fl_pid == fl2->fl_pid; | 744 | return fl1->fl_owner == fl2->fl_owner && fl1->fl_pid == fl2->fl_pid; |
745 | } | 745 | } |
746 | 746 | ||
747 | /* | ||
748 | * Since NLM uses two "keys" for tracking locks, we need to hash them down | ||
749 | * to one for the blocked_hash. Here, we're just xor'ing the host address | ||
750 | * with the pid in order to create a key value for picking a hash bucket. | ||
751 | */ | ||
752 | static unsigned long | ||
753 | nlmsvc_owner_key(struct file_lock *fl) | ||
754 | { | ||
755 | return (unsigned long)fl->fl_owner ^ (unsigned long)fl->fl_pid; | ||
756 | } | ||
757 | |||
747 | const struct lock_manager_operations nlmsvc_lock_operations = { | 758 | const struct lock_manager_operations nlmsvc_lock_operations = { |
748 | .lm_compare_owner = nlmsvc_same_owner, | 759 | .lm_compare_owner = nlmsvc_same_owner, |
760 | .lm_owner_key = nlmsvc_owner_key, | ||
749 | .lm_notify = nlmsvc_notify_blocked, | 761 | .lm_notify = nlmsvc_notify_blocked, |
750 | .lm_grant = nlmsvc_grant_deferred, | 762 | .lm_grant = nlmsvc_grant_deferred, |
751 | }; | 763 | }; |
@@ -939,6 +951,7 @@ nlmsvc_retry_blocked(void) | |||
939 | unsigned long timeout = MAX_SCHEDULE_TIMEOUT; | 951 | unsigned long timeout = MAX_SCHEDULE_TIMEOUT; |
940 | struct nlm_block *block; | 952 | struct nlm_block *block; |
941 | 953 | ||
954 | spin_lock(&nlm_blocked_lock); | ||
942 | while (!list_empty(&nlm_blocked) && !kthread_should_stop()) { | 955 | while (!list_empty(&nlm_blocked) && !kthread_should_stop()) { |
943 | block = list_entry(nlm_blocked.next, struct nlm_block, b_list); | 956 | block = list_entry(nlm_blocked.next, struct nlm_block, b_list); |
944 | 957 | ||
@@ -948,6 +961,7 @@ nlmsvc_retry_blocked(void) | |||
948 | timeout = block->b_when - jiffies; | 961 | timeout = block->b_when - jiffies; |
949 | break; | 962 | break; |
950 | } | 963 | } |
964 | spin_unlock(&nlm_blocked_lock); | ||
951 | 965 | ||
952 | dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n", | 966 | dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n", |
953 | block, block->b_when); | 967 | block, block->b_when); |
@@ -957,7 +971,9 @@ nlmsvc_retry_blocked(void) | |||
957 | retry_deferred_block(block); | 971 | retry_deferred_block(block); |
958 | } else | 972 | } else |
959 | nlmsvc_grant_blocked(block); | 973 | nlmsvc_grant_blocked(block); |
974 | spin_lock(&nlm_blocked_lock); | ||
960 | } | 975 | } |
976 | spin_unlock(&nlm_blocked_lock); | ||
961 | 977 | ||
962 | return timeout; | 978 | return timeout; |
963 | } | 979 | } |
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c index 97e87415b145..dc5c75930f0f 100644 --- a/fs/lockd/svcsubs.c +++ b/fs/lockd/svcsubs.c | |||
@@ -169,7 +169,7 @@ nlm_traverse_locks(struct nlm_host *host, struct nlm_file *file, | |||
169 | 169 | ||
170 | again: | 170 | again: |
171 | file->f_locks = 0; | 171 | file->f_locks = 0; |
172 | lock_flocks(); /* protects i_flock list */ | 172 | spin_lock(&inode->i_lock); |
173 | for (fl = inode->i_flock; fl; fl = fl->fl_next) { | 173 | for (fl = inode->i_flock; fl; fl = fl->fl_next) { |
174 | if (fl->fl_lmops != &nlmsvc_lock_operations) | 174 | if (fl->fl_lmops != &nlmsvc_lock_operations) |
175 | continue; | 175 | continue; |
@@ -181,7 +181,7 @@ again: | |||
181 | if (match(lockhost, host)) { | 181 | if (match(lockhost, host)) { |
182 | struct file_lock lock = *fl; | 182 | struct file_lock lock = *fl; |
183 | 183 | ||
184 | unlock_flocks(); | 184 | spin_unlock(&inode->i_lock); |
185 | lock.fl_type = F_UNLCK; | 185 | lock.fl_type = F_UNLCK; |
186 | lock.fl_start = 0; | 186 | lock.fl_start = 0; |
187 | lock.fl_end = OFFSET_MAX; | 187 | lock.fl_end = OFFSET_MAX; |
@@ -193,7 +193,7 @@ again: | |||
193 | goto again; | 193 | goto again; |
194 | } | 194 | } |
195 | } | 195 | } |
196 | unlock_flocks(); | 196 | spin_unlock(&inode->i_lock); |
197 | 197 | ||
198 | return 0; | 198 | return 0; |
199 | } | 199 | } |
@@ -228,14 +228,14 @@ nlm_file_inuse(struct nlm_file *file) | |||
228 | if (file->f_count || !list_empty(&file->f_blocks) || file->f_shares) | 228 | if (file->f_count || !list_empty(&file->f_blocks) || file->f_shares) |
229 | return 1; | 229 | return 1; |
230 | 230 | ||
231 | lock_flocks(); | 231 | spin_lock(&inode->i_lock); |
232 | for (fl = inode->i_flock; fl; fl = fl->fl_next) { | 232 | for (fl = inode->i_flock; fl; fl = fl->fl_next) { |
233 | if (fl->fl_lmops == &nlmsvc_lock_operations) { | 233 | if (fl->fl_lmops == &nlmsvc_lock_operations) { |
234 | unlock_flocks(); | 234 | spin_unlock(&inode->i_lock); |
235 | return 1; | 235 | return 1; |
236 | } | 236 | } |
237 | } | 237 | } |
238 | unlock_flocks(); | 238 | spin_unlock(&inode->i_lock); |
239 | file->f_locks = 0; | 239 | file->f_locks = 0; |
240 | return 0; | 240 | return 0; |
241 | } | 241 | } |