aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-01-30 17:29:31 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-01-30 17:29:31 -0500
commitf389e9fcecdec4c4cb890ad28ea30a87a579ec3e (patch)
treea26a94886ca384da320bb972fed56fcaf7722512 /fs
parent2419505acc479d2f1feed94d195b0554a64269a4 (diff)
parent0fe410d3f3b1496190f37ef74cd089229cef97fa (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/dlm
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/dlm: (21 commits) dlm: static initialization improvements dlm: clean ups dlm: Sanity check namelen before copying it dlm: keep cached master rsbs during recovery dlm: change error message to debug dlm: fix possible use-after-free dlm: limit dir lookup loop dlm: reject normal unlock when lock is waiting for lookup dlm: validate messages before processing dlm: reject messages from non-members dlm: another call to confirm_master in receive_request_reply dlm: recover locks waiting for overlap replies dlm: clear ast_type when removing from astqueue dlm: use fixed errno values in messages dlm: swap bytes for rcom lock reply dlm: align midcomms message buffer dlm: close othercons dlm: use dlm prefix on alloc and free functions dlm: don't print common non-errors dlm: proper prototypes ...
Diffstat (limited to 'fs')
-rw-r--r--fs/dlm/dir.c76
-rw-r--r--fs/dlm/dlm_internal.h16
-rw-r--r--fs/dlm/lock.c249
-rw-r--r--fs/dlm/lock.h2
-rw-r--r--fs/dlm/lockspace.c16
-rw-r--r--fs/dlm/lowcomms.c15
-rw-r--r--fs/dlm/main.c10
-rw-r--r--fs/dlm/member.c4
-rw-r--r--fs/dlm/member.h3
-rw-r--r--fs/dlm/memory.c32
-rw-r--r--fs/dlm/memory.h16
-rw-r--r--fs/dlm/midcomms.c15
-rw-r--r--fs/dlm/rcom.c25
-rw-r--r--fs/dlm/recover.c27
-rw-r--r--fs/dlm/recoverd.c11
-rw-r--r--fs/dlm/user.c29
-rw-r--r--fs/dlm/util.c82
17 files changed, 395 insertions, 233 deletions
diff --git a/fs/dlm/dir.c b/fs/dlm/dir.c
index 46754553fdcc..ff97ba924333 100644
--- a/fs/dlm/dir.c
+++ b/fs/dlm/dir.c
@@ -49,7 +49,7 @@ static struct dlm_direntry *get_free_de(struct dlm_ls *ls, int len)
49 spin_unlock(&ls->ls_recover_list_lock); 49 spin_unlock(&ls->ls_recover_list_lock);
50 50
51 if (!found) 51 if (!found)
52 de = allocate_direntry(ls, len); 52 de = kzalloc(sizeof(struct dlm_direntry) + len, GFP_KERNEL);
53 return de; 53 return de;
54} 54}
55 55
@@ -62,7 +62,7 @@ void dlm_clear_free_entries(struct dlm_ls *ls)
62 de = list_entry(ls->ls_recover_list.next, struct dlm_direntry, 62 de = list_entry(ls->ls_recover_list.next, struct dlm_direntry,
63 list); 63 list);
64 list_del(&de->list); 64 list_del(&de->list);
65 free_direntry(de); 65 kfree(de);
66 } 66 }
67 spin_unlock(&ls->ls_recover_list_lock); 67 spin_unlock(&ls->ls_recover_list_lock);
68} 68}
@@ -171,7 +171,7 @@ void dlm_dir_remove_entry(struct dlm_ls *ls, int nodeid, char *name, int namelen
171 } 171 }
172 172
173 list_del(&de->list); 173 list_del(&de->list);
174 free_direntry(de); 174 kfree(de);
175 out: 175 out:
176 write_unlock(&ls->ls_dirtbl[bucket].lock); 176 write_unlock(&ls->ls_dirtbl[bucket].lock);
177} 177}
@@ -302,7 +302,7 @@ static int get_entry(struct dlm_ls *ls, int nodeid, char *name,
302 302
303 write_unlock(&ls->ls_dirtbl[bucket].lock); 303 write_unlock(&ls->ls_dirtbl[bucket].lock);
304 304
305 de = allocate_direntry(ls, namelen); 305 de = kzalloc(sizeof(struct dlm_direntry) + namelen, GFP_KERNEL);
306 if (!de) 306 if (!de)
307 return -ENOMEM; 307 return -ENOMEM;
308 308
@@ -313,7 +313,7 @@ static int get_entry(struct dlm_ls *ls, int nodeid, char *name,
313 write_lock(&ls->ls_dirtbl[bucket].lock); 313 write_lock(&ls->ls_dirtbl[bucket].lock);
314 tmp = search_bucket(ls, name, namelen, bucket); 314 tmp = search_bucket(ls, name, namelen, bucket);
315 if (tmp) { 315 if (tmp) {
316 free_direntry(de); 316 kfree(de);
317 de = tmp; 317 de = tmp;
318 } else { 318 } else {
319 list_add_tail(&de->list, &ls->ls_dirtbl[bucket].list); 319 list_add_tail(&de->list, &ls->ls_dirtbl[bucket].list);
@@ -329,49 +329,47 @@ int dlm_dir_lookup(struct dlm_ls *ls, int nodeid, char *name, int namelen,
329 return get_entry(ls, nodeid, name, namelen, r_nodeid); 329 return get_entry(ls, nodeid, name, namelen, r_nodeid);
330} 330}
331 331
332/* Copy the names of master rsb's into the buffer provided. 332static struct dlm_rsb *find_rsb_root(struct dlm_ls *ls, char *name, int len)
333 Only select names whose dir node is the given nodeid. */ 333{
334 struct dlm_rsb *r;
335
336 down_read(&ls->ls_root_sem);
337 list_for_each_entry(r, &ls->ls_root_list, res_root_list) {
338 if (len == r->res_length && !memcmp(name, r->res_name, len)) {
339 up_read(&ls->ls_root_sem);
340 return r;
341 }
342 }
343 up_read(&ls->ls_root_sem);
344 return NULL;
345}
346
347/* Find the rsb where we left off (or start again), then send rsb names
348 for rsb's we're master of and whose directory node matches the requesting
349 node. inbuf is the rsb name last sent, inlen is the name's length */
334 350
335void dlm_copy_master_names(struct dlm_ls *ls, char *inbuf, int inlen, 351void dlm_copy_master_names(struct dlm_ls *ls, char *inbuf, int inlen,
336 char *outbuf, int outlen, int nodeid) 352 char *outbuf, int outlen, int nodeid)
337{ 353{
338 struct list_head *list; 354 struct list_head *list;
339 struct dlm_rsb *start_r = NULL, *r = NULL; 355 struct dlm_rsb *r;
340 int offset = 0, start_namelen, error, dir_nodeid; 356 int offset = 0, dir_nodeid;
341 char *start_name;
342 uint16_t be_namelen; 357 uint16_t be_namelen;
343 358
344 /*
345 * Find the rsb where we left off (or start again)
346 */
347
348 start_namelen = inlen;
349 start_name = inbuf;
350
351 if (start_namelen > 1) {
352 /*
353 * We could also use a find_rsb_root() function here that
354 * searched the ls_root_list.
355 */
356 error = dlm_find_rsb(ls, start_name, start_namelen, R_MASTER,
357 &start_r);
358 DLM_ASSERT(!error && start_r,
359 printk("error %d\n", error););
360 DLM_ASSERT(!list_empty(&start_r->res_root_list),
361 dlm_print_rsb(start_r););
362 dlm_put_rsb(start_r);
363 }
364
365 /*
366 * Send rsb names for rsb's we're master of and whose directory node
367 * matches the requesting node.
368 */
369
370 down_read(&ls->ls_root_sem); 359 down_read(&ls->ls_root_sem);
371 if (start_r) 360
372 list = start_r->res_root_list.next; 361 if (inlen > 1) {
373 else 362 r = find_rsb_root(ls, inbuf, inlen);
363 if (!r) {
364 inbuf[inlen - 1] = '\0';
365 log_error(ls, "copy_master_names from %d start %d %s",
366 nodeid, inlen, inbuf);
367 goto out;
368 }
369 list = r->res_root_list.next;
370 } else {
374 list = ls->ls_root_list.next; 371 list = ls->ls_root_list.next;
372 }
375 373
376 for (offset = 0; list != &ls->ls_root_list; list = list->next) { 374 for (offset = 0; list != &ls->ls_root_list; list = list->next) {
377 r = list_entry(list, struct dlm_rsb, res_root_list); 375 r = list_entry(list, struct dlm_rsb, res_root_list);
diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h
index d2fc2384c3be..ec61bbaf25df 100644
--- a/fs/dlm/dlm_internal.h
+++ b/fs/dlm/dlm_internal.h
@@ -570,5 +570,21 @@ static inline int dlm_no_directory(struct dlm_ls *ls)
570 return (ls->ls_exflags & DLM_LSFL_NODIR) ? 1 : 0; 570 return (ls->ls_exflags & DLM_LSFL_NODIR) ? 1 : 0;
571} 571}
572 572
573int dlm_netlink_init(void);
574void dlm_netlink_exit(void);
575void dlm_timeout_warn(struct dlm_lkb *lkb);
576
577#ifdef CONFIG_DLM_DEBUG
578int dlm_register_debugfs(void);
579void dlm_unregister_debugfs(void);
580int dlm_create_debug_file(struct dlm_ls *ls);
581void dlm_delete_debug_file(struct dlm_ls *ls);
582#else
583static inline int dlm_register_debugfs(void) { return 0; }
584static inline void dlm_unregister_debugfs(void) { }
585static inline int dlm_create_debug_file(struct dlm_ls *ls) { return 0; }
586static inline void dlm_delete_debug_file(struct dlm_ls *ls) { }
587#endif
588
573#endif /* __DLM_INTERNAL_DOT_H__ */ 589#endif /* __DLM_INTERNAL_DOT_H__ */
574 590
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
index 3915b8e14146..ff4a198fa677 100644
--- a/fs/dlm/lock.c
+++ b/fs/dlm/lock.c
@@ -1,7 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2******************************************************************************* 2*******************************************************************************
3** 3**
4** Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved. 4** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
5** 5**
6** This copyrighted material is made available to anyone wishing to use, 6** This copyrighted material is made available to anyone wishing to use,
7** modify, copy, or redistribute it subject to the terms and conditions 7** modify, copy, or redistribute it subject to the terms and conditions
@@ -88,7 +88,6 @@ static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb,
88static int receive_extralen(struct dlm_message *ms); 88static int receive_extralen(struct dlm_message *ms);
89static void do_purge(struct dlm_ls *ls, int nodeid, int pid); 89static void do_purge(struct dlm_ls *ls, int nodeid, int pid);
90static void del_timeout(struct dlm_lkb *lkb); 90static void del_timeout(struct dlm_lkb *lkb);
91void dlm_timeout_warn(struct dlm_lkb *lkb);
92 91
93/* 92/*
94 * Lock compatibilty matrix - thanks Steve 93 * Lock compatibilty matrix - thanks Steve
@@ -335,7 +334,7 @@ static struct dlm_rsb *create_rsb(struct dlm_ls *ls, char *name, int len)
335{ 334{
336 struct dlm_rsb *r; 335 struct dlm_rsb *r;
337 336
338 r = allocate_rsb(ls, len); 337 r = dlm_allocate_rsb(ls, len);
339 if (!r) 338 if (!r)
340 return NULL; 339 return NULL;
341 340
@@ -478,7 +477,7 @@ static int find_rsb(struct dlm_ls *ls, char *name, int namelen,
478 error = _search_rsb(ls, name, namelen, bucket, 0, &tmp); 477 error = _search_rsb(ls, name, namelen, bucket, 0, &tmp);
479 if (!error) { 478 if (!error) {
480 write_unlock(&ls->ls_rsbtbl[bucket].lock); 479 write_unlock(&ls->ls_rsbtbl[bucket].lock);
481 free_rsb(r); 480 dlm_free_rsb(r);
482 r = tmp; 481 r = tmp;
483 goto out; 482 goto out;
484 } 483 }
@@ -490,12 +489,6 @@ static int find_rsb(struct dlm_ls *ls, char *name, int namelen,
490 return error; 489 return error;
491} 490}
492 491
493int dlm_find_rsb(struct dlm_ls *ls, char *name, int namelen,
494 unsigned int flags, struct dlm_rsb **r_ret)
495{
496 return find_rsb(ls, name, namelen, flags, r_ret);
497}
498
499/* This is only called to add a reference when the code already holds 492/* This is only called to add a reference when the code already holds
500 a valid reference to the rsb, so there's no need for locking. */ 493 a valid reference to the rsb, so there's no need for locking. */
501 494
@@ -519,7 +512,7 @@ static void toss_rsb(struct kref *kref)
519 list_move(&r->res_hashchain, &ls->ls_rsbtbl[r->res_bucket].toss); 512 list_move(&r->res_hashchain, &ls->ls_rsbtbl[r->res_bucket].toss);
520 r->res_toss_time = jiffies; 513 r->res_toss_time = jiffies;
521 if (r->res_lvbptr) { 514 if (r->res_lvbptr) {
522 free_lvb(r->res_lvbptr); 515 dlm_free_lvb(r->res_lvbptr);
523 r->res_lvbptr = NULL; 516 r->res_lvbptr = NULL;
524 } 517 }
525} 518}
@@ -589,7 +582,7 @@ static int create_lkb(struct dlm_ls *ls, struct dlm_lkb **lkb_ret)
589 uint32_t lkid = 0; 582 uint32_t lkid = 0;
590 uint16_t bucket; 583 uint16_t bucket;
591 584
592 lkb = allocate_lkb(ls); 585 lkb = dlm_allocate_lkb(ls);
593 if (!lkb) 586 if (!lkb)
594 return -ENOMEM; 587 return -ENOMEM;
595 588
@@ -683,8 +676,8 @@ static int __put_lkb(struct dlm_ls *ls, struct dlm_lkb *lkb)
683 676
684 /* for local/process lkbs, lvbptr points to caller's lksb */ 677 /* for local/process lkbs, lvbptr points to caller's lksb */
685 if (lkb->lkb_lvbptr && is_master_copy(lkb)) 678 if (lkb->lkb_lvbptr && is_master_copy(lkb))
686 free_lvb(lkb->lkb_lvbptr); 679 dlm_free_lvb(lkb->lkb_lvbptr);
687 free_lkb(lkb); 680 dlm_free_lkb(lkb);
688 return 1; 681 return 1;
689 } else { 682 } else {
690 write_unlock(&ls->ls_lkbtbl[bucket].lock); 683 write_unlock(&ls->ls_lkbtbl[bucket].lock);
@@ -988,7 +981,7 @@ static int shrink_bucket(struct dlm_ls *ls, int b)
988 981
989 if (is_master(r)) 982 if (is_master(r))
990 dir_remove(r); 983 dir_remove(r);
991 free_rsb(r); 984 dlm_free_rsb(r);
992 count++; 985 count++;
993 } else { 986 } else {
994 write_unlock(&ls->ls_rsbtbl[b].lock); 987 write_unlock(&ls->ls_rsbtbl[b].lock);
@@ -1171,7 +1164,7 @@ static void set_lvb_lock(struct dlm_rsb *r, struct dlm_lkb *lkb)
1171 return; 1164 return;
1172 1165
1173 if (!r->res_lvbptr) 1166 if (!r->res_lvbptr)
1174 r->res_lvbptr = allocate_lvb(r->res_ls); 1167 r->res_lvbptr = dlm_allocate_lvb(r->res_ls);
1175 1168
1176 if (!r->res_lvbptr) 1169 if (!r->res_lvbptr)
1177 return; 1170 return;
@@ -1203,7 +1196,7 @@ static void set_lvb_unlock(struct dlm_rsb *r, struct dlm_lkb *lkb)
1203 return; 1196 return;
1204 1197
1205 if (!r->res_lvbptr) 1198 if (!r->res_lvbptr)
1206 r->res_lvbptr = allocate_lvb(r->res_ls); 1199 r->res_lvbptr = dlm_allocate_lvb(r->res_ls);
1207 1200
1208 if (!r->res_lvbptr) 1201 if (!r->res_lvbptr)
1209 return; 1202 return;
@@ -1852,7 +1845,7 @@ static void send_blocking_asts_all(struct dlm_rsb *r, struct dlm_lkb *lkb)
1852static int set_master(struct dlm_rsb *r, struct dlm_lkb *lkb) 1845static int set_master(struct dlm_rsb *r, struct dlm_lkb *lkb)
1853{ 1846{
1854 struct dlm_ls *ls = r->res_ls; 1847 struct dlm_ls *ls = r->res_ls;
1855 int error, dir_nodeid, ret_nodeid, our_nodeid = dlm_our_nodeid(); 1848 int i, error, dir_nodeid, ret_nodeid, our_nodeid = dlm_our_nodeid();
1856 1849
1857 if (rsb_flag(r, RSB_MASTER_UNCERTAIN)) { 1850 if (rsb_flag(r, RSB_MASTER_UNCERTAIN)) {
1858 rsb_clear_flag(r, RSB_MASTER_UNCERTAIN); 1851 rsb_clear_flag(r, RSB_MASTER_UNCERTAIN);
@@ -1886,7 +1879,7 @@ static int set_master(struct dlm_rsb *r, struct dlm_lkb *lkb)
1886 return 1; 1879 return 1;
1887 } 1880 }
1888 1881
1889 for (;;) { 1882 for (i = 0; i < 2; i++) {
1890 /* It's possible for dlm_scand to remove an old rsb for 1883 /* It's possible for dlm_scand to remove an old rsb for
1891 this same resource from the toss list, us to create 1884 this same resource from the toss list, us to create
1892 a new one, look up the master locally, and find it 1885 a new one, look up the master locally, and find it
@@ -1900,6 +1893,8 @@ static int set_master(struct dlm_rsb *r, struct dlm_lkb *lkb)
1900 log_debug(ls, "dir_lookup error %d %s", error, r->res_name); 1893 log_debug(ls, "dir_lookup error %d %s", error, r->res_name);
1901 schedule(); 1894 schedule();
1902 } 1895 }
1896 if (error && error != -EEXIST)
1897 return error;
1903 1898
1904 if (ret_nodeid == our_nodeid) { 1899 if (ret_nodeid == our_nodeid) {
1905 r->res_first_lkid = 0; 1900 r->res_first_lkid = 0;
@@ -1941,8 +1936,11 @@ static void confirm_master(struct dlm_rsb *r, int error)
1941 break; 1936 break;
1942 1937
1943 case -EAGAIN: 1938 case -EAGAIN:
1944 /* the remote master didn't queue our NOQUEUE request; 1939 case -EBADR:
1945 make a waiting lkb the first_lkid */ 1940 case -ENOTBLK:
1941 /* the remote request failed and won't be retried (it was
1942 a NOQUEUE, or has been canceled/unlocked); make a waiting
1943 lkb the first_lkid */
1946 1944
1947 r->res_first_lkid = 0; 1945 r->res_first_lkid = 0;
1948 1946
@@ -2108,17 +2106,18 @@ static int validate_unlock_args(struct dlm_lkb *lkb, struct dlm_args *args)
2108 /* an lkb may be waiting for an rsb lookup to complete where the 2106 /* an lkb may be waiting for an rsb lookup to complete where the
2109 lookup was initiated by another lock */ 2107 lookup was initiated by another lock */
2110 2108
2111 if (args->flags & (DLM_LKF_CANCEL | DLM_LKF_FORCEUNLOCK)) { 2109 if (!list_empty(&lkb->lkb_rsb_lookup)) {
2112 if (!list_empty(&lkb->lkb_rsb_lookup)) { 2110 if (args->flags & (DLM_LKF_CANCEL | DLM_LKF_FORCEUNLOCK)) {
2113 log_debug(ls, "unlock on rsb_lookup %x", lkb->lkb_id); 2111 log_debug(ls, "unlock on rsb_lookup %x", lkb->lkb_id);
2114 list_del_init(&lkb->lkb_rsb_lookup); 2112 list_del_init(&lkb->lkb_rsb_lookup);
2115 queue_cast(lkb->lkb_resource, lkb, 2113 queue_cast(lkb->lkb_resource, lkb,
2116 args->flags & DLM_LKF_CANCEL ? 2114 args->flags & DLM_LKF_CANCEL ?
2117 -DLM_ECANCEL : -DLM_EUNLOCK); 2115 -DLM_ECANCEL : -DLM_EUNLOCK);
2118 unhold_lkb(lkb); /* undoes create_lkb() */ 2116 unhold_lkb(lkb); /* undoes create_lkb() */
2119 rv = -EBUSY;
2120 goto out;
2121 } 2117 }
2118 /* caller changes -EBUSY to 0 for CANCEL and FORCEUNLOCK */
2119 rv = -EBUSY;
2120 goto out;
2122 } 2121 }
2123 2122
2124 /* cancel not allowed with another cancel/unlock in progress */ 2123 /* cancel not allowed with another cancel/unlock in progress */
@@ -2986,7 +2985,7 @@ static int receive_lvb(struct dlm_ls *ls, struct dlm_lkb *lkb,
2986 2985
2987 if (lkb->lkb_exflags & DLM_LKF_VALBLK) { 2986 if (lkb->lkb_exflags & DLM_LKF_VALBLK) {
2988 if (!lkb->lkb_lvbptr) 2987 if (!lkb->lkb_lvbptr)
2989 lkb->lkb_lvbptr = allocate_lvb(ls); 2988 lkb->lkb_lvbptr = dlm_allocate_lvb(ls);
2990 if (!lkb->lkb_lvbptr) 2989 if (!lkb->lkb_lvbptr)
2991 return -ENOMEM; 2990 return -ENOMEM;
2992 len = receive_extralen(ms); 2991 len = receive_extralen(ms);
@@ -3006,11 +3005,9 @@ static int receive_request_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
3006 lkb->lkb_bastaddr = (void *) (long) (ms->m_asts & AST_BAST); 3005 lkb->lkb_bastaddr = (void *) (long) (ms->m_asts & AST_BAST);
3007 lkb->lkb_astaddr = (void *) (long) (ms->m_asts & AST_COMP); 3006 lkb->lkb_astaddr = (void *) (long) (ms->m_asts & AST_COMP);
3008 3007
3009 DLM_ASSERT(is_master_copy(lkb), dlm_print_lkb(lkb););
3010
3011 if (lkb->lkb_exflags & DLM_LKF_VALBLK) { 3008 if (lkb->lkb_exflags & DLM_LKF_VALBLK) {
3012 /* lkb was just created so there won't be an lvb yet */ 3009 /* lkb was just created so there won't be an lvb yet */
3013 lkb->lkb_lvbptr = allocate_lvb(ls); 3010 lkb->lkb_lvbptr = dlm_allocate_lvb(ls);
3014 if (!lkb->lkb_lvbptr) 3011 if (!lkb->lkb_lvbptr)
3015 return -ENOMEM; 3012 return -ENOMEM;
3016 } 3013 }
@@ -3021,16 +3018,6 @@ static int receive_request_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
3021static int receive_convert_args(struct dlm_ls *ls, struct dlm_lkb *lkb, 3018static int receive_convert_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
3022 struct dlm_message *ms) 3019 struct dlm_message *ms)
3023{ 3020{
3024 if (lkb->lkb_nodeid != ms->m_header.h_nodeid) {
3025 log_error(ls, "convert_args nodeid %d %d lkid %x %x",
3026 lkb->lkb_nodeid, ms->m_header.h_nodeid,
3027 lkb->lkb_id, lkb->lkb_remid);
3028 return -EINVAL;
3029 }
3030
3031 if (!is_master_copy(lkb))
3032 return -EINVAL;
3033
3034 if (lkb->lkb_status != DLM_LKSTS_GRANTED) 3021 if (lkb->lkb_status != DLM_LKSTS_GRANTED)
3035 return -EBUSY; 3022 return -EBUSY;
3036 3023
@@ -3046,8 +3033,6 @@ static int receive_convert_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
3046static int receive_unlock_args(struct dlm_ls *ls, struct dlm_lkb *lkb, 3033static int receive_unlock_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
3047 struct dlm_message *ms) 3034 struct dlm_message *ms)
3048{ 3035{
3049 if (!is_master_copy(lkb))
3050 return -EINVAL;
3051 if (receive_lvb(ls, lkb, ms)) 3036 if (receive_lvb(ls, lkb, ms))
3052 return -ENOMEM; 3037 return -ENOMEM;
3053 return 0; 3038 return 0;
@@ -3063,6 +3048,50 @@ static void setup_stub_lkb(struct dlm_ls *ls, struct dlm_message *ms)
3063 lkb->lkb_remid = ms->m_lkid; 3048 lkb->lkb_remid = ms->m_lkid;
3064} 3049}
3065 3050
3051/* This is called after the rsb is locked so that we can safely inspect
3052 fields in the lkb. */
3053
3054static int validate_message(struct dlm_lkb *lkb, struct dlm_message *ms)
3055{
3056 int from = ms->m_header.h_nodeid;
3057 int error = 0;
3058
3059 switch (ms->m_type) {
3060 case DLM_MSG_CONVERT:
3061 case DLM_MSG_UNLOCK:
3062 case DLM_MSG_CANCEL:
3063 if (!is_master_copy(lkb) || lkb->lkb_nodeid != from)
3064 error = -EINVAL;
3065 break;
3066
3067 case DLM_MSG_CONVERT_REPLY:
3068 case DLM_MSG_UNLOCK_REPLY:
3069 case DLM_MSG_CANCEL_REPLY:
3070 case DLM_MSG_GRANT:
3071 case DLM_MSG_BAST:
3072 if (!is_process_copy(lkb) || lkb->lkb_nodeid != from)
3073 error = -EINVAL;
3074 break;
3075
3076 case DLM_MSG_REQUEST_REPLY:
3077 if (!is_process_copy(lkb))
3078 error = -EINVAL;
3079 else if (lkb->lkb_nodeid != -1 && lkb->lkb_nodeid != from)
3080 error = -EINVAL;
3081 break;
3082
3083 default:
3084 error = -EINVAL;
3085 }
3086
3087 if (error)
3088 log_error(lkb->lkb_resource->res_ls,
3089 "ignore invalid message %d from %d %x %x %x %d",
3090 ms->m_type, from, lkb->lkb_id, lkb->lkb_remid,
3091 lkb->lkb_flags, lkb->lkb_nodeid);
3092 return error;
3093}
3094
3066static void receive_request(struct dlm_ls *ls, struct dlm_message *ms) 3095static void receive_request(struct dlm_ls *ls, struct dlm_message *ms)
3067{ 3096{
3068 struct dlm_lkb *lkb; 3097 struct dlm_lkb *lkb;
@@ -3124,17 +3153,21 @@ static void receive_convert(struct dlm_ls *ls, struct dlm_message *ms)
3124 hold_rsb(r); 3153 hold_rsb(r);
3125 lock_rsb(r); 3154 lock_rsb(r);
3126 3155
3156 error = validate_message(lkb, ms);
3157 if (error)
3158 goto out;
3159
3127 receive_flags(lkb, ms); 3160 receive_flags(lkb, ms);
3128 error = receive_convert_args(ls, lkb, ms); 3161 error = receive_convert_args(ls, lkb, ms);
3129 if (error) 3162 if (error)
3130 goto out; 3163 goto out_reply;
3131 reply = !down_conversion(lkb); 3164 reply = !down_conversion(lkb);
3132 3165
3133 error = do_convert(r, lkb); 3166 error = do_convert(r, lkb);
3134 out: 3167 out_reply:
3135 if (reply) 3168 if (reply)
3136 send_convert_reply(r, lkb, error); 3169 send_convert_reply(r, lkb, error);
3137 3170 out:
3138 unlock_rsb(r); 3171 unlock_rsb(r);
3139 put_rsb(r); 3172 put_rsb(r);
3140 dlm_put_lkb(lkb); 3173 dlm_put_lkb(lkb);
@@ -3160,15 +3193,19 @@ static void receive_unlock(struct dlm_ls *ls, struct dlm_message *ms)
3160 hold_rsb(r); 3193 hold_rsb(r);
3161 lock_rsb(r); 3194 lock_rsb(r);
3162 3195
3196 error = validate_message(lkb, ms);
3197 if (error)
3198 goto out;
3199
3163 receive_flags(lkb, ms); 3200 receive_flags(lkb, ms);
3164 error = receive_unlock_args(ls, lkb, ms); 3201 error = receive_unlock_args(ls, lkb, ms);
3165 if (error) 3202 if (error)
3166 goto out; 3203 goto out_reply;
3167 3204
3168 error = do_unlock(r, lkb); 3205 error = do_unlock(r, lkb);
3169 out: 3206 out_reply:
3170 send_unlock_reply(r, lkb, error); 3207 send_unlock_reply(r, lkb, error);
3171 3208 out:
3172 unlock_rsb(r); 3209 unlock_rsb(r);
3173 put_rsb(r); 3210 put_rsb(r);
3174 dlm_put_lkb(lkb); 3211 dlm_put_lkb(lkb);
@@ -3196,9 +3233,13 @@ static void receive_cancel(struct dlm_ls *ls, struct dlm_message *ms)
3196 hold_rsb(r); 3233 hold_rsb(r);
3197 lock_rsb(r); 3234 lock_rsb(r);
3198 3235
3236 error = validate_message(lkb, ms);
3237 if (error)
3238 goto out;
3239
3199 error = do_cancel(r, lkb); 3240 error = do_cancel(r, lkb);
3200 send_cancel_reply(r, lkb, error); 3241 send_cancel_reply(r, lkb, error);
3201 3242 out:
3202 unlock_rsb(r); 3243 unlock_rsb(r);
3203 put_rsb(r); 3244 put_rsb(r);
3204 dlm_put_lkb(lkb); 3245 dlm_put_lkb(lkb);
@@ -3217,22 +3258,26 @@ static void receive_grant(struct dlm_ls *ls, struct dlm_message *ms)
3217 3258
3218 error = find_lkb(ls, ms->m_remid, &lkb); 3259 error = find_lkb(ls, ms->m_remid, &lkb);
3219 if (error) { 3260 if (error) {
3220 log_error(ls, "receive_grant no lkb"); 3261 log_debug(ls, "receive_grant from %d no lkb %x",
3262 ms->m_header.h_nodeid, ms->m_remid);
3221 return; 3263 return;
3222 } 3264 }
3223 DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb););
3224 3265
3225 r = lkb->lkb_resource; 3266 r = lkb->lkb_resource;
3226 3267
3227 hold_rsb(r); 3268 hold_rsb(r);
3228 lock_rsb(r); 3269 lock_rsb(r);
3229 3270
3271 error = validate_message(lkb, ms);
3272 if (error)
3273 goto out;
3274
3230 receive_flags_reply(lkb, ms); 3275 receive_flags_reply(lkb, ms);
3231 if (is_altmode(lkb)) 3276 if (is_altmode(lkb))
3232 munge_altmode(lkb, ms); 3277 munge_altmode(lkb, ms);
3233 grant_lock_pc(r, lkb, ms); 3278 grant_lock_pc(r, lkb, ms);
3234 queue_cast(r, lkb, 0); 3279 queue_cast(r, lkb, 0);
3235 3280 out:
3236 unlock_rsb(r); 3281 unlock_rsb(r);
3237 put_rsb(r); 3282 put_rsb(r);
3238 dlm_put_lkb(lkb); 3283 dlm_put_lkb(lkb);
@@ -3246,18 +3291,22 @@ static void receive_bast(struct dlm_ls *ls, struct dlm_message *ms)
3246 3291
3247 error = find_lkb(ls, ms->m_remid, &lkb); 3292 error = find_lkb(ls, ms->m_remid, &lkb);
3248 if (error) { 3293 if (error) {
3249 log_error(ls, "receive_bast no lkb"); 3294 log_debug(ls, "receive_bast from %d no lkb %x",
3295 ms->m_header.h_nodeid, ms->m_remid);
3250 return; 3296 return;
3251 } 3297 }
3252 DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb););
3253 3298
3254 r = lkb->lkb_resource; 3299 r = lkb->lkb_resource;
3255 3300
3256 hold_rsb(r); 3301 hold_rsb(r);
3257 lock_rsb(r); 3302 lock_rsb(r);
3258 3303
3259 queue_bast(r, lkb, ms->m_bastmode); 3304 error = validate_message(lkb, ms);
3305 if (error)
3306 goto out;
3260 3307
3308 queue_bast(r, lkb, ms->m_bastmode);
3309 out:
3261 unlock_rsb(r); 3310 unlock_rsb(r);
3262 put_rsb(r); 3311 put_rsb(r);
3263 dlm_put_lkb(lkb); 3312 dlm_put_lkb(lkb);
@@ -3323,15 +3372,19 @@ static void receive_request_reply(struct dlm_ls *ls, struct dlm_message *ms)
3323 3372
3324 error = find_lkb(ls, ms->m_remid, &lkb); 3373 error = find_lkb(ls, ms->m_remid, &lkb);
3325 if (error) { 3374 if (error) {
3326 log_error(ls, "receive_request_reply no lkb"); 3375 log_debug(ls, "receive_request_reply from %d no lkb %x",
3376 ms->m_header.h_nodeid, ms->m_remid);
3327 return; 3377 return;
3328 } 3378 }
3329 DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb););
3330 3379
3331 r = lkb->lkb_resource; 3380 r = lkb->lkb_resource;
3332 hold_rsb(r); 3381 hold_rsb(r);
3333 lock_rsb(r); 3382 lock_rsb(r);
3334 3383
3384 error = validate_message(lkb, ms);
3385 if (error)
3386 goto out;
3387
3335 mstype = lkb->lkb_wait_type; 3388 mstype = lkb->lkb_wait_type;
3336 error = remove_from_waiters(lkb, DLM_MSG_REQUEST_REPLY); 3389 error = remove_from_waiters(lkb, DLM_MSG_REQUEST_REPLY);
3337 if (error) 3390 if (error)
@@ -3383,6 +3436,7 @@ static void receive_request_reply(struct dlm_ls *ls, struct dlm_message *ms)
3383 if (is_overlap(lkb)) { 3436 if (is_overlap(lkb)) {
3384 /* we'll ignore error in cancel/unlock reply */ 3437 /* we'll ignore error in cancel/unlock reply */
3385 queue_cast_overlap(r, lkb); 3438 queue_cast_overlap(r, lkb);
3439 confirm_master(r, result);
3386 unhold_lkb(lkb); /* undoes create_lkb() */ 3440 unhold_lkb(lkb); /* undoes create_lkb() */
3387 } else 3441 } else
3388 _request_lock(r, lkb); 3442 _request_lock(r, lkb);
@@ -3463,6 +3517,10 @@ static void _receive_convert_reply(struct dlm_lkb *lkb, struct dlm_message *ms)
3463 hold_rsb(r); 3517 hold_rsb(r);
3464 lock_rsb(r); 3518 lock_rsb(r);
3465 3519
3520 error = validate_message(lkb, ms);
3521 if (error)
3522 goto out;
3523
3466 /* stub reply can happen with waiters_mutex held */ 3524 /* stub reply can happen with waiters_mutex held */
3467 error = remove_from_waiters_ms(lkb, ms); 3525 error = remove_from_waiters_ms(lkb, ms);
3468 if (error) 3526 if (error)
@@ -3481,10 +3539,10 @@ static void receive_convert_reply(struct dlm_ls *ls, struct dlm_message *ms)
3481 3539
3482 error = find_lkb(ls, ms->m_remid, &lkb); 3540 error = find_lkb(ls, ms->m_remid, &lkb);
3483 if (error) { 3541 if (error) {
3484 log_error(ls, "receive_convert_reply no lkb"); 3542 log_debug(ls, "receive_convert_reply from %d no lkb %x",
3543 ms->m_header.h_nodeid, ms->m_remid);
3485 return; 3544 return;
3486 } 3545 }
3487 DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb););
3488 3546
3489 _receive_convert_reply(lkb, ms); 3547 _receive_convert_reply(lkb, ms);
3490 dlm_put_lkb(lkb); 3548 dlm_put_lkb(lkb);
@@ -3498,6 +3556,10 @@ static void _receive_unlock_reply(struct dlm_lkb *lkb, struct dlm_message *ms)
3498 hold_rsb(r); 3556 hold_rsb(r);
3499 lock_rsb(r); 3557 lock_rsb(r);
3500 3558
3559 error = validate_message(lkb, ms);
3560 if (error)
3561 goto out;
3562
3501 /* stub reply can happen with waiters_mutex held */ 3563 /* stub reply can happen with waiters_mutex held */
3502 error = remove_from_waiters_ms(lkb, ms); 3564 error = remove_from_waiters_ms(lkb, ms);
3503 if (error) 3565 if (error)
@@ -3529,10 +3591,10 @@ static void receive_unlock_reply(struct dlm_ls *ls, struct dlm_message *ms)
3529 3591
3530 error = find_lkb(ls, ms->m_remid, &lkb); 3592 error = find_lkb(ls, ms->m_remid, &lkb);
3531 if (error) { 3593 if (error) {
3532 log_error(ls, "receive_unlock_reply no lkb"); 3594 log_debug(ls, "receive_unlock_reply from %d no lkb %x",
3595 ms->m_header.h_nodeid, ms->m_remid);
3533 return; 3596 return;
3534 } 3597 }
3535 DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb););
3536 3598
3537 _receive_unlock_reply(lkb, ms); 3599 _receive_unlock_reply(lkb, ms);
3538 dlm_put_lkb(lkb); 3600 dlm_put_lkb(lkb);
@@ -3546,6 +3608,10 @@ static void _receive_cancel_reply(struct dlm_lkb *lkb, struct dlm_message *ms)
3546 hold_rsb(r); 3608 hold_rsb(r);
3547 lock_rsb(r); 3609 lock_rsb(r);
3548 3610
3611 error = validate_message(lkb, ms);
3612 if (error)
3613 goto out;
3614
3549 /* stub reply can happen with waiters_mutex held */ 3615 /* stub reply can happen with waiters_mutex held */
3550 error = remove_from_waiters_ms(lkb, ms); 3616 error = remove_from_waiters_ms(lkb, ms);
3551 if (error) 3617 if (error)
@@ -3577,10 +3643,10 @@ static void receive_cancel_reply(struct dlm_ls *ls, struct dlm_message *ms)
3577 3643
3578 error = find_lkb(ls, ms->m_remid, &lkb); 3644 error = find_lkb(ls, ms->m_remid, &lkb);
3579 if (error) { 3645 if (error) {
3580 log_error(ls, "receive_cancel_reply no lkb"); 3646 log_debug(ls, "receive_cancel_reply from %d no lkb %x",
3647 ms->m_header.h_nodeid, ms->m_remid);
3581 return; 3648 return;
3582 } 3649 }
3583 DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb););
3584 3650
3585 _receive_cancel_reply(lkb, ms); 3651 _receive_cancel_reply(lkb, ms);
3586 dlm_put_lkb(lkb); 3652 dlm_put_lkb(lkb);
@@ -3640,6 +3706,13 @@ static void receive_lookup_reply(struct dlm_ls *ls, struct dlm_message *ms)
3640 3706
3641static void _receive_message(struct dlm_ls *ls, struct dlm_message *ms) 3707static void _receive_message(struct dlm_ls *ls, struct dlm_message *ms)
3642{ 3708{
3709 if (!dlm_is_member(ls, ms->m_header.h_nodeid)) {
3710 log_debug(ls, "ignore non-member message %d from %d %x %x %d",
3711 ms->m_type, ms->m_header.h_nodeid, ms->m_lkid,
3712 ms->m_remid, ms->m_result);
3713 return;
3714 }
3715
3643 switch (ms->m_type) { 3716 switch (ms->m_type) {
3644 3717
3645 /* messages sent to a master node */ 3718 /* messages sent to a master node */
@@ -3778,8 +3851,9 @@ void dlm_receive_buffer(struct dlm_header *hd, int nodeid)
3778 3851
3779 ls = dlm_find_lockspace_global(hd->h_lockspace); 3852 ls = dlm_find_lockspace_global(hd->h_lockspace);
3780 if (!ls) { 3853 if (!ls) {
3781 log_print("invalid h_lockspace %x from %d cmd %d type %d", 3854 if (dlm_config.ci_log_debug)
3782 hd->h_lockspace, nodeid, hd->h_cmd, type); 3855 log_print("invalid lockspace %x from %d cmd %d type %d",
3856 hd->h_lockspace, nodeid, hd->h_cmd, type);
3783 3857
3784 if (hd->h_cmd == DLM_RCOM && type == DLM_RCOM_STATUS) 3858 if (hd->h_cmd == DLM_RCOM && type == DLM_RCOM_STATUS)
3785 dlm_send_ls_not_ready(nodeid, rc); 3859 dlm_send_ls_not_ready(nodeid, rc);
@@ -3806,6 +3880,7 @@ static void recover_convert_waiter(struct dlm_ls *ls, struct dlm_lkb *lkb)
3806 ls->ls_stub_ms.m_type = DLM_MSG_CONVERT_REPLY; 3880 ls->ls_stub_ms.m_type = DLM_MSG_CONVERT_REPLY;
3807 ls->ls_stub_ms.m_result = -EINPROGRESS; 3881 ls->ls_stub_ms.m_result = -EINPROGRESS;
3808 ls->ls_stub_ms.m_flags = lkb->lkb_flags; 3882 ls->ls_stub_ms.m_flags = lkb->lkb_flags;
3883 ls->ls_stub_ms.m_header.h_nodeid = lkb->lkb_nodeid;
3809 _receive_convert_reply(lkb, &ls->ls_stub_ms); 3884 _receive_convert_reply(lkb, &ls->ls_stub_ms);
3810 3885
3811 /* Same special case as in receive_rcom_lock_args() */ 3886 /* Same special case as in receive_rcom_lock_args() */
@@ -3847,6 +3922,7 @@ static int waiter_needs_recovery(struct dlm_ls *ls, struct dlm_lkb *lkb)
3847void dlm_recover_waiters_pre(struct dlm_ls *ls) 3922void dlm_recover_waiters_pre(struct dlm_ls *ls)
3848{ 3923{
3849 struct dlm_lkb *lkb, *safe; 3924 struct dlm_lkb *lkb, *safe;
3925 int wait_type, stub_unlock_result, stub_cancel_result;
3850 3926
3851 mutex_lock(&ls->ls_waiters_mutex); 3927 mutex_lock(&ls->ls_waiters_mutex);
3852 3928
@@ -3865,7 +3941,33 @@ void dlm_recover_waiters_pre(struct dlm_ls *ls)
3865 if (!waiter_needs_recovery(ls, lkb)) 3941 if (!waiter_needs_recovery(ls, lkb))
3866 continue; 3942 continue;
3867 3943
3868 switch (lkb->lkb_wait_type) { 3944 wait_type = lkb->lkb_wait_type;
3945 stub_unlock_result = -DLM_EUNLOCK;
3946 stub_cancel_result = -DLM_ECANCEL;
3947
3948 /* Main reply may have been received leaving a zero wait_type,
3949 but a reply for the overlapping op may not have been
3950 received. In that case we need to fake the appropriate
3951 reply for the overlap op. */
3952
3953 if (!wait_type) {
3954 if (is_overlap_cancel(lkb)) {
3955 wait_type = DLM_MSG_CANCEL;
3956 if (lkb->lkb_grmode == DLM_LOCK_IV)
3957 stub_cancel_result = 0;
3958 }
3959 if (is_overlap_unlock(lkb)) {
3960 wait_type = DLM_MSG_UNLOCK;
3961 if (lkb->lkb_grmode == DLM_LOCK_IV)
3962 stub_unlock_result = -ENOENT;
3963 }
3964
3965 log_debug(ls, "rwpre overlap %x %x %d %d %d",
3966 lkb->lkb_id, lkb->lkb_flags, wait_type,
3967 stub_cancel_result, stub_unlock_result);
3968 }
3969
3970 switch (wait_type) {
3869 3971
3870 case DLM_MSG_REQUEST: 3972 case DLM_MSG_REQUEST:
3871 lkb->lkb_flags |= DLM_IFL_RESEND; 3973 lkb->lkb_flags |= DLM_IFL_RESEND;
@@ -3878,8 +3980,9 @@ void dlm_recover_waiters_pre(struct dlm_ls *ls)
3878 case DLM_MSG_UNLOCK: 3980 case DLM_MSG_UNLOCK:
3879 hold_lkb(lkb); 3981 hold_lkb(lkb);
3880 ls->ls_stub_ms.m_type = DLM_MSG_UNLOCK_REPLY; 3982 ls->ls_stub_ms.m_type = DLM_MSG_UNLOCK_REPLY;
3881 ls->ls_stub_ms.m_result = -DLM_EUNLOCK; 3983 ls->ls_stub_ms.m_result = stub_unlock_result;
3882 ls->ls_stub_ms.m_flags = lkb->lkb_flags; 3984 ls->ls_stub_ms.m_flags = lkb->lkb_flags;
3985 ls->ls_stub_ms.m_header.h_nodeid = lkb->lkb_nodeid;
3883 _receive_unlock_reply(lkb, &ls->ls_stub_ms); 3986 _receive_unlock_reply(lkb, &ls->ls_stub_ms);
3884 dlm_put_lkb(lkb); 3987 dlm_put_lkb(lkb);
3885 break; 3988 break;
@@ -3887,15 +3990,16 @@ void dlm_recover_waiters_pre(struct dlm_ls *ls)
3887 case DLM_MSG_CANCEL: 3990 case DLM_MSG_CANCEL:
3888 hold_lkb(lkb); 3991 hold_lkb(lkb);
3889 ls->ls_stub_ms.m_type = DLM_MSG_CANCEL_REPLY; 3992 ls->ls_stub_ms.m_type = DLM_MSG_CANCEL_REPLY;
3890 ls->ls_stub_ms.m_result = -DLM_ECANCEL; 3993 ls->ls_stub_ms.m_result = stub_cancel_result;
3891 ls->ls_stub_ms.m_flags = lkb->lkb_flags; 3994 ls->ls_stub_ms.m_flags = lkb->lkb_flags;
3995 ls->ls_stub_ms.m_header.h_nodeid = lkb->lkb_nodeid;
3892 _receive_cancel_reply(lkb, &ls->ls_stub_ms); 3996 _receive_cancel_reply(lkb, &ls->ls_stub_ms);
3893 dlm_put_lkb(lkb); 3997 dlm_put_lkb(lkb);
3894 break; 3998 break;
3895 3999
3896 default: 4000 default:
3897 log_error(ls, "invalid lkb wait_type %d", 4001 log_error(ls, "invalid lkb wait_type %d %d",
3898 lkb->lkb_wait_type); 4002 lkb->lkb_wait_type, wait_type);
3899 } 4003 }
3900 schedule(); 4004 schedule();
3901 } 4005 }
@@ -4184,7 +4288,7 @@ static int receive_rcom_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
4184 lkb->lkb_astaddr = (void *) (long) (rl->rl_asts & AST_COMP); 4288 lkb->lkb_astaddr = (void *) (long) (rl->rl_asts & AST_COMP);
4185 4289
4186 if (lkb->lkb_exflags & DLM_LKF_VALBLK) { 4290 if (lkb->lkb_exflags & DLM_LKF_VALBLK) {
4187 lkb->lkb_lvbptr = allocate_lvb(ls); 4291 lkb->lkb_lvbptr = dlm_allocate_lvb(ls);
4188 if (!lkb->lkb_lvbptr) 4292 if (!lkb->lkb_lvbptr)
4189 return -ENOMEM; 4293 return -ENOMEM;
4190 lvblen = rc->rc_header.h_length - sizeof(struct dlm_rcom) - 4294 lvblen = rc->rc_header.h_length - sizeof(struct dlm_rcom) -
@@ -4259,7 +4363,7 @@ int dlm_recover_master_copy(struct dlm_ls *ls, struct dlm_rcom *rc)
4259 put_rsb(r); 4363 put_rsb(r);
4260 out: 4364 out:
4261 if (error) 4365 if (error)
4262 log_print("recover_master_copy %d %x", error, rl->rl_lkid); 4366 log_debug(ls, "recover_master_copy %d %x", error, rl->rl_lkid);
4263 rl->rl_result = error; 4367 rl->rl_result = error;
4264 return error; 4368 return error;
4265} 4369}
@@ -4342,7 +4446,7 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua,
4342 } 4446 }
4343 } 4447 }
4344 4448
4345 /* After ua is attached to lkb it will be freed by free_lkb(). 4449 /* After ua is attached to lkb it will be freed by dlm_free_lkb().
4346 When DLM_IFL_USER is set, the dlm knows that this is a userspace 4450 When DLM_IFL_USER is set, the dlm knows that this is a userspace
4347 lock and that lkb_astparam is the dlm_user_args structure. */ 4451 lock and that lkb_astparam is the dlm_user_args structure. */
4348 4452
@@ -4679,6 +4783,7 @@ void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc)
4679 } 4783 }
4680 4784
4681 list_for_each_entry_safe(lkb, safe, &proc->asts, lkb_astqueue) { 4785 list_for_each_entry_safe(lkb, safe, &proc->asts, lkb_astqueue) {
4786 lkb->lkb_ast_type = 0;
4682 list_del(&lkb->lkb_astqueue); 4787 list_del(&lkb->lkb_astqueue);
4683 dlm_put_lkb(lkb); 4788 dlm_put_lkb(lkb);
4684 } 4789 }
diff --git a/fs/dlm/lock.h b/fs/dlm/lock.h
index ada04680a1e5..27b6ed302911 100644
--- a/fs/dlm/lock.h
+++ b/fs/dlm/lock.h
@@ -19,8 +19,6 @@ void dlm_print_lkb(struct dlm_lkb *lkb);
19void dlm_receive_message_saved(struct dlm_ls *ls, struct dlm_message *ms); 19void dlm_receive_message_saved(struct dlm_ls *ls, struct dlm_message *ms);
20void dlm_receive_buffer(struct dlm_header *hd, int nodeid); 20void dlm_receive_buffer(struct dlm_header *hd, int nodeid);
21int dlm_modes_compat(int mode1, int mode2); 21int dlm_modes_compat(int mode1, int mode2);
22int dlm_find_rsb(struct dlm_ls *ls, char *name, int namelen,
23 unsigned int flags, struct dlm_rsb **r_ret);
24void dlm_put_rsb(struct dlm_rsb *r); 22void dlm_put_rsb(struct dlm_rsb *r);
25void dlm_hold_rsb(struct dlm_rsb *r); 23void dlm_hold_rsb(struct dlm_rsb *r);
26int dlm_put_lkb(struct dlm_lkb *lkb); 24int dlm_put_lkb(struct dlm_lkb *lkb);
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c
index 5c108c49cb8c..b180fdc51085 100644
--- a/fs/dlm/lockspace.c
+++ b/fs/dlm/lockspace.c
@@ -24,14 +24,6 @@
24#include "recover.h" 24#include "recover.h"
25#include "requestqueue.h" 25#include "requestqueue.h"
26 26
27#ifdef CONFIG_DLM_DEBUG
28int dlm_create_debug_file(struct dlm_ls *ls);
29void dlm_delete_debug_file(struct dlm_ls *ls);
30#else
31static inline int dlm_create_debug_file(struct dlm_ls *ls) { return 0; }
32static inline void dlm_delete_debug_file(struct dlm_ls *ls) { }
33#endif
34
35static int ls_count; 27static int ls_count;
36static struct mutex ls_lock; 28static struct mutex ls_lock;
37static struct list_head lslist; 29static struct list_head lslist;
@@ -684,9 +676,9 @@ static int release_lockspace(struct dlm_ls *ls, int force)
684 dlm_del_ast(lkb); 676 dlm_del_ast(lkb);
685 677
686 if (lkb->lkb_lvbptr && lkb->lkb_flags & DLM_IFL_MSTCPY) 678 if (lkb->lkb_lvbptr && lkb->lkb_flags & DLM_IFL_MSTCPY)
687 free_lvb(lkb->lkb_lvbptr); 679 dlm_free_lvb(lkb->lkb_lvbptr);
688 680
689 free_lkb(lkb); 681 dlm_free_lkb(lkb);
690 } 682 }
691 } 683 }
692 dlm_astd_resume(); 684 dlm_astd_resume();
@@ -704,7 +696,7 @@ static int release_lockspace(struct dlm_ls *ls, int force)
704 res_hashchain); 696 res_hashchain);
705 697
706 list_del(&rsb->res_hashchain); 698 list_del(&rsb->res_hashchain);
707 free_rsb(rsb); 699 dlm_free_rsb(rsb);
708 } 700 }
709 701
710 head = &ls->ls_rsbtbl[i].toss; 702 head = &ls->ls_rsbtbl[i].toss;
@@ -712,7 +704,7 @@ static int release_lockspace(struct dlm_ls *ls, int force)
712 rsb = list_entry(head->next, struct dlm_rsb, 704 rsb = list_entry(head->next, struct dlm_rsb,
713 res_hashchain); 705 res_hashchain);
714 list_del(&rsb->res_hashchain); 706 list_del(&rsb->res_hashchain);
715 free_rsb(rsb); 707 dlm_free_rsb(rsb);
716 } 708 }
717 } 709 }
718 710
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
index e9923ca9c2d9..7c1e5e5cccd8 100644
--- a/fs/dlm/lowcomms.c
+++ b/fs/dlm/lowcomms.c
@@ -864,7 +864,7 @@ static void sctp_init_assoc(struct connection *con)
864static void tcp_connect_to_sock(struct connection *con) 864static void tcp_connect_to_sock(struct connection *con)
865{ 865{
866 int result = -EHOSTUNREACH; 866 int result = -EHOSTUNREACH;
867 struct sockaddr_storage saddr; 867 struct sockaddr_storage saddr, src_addr;
868 int addr_len; 868 int addr_len;
869 struct socket *sock; 869 struct socket *sock;
870 870
@@ -898,6 +898,17 @@ static void tcp_connect_to_sock(struct connection *con)
898 con->connect_action = tcp_connect_to_sock; 898 con->connect_action = tcp_connect_to_sock;
899 add_sock(sock, con); 899 add_sock(sock, con);
900 900
901 /* Bind to our cluster-known address connecting to avoid
902 routing problems */
903 memcpy(&src_addr, dlm_local_addr[0], sizeof(src_addr));
904 make_sockaddr(&src_addr, 0, &addr_len);
905 result = sock->ops->bind(sock, (struct sockaddr *) &src_addr,
906 addr_len);
907 if (result < 0) {
908 log_print("could not bind for connect: %d", result);
909 /* This *may* not indicate a critical error */
910 }
911
901 make_sockaddr(&saddr, dlm_config.ci_tcp_port, &addr_len); 912 make_sockaddr(&saddr, dlm_config.ci_tcp_port, &addr_len);
902 913
903 log_print("connecting to %d", con->nodeid); 914 log_print("connecting to %d", con->nodeid);
@@ -1426,6 +1437,8 @@ void dlm_lowcomms_stop(void)
1426 con = __nodeid2con(i, 0); 1437 con = __nodeid2con(i, 0);
1427 if (con) { 1438 if (con) {
1428 close_connection(con, true); 1439 close_connection(con, true);
1440 if (con->othercon)
1441 kmem_cache_free(con_cache, con->othercon);
1429 kmem_cache_free(con_cache, con); 1442 kmem_cache_free(con_cache, con);
1430 } 1443 }
1431 } 1444 }
diff --git a/fs/dlm/main.c b/fs/dlm/main.c
index eca2907f2386..58487fb95a4c 100644
--- a/fs/dlm/main.c
+++ b/fs/dlm/main.c
@@ -18,16 +18,6 @@
18#include "memory.h" 18#include "memory.h"
19#include "config.h" 19#include "config.h"
20 20
21#ifdef CONFIG_DLM_DEBUG
22int dlm_register_debugfs(void);
23void dlm_unregister_debugfs(void);
24#else
25static inline int dlm_register_debugfs(void) { return 0; }
26static inline void dlm_unregister_debugfs(void) { }
27#endif
28int dlm_netlink_init(void);
29void dlm_netlink_exit(void);
30
31static int __init init_dlm(void) 21static int __init init_dlm(void)
32{ 22{
33 int error; 23 int error;
diff --git a/fs/dlm/member.c b/fs/dlm/member.c
index e9cdcab306e2..fa17f5a27883 100644
--- a/fs/dlm/member.c
+++ b/fs/dlm/member.c
@@ -1,7 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2******************************************************************************* 2*******************************************************************************
3** 3**
4** Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved. 4** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
5** 5**
6** This copyrighted material is made available to anyone wishing to use, 6** This copyrighted material is made available to anyone wishing to use,
7** modify, copy, or redistribute it subject to the terms and conditions 7** modify, copy, or redistribute it subject to the terms and conditions
@@ -70,7 +70,7 @@ static void dlm_remove_member(struct dlm_ls *ls, struct dlm_member *memb)
70 ls->ls_num_nodes--; 70 ls->ls_num_nodes--;
71} 71}
72 72
73static int dlm_is_member(struct dlm_ls *ls, int nodeid) 73int dlm_is_member(struct dlm_ls *ls, int nodeid)
74{ 74{
75 struct dlm_member *memb; 75 struct dlm_member *memb;
76 76
diff --git a/fs/dlm/member.h b/fs/dlm/member.h
index 927c08c19214..7a26fca1e0b5 100644
--- a/fs/dlm/member.h
+++ b/fs/dlm/member.h
@@ -1,7 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2******************************************************************************* 2*******************************************************************************
3** 3**
4** Copyright (C) 2005 Red Hat, Inc. All rights reserved. 4** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
5** 5**
6** This copyrighted material is made available to anyone wishing to use, 6** This copyrighted material is made available to anyone wishing to use,
7** modify, copy, or redistribute it subject to the terms and conditions 7** modify, copy, or redistribute it subject to the terms and conditions
@@ -19,6 +19,7 @@ void dlm_clear_members(struct dlm_ls *ls);
19void dlm_clear_members_gone(struct dlm_ls *ls); 19void dlm_clear_members_gone(struct dlm_ls *ls);
20int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv,int *neg_out); 20int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv,int *neg_out);
21int dlm_is_removed(struct dlm_ls *ls, int nodeid); 21int dlm_is_removed(struct dlm_ls *ls, int nodeid);
22int dlm_is_member(struct dlm_ls *ls, int nodeid);
22 23
23#endif /* __MEMBER_DOT_H__ */ 24#endif /* __MEMBER_DOT_H__ */
24 25
diff --git a/fs/dlm/memory.c b/fs/dlm/memory.c
index ecf0e5cb2035..f7783867491a 100644
--- a/fs/dlm/memory.c
+++ b/fs/dlm/memory.c
@@ -2,7 +2,7 @@
2******************************************************************************* 2*******************************************************************************
3** 3**
4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
5** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. 5** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
6** 6**
7** This copyrighted material is made available to anyone wishing to use, 7** This copyrighted material is made available to anyone wishing to use,
8** modify, copy, or redistribute it subject to the terms and conditions 8** modify, copy, or redistribute it subject to the terms and conditions
@@ -35,7 +35,7 @@ void dlm_memory_exit(void)
35 kmem_cache_destroy(lkb_cache); 35 kmem_cache_destroy(lkb_cache);
36} 36}
37 37
38char *allocate_lvb(struct dlm_ls *ls) 38char *dlm_allocate_lvb(struct dlm_ls *ls)
39{ 39{
40 char *p; 40 char *p;
41 41
@@ -43,7 +43,7 @@ char *allocate_lvb(struct dlm_ls *ls)
43 return p; 43 return p;
44} 44}
45 45
46void free_lvb(char *p) 46void dlm_free_lvb(char *p)
47{ 47{
48 kfree(p); 48 kfree(p);
49} 49}
@@ -51,7 +51,7 @@ void free_lvb(char *p)
51/* FIXME: have some minimal space built-in to rsb for the name and 51/* FIXME: have some minimal space built-in to rsb for the name and
52 kmalloc a separate name if needed, like dentries are done */ 52 kmalloc a separate name if needed, like dentries are done */
53 53
54struct dlm_rsb *allocate_rsb(struct dlm_ls *ls, int namelen) 54struct dlm_rsb *dlm_allocate_rsb(struct dlm_ls *ls, int namelen)
55{ 55{
56 struct dlm_rsb *r; 56 struct dlm_rsb *r;
57 57
@@ -61,14 +61,14 @@ struct dlm_rsb *allocate_rsb(struct dlm_ls *ls, int namelen)
61 return r; 61 return r;
62} 62}
63 63
64void free_rsb(struct dlm_rsb *r) 64void dlm_free_rsb(struct dlm_rsb *r)
65{ 65{
66 if (r->res_lvbptr) 66 if (r->res_lvbptr)
67 free_lvb(r->res_lvbptr); 67 dlm_free_lvb(r->res_lvbptr);
68 kfree(r); 68 kfree(r);
69} 69}
70 70
71struct dlm_lkb *allocate_lkb(struct dlm_ls *ls) 71struct dlm_lkb *dlm_allocate_lkb(struct dlm_ls *ls)
72{ 72{
73 struct dlm_lkb *lkb; 73 struct dlm_lkb *lkb;
74 74
@@ -76,7 +76,7 @@ struct dlm_lkb *allocate_lkb(struct dlm_ls *ls)
76 return lkb; 76 return lkb;
77} 77}
78 78
79void free_lkb(struct dlm_lkb *lkb) 79void dlm_free_lkb(struct dlm_lkb *lkb)
80{ 80{
81 if (lkb->lkb_flags & DLM_IFL_USER) { 81 if (lkb->lkb_flags & DLM_IFL_USER) {
82 struct dlm_user_args *ua; 82 struct dlm_user_args *ua;
@@ -90,19 +90,3 @@ void free_lkb(struct dlm_lkb *lkb)
90 kmem_cache_free(lkb_cache, lkb); 90 kmem_cache_free(lkb_cache, lkb);
91} 91}
92 92
93struct dlm_direntry *allocate_direntry(struct dlm_ls *ls, int namelen)
94{
95 struct dlm_direntry *de;
96
97 DLM_ASSERT(namelen <= DLM_RESNAME_MAXLEN,
98 printk("namelen = %d\n", namelen););
99
100 de = kzalloc(sizeof(*de) + namelen, GFP_KERNEL);
101 return de;
102}
103
104void free_direntry(struct dlm_direntry *de)
105{
106 kfree(de);
107}
108
diff --git a/fs/dlm/memory.h b/fs/dlm/memory.h
index 6ead158ccc5c..485fb29143bd 100644
--- a/fs/dlm/memory.h
+++ b/fs/dlm/memory.h
@@ -2,7 +2,7 @@
2******************************************************************************* 2*******************************************************************************
3** 3**
4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
5** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. 5** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
6** 6**
7** This copyrighted material is made available to anyone wishing to use, 7** This copyrighted material is made available to anyone wishing to use,
8** modify, copy, or redistribute it subject to the terms and conditions 8** modify, copy, or redistribute it subject to the terms and conditions
@@ -16,14 +16,12 @@
16 16
17int dlm_memory_init(void); 17int dlm_memory_init(void);
18void dlm_memory_exit(void); 18void dlm_memory_exit(void);
19struct dlm_rsb *allocate_rsb(struct dlm_ls *ls, int namelen); 19struct dlm_rsb *dlm_allocate_rsb(struct dlm_ls *ls, int namelen);
20void free_rsb(struct dlm_rsb *r); 20void dlm_free_rsb(struct dlm_rsb *r);
21struct dlm_lkb *allocate_lkb(struct dlm_ls *ls); 21struct dlm_lkb *dlm_allocate_lkb(struct dlm_ls *ls);
22void free_lkb(struct dlm_lkb *l); 22void dlm_free_lkb(struct dlm_lkb *l);
23struct dlm_direntry *allocate_direntry(struct dlm_ls *ls, int namelen); 23char *dlm_allocate_lvb(struct dlm_ls *ls);
24void free_direntry(struct dlm_direntry *de); 24void dlm_free_lvb(char *l);
25char *allocate_lvb(struct dlm_ls *ls);
26void free_lvb(char *l);
27 25
28#endif /* __MEMORY_DOT_H__ */ 26#endif /* __MEMORY_DOT_H__ */
29 27
diff --git a/fs/dlm/midcomms.c b/fs/dlm/midcomms.c
index f8c69dda16a0..e69926e984db 100644
--- a/fs/dlm/midcomms.c
+++ b/fs/dlm/midcomms.c
@@ -2,7 +2,7 @@
2******************************************************************************* 2*******************************************************************************
3** 3**
4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
5** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. 5** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
6** 6**
7** This copyrighted material is made available to anyone wishing to use, 7** This copyrighted material is made available to anyone wishing to use,
8** modify, copy, or redistribute it subject to the terms and conditions 8** modify, copy, or redistribute it subject to the terms and conditions
@@ -58,8 +58,12 @@ static void copy_from_cb(void *dst, const void *base, unsigned offset,
58int dlm_process_incoming_buffer(int nodeid, const void *base, 58int dlm_process_incoming_buffer(int nodeid, const void *base,
59 unsigned offset, unsigned len, unsigned limit) 59 unsigned offset, unsigned len, unsigned limit)
60{ 60{
61 unsigned char __tmp[DLM_INBUF_LEN]; 61 union {
62 struct dlm_header *msg = (struct dlm_header *) __tmp; 62 unsigned char __buf[DLM_INBUF_LEN];
63 /* this is to force proper alignment on some arches */
64 struct dlm_header dlm;
65 } __tmp;
66 struct dlm_header *msg = &__tmp.dlm;
63 int ret = 0; 67 int ret = 0;
64 int err = 0; 68 int err = 0;
65 uint16_t msglen; 69 uint16_t msglen;
@@ -100,8 +104,7 @@ int dlm_process_incoming_buffer(int nodeid, const void *base,
100 in the buffer on the stack (which should work for most 104 in the buffer on the stack (which should work for most
101 ordinary messages). */ 105 ordinary messages). */
102 106
103 if (msglen > sizeof(__tmp) && 107 if (msglen > DLM_INBUF_LEN && msg == &__tmp.dlm) {
104 msg == (struct dlm_header *) __tmp) {
105 msg = kmalloc(dlm_config.ci_buffer_size, GFP_KERNEL); 108 msg = kmalloc(dlm_config.ci_buffer_size, GFP_KERNEL);
106 if (msg == NULL) 109 if (msg == NULL)
107 return ret; 110 return ret;
@@ -119,7 +122,7 @@ int dlm_process_incoming_buffer(int nodeid, const void *base,
119 dlm_receive_buffer(msg, nodeid); 122 dlm_receive_buffer(msg, nodeid);
120 } 123 }
121 124
122 if (msg != (struct dlm_header *) __tmp) 125 if (msg != &__tmp.dlm)
123 kfree(msg); 126 kfree(msg);
124 127
125 return err ? err : ret; 128 return err ? err : ret;
diff --git a/fs/dlm/rcom.c b/fs/dlm/rcom.c
index ae2fd97fa4ad..026824cd3acb 100644
--- a/fs/dlm/rcom.c
+++ b/fs/dlm/rcom.c
@@ -2,7 +2,7 @@
2******************************************************************************* 2*******************************************************************************
3** 3**
4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
5** Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved. 5** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
6** 6**
7** This copyrighted material is made available to anyone wishing to use, 7** This copyrighted material is made available to anyone wishing to use,
8** modify, copy, or redistribute it subject to the terms and conditions 8** modify, copy, or redistribute it subject to the terms and conditions
@@ -197,11 +197,6 @@ static void receive_sync_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in)
197 spin_unlock(&ls->ls_rcom_spin); 197 spin_unlock(&ls->ls_rcom_spin);
198} 198}
199 199
200static void receive_rcom_status_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in)
201{
202 receive_sync_reply(ls, rc_in);
203}
204
205int dlm_rcom_names(struct dlm_ls *ls, int nodeid, char *last_name, int last_len) 200int dlm_rcom_names(struct dlm_ls *ls, int nodeid, char *last_name, int last_len)
206{ 201{
207 struct dlm_rcom *rc; 202 struct dlm_rcom *rc;
@@ -254,11 +249,6 @@ static void receive_rcom_names(struct dlm_ls *ls, struct dlm_rcom *rc_in)
254 send_rcom(ls, mh, rc); 249 send_rcom(ls, mh, rc);
255} 250}
256 251
257static void receive_rcom_names_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in)
258{
259 receive_sync_reply(ls, rc_in);
260}
261
262int dlm_send_rcom_lookup(struct dlm_rsb *r, int dir_nodeid) 252int dlm_send_rcom_lookup(struct dlm_rsb *r, int dir_nodeid)
263{ 253{
264 struct dlm_rcom *rc; 254 struct dlm_rcom *rc;
@@ -381,11 +371,6 @@ static void receive_rcom_lock(struct dlm_ls *ls, struct dlm_rcom *rc_in)
381 send_rcom(ls, mh, rc); 371 send_rcom(ls, mh, rc);
382} 372}
383 373
384static void receive_rcom_lock_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in)
385{
386 dlm_recover_process_copy(ls, rc_in);
387}
388
389/* If the lockspace doesn't exist then still send a status message 374/* If the lockspace doesn't exist then still send a status message
390 back; it's possible that it just doesn't have its global_id yet. */ 375 back; it's possible that it just doesn't have its global_id yet. */
391 376
@@ -481,11 +466,11 @@ void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
481 break; 466 break;
482 467
483 case DLM_RCOM_STATUS_REPLY: 468 case DLM_RCOM_STATUS_REPLY:
484 receive_rcom_status_reply(ls, rc); 469 receive_sync_reply(ls, rc);
485 break; 470 break;
486 471
487 case DLM_RCOM_NAMES_REPLY: 472 case DLM_RCOM_NAMES_REPLY:
488 receive_rcom_names_reply(ls, rc); 473 receive_sync_reply(ls, rc);
489 break; 474 break;
490 475
491 case DLM_RCOM_LOOKUP_REPLY: 476 case DLM_RCOM_LOOKUP_REPLY:
@@ -493,11 +478,11 @@ void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
493 break; 478 break;
494 479
495 case DLM_RCOM_LOCK_REPLY: 480 case DLM_RCOM_LOCK_REPLY:
496 receive_rcom_lock_reply(ls, rc); 481 dlm_recover_process_copy(ls, rc);
497 break; 482 break;
498 483
499 default: 484 default:
500 DLM_ASSERT(0, printk("rc_type=%x\n", rc->rc_type);); 485 log_error(ls, "receive_rcom bad type %d", rc->rc_type);
501 } 486 }
502 out: 487 out:
503 return; 488 return;
diff --git a/fs/dlm/recover.c b/fs/dlm/recover.c
index c2cc7694cd16..df075dc300fa 100644
--- a/fs/dlm/recover.c
+++ b/fs/dlm/recover.c
@@ -629,7 +629,7 @@ static void recover_lvb(struct dlm_rsb *r)
629 goto out; 629 goto out;
630 630
631 if (!r->res_lvbptr) { 631 if (!r->res_lvbptr) {
632 r->res_lvbptr = allocate_lvb(r->res_ls); 632 r->res_lvbptr = dlm_allocate_lvb(r->res_ls);
633 if (!r->res_lvbptr) 633 if (!r->res_lvbptr)
634 goto out; 634 goto out;
635 } 635 }
@@ -731,6 +731,20 @@ int dlm_create_root_list(struct dlm_ls *ls)
731 list_add(&r->res_root_list, &ls->ls_root_list); 731 list_add(&r->res_root_list, &ls->ls_root_list);
732 dlm_hold_rsb(r); 732 dlm_hold_rsb(r);
733 } 733 }
734
735 /* If we're using a directory, add tossed rsbs to the root
736 list; they'll have entries created in the new directory,
737 but no other recovery steps should do anything with them. */
738
739 if (dlm_no_directory(ls)) {
740 read_unlock(&ls->ls_rsbtbl[i].lock);
741 continue;
742 }
743
744 list_for_each_entry(r, &ls->ls_rsbtbl[i].toss, res_hashchain) {
745 list_add(&r->res_root_list, &ls->ls_root_list);
746 dlm_hold_rsb(r);
747 }
734 read_unlock(&ls->ls_rsbtbl[i].lock); 748 read_unlock(&ls->ls_rsbtbl[i].lock);
735 } 749 }
736 out: 750 out:
@@ -750,6 +764,11 @@ void dlm_release_root_list(struct dlm_ls *ls)
750 up_write(&ls->ls_root_sem); 764 up_write(&ls->ls_root_sem);
751} 765}
752 766
767/* If not using a directory, clear the entire toss list, there's no benefit to
768 caching the master value since it's fixed. If we are using a dir, keep the
769 rsb's we're the master of. Recovery will add them to the root list and from
770 there they'll be entered in the rebuilt directory. */
771
753void dlm_clear_toss_list(struct dlm_ls *ls) 772void dlm_clear_toss_list(struct dlm_ls *ls)
754{ 773{
755 struct dlm_rsb *r, *safe; 774 struct dlm_rsb *r, *safe;
@@ -759,8 +778,10 @@ void dlm_clear_toss_list(struct dlm_ls *ls)
759 write_lock(&ls->ls_rsbtbl[i].lock); 778 write_lock(&ls->ls_rsbtbl[i].lock);
760 list_for_each_entry_safe(r, safe, &ls->ls_rsbtbl[i].toss, 779 list_for_each_entry_safe(r, safe, &ls->ls_rsbtbl[i].toss,
761 res_hashchain) { 780 res_hashchain) {
762 list_del(&r->res_hashchain); 781 if (dlm_no_directory(ls) || !is_master(r)) {
763 free_rsb(r); 782 list_del(&r->res_hashchain);
783 dlm_free_rsb(r);
784 }
764 } 785 }
765 write_unlock(&ls->ls_rsbtbl[i].lock); 786 write_unlock(&ls->ls_rsbtbl[i].lock);
766 } 787 }
diff --git a/fs/dlm/recoverd.c b/fs/dlm/recoverd.c
index 4b89e20eebe7..997f9531d594 100644
--- a/fs/dlm/recoverd.c
+++ b/fs/dlm/recoverd.c
@@ -67,17 +67,18 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
67 dlm_astd_resume(); 67 dlm_astd_resume();
68 68
69 /* 69 /*
70 * This list of root rsb's will be the basis of most of the recovery 70 * Free non-master tossed rsb's. Master rsb's are kept on toss
71 * routines. 71 * list and put on root list to be included in resdir recovery.
72 */ 72 */
73 73
74 dlm_create_root_list(ls); 74 dlm_clear_toss_list(ls);
75 75
76 /* 76 /*
77 * Free all the tossed rsb's so we don't have to recover them. 77 * This list of root rsb's will be the basis of most of the recovery
78 * routines.
78 */ 79 */
79 80
80 dlm_clear_toss_list(ls); 81 dlm_create_root_list(ls);
81 82
82 /* 83 /*
83 * Add or remove nodes from the lockspace's ls_nodes list. 84 * Add or remove nodes from the lockspace's ls_nodes list.
diff --git a/fs/dlm/user.c b/fs/dlm/user.c
index 4f741546f4bb..7cbc6826239b 100644
--- a/fs/dlm/user.c
+++ b/fs/dlm/user.c
@@ -24,8 +24,7 @@
24#include "lvb_table.h" 24#include "lvb_table.h"
25#include "user.h" 25#include "user.h"
26 26
27static const char *name_prefix="dlm"; 27static const char name_prefix[] = "dlm";
28static struct miscdevice ctl_device;
29static const struct file_operations device_fops; 28static const struct file_operations device_fops;
30 29
31#ifdef CONFIG_COMPAT 30#ifdef CONFIG_COMPAT
@@ -82,7 +81,8 @@ struct dlm_lock_result32 {
82}; 81};
83 82
84static void compat_input(struct dlm_write_request *kb, 83static void compat_input(struct dlm_write_request *kb,
85 struct dlm_write_request32 *kb32) 84 struct dlm_write_request32 *kb32,
85 int max_namelen)
86{ 86{
87 kb->version[0] = kb32->version[0]; 87 kb->version[0] = kb32->version[0];
88 kb->version[1] = kb32->version[1]; 88 kb->version[1] = kb32->version[1];
@@ -112,7 +112,11 @@ static void compat_input(struct dlm_write_request *kb,
112 kb->i.lock.bastaddr = (void *)(long)kb32->i.lock.bastaddr; 112 kb->i.lock.bastaddr = (void *)(long)kb32->i.lock.bastaddr;
113 kb->i.lock.lksb = (void *)(long)kb32->i.lock.lksb; 113 kb->i.lock.lksb = (void *)(long)kb32->i.lock.lksb;
114 memcpy(kb->i.lock.lvb, kb32->i.lock.lvb, DLM_USER_LVB_LEN); 114 memcpy(kb->i.lock.lvb, kb32->i.lock.lvb, DLM_USER_LVB_LEN);
115 memcpy(kb->i.lock.name, kb32->i.lock.name, kb->i.lock.namelen); 115 if (kb->i.lock.namelen <= max_namelen)
116 memcpy(kb->i.lock.name, kb32->i.lock.name,
117 kb->i.lock.namelen);
118 else
119 kb->i.lock.namelen = max_namelen;
116 } 120 }
117} 121}
118 122
@@ -236,12 +240,12 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type)
236 spin_unlock(&proc->asts_spin); 240 spin_unlock(&proc->asts_spin);
237 241
238 if (eol) { 242 if (eol) {
239 spin_lock(&ua->proc->locks_spin); 243 spin_lock(&proc->locks_spin);
240 if (!list_empty(&lkb->lkb_ownqueue)) { 244 if (!list_empty(&lkb->lkb_ownqueue)) {
241 list_del_init(&lkb->lkb_ownqueue); 245 list_del_init(&lkb->lkb_ownqueue);
242 dlm_put_lkb(lkb); 246 dlm_put_lkb(lkb);
243 } 247 }
244 spin_unlock(&ua->proc->locks_spin); 248 spin_unlock(&proc->locks_spin);
245 } 249 }
246 out: 250 out:
247 mutex_unlock(&ls->ls_clear_proc_locks); 251 mutex_unlock(&ls->ls_clear_proc_locks);
@@ -529,7 +533,8 @@ static ssize_t device_write(struct file *file, const char __user *buf,
529 533
530 if (proc) 534 if (proc)
531 set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags); 535 set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags);
532 compat_input(kbuf, k32buf); 536 compat_input(kbuf, k32buf,
537 count - sizeof(struct dlm_write_request32));
533 kfree(k32buf); 538 kfree(k32buf);
534 } 539 }
535#endif 540#endif
@@ -896,14 +901,16 @@ static const struct file_operations ctl_device_fops = {
896 .owner = THIS_MODULE, 901 .owner = THIS_MODULE,
897}; 902};
898 903
904static struct miscdevice ctl_device = {
905 .name = "dlm-control",
906 .fops = &ctl_device_fops,
907 .minor = MISC_DYNAMIC_MINOR,
908};
909
899int dlm_user_init(void) 910int dlm_user_init(void)
900{ 911{
901 int error; 912 int error;
902 913
903 ctl_device.name = "dlm-control";
904 ctl_device.fops = &ctl_device_fops;
905 ctl_device.minor = MISC_DYNAMIC_MINOR;
906
907 error = misc_register(&ctl_device); 914 error = misc_register(&ctl_device);
908 if (error) 915 if (error)
909 log_print("misc_register failed for control device"); 916 log_print("misc_register failed for control device");
diff --git a/fs/dlm/util.c b/fs/dlm/util.c
index 963889cf6740..4d9c1f4e1bd1 100644
--- a/fs/dlm/util.c
+++ b/fs/dlm/util.c
@@ -1,7 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2******************************************************************************* 2*******************************************************************************
3** 3**
4** Copyright (C) 2005 Red Hat, Inc. All rights reserved. 4** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
5** 5**
6** This copyrighted material is made available to anyone wishing to use, 6** This copyrighted material is made available to anyone wishing to use,
7** modify, copy, or redistribute it subject to the terms and conditions 7** modify, copy, or redistribute it subject to the terms and conditions
@@ -14,6 +14,14 @@
14#include "rcom.h" 14#include "rcom.h"
15#include "util.h" 15#include "util.h"
16 16
17#define DLM_ERRNO_EDEADLK 35
18#define DLM_ERRNO_EBADR 53
19#define DLM_ERRNO_EBADSLT 57
20#define DLM_ERRNO_EPROTO 71
21#define DLM_ERRNO_EOPNOTSUPP 95
22#define DLM_ERRNO_ETIMEDOUT 110
23#define DLM_ERRNO_EINPROGRESS 115
24
17static void header_out(struct dlm_header *hd) 25static void header_out(struct dlm_header *hd)
18{ 26{
19 hd->h_version = cpu_to_le32(hd->h_version); 27 hd->h_version = cpu_to_le32(hd->h_version);
@@ -30,11 +38,54 @@ static void header_in(struct dlm_header *hd)
30 hd->h_length = le16_to_cpu(hd->h_length); 38 hd->h_length = le16_to_cpu(hd->h_length);
31} 39}
32 40
33void dlm_message_out(struct dlm_message *ms) 41/* higher errno values are inconsistent across architectures, so select
42 one set of values for on the wire */
43
44static int to_dlm_errno(int err)
45{
46 switch (err) {
47 case -EDEADLK:
48 return -DLM_ERRNO_EDEADLK;
49 case -EBADR:
50 return -DLM_ERRNO_EBADR;
51 case -EBADSLT:
52 return -DLM_ERRNO_EBADSLT;
53 case -EPROTO:
54 return -DLM_ERRNO_EPROTO;
55 case -EOPNOTSUPP:
56 return -DLM_ERRNO_EOPNOTSUPP;
57 case -ETIMEDOUT:
58 return -DLM_ERRNO_ETIMEDOUT;
59 case -EINPROGRESS:
60 return -DLM_ERRNO_EINPROGRESS;
61 }
62 return err;
63}
64
65static int from_dlm_errno(int err)
34{ 66{
35 struct dlm_header *hd = (struct dlm_header *) ms; 67 switch (err) {
68 case -DLM_ERRNO_EDEADLK:
69 return -EDEADLK;
70 case -DLM_ERRNO_EBADR:
71 return -EBADR;
72 case -DLM_ERRNO_EBADSLT:
73 return -EBADSLT;
74 case -DLM_ERRNO_EPROTO:
75 return -EPROTO;
76 case -DLM_ERRNO_EOPNOTSUPP:
77 return -EOPNOTSUPP;
78 case -DLM_ERRNO_ETIMEDOUT:
79 return -ETIMEDOUT;
80 case -DLM_ERRNO_EINPROGRESS:
81 return -EINPROGRESS;
82 }
83 return err;
84}
36 85
37 header_out(hd); 86void dlm_message_out(struct dlm_message *ms)
87{
88 header_out(&ms->m_header);
38 89
39 ms->m_type = cpu_to_le32(ms->m_type); 90 ms->m_type = cpu_to_le32(ms->m_type);
40 ms->m_nodeid = cpu_to_le32(ms->m_nodeid); 91 ms->m_nodeid = cpu_to_le32(ms->m_nodeid);
@@ -53,14 +104,12 @@ void dlm_message_out(struct dlm_message *ms)
53 ms->m_rqmode = cpu_to_le32(ms->m_rqmode); 104 ms->m_rqmode = cpu_to_le32(ms->m_rqmode);
54 ms->m_bastmode = cpu_to_le32(ms->m_bastmode); 105 ms->m_bastmode = cpu_to_le32(ms->m_bastmode);
55 ms->m_asts = cpu_to_le32(ms->m_asts); 106 ms->m_asts = cpu_to_le32(ms->m_asts);
56 ms->m_result = cpu_to_le32(ms->m_result); 107 ms->m_result = cpu_to_le32(to_dlm_errno(ms->m_result));
57} 108}
58 109
59void dlm_message_in(struct dlm_message *ms) 110void dlm_message_in(struct dlm_message *ms)
60{ 111{
61 struct dlm_header *hd = (struct dlm_header *) ms; 112 header_in(&ms->m_header);
62
63 header_in(hd);
64 113
65 ms->m_type = le32_to_cpu(ms->m_type); 114 ms->m_type = le32_to_cpu(ms->m_type);
66 ms->m_nodeid = le32_to_cpu(ms->m_nodeid); 115 ms->m_nodeid = le32_to_cpu(ms->m_nodeid);
@@ -79,7 +128,7 @@ void dlm_message_in(struct dlm_message *ms)
79 ms->m_rqmode = le32_to_cpu(ms->m_rqmode); 128 ms->m_rqmode = le32_to_cpu(ms->m_rqmode);
80 ms->m_bastmode = le32_to_cpu(ms->m_bastmode); 129 ms->m_bastmode = le32_to_cpu(ms->m_bastmode);
81 ms->m_asts = le32_to_cpu(ms->m_asts); 130 ms->m_asts = le32_to_cpu(ms->m_asts);
82 ms->m_result = le32_to_cpu(ms->m_result); 131 ms->m_result = from_dlm_errno(le32_to_cpu(ms->m_result));
83} 132}
84 133
85static void rcom_lock_out(struct rcom_lock *rl) 134static void rcom_lock_out(struct rcom_lock *rl)
@@ -126,10 +175,9 @@ static void rcom_config_in(struct rcom_config *rf)
126 175
127void dlm_rcom_out(struct dlm_rcom *rc) 176void dlm_rcom_out(struct dlm_rcom *rc)
128{ 177{
129 struct dlm_header *hd = (struct dlm_header *) rc;
130 int type = rc->rc_type; 178 int type = rc->rc_type;
131 179
132 header_out(hd); 180 header_out(&rc->rc_header);
133 181
134 rc->rc_type = cpu_to_le32(rc->rc_type); 182 rc->rc_type = cpu_to_le32(rc->rc_type);
135 rc->rc_result = cpu_to_le32(rc->rc_result); 183 rc->rc_result = cpu_to_le32(rc->rc_result);
@@ -137,7 +185,7 @@ void dlm_rcom_out(struct dlm_rcom *rc)
137 rc->rc_seq = cpu_to_le64(rc->rc_seq); 185 rc->rc_seq = cpu_to_le64(rc->rc_seq);
138 rc->rc_seq_reply = cpu_to_le64(rc->rc_seq_reply); 186 rc->rc_seq_reply = cpu_to_le64(rc->rc_seq_reply);
139 187
140 if (type == DLM_RCOM_LOCK) 188 if ((type == DLM_RCOM_LOCK) || (type == DLM_RCOM_LOCK_REPLY))
141 rcom_lock_out((struct rcom_lock *) rc->rc_buf); 189 rcom_lock_out((struct rcom_lock *) rc->rc_buf);
142 190
143 else if (type == DLM_RCOM_STATUS_REPLY) 191 else if (type == DLM_RCOM_STATUS_REPLY)
@@ -146,9 +194,9 @@ void dlm_rcom_out(struct dlm_rcom *rc)
146 194
147void dlm_rcom_in(struct dlm_rcom *rc) 195void dlm_rcom_in(struct dlm_rcom *rc)
148{ 196{
149 struct dlm_header *hd = (struct dlm_header *) rc; 197 int type;
150 198
151 header_in(hd); 199 header_in(&rc->rc_header);
152 200
153 rc->rc_type = le32_to_cpu(rc->rc_type); 201 rc->rc_type = le32_to_cpu(rc->rc_type);
154 rc->rc_result = le32_to_cpu(rc->rc_result); 202 rc->rc_result = le32_to_cpu(rc->rc_result);
@@ -156,10 +204,12 @@ void dlm_rcom_in(struct dlm_rcom *rc)
156 rc->rc_seq = le64_to_cpu(rc->rc_seq); 204 rc->rc_seq = le64_to_cpu(rc->rc_seq);
157 rc->rc_seq_reply = le64_to_cpu(rc->rc_seq_reply); 205 rc->rc_seq_reply = le64_to_cpu(rc->rc_seq_reply);
158 206
159 if (rc->rc_type == DLM_RCOM_LOCK) 207 type = rc->rc_type;
208
209 if ((type == DLM_RCOM_LOCK) || (type == DLM_RCOM_LOCK_REPLY))
160 rcom_lock_in((struct rcom_lock *) rc->rc_buf); 210 rcom_lock_in((struct rcom_lock *) rc->rc_buf);
161 211
162 else if (rc->rc_type == DLM_RCOM_STATUS_REPLY) 212 else if (type == DLM_RCOM_STATUS_REPLY)
163 rcom_config_in((struct rcom_config *) rc->rc_buf); 213 rcom_config_in((struct rcom_config *) rc->rc_buf);
164} 214}
165 215