diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-08 12:33:02 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-08 12:33:02 -0500 |
commit | b5eb9513f7c1bee862ada22bf1489f53752686bd (patch) | |
tree | 707404a45b1ca8809fa8607c5d9d96ca9c657db7 /fs | |
parent | dde0013782dbd09e1cc68ca03860f3a62b03cb34 (diff) | |
parent | 30727174b6273c67fa96fb818fe5bdde1ad70e5c (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:
dlm: add __init and __exit marks to init and exit functions
dlm: eliminate astparam type casting
dlm: proper types for asts and basts
dlm: dlm/user.c input validation fixes
dlm: fix dlm_dir_lookup() handling of too long names
dlm: fix overflows when copying from ->m_extra to lvb
dlm: make find_rsb() fail gracefully when namelen is too large
dlm: receive_rcom_lock_args() overflow check
dlm: verify that places expecting rcom_lock have packet long enough
dlm: validate data in dlm_recover_directory()
dlm: missing length check in check_config()
dlm: use proper type for ->ls_recover_buf
dlm: do not byteswap rcom_config
dlm: do not byteswap rcom_lock
dlm: dlm_process_incoming_buffer() fixes
dlm: use proper C for dlm/requestqueue stuff (and fix alignment bug)
Diffstat (limited to 'fs')
-rw-r--r-- | fs/dlm/ast.c | 9 | ||||
-rw-r--r-- | fs/dlm/config.c | 2 | ||||
-rw-r--r-- | fs/dlm/debug_fs.c | 8 | ||||
-rw-r--r-- | fs/dlm/dir.c | 28 | ||||
-rw-r--r-- | fs/dlm/dlm_internal.h | 53 | ||||
-rw-r--r-- | fs/dlm/lock.c | 139 | ||||
-rw-r--r-- | fs/dlm/lock.h | 2 | ||||
-rw-r--r-- | fs/dlm/lockspace.c | 2 | ||||
-rw-r--r-- | fs/dlm/memory.c | 4 | ||||
-rw-r--r-- | fs/dlm/midcomms.c | 33 | ||||
-rw-r--r-- | fs/dlm/netlink.c | 9 | ||||
-rw-r--r-- | fs/dlm/rcom.c | 63 | ||||
-rw-r--r-- | fs/dlm/recover.c | 4 | ||||
-rw-r--r-- | fs/dlm/requestqueue.c | 12 | ||||
-rw-r--r-- | fs/dlm/requestqueue.h | 2 | ||||
-rw-r--r-- | fs/dlm/user.c | 29 | ||||
-rw-r--r-- | fs/dlm/util.c | 61 |
17 files changed, 235 insertions, 225 deletions
diff --git a/fs/dlm/ast.c b/fs/dlm/ast.c index 6308122890ca..8bf31e3fbf01 100644 --- a/fs/dlm/ast.c +++ b/fs/dlm/ast.c | |||
@@ -39,7 +39,6 @@ void dlm_add_ast(struct dlm_lkb *lkb, int type) | |||
39 | dlm_user_add_ast(lkb, type); | 39 | dlm_user_add_ast(lkb, type); |
40 | return; | 40 | return; |
41 | } | 41 | } |
42 | DLM_ASSERT(lkb->lkb_astaddr != DLM_FAKE_USER_AST, dlm_print_lkb(lkb);); | ||
43 | 42 | ||
44 | spin_lock(&ast_queue_lock); | 43 | spin_lock(&ast_queue_lock); |
45 | if (!(lkb->lkb_ast_type & (AST_COMP | AST_BAST))) { | 44 | if (!(lkb->lkb_ast_type & (AST_COMP | AST_BAST))) { |
@@ -58,8 +57,8 @@ static void process_asts(void) | |||
58 | struct dlm_ls *ls = NULL; | 57 | struct dlm_ls *ls = NULL; |
59 | struct dlm_rsb *r = NULL; | 58 | struct dlm_rsb *r = NULL; |
60 | struct dlm_lkb *lkb; | 59 | struct dlm_lkb *lkb; |
61 | void (*cast) (long param); | 60 | void (*cast) (void *astparam); |
62 | void (*bast) (long param, int mode); | 61 | void (*bast) (void *astparam, int mode); |
63 | int type = 0, found, bmode; | 62 | int type = 0, found, bmode; |
64 | 63 | ||
65 | for (;;) { | 64 | for (;;) { |
@@ -83,8 +82,8 @@ static void process_asts(void) | |||
83 | if (!found) | 82 | if (!found) |
84 | break; | 83 | break; |
85 | 84 | ||
86 | cast = lkb->lkb_astaddr; | 85 | cast = lkb->lkb_astfn; |
87 | bast = lkb->lkb_bastaddr; | 86 | bast = lkb->lkb_bastfn; |
88 | bmode = lkb->lkb_bastmode; | 87 | bmode = lkb->lkb_bastmode; |
89 | 88 | ||
90 | if ((type & AST_COMP) && cast) | 89 | if ((type & AST_COMP) && cast) |
diff --git a/fs/dlm/config.c b/fs/dlm/config.c index 2f8e3c81bc19..c3ad1dff3b25 100644 --- a/fs/dlm/config.c +++ b/fs/dlm/config.c | |||
@@ -604,7 +604,7 @@ static struct clusters clusters_root = { | |||
604 | }, | 604 | }, |
605 | }; | 605 | }; |
606 | 606 | ||
607 | int dlm_config_init(void) | 607 | int __init dlm_config_init(void) |
608 | { | 608 | { |
609 | config_group_init(&clusters_root.subsys.su_group); | 609 | config_group_init(&clusters_root.subsys.su_group); |
610 | mutex_init(&clusters_root.subsys.su_mutex); | 610 | mutex_init(&clusters_root.subsys.su_mutex); |
diff --git a/fs/dlm/debug_fs.c b/fs/dlm/debug_fs.c index 12c3bfd5e660..8fc24f4507a3 100644 --- a/fs/dlm/debug_fs.c +++ b/fs/dlm/debug_fs.c | |||
@@ -162,14 +162,12 @@ static int print_resource(struct dlm_rsb *res, struct seq_file *s) | |||
162 | 162 | ||
163 | static void print_lock(struct seq_file *s, struct dlm_lkb *lkb, struct dlm_rsb *r) | 163 | static void print_lock(struct seq_file *s, struct dlm_lkb *lkb, struct dlm_rsb *r) |
164 | { | 164 | { |
165 | struct dlm_user_args *ua; | ||
166 | unsigned int waiting = 0; | 165 | unsigned int waiting = 0; |
167 | uint64_t xid = 0; | 166 | uint64_t xid = 0; |
168 | 167 | ||
169 | if (lkb->lkb_flags & DLM_IFL_USER) { | 168 | if (lkb->lkb_flags & DLM_IFL_USER) { |
170 | ua = (struct dlm_user_args *) lkb->lkb_astparam; | 169 | if (lkb->lkb_ua) |
171 | if (ua) | 170 | xid = lkb->lkb_ua->xid; |
172 | xid = ua->xid; | ||
173 | } | 171 | } |
174 | 172 | ||
175 | if (lkb->lkb_timestamp) | 173 | if (lkb->lkb_timestamp) |
@@ -543,7 +541,7 @@ void dlm_delete_debug_file(struct dlm_ls *ls) | |||
543 | debugfs_remove(ls->ls_debug_locks_dentry); | 541 | debugfs_remove(ls->ls_debug_locks_dentry); |
544 | } | 542 | } |
545 | 543 | ||
546 | int dlm_register_debugfs(void) | 544 | int __init dlm_register_debugfs(void) |
547 | { | 545 | { |
548 | mutex_init(&debug_buf_lock); | 546 | mutex_init(&debug_buf_lock); |
549 | dlm_root = debugfs_create_dir("dlm", NULL); | 547 | dlm_root = debugfs_create_dir("dlm", NULL); |
diff --git a/fs/dlm/dir.c b/fs/dlm/dir.c index ff97ba924333..85defeb64df4 100644 --- a/fs/dlm/dir.c +++ b/fs/dlm/dir.c | |||
@@ -220,6 +220,7 @@ int dlm_recover_directory(struct dlm_ls *ls) | |||
220 | last_len = 0; | 220 | last_len = 0; |
221 | 221 | ||
222 | for (;;) { | 222 | for (;;) { |
223 | int left; | ||
223 | error = dlm_recovery_stopped(ls); | 224 | error = dlm_recovery_stopped(ls); |
224 | if (error) | 225 | if (error) |
225 | goto out_free; | 226 | goto out_free; |
@@ -235,12 +236,21 @@ int dlm_recover_directory(struct dlm_ls *ls) | |||
235 | * pick namelen/name pairs out of received buffer | 236 | * pick namelen/name pairs out of received buffer |
236 | */ | 237 | */ |
237 | 238 | ||
238 | b = ls->ls_recover_buf + sizeof(struct dlm_rcom); | 239 | b = ls->ls_recover_buf->rc_buf; |
240 | left = ls->ls_recover_buf->rc_header.h_length; | ||
241 | left -= sizeof(struct dlm_rcom); | ||
239 | 242 | ||
240 | for (;;) { | 243 | for (;;) { |
241 | memcpy(&namelen, b, sizeof(uint16_t)); | 244 | __be16 v; |
242 | namelen = be16_to_cpu(namelen); | 245 | |
243 | b += sizeof(uint16_t); | 246 | error = -EINVAL; |
247 | if (left < sizeof(__be16)) | ||
248 | goto out_free; | ||
249 | |||
250 | memcpy(&v, b, sizeof(__be16)); | ||
251 | namelen = be16_to_cpu(v); | ||
252 | b += sizeof(__be16); | ||
253 | left -= sizeof(__be16); | ||
244 | 254 | ||
245 | /* namelen of 0xFFFFF marks end of names for | 255 | /* namelen of 0xFFFFF marks end of names for |
246 | this node; namelen of 0 marks end of the | 256 | this node; namelen of 0 marks end of the |
@@ -251,6 +261,12 @@ int dlm_recover_directory(struct dlm_ls *ls) | |||
251 | if (!namelen) | 261 | if (!namelen) |
252 | break; | 262 | break; |
253 | 263 | ||
264 | if (namelen > left) | ||
265 | goto out_free; | ||
266 | |||
267 | if (namelen > DLM_RESNAME_MAXLEN) | ||
268 | goto out_free; | ||
269 | |||
254 | error = -ENOMEM; | 270 | error = -ENOMEM; |
255 | de = get_free_de(ls, namelen); | 271 | de = get_free_de(ls, namelen); |
256 | if (!de) | 272 | if (!de) |
@@ -262,6 +278,7 @@ int dlm_recover_directory(struct dlm_ls *ls) | |||
262 | memcpy(de->name, b, namelen); | 278 | memcpy(de->name, b, namelen); |
263 | memcpy(last_name, b, namelen); | 279 | memcpy(last_name, b, namelen); |
264 | b += namelen; | 280 | b += namelen; |
281 | left -= namelen; | ||
265 | 282 | ||
266 | add_entry_to_hash(ls, de); | 283 | add_entry_to_hash(ls, de); |
267 | count++; | 284 | count++; |
@@ -302,6 +319,9 @@ static int get_entry(struct dlm_ls *ls, int nodeid, char *name, | |||
302 | 319 | ||
303 | write_unlock(&ls->ls_dirtbl[bucket].lock); | 320 | write_unlock(&ls->ls_dirtbl[bucket].lock); |
304 | 321 | ||
322 | if (namelen > DLM_RESNAME_MAXLEN) | ||
323 | return -EINVAL; | ||
324 | |||
305 | de = kzalloc(sizeof(struct dlm_direntry) + namelen, GFP_KERNEL); | 325 | de = kzalloc(sizeof(struct dlm_direntry) + namelen, GFP_KERNEL); |
306 | if (!de) | 326 | if (!de) |
307 | return -ENOMEM; | 327 | return -ENOMEM; |
diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h index ec61bbaf25df..d30ea8b433a2 100644 --- a/fs/dlm/dlm_internal.h +++ b/fs/dlm/dlm_internal.h | |||
@@ -92,8 +92,6 @@ do { \ | |||
92 | } \ | 92 | } \ |
93 | } | 93 | } |
94 | 94 | ||
95 | #define DLM_FAKE_USER_AST ERR_PTR(-EINVAL) | ||
96 | |||
97 | 95 | ||
98 | struct dlm_direntry { | 96 | struct dlm_direntry { |
99 | struct list_head list; | 97 | struct list_head list; |
@@ -146,9 +144,9 @@ struct dlm_recover { | |||
146 | 144 | ||
147 | struct dlm_args { | 145 | struct dlm_args { |
148 | uint32_t flags; | 146 | uint32_t flags; |
149 | void *astaddr; | 147 | void (*astfn) (void *astparam); |
150 | long astparam; | 148 | void *astparam; |
151 | void *bastaddr; | 149 | void (*bastfn) (void *astparam, int mode); |
152 | int mode; | 150 | int mode; |
153 | struct dlm_lksb *lksb; | 151 | struct dlm_lksb *lksb; |
154 | unsigned long timeout; | 152 | unsigned long timeout; |
@@ -253,9 +251,12 @@ struct dlm_lkb { | |||
253 | 251 | ||
254 | char *lkb_lvbptr; | 252 | char *lkb_lvbptr; |
255 | struct dlm_lksb *lkb_lksb; /* caller's status block */ | 253 | struct dlm_lksb *lkb_lksb; /* caller's status block */ |
256 | void *lkb_astaddr; /* caller's ast function */ | 254 | void (*lkb_astfn) (void *astparam); |
257 | void *lkb_bastaddr; /* caller's bast function */ | 255 | void (*lkb_bastfn) (void *astparam, int mode); |
258 | long lkb_astparam; /* caller's ast arg */ | 256 | union { |
257 | void *lkb_astparam; /* caller's ast arg */ | ||
258 | struct dlm_user_args *lkb_ua; | ||
259 | }; | ||
259 | }; | 260 | }; |
260 | 261 | ||
261 | 262 | ||
@@ -403,28 +404,34 @@ struct dlm_rcom { | |||
403 | char rc_buf[0]; | 404 | char rc_buf[0]; |
404 | }; | 405 | }; |
405 | 406 | ||
407 | union dlm_packet { | ||
408 | struct dlm_header header; /* common to other two */ | ||
409 | struct dlm_message message; | ||
410 | struct dlm_rcom rcom; | ||
411 | }; | ||
412 | |||
406 | struct rcom_config { | 413 | struct rcom_config { |
407 | uint32_t rf_lvblen; | 414 | __le32 rf_lvblen; |
408 | uint32_t rf_lsflags; | 415 | __le32 rf_lsflags; |
409 | uint64_t rf_unused; | 416 | __le64 rf_unused; |
410 | }; | 417 | }; |
411 | 418 | ||
412 | struct rcom_lock { | 419 | struct rcom_lock { |
413 | uint32_t rl_ownpid; | 420 | __le32 rl_ownpid; |
414 | uint32_t rl_lkid; | 421 | __le32 rl_lkid; |
415 | uint32_t rl_remid; | 422 | __le32 rl_remid; |
416 | uint32_t rl_parent_lkid; | 423 | __le32 rl_parent_lkid; |
417 | uint32_t rl_parent_remid; | 424 | __le32 rl_parent_remid; |
418 | uint32_t rl_exflags; | 425 | __le32 rl_exflags; |
419 | uint32_t rl_flags; | 426 | __le32 rl_flags; |
420 | uint32_t rl_lvbseq; | 427 | __le32 rl_lvbseq; |
421 | int rl_result; | 428 | __le32 rl_result; |
422 | int8_t rl_rqmode; | 429 | int8_t rl_rqmode; |
423 | int8_t rl_grmode; | 430 | int8_t rl_grmode; |
424 | int8_t rl_status; | 431 | int8_t rl_status; |
425 | int8_t rl_asts; | 432 | int8_t rl_asts; |
426 | uint16_t rl_wait_type; | 433 | __le16 rl_wait_type; |
427 | uint16_t rl_namelen; | 434 | __le16 rl_namelen; |
428 | char rl_name[DLM_RESNAME_MAXLEN]; | 435 | char rl_name[DLM_RESNAME_MAXLEN]; |
429 | char rl_lvb[0]; | 436 | char rl_lvb[0]; |
430 | }; | 437 | }; |
@@ -494,7 +501,7 @@ struct dlm_ls { | |||
494 | struct rw_semaphore ls_recv_active; /* block dlm_recv */ | 501 | struct rw_semaphore ls_recv_active; /* block dlm_recv */ |
495 | struct list_head ls_requestqueue;/* queue remote requests */ | 502 | struct list_head ls_requestqueue;/* queue remote requests */ |
496 | struct mutex ls_requestqueue_mutex; | 503 | struct mutex ls_requestqueue_mutex; |
497 | char *ls_recover_buf; | 504 | struct dlm_rcom *ls_recover_buf; |
498 | int ls_recover_nodeid; /* for debugging */ | 505 | int ls_recover_nodeid; /* for debugging */ |
499 | uint64_t ls_rcom_seq; | 506 | uint64_t ls_rcom_seq; |
500 | spinlock_t ls_rcom_spin; | 507 | spinlock_t ls_rcom_spin; |
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index ff4a198fa677..8f250ac8b928 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c | |||
@@ -436,11 +436,15 @@ static int find_rsb(struct dlm_ls *ls, char *name, int namelen, | |||
436 | { | 436 | { |
437 | struct dlm_rsb *r, *tmp; | 437 | struct dlm_rsb *r, *tmp; |
438 | uint32_t hash, bucket; | 438 | uint32_t hash, bucket; |
439 | int error = 0; | 439 | int error = -EINVAL; |
440 | |||
441 | if (namelen > DLM_RESNAME_MAXLEN) | ||
442 | goto out; | ||
440 | 443 | ||
441 | if (dlm_no_directory(ls)) | 444 | if (dlm_no_directory(ls)) |
442 | flags |= R_CREATE; | 445 | flags |= R_CREATE; |
443 | 446 | ||
447 | error = 0; | ||
444 | hash = jhash(name, namelen, 0); | 448 | hash = jhash(name, namelen, 0); |
445 | bucket = hash & (ls->ls_rsbtbl_size - 1); | 449 | bucket = hash & (ls->ls_rsbtbl_size - 1); |
446 | 450 | ||
@@ -1222,6 +1226,8 @@ static void set_lvb_lock_pc(struct dlm_rsb *r, struct dlm_lkb *lkb, | |||
1222 | b = dlm_lvb_operations[lkb->lkb_grmode + 1][lkb->lkb_rqmode + 1]; | 1226 | b = dlm_lvb_operations[lkb->lkb_grmode + 1][lkb->lkb_rqmode + 1]; |
1223 | if (b == 1) { | 1227 | if (b == 1) { |
1224 | int len = receive_extralen(ms); | 1228 | int len = receive_extralen(ms); |
1229 | if (len > DLM_RESNAME_MAXLEN) | ||
1230 | len = DLM_RESNAME_MAXLEN; | ||
1225 | memcpy(lkb->lkb_lvbptr, ms->m_extra, len); | 1231 | memcpy(lkb->lkb_lvbptr, ms->m_extra, len); |
1226 | lkb->lkb_lvbseq = ms->m_lvbseq; | 1232 | lkb->lkb_lvbseq = ms->m_lvbseq; |
1227 | } | 1233 | } |
@@ -1775,7 +1781,7 @@ static void grant_pending_locks(struct dlm_rsb *r) | |||
1775 | */ | 1781 | */ |
1776 | 1782 | ||
1777 | list_for_each_entry_safe(lkb, s, &r->res_grantqueue, lkb_statequeue) { | 1783 | list_for_each_entry_safe(lkb, s, &r->res_grantqueue, lkb_statequeue) { |
1778 | if (lkb->lkb_bastaddr && lock_requires_bast(lkb, high, cw)) { | 1784 | if (lkb->lkb_bastfn && lock_requires_bast(lkb, high, cw)) { |
1779 | if (cw && high == DLM_LOCK_PR) | 1785 | if (cw && high == DLM_LOCK_PR) |
1780 | queue_bast(r, lkb, DLM_LOCK_CW); | 1786 | queue_bast(r, lkb, DLM_LOCK_CW); |
1781 | else | 1787 | else |
@@ -1805,7 +1811,7 @@ static void send_bast_queue(struct dlm_rsb *r, struct list_head *head, | |||
1805 | struct dlm_lkb *gr; | 1811 | struct dlm_lkb *gr; |
1806 | 1812 | ||
1807 | list_for_each_entry(gr, head, lkb_statequeue) { | 1813 | list_for_each_entry(gr, head, lkb_statequeue) { |
1808 | if (gr->lkb_bastaddr && modes_require_bast(gr, lkb)) { | 1814 | if (gr->lkb_bastfn && modes_require_bast(gr, lkb)) { |
1809 | queue_bast(r, gr, lkb->lkb_rqmode); | 1815 | queue_bast(r, gr, lkb->lkb_rqmode); |
1810 | gr->lkb_highbast = lkb->lkb_rqmode; | 1816 | gr->lkb_highbast = lkb->lkb_rqmode; |
1811 | } | 1817 | } |
@@ -1960,8 +1966,11 @@ static void confirm_master(struct dlm_rsb *r, int error) | |||
1960 | } | 1966 | } |
1961 | 1967 | ||
1962 | static int set_lock_args(int mode, struct dlm_lksb *lksb, uint32_t flags, | 1968 | static int set_lock_args(int mode, struct dlm_lksb *lksb, uint32_t flags, |
1963 | int namelen, unsigned long timeout_cs, void *ast, | 1969 | int namelen, unsigned long timeout_cs, |
1964 | void *astarg, void *bast, struct dlm_args *args) | 1970 | void (*ast) (void *astparam), |
1971 | void *astparam, | ||
1972 | void (*bast) (void *astparam, int mode), | ||
1973 | struct dlm_args *args) | ||
1965 | { | 1974 | { |
1966 | int rv = -EINVAL; | 1975 | int rv = -EINVAL; |
1967 | 1976 | ||
@@ -2011,9 +2020,9 @@ static int set_lock_args(int mode, struct dlm_lksb *lksb, uint32_t flags, | |||
2011 | an active lkb cannot be modified before locking the rsb */ | 2020 | an active lkb cannot be modified before locking the rsb */ |
2012 | 2021 | ||
2013 | args->flags = flags; | 2022 | args->flags = flags; |
2014 | args->astaddr = ast; | 2023 | args->astfn = ast; |
2015 | args->astparam = (long) astarg; | 2024 | args->astparam = astparam; |
2016 | args->bastaddr = bast; | 2025 | args->bastfn = bast; |
2017 | args->timeout = timeout_cs; | 2026 | args->timeout = timeout_cs; |
2018 | args->mode = mode; | 2027 | args->mode = mode; |
2019 | args->lksb = lksb; | 2028 | args->lksb = lksb; |
@@ -2032,7 +2041,7 @@ static int set_unlock_args(uint32_t flags, void *astarg, struct dlm_args *args) | |||
2032 | return -EINVAL; | 2041 | return -EINVAL; |
2033 | 2042 | ||
2034 | args->flags = flags; | 2043 | args->flags = flags; |
2035 | args->astparam = (long) astarg; | 2044 | args->astparam = astarg; |
2036 | return 0; | 2045 | return 0; |
2037 | } | 2046 | } |
2038 | 2047 | ||
@@ -2062,9 +2071,9 @@ static int validate_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb, | |||
2062 | 2071 | ||
2063 | lkb->lkb_exflags = args->flags; | 2072 | lkb->lkb_exflags = args->flags; |
2064 | lkb->lkb_sbflags = 0; | 2073 | lkb->lkb_sbflags = 0; |
2065 | lkb->lkb_astaddr = args->astaddr; | 2074 | lkb->lkb_astfn = args->astfn; |
2066 | lkb->lkb_astparam = args->astparam; | 2075 | lkb->lkb_astparam = args->astparam; |
2067 | lkb->lkb_bastaddr = args->bastaddr; | 2076 | lkb->lkb_bastfn = args->bastfn; |
2068 | lkb->lkb_rqmode = args->mode; | 2077 | lkb->lkb_rqmode = args->mode; |
2069 | lkb->lkb_lksb = args->lksb; | 2078 | lkb->lkb_lksb = args->lksb; |
2070 | lkb->lkb_lvbptr = args->lksb->sb_lvbptr; | 2079 | lkb->lkb_lvbptr = args->lksb->sb_lvbptr; |
@@ -2711,9 +2720,9 @@ static void send_args(struct dlm_rsb *r, struct dlm_lkb *lkb, | |||
2711 | /* m_result and m_bastmode are set from function args, | 2720 | /* m_result and m_bastmode are set from function args, |
2712 | not from lkb fields */ | 2721 | not from lkb fields */ |
2713 | 2722 | ||
2714 | if (lkb->lkb_bastaddr) | 2723 | if (lkb->lkb_bastfn) |
2715 | ms->m_asts |= AST_BAST; | 2724 | ms->m_asts |= AST_BAST; |
2716 | if (lkb->lkb_astaddr) | 2725 | if (lkb->lkb_astfn) |
2717 | ms->m_asts |= AST_COMP; | 2726 | ms->m_asts |= AST_COMP; |
2718 | 2727 | ||
2719 | /* compare with switch in create_message; send_remove() doesn't | 2728 | /* compare with switch in create_message; send_remove() doesn't |
@@ -2989,11 +2998,23 @@ static int receive_lvb(struct dlm_ls *ls, struct dlm_lkb *lkb, | |||
2989 | if (!lkb->lkb_lvbptr) | 2998 | if (!lkb->lkb_lvbptr) |
2990 | return -ENOMEM; | 2999 | return -ENOMEM; |
2991 | len = receive_extralen(ms); | 3000 | len = receive_extralen(ms); |
3001 | if (len > DLM_RESNAME_MAXLEN) | ||
3002 | len = DLM_RESNAME_MAXLEN; | ||
2992 | memcpy(lkb->lkb_lvbptr, ms->m_extra, len); | 3003 | memcpy(lkb->lkb_lvbptr, ms->m_extra, len); |
2993 | } | 3004 | } |
2994 | return 0; | 3005 | return 0; |
2995 | } | 3006 | } |
2996 | 3007 | ||
3008 | static void fake_bastfn(void *astparam, int mode) | ||
3009 | { | ||
3010 | log_print("fake_bastfn should not be called"); | ||
3011 | } | ||
3012 | |||
3013 | static void fake_astfn(void *astparam) | ||
3014 | { | ||
3015 | log_print("fake_astfn should not be called"); | ||
3016 | } | ||
3017 | |||
2997 | static int receive_request_args(struct dlm_ls *ls, struct dlm_lkb *lkb, | 3018 | static int receive_request_args(struct dlm_ls *ls, struct dlm_lkb *lkb, |
2998 | struct dlm_message *ms) | 3019 | struct dlm_message *ms) |
2999 | { | 3020 | { |
@@ -3002,8 +3023,9 @@ static int receive_request_args(struct dlm_ls *ls, struct dlm_lkb *lkb, | |||
3002 | lkb->lkb_remid = ms->m_lkid; | 3023 | lkb->lkb_remid = ms->m_lkid; |
3003 | lkb->lkb_grmode = DLM_LOCK_IV; | 3024 | lkb->lkb_grmode = DLM_LOCK_IV; |
3004 | lkb->lkb_rqmode = ms->m_rqmode; | 3025 | lkb->lkb_rqmode = ms->m_rqmode; |
3005 | lkb->lkb_bastaddr = (void *) (long) (ms->m_asts & AST_BAST); | 3026 | |
3006 | lkb->lkb_astaddr = (void *) (long) (ms->m_asts & AST_COMP); | 3027 | lkb->lkb_bastfn = (ms->m_asts & AST_BAST) ? &fake_bastfn : NULL; |
3028 | lkb->lkb_astfn = (ms->m_asts & AST_COMP) ? &fake_astfn : NULL; | ||
3007 | 3029 | ||
3008 | if (lkb->lkb_exflags & DLM_LKF_VALBLK) { | 3030 | if (lkb->lkb_exflags & DLM_LKF_VALBLK) { |
3009 | /* lkb was just created so there won't be an lvb yet */ | 3031 | /* lkb was just created so there won't be an lvb yet */ |
@@ -3802,7 +3824,7 @@ static void dlm_receive_message(struct dlm_ls *ls, struct dlm_message *ms, | |||
3802 | int nodeid) | 3824 | int nodeid) |
3803 | { | 3825 | { |
3804 | if (dlm_locking_stopped(ls)) { | 3826 | if (dlm_locking_stopped(ls)) { |
3805 | dlm_add_requestqueue(ls, nodeid, (struct dlm_header *) ms); | 3827 | dlm_add_requestqueue(ls, nodeid, ms); |
3806 | } else { | 3828 | } else { |
3807 | dlm_wait_requestqueue(ls); | 3829 | dlm_wait_requestqueue(ls); |
3808 | _receive_message(ls, ms); | 3830 | _receive_message(ls, ms); |
@@ -3822,21 +3844,20 @@ void dlm_receive_message_saved(struct dlm_ls *ls, struct dlm_message *ms) | |||
3822 | standard locking activity) or an RCOM (recovery message sent as part of | 3844 | standard locking activity) or an RCOM (recovery message sent as part of |
3823 | lockspace recovery). */ | 3845 | lockspace recovery). */ |
3824 | 3846 | ||
3825 | void dlm_receive_buffer(struct dlm_header *hd, int nodeid) | 3847 | void dlm_receive_buffer(union dlm_packet *p, int nodeid) |
3826 | { | 3848 | { |
3827 | struct dlm_message *ms = (struct dlm_message *) hd; | 3849 | struct dlm_header *hd = &p->header; |
3828 | struct dlm_rcom *rc = (struct dlm_rcom *) hd; | ||
3829 | struct dlm_ls *ls; | 3850 | struct dlm_ls *ls; |
3830 | int type = 0; | 3851 | int type = 0; |
3831 | 3852 | ||
3832 | switch (hd->h_cmd) { | 3853 | switch (hd->h_cmd) { |
3833 | case DLM_MSG: | 3854 | case DLM_MSG: |
3834 | dlm_message_in(ms); | 3855 | dlm_message_in(&p->message); |
3835 | type = ms->m_type; | 3856 | type = p->message.m_type; |
3836 | break; | 3857 | break; |
3837 | case DLM_RCOM: | 3858 | case DLM_RCOM: |
3838 | dlm_rcom_in(rc); | 3859 | dlm_rcom_in(&p->rcom); |
3839 | type = rc->rc_type; | 3860 | type = p->rcom.rc_type; |
3840 | break; | 3861 | break; |
3841 | default: | 3862 | default: |
3842 | log_print("invalid h_cmd %d from %u", hd->h_cmd, nodeid); | 3863 | log_print("invalid h_cmd %d from %u", hd->h_cmd, nodeid); |
@@ -3856,7 +3877,7 @@ void dlm_receive_buffer(struct dlm_header *hd, int nodeid) | |||
3856 | hd->h_lockspace, nodeid, hd->h_cmd, type); | 3877 | hd->h_lockspace, nodeid, hd->h_cmd, type); |
3857 | 3878 | ||
3858 | if (hd->h_cmd == DLM_RCOM && type == DLM_RCOM_STATUS) | 3879 | if (hd->h_cmd == DLM_RCOM && type == DLM_RCOM_STATUS) |
3859 | dlm_send_ls_not_ready(nodeid, rc); | 3880 | dlm_send_ls_not_ready(nodeid, &p->rcom); |
3860 | return; | 3881 | return; |
3861 | } | 3882 | } |
3862 | 3883 | ||
@@ -3865,9 +3886,9 @@ void dlm_receive_buffer(struct dlm_header *hd, int nodeid) | |||
3865 | 3886 | ||
3866 | down_read(&ls->ls_recv_active); | 3887 | down_read(&ls->ls_recv_active); |
3867 | if (hd->h_cmd == DLM_MSG) | 3888 | if (hd->h_cmd == DLM_MSG) |
3868 | dlm_receive_message(ls, ms, nodeid); | 3889 | dlm_receive_message(ls, &p->message, nodeid); |
3869 | else | 3890 | else |
3870 | dlm_receive_rcom(ls, rc, nodeid); | 3891 | dlm_receive_rcom(ls, &p->rcom, nodeid); |
3871 | up_read(&ls->ls_recv_active); | 3892 | up_read(&ls->ls_recv_active); |
3872 | 3893 | ||
3873 | dlm_put_lockspace(ls); | 3894 | dlm_put_lockspace(ls); |
@@ -4267,32 +4288,34 @@ static struct dlm_lkb *search_remid(struct dlm_rsb *r, int nodeid, | |||
4267 | return NULL; | 4288 | return NULL; |
4268 | } | 4289 | } |
4269 | 4290 | ||
4291 | /* needs at least dlm_rcom + rcom_lock */ | ||
4270 | static int receive_rcom_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb, | 4292 | static int receive_rcom_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb, |
4271 | struct dlm_rsb *r, struct dlm_rcom *rc) | 4293 | struct dlm_rsb *r, struct dlm_rcom *rc) |
4272 | { | 4294 | { |
4273 | struct rcom_lock *rl = (struct rcom_lock *) rc->rc_buf; | 4295 | struct rcom_lock *rl = (struct rcom_lock *) rc->rc_buf; |
4274 | int lvblen; | ||
4275 | 4296 | ||
4276 | lkb->lkb_nodeid = rc->rc_header.h_nodeid; | 4297 | lkb->lkb_nodeid = rc->rc_header.h_nodeid; |
4277 | lkb->lkb_ownpid = rl->rl_ownpid; | 4298 | lkb->lkb_ownpid = le32_to_cpu(rl->rl_ownpid); |
4278 | lkb->lkb_remid = rl->rl_lkid; | 4299 | lkb->lkb_remid = le32_to_cpu(rl->rl_lkid); |
4279 | lkb->lkb_exflags = rl->rl_exflags; | 4300 | lkb->lkb_exflags = le32_to_cpu(rl->rl_exflags); |
4280 | lkb->lkb_flags = rl->rl_flags & 0x0000FFFF; | 4301 | lkb->lkb_flags = le32_to_cpu(rl->rl_flags) & 0x0000FFFF; |
4281 | lkb->lkb_flags |= DLM_IFL_MSTCPY; | 4302 | lkb->lkb_flags |= DLM_IFL_MSTCPY; |
4282 | lkb->lkb_lvbseq = rl->rl_lvbseq; | 4303 | lkb->lkb_lvbseq = le32_to_cpu(rl->rl_lvbseq); |
4283 | lkb->lkb_rqmode = rl->rl_rqmode; | 4304 | lkb->lkb_rqmode = rl->rl_rqmode; |
4284 | lkb->lkb_grmode = rl->rl_grmode; | 4305 | lkb->lkb_grmode = rl->rl_grmode; |
4285 | /* don't set lkb_status because add_lkb wants to itself */ | 4306 | /* don't set lkb_status because add_lkb wants to itself */ |
4286 | 4307 | ||
4287 | lkb->lkb_bastaddr = (void *) (long) (rl->rl_asts & AST_BAST); | 4308 | lkb->lkb_bastfn = (rl->rl_asts & AST_BAST) ? &fake_bastfn : NULL; |
4288 | lkb->lkb_astaddr = (void *) (long) (rl->rl_asts & AST_COMP); | 4309 | lkb->lkb_astfn = (rl->rl_asts & AST_COMP) ? &fake_astfn : NULL; |
4289 | 4310 | ||
4290 | if (lkb->lkb_exflags & DLM_LKF_VALBLK) { | 4311 | if (lkb->lkb_exflags & DLM_LKF_VALBLK) { |
4312 | int lvblen = rc->rc_header.h_length - sizeof(struct dlm_rcom) - | ||
4313 | sizeof(struct rcom_lock); | ||
4314 | if (lvblen > ls->ls_lvblen) | ||
4315 | return -EINVAL; | ||
4291 | lkb->lkb_lvbptr = dlm_allocate_lvb(ls); | 4316 | lkb->lkb_lvbptr = dlm_allocate_lvb(ls); |
4292 | if (!lkb->lkb_lvbptr) | 4317 | if (!lkb->lkb_lvbptr) |
4293 | return -ENOMEM; | 4318 | return -ENOMEM; |
4294 | lvblen = rc->rc_header.h_length - sizeof(struct dlm_rcom) - | ||
4295 | sizeof(struct rcom_lock); | ||
4296 | memcpy(lkb->lkb_lvbptr, rl->rl_lvb, lvblen); | 4319 | memcpy(lkb->lkb_lvbptr, rl->rl_lvb, lvblen); |
4297 | } | 4320 | } |
4298 | 4321 | ||
@@ -4300,7 +4323,8 @@ static int receive_rcom_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb, | |||
4300 | The real granted mode of these converting locks cannot be determined | 4323 | The real granted mode of these converting locks cannot be determined |
4301 | until all locks have been rebuilt on the rsb (recover_conversion) */ | 4324 | until all locks have been rebuilt on the rsb (recover_conversion) */ |
4302 | 4325 | ||
4303 | if (rl->rl_wait_type == DLM_MSG_CONVERT && middle_conversion(lkb)) { | 4326 | if (rl->rl_wait_type == cpu_to_le16(DLM_MSG_CONVERT) && |
4327 | middle_conversion(lkb)) { | ||
4304 | rl->rl_status = DLM_LKSTS_CONVERT; | 4328 | rl->rl_status = DLM_LKSTS_CONVERT; |
4305 | lkb->lkb_grmode = DLM_LOCK_IV; | 4329 | lkb->lkb_grmode = DLM_LOCK_IV; |
4306 | rsb_set_flag(r, RSB_RECOVER_CONVERT); | 4330 | rsb_set_flag(r, RSB_RECOVER_CONVERT); |
@@ -4315,6 +4339,7 @@ static int receive_rcom_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb, | |||
4315 | the given values and send back our lkid. We send back our lkid by sending | 4339 | the given values and send back our lkid. We send back our lkid by sending |
4316 | back the rcom_lock struct we got but with the remid field filled in. */ | 4340 | back the rcom_lock struct we got but with the remid field filled in. */ |
4317 | 4341 | ||
4342 | /* needs at least dlm_rcom + rcom_lock */ | ||
4318 | int dlm_recover_master_copy(struct dlm_ls *ls, struct dlm_rcom *rc) | 4343 | int dlm_recover_master_copy(struct dlm_ls *ls, struct dlm_rcom *rc) |
4319 | { | 4344 | { |
4320 | struct rcom_lock *rl = (struct rcom_lock *) rc->rc_buf; | 4345 | struct rcom_lock *rl = (struct rcom_lock *) rc->rc_buf; |
@@ -4327,13 +4352,14 @@ int dlm_recover_master_copy(struct dlm_ls *ls, struct dlm_rcom *rc) | |||
4327 | goto out; | 4352 | goto out; |
4328 | } | 4353 | } |
4329 | 4354 | ||
4330 | error = find_rsb(ls, rl->rl_name, rl->rl_namelen, R_MASTER, &r); | 4355 | error = find_rsb(ls, rl->rl_name, le16_to_cpu(rl->rl_namelen), |
4356 | R_MASTER, &r); | ||
4331 | if (error) | 4357 | if (error) |
4332 | goto out; | 4358 | goto out; |
4333 | 4359 | ||
4334 | lock_rsb(r); | 4360 | lock_rsb(r); |
4335 | 4361 | ||
4336 | lkb = search_remid(r, rc->rc_header.h_nodeid, rl->rl_lkid); | 4362 | lkb = search_remid(r, rc->rc_header.h_nodeid, le32_to_cpu(rl->rl_lkid)); |
4337 | if (lkb) { | 4363 | if (lkb) { |
4338 | error = -EEXIST; | 4364 | error = -EEXIST; |
4339 | goto out_remid; | 4365 | goto out_remid; |
@@ -4356,18 +4382,20 @@ int dlm_recover_master_copy(struct dlm_ls *ls, struct dlm_rcom *rc) | |||
4356 | out_remid: | 4382 | out_remid: |
4357 | /* this is the new value returned to the lock holder for | 4383 | /* this is the new value returned to the lock holder for |
4358 | saving in its process-copy lkb */ | 4384 | saving in its process-copy lkb */ |
4359 | rl->rl_remid = lkb->lkb_id; | 4385 | rl->rl_remid = cpu_to_le32(lkb->lkb_id); |
4360 | 4386 | ||
4361 | out_unlock: | 4387 | out_unlock: |
4362 | unlock_rsb(r); | 4388 | unlock_rsb(r); |
4363 | put_rsb(r); | 4389 | put_rsb(r); |
4364 | out: | 4390 | out: |
4365 | if (error) | 4391 | if (error) |
4366 | log_debug(ls, "recover_master_copy %d %x", error, rl->rl_lkid); | 4392 | log_debug(ls, "recover_master_copy %d %x", error, |
4367 | rl->rl_result = error; | 4393 | le32_to_cpu(rl->rl_lkid)); |
4394 | rl->rl_result = cpu_to_le32(error); | ||
4368 | return error; | 4395 | return error; |
4369 | } | 4396 | } |
4370 | 4397 | ||
4398 | /* needs at least dlm_rcom + rcom_lock */ | ||
4371 | int dlm_recover_process_copy(struct dlm_ls *ls, struct dlm_rcom *rc) | 4399 | int dlm_recover_process_copy(struct dlm_ls *ls, struct dlm_rcom *rc) |
4372 | { | 4400 | { |
4373 | struct rcom_lock *rl = (struct rcom_lock *) rc->rc_buf; | 4401 | struct rcom_lock *rl = (struct rcom_lock *) rc->rc_buf; |
@@ -4375,15 +4403,16 @@ int dlm_recover_process_copy(struct dlm_ls *ls, struct dlm_rcom *rc) | |||
4375 | struct dlm_lkb *lkb; | 4403 | struct dlm_lkb *lkb; |
4376 | int error; | 4404 | int error; |
4377 | 4405 | ||
4378 | error = find_lkb(ls, rl->rl_lkid, &lkb); | 4406 | error = find_lkb(ls, le32_to_cpu(rl->rl_lkid), &lkb); |
4379 | if (error) { | 4407 | if (error) { |
4380 | log_error(ls, "recover_process_copy no lkid %x", rl->rl_lkid); | 4408 | log_error(ls, "recover_process_copy no lkid %x", |
4409 | le32_to_cpu(rl->rl_lkid)); | ||
4381 | return error; | 4410 | return error; |
4382 | } | 4411 | } |
4383 | 4412 | ||
4384 | DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb);); | 4413 | DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb);); |
4385 | 4414 | ||
4386 | error = rl->rl_result; | 4415 | error = le32_to_cpu(rl->rl_result); |
4387 | 4416 | ||
4388 | r = lkb->lkb_resource; | 4417 | r = lkb->lkb_resource; |
4389 | hold_rsb(r); | 4418 | hold_rsb(r); |
@@ -4402,7 +4431,7 @@ int dlm_recover_process_copy(struct dlm_ls *ls, struct dlm_rcom *rc) | |||
4402 | log_debug(ls, "master copy exists %x", lkb->lkb_id); | 4431 | log_debug(ls, "master copy exists %x", lkb->lkb_id); |
4403 | /* fall through */ | 4432 | /* fall through */ |
4404 | case 0: | 4433 | case 0: |
4405 | lkb->lkb_remid = rl->rl_remid; | 4434 | lkb->lkb_remid = le32_to_cpu(rl->rl_remid); |
4406 | break; | 4435 | break; |
4407 | default: | 4436 | default: |
4408 | log_error(ls, "dlm_recover_process_copy unknown error %d %x", | 4437 | log_error(ls, "dlm_recover_process_copy unknown error %d %x", |
@@ -4451,7 +4480,7 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, | |||
4451 | lock and that lkb_astparam is the dlm_user_args structure. */ | 4480 | lock and that lkb_astparam is the dlm_user_args structure. */ |
4452 | 4481 | ||
4453 | error = set_lock_args(mode, &ua->lksb, flags, namelen, timeout_cs, | 4482 | error = set_lock_args(mode, &ua->lksb, flags, namelen, timeout_cs, |
4454 | DLM_FAKE_USER_AST, ua, DLM_FAKE_USER_AST, &args); | 4483 | fake_astfn, ua, fake_bastfn, &args); |
4455 | lkb->lkb_flags |= DLM_IFL_USER; | 4484 | lkb->lkb_flags |= DLM_IFL_USER; |
4456 | ua->old_mode = DLM_LOCK_IV; | 4485 | ua->old_mode = DLM_LOCK_IV; |
4457 | 4486 | ||
@@ -4504,7 +4533,7 @@ int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, | |||
4504 | /* user can change the params on its lock when it converts it, or | 4533 | /* user can change the params on its lock when it converts it, or |
4505 | add an lvb that didn't exist before */ | 4534 | add an lvb that didn't exist before */ |
4506 | 4535 | ||
4507 | ua = (struct dlm_user_args *)lkb->lkb_astparam; | 4536 | ua = lkb->lkb_ua; |
4508 | 4537 | ||
4509 | if (flags & DLM_LKF_VALBLK && !ua->lksb.sb_lvbptr) { | 4538 | if (flags & DLM_LKF_VALBLK && !ua->lksb.sb_lvbptr) { |
4510 | ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_KERNEL); | 4539 | ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_KERNEL); |
@@ -4525,7 +4554,7 @@ int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, | |||
4525 | ua->old_mode = lkb->lkb_grmode; | 4554 | ua->old_mode = lkb->lkb_grmode; |
4526 | 4555 | ||
4527 | error = set_lock_args(mode, &ua->lksb, flags, 0, timeout_cs, | 4556 | error = set_lock_args(mode, &ua->lksb, flags, 0, timeout_cs, |
4528 | DLM_FAKE_USER_AST, ua, DLM_FAKE_USER_AST, &args); | 4557 | fake_astfn, ua, fake_bastfn, &args); |
4529 | if (error) | 4558 | if (error) |
4530 | goto out_put; | 4559 | goto out_put; |
4531 | 4560 | ||
@@ -4555,7 +4584,7 @@ int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, | |||
4555 | if (error) | 4584 | if (error) |
4556 | goto out; | 4585 | goto out; |
4557 | 4586 | ||
4558 | ua = (struct dlm_user_args *)lkb->lkb_astparam; | 4587 | ua = lkb->lkb_ua; |
4559 | 4588 | ||
4560 | if (lvb_in && ua->lksb.sb_lvbptr) | 4589 | if (lvb_in && ua->lksb.sb_lvbptr) |
4561 | memcpy(ua->lksb.sb_lvbptr, lvb_in, DLM_USER_LVB_LEN); | 4590 | memcpy(ua->lksb.sb_lvbptr, lvb_in, DLM_USER_LVB_LEN); |
@@ -4604,7 +4633,7 @@ int dlm_user_cancel(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, | |||
4604 | if (error) | 4633 | if (error) |
4605 | goto out; | 4634 | goto out; |
4606 | 4635 | ||
4607 | ua = (struct dlm_user_args *)lkb->lkb_astparam; | 4636 | ua = lkb->lkb_ua; |
4608 | if (ua_tmp->castparam) | 4637 | if (ua_tmp->castparam) |
4609 | ua->castparam = ua_tmp->castparam; | 4638 | ua->castparam = ua_tmp->castparam; |
4610 | ua->user_lksb = ua_tmp->user_lksb; | 4639 | ua->user_lksb = ua_tmp->user_lksb; |
@@ -4642,7 +4671,7 @@ int dlm_user_deadlock(struct dlm_ls *ls, uint32_t flags, uint32_t lkid) | |||
4642 | if (error) | 4671 | if (error) |
4643 | goto out; | 4672 | goto out; |
4644 | 4673 | ||
4645 | ua = (struct dlm_user_args *)lkb->lkb_astparam; | 4674 | ua = lkb->lkb_ua; |
4646 | 4675 | ||
4647 | error = set_unlock_args(flags, ua, &args); | 4676 | error = set_unlock_args(flags, ua, &args); |
4648 | if (error) | 4677 | if (error) |
@@ -4681,7 +4710,6 @@ int dlm_user_deadlock(struct dlm_ls *ls, uint32_t flags, uint32_t lkid) | |||
4681 | 4710 | ||
4682 | static int orphan_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb) | 4711 | static int orphan_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb) |
4683 | { | 4712 | { |
4684 | struct dlm_user_args *ua = (struct dlm_user_args *)lkb->lkb_astparam; | ||
4685 | struct dlm_args args; | 4713 | struct dlm_args args; |
4686 | int error; | 4714 | int error; |
4687 | 4715 | ||
@@ -4690,7 +4718,7 @@ static int orphan_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb) | |||
4690 | list_add_tail(&lkb->lkb_ownqueue, &ls->ls_orphans); | 4718 | list_add_tail(&lkb->lkb_ownqueue, &ls->ls_orphans); |
4691 | mutex_unlock(&ls->ls_orphans_mutex); | 4719 | mutex_unlock(&ls->ls_orphans_mutex); |
4692 | 4720 | ||
4693 | set_unlock_args(0, ua, &args); | 4721 | set_unlock_args(0, lkb->lkb_ua, &args); |
4694 | 4722 | ||
4695 | error = cancel_lock(ls, lkb, &args); | 4723 | error = cancel_lock(ls, lkb, &args); |
4696 | if (error == -DLM_ECANCEL) | 4724 | if (error == -DLM_ECANCEL) |
@@ -4703,11 +4731,10 @@ static int orphan_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb) | |||
4703 | 4731 | ||
4704 | static int unlock_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb) | 4732 | static int unlock_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb) |
4705 | { | 4733 | { |
4706 | struct dlm_user_args *ua = (struct dlm_user_args *)lkb->lkb_astparam; | ||
4707 | struct dlm_args args; | 4734 | struct dlm_args args; |
4708 | int error; | 4735 | int error; |
4709 | 4736 | ||
4710 | set_unlock_args(DLM_LKF_FORCEUNLOCK, ua, &args); | 4737 | set_unlock_args(DLM_LKF_FORCEUNLOCK, lkb->lkb_ua, &args); |
4711 | 4738 | ||
4712 | error = unlock_lock(ls, lkb, &args); | 4739 | error = unlock_lock(ls, lkb, &args); |
4713 | if (error == -DLM_EUNLOCK) | 4740 | if (error == -DLM_EUNLOCK) |
diff --git a/fs/dlm/lock.h b/fs/dlm/lock.h index 27b6ed302911..05d9c82e646b 100644 --- a/fs/dlm/lock.h +++ b/fs/dlm/lock.h | |||
@@ -17,7 +17,7 @@ void dlm_print_rsb(struct dlm_rsb *r); | |||
17 | void dlm_dump_rsb(struct dlm_rsb *r); | 17 | void dlm_dump_rsb(struct dlm_rsb *r); |
18 | void dlm_print_lkb(struct dlm_lkb *lkb); | 18 | void dlm_print_lkb(struct dlm_lkb *lkb); |
19 | void dlm_receive_message_saved(struct dlm_ls *ls, struct dlm_message *ms); | 19 | void dlm_receive_message_saved(struct dlm_ls *ls, struct dlm_message *ms); |
20 | void dlm_receive_buffer(struct dlm_header *hd, int nodeid); | 20 | void dlm_receive_buffer(union dlm_packet *p, int nodeid); |
21 | int dlm_modes_compat(int mode1, int mode2); | 21 | int dlm_modes_compat(int mode1, int mode2); |
22 | void dlm_put_rsb(struct dlm_rsb *r); | 22 | void dlm_put_rsb(struct dlm_rsb *r); |
23 | void dlm_hold_rsb(struct dlm_rsb *r); | 23 | void dlm_hold_rsb(struct dlm_rsb *r); |
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index b180fdc51085..b64e55e0515d 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c | |||
@@ -191,7 +191,7 @@ static int do_uevent(struct dlm_ls *ls, int in) | |||
191 | } | 191 | } |
192 | 192 | ||
193 | 193 | ||
194 | int dlm_lockspace_init(void) | 194 | int __init dlm_lockspace_init(void) |
195 | { | 195 | { |
196 | ls_count = 0; | 196 | ls_count = 0; |
197 | mutex_init(&ls_lock); | 197 | mutex_init(&ls_lock); |
diff --git a/fs/dlm/memory.c b/fs/dlm/memory.c index f7783867491a..54c14c6d06cb 100644 --- a/fs/dlm/memory.c +++ b/fs/dlm/memory.c | |||
@@ -18,7 +18,7 @@ | |||
18 | static struct kmem_cache *lkb_cache; | 18 | static struct kmem_cache *lkb_cache; |
19 | 19 | ||
20 | 20 | ||
21 | int dlm_memory_init(void) | 21 | int __init dlm_memory_init(void) |
22 | { | 22 | { |
23 | int ret = 0; | 23 | int ret = 0; |
24 | 24 | ||
@@ -80,7 +80,7 @@ void 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; |
83 | ua = (struct dlm_user_args *)lkb->lkb_astparam; | 83 | ua = lkb->lkb_ua; |
84 | if (ua) { | 84 | if (ua) { |
85 | if (ua->lksb.sb_lvbptr) | 85 | if (ua->lksb.sb_lvbptr) |
86 | kfree(ua->lksb.sb_lvbptr); | 86 | kfree(ua->lksb.sb_lvbptr); |
diff --git a/fs/dlm/midcomms.c b/fs/dlm/midcomms.c index e69926e984db..07ac709f3ed7 100644 --- a/fs/dlm/midcomms.c +++ b/fs/dlm/midcomms.c | |||
@@ -61,9 +61,9 @@ int dlm_process_incoming_buffer(int nodeid, const void *base, | |||
61 | union { | 61 | union { |
62 | unsigned char __buf[DLM_INBUF_LEN]; | 62 | unsigned char __buf[DLM_INBUF_LEN]; |
63 | /* this is to force proper alignment on some arches */ | 63 | /* this is to force proper alignment on some arches */ |
64 | struct dlm_header dlm; | 64 | union dlm_packet p; |
65 | } __tmp; | 65 | } __tmp; |
66 | struct dlm_header *msg = &__tmp.dlm; | 66 | union dlm_packet *p = &__tmp.p; |
67 | int ret = 0; | 67 | int ret = 0; |
68 | int err = 0; | 68 | int err = 0; |
69 | uint16_t msglen; | 69 | uint16_t msglen; |
@@ -75,15 +75,22 @@ int dlm_process_incoming_buffer(int nodeid, const void *base, | |||
75 | message may wrap around the end of the buffer back to the | 75 | message may wrap around the end of the buffer back to the |
76 | start, so we need to use a temp buffer and copy_from_cb. */ | 76 | start, so we need to use a temp buffer and copy_from_cb. */ |
77 | 77 | ||
78 | copy_from_cb(msg, base, offset, sizeof(struct dlm_header), | 78 | copy_from_cb(p, base, offset, sizeof(struct dlm_header), |
79 | limit); | 79 | limit); |
80 | 80 | ||
81 | msglen = le16_to_cpu(msg->h_length); | 81 | msglen = le16_to_cpu(p->header.h_length); |
82 | lockspace = msg->h_lockspace; | 82 | lockspace = p->header.h_lockspace; |
83 | 83 | ||
84 | err = -EINVAL; | 84 | err = -EINVAL; |
85 | if (msglen < sizeof(struct dlm_header)) | 85 | if (msglen < sizeof(struct dlm_header)) |
86 | break; | 86 | break; |
87 | if (p->header.h_cmd == DLM_MSG) { | ||
88 | if (msglen < sizeof(struct dlm_message)) | ||
89 | break; | ||
90 | } else { | ||
91 | if (msglen < sizeof(struct dlm_rcom)) | ||
92 | break; | ||
93 | } | ||
87 | err = -E2BIG; | 94 | err = -E2BIG; |
88 | if (msglen > dlm_config.ci_buffer_size) { | 95 | if (msglen > dlm_config.ci_buffer_size) { |
89 | log_print("message size %d from %d too big, buf len %d", | 96 | log_print("message size %d from %d too big, buf len %d", |
@@ -104,26 +111,26 @@ int dlm_process_incoming_buffer(int nodeid, const void *base, | |||
104 | in the buffer on the stack (which should work for most | 111 | in the buffer on the stack (which should work for most |
105 | ordinary messages). */ | 112 | ordinary messages). */ |
106 | 113 | ||
107 | if (msglen > DLM_INBUF_LEN && msg == &__tmp.dlm) { | 114 | if (msglen > sizeof(__tmp) && p == &__tmp.p) { |
108 | msg = kmalloc(dlm_config.ci_buffer_size, GFP_KERNEL); | 115 | p = kmalloc(dlm_config.ci_buffer_size, GFP_KERNEL); |
109 | if (msg == NULL) | 116 | if (p == NULL) |
110 | return ret; | 117 | return ret; |
111 | } | 118 | } |
112 | 119 | ||
113 | copy_from_cb(msg, base, offset, msglen, limit); | 120 | copy_from_cb(p, base, offset, msglen, limit); |
114 | 121 | ||
115 | BUG_ON(lockspace != msg->h_lockspace); | 122 | BUG_ON(lockspace != p->header.h_lockspace); |
116 | 123 | ||
117 | ret += msglen; | 124 | ret += msglen; |
118 | offset += msglen; | 125 | offset += msglen; |
119 | offset &= (limit - 1); | 126 | offset &= (limit - 1); |
120 | len -= msglen; | 127 | len -= msglen; |
121 | 128 | ||
122 | dlm_receive_buffer(msg, nodeid); | 129 | dlm_receive_buffer(p, nodeid); |
123 | } | 130 | } |
124 | 131 | ||
125 | if (msg != &__tmp.dlm) | 132 | if (p != &__tmp.p) |
126 | kfree(msg); | 133 | kfree(p); |
127 | 134 | ||
128 | return err ? err : ret; | 135 | return err ? err : ret; |
129 | } | 136 | } |
diff --git a/fs/dlm/netlink.c b/fs/dlm/netlink.c index 863b87d0dc71..714593621f4f 100644 --- a/fs/dlm/netlink.c +++ b/fs/dlm/netlink.c | |||
@@ -78,7 +78,7 @@ static struct genl_ops dlm_nl_ops = { | |||
78 | .doit = user_cmd, | 78 | .doit = user_cmd, |
79 | }; | 79 | }; |
80 | 80 | ||
81 | int dlm_netlink_init(void) | 81 | int __init dlm_netlink_init(void) |
82 | { | 82 | { |
83 | int rv; | 83 | int rv; |
84 | 84 | ||
@@ -95,7 +95,7 @@ int dlm_netlink_init(void) | |||
95 | return rv; | 95 | return rv; |
96 | } | 96 | } |
97 | 97 | ||
98 | void dlm_netlink_exit(void) | 98 | void __exit dlm_netlink_exit(void) |
99 | { | 99 | { |
100 | genl_unregister_ops(&family, &dlm_nl_ops); | 100 | genl_unregister_ops(&family, &dlm_nl_ops); |
101 | genl_unregister_family(&family); | 101 | genl_unregister_family(&family); |
@@ -104,7 +104,6 @@ void dlm_netlink_exit(void) | |||
104 | static void fill_data(struct dlm_lock_data *data, struct dlm_lkb *lkb) | 104 | static void fill_data(struct dlm_lock_data *data, struct dlm_lkb *lkb) |
105 | { | 105 | { |
106 | struct dlm_rsb *r = lkb->lkb_resource; | 106 | struct dlm_rsb *r = lkb->lkb_resource; |
107 | struct dlm_user_args *ua = (struct dlm_user_args *) lkb->lkb_astparam; | ||
108 | 107 | ||
109 | memset(data, 0, sizeof(struct dlm_lock_data)); | 108 | memset(data, 0, sizeof(struct dlm_lock_data)); |
110 | 109 | ||
@@ -117,8 +116,8 @@ static void fill_data(struct dlm_lock_data *data, struct dlm_lkb *lkb) | |||
117 | data->grmode = lkb->lkb_grmode; | 116 | data->grmode = lkb->lkb_grmode; |
118 | data->rqmode = lkb->lkb_rqmode; | 117 | data->rqmode = lkb->lkb_rqmode; |
119 | data->timestamp = lkb->lkb_timestamp; | 118 | data->timestamp = lkb->lkb_timestamp; |
120 | if (ua) | 119 | if (lkb->lkb_ua) |
121 | data->xid = ua->xid; | 120 | data->xid = lkb->lkb_ua->xid; |
122 | if (r) { | 121 | if (r) { |
123 | data->lockspace_id = r->res_ls->ls_global_id; | 122 | data->lockspace_id = r->res_ls->ls_global_id; |
124 | data->resource_namelen = r->res_length; | 123 | data->resource_namelen = r->res_length; |
diff --git a/fs/dlm/rcom.c b/fs/dlm/rcom.c index 026824cd3acb..035e6f9990b0 100644 --- a/fs/dlm/rcom.c +++ b/fs/dlm/rcom.c | |||
@@ -78,13 +78,14 @@ static void send_rcom(struct dlm_ls *ls, struct dlm_mhandle *mh, | |||
78 | 78 | ||
79 | static void make_config(struct dlm_ls *ls, struct rcom_config *rf) | 79 | static void make_config(struct dlm_ls *ls, struct rcom_config *rf) |
80 | { | 80 | { |
81 | rf->rf_lvblen = ls->ls_lvblen; | 81 | rf->rf_lvblen = cpu_to_le32(ls->ls_lvblen); |
82 | rf->rf_lsflags = ls->ls_exflags; | 82 | rf->rf_lsflags = cpu_to_le32(ls->ls_exflags); |
83 | } | 83 | } |
84 | 84 | ||
85 | static int check_config(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid) | 85 | static int check_config(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid) |
86 | { | 86 | { |
87 | struct rcom_config *rf = (struct rcom_config *) rc->rc_buf; | 87 | struct rcom_config *rf = (struct rcom_config *) rc->rc_buf; |
88 | size_t conf_size = sizeof(struct dlm_rcom) + sizeof(struct rcom_config); | ||
88 | 89 | ||
89 | if ((rc->rc_header.h_version & 0xFFFF0000) != DLM_HEADER_MAJOR) { | 90 | if ((rc->rc_header.h_version & 0xFFFF0000) != DLM_HEADER_MAJOR) { |
90 | log_error(ls, "version mismatch: %x nodeid %d: %x", | 91 | log_error(ls, "version mismatch: %x nodeid %d: %x", |
@@ -93,11 +94,18 @@ static int check_config(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid) | |||
93 | return -EPROTO; | 94 | return -EPROTO; |
94 | } | 95 | } |
95 | 96 | ||
96 | if (rf->rf_lvblen != ls->ls_lvblen || | 97 | if (rc->rc_header.h_length < conf_size) { |
97 | rf->rf_lsflags != ls->ls_exflags) { | 98 | log_error(ls, "config too short: %d nodeid %d", |
99 | rc->rc_header.h_length, nodeid); | ||
100 | return -EPROTO; | ||
101 | } | ||
102 | |||
103 | if (le32_to_cpu(rf->rf_lvblen) != ls->ls_lvblen || | ||
104 | le32_to_cpu(rf->rf_lsflags) != ls->ls_exflags) { | ||
98 | log_error(ls, "config mismatch: %d,%x nodeid %d: %d,%x", | 105 | log_error(ls, "config mismatch: %d,%x nodeid %d: %d,%x", |
99 | ls->ls_lvblen, ls->ls_exflags, | 106 | ls->ls_lvblen, ls->ls_exflags, nodeid, |
100 | nodeid, rf->rf_lvblen, rf->rf_lsflags); | 107 | le32_to_cpu(rf->rf_lvblen), |
108 | le32_to_cpu(rf->rf_lsflags)); | ||
101 | return -EPROTO; | 109 | return -EPROTO; |
102 | } | 110 | } |
103 | return 0; | 111 | return 0; |
@@ -128,7 +136,7 @@ int dlm_rcom_status(struct dlm_ls *ls, int nodeid) | |||
128 | ls->ls_recover_nodeid = nodeid; | 136 | ls->ls_recover_nodeid = nodeid; |
129 | 137 | ||
130 | if (nodeid == dlm_our_nodeid()) { | 138 | if (nodeid == dlm_our_nodeid()) { |
131 | rc = (struct dlm_rcom *) ls->ls_recover_buf; | 139 | rc = ls->ls_recover_buf; |
132 | rc->rc_result = dlm_recover_status(ls); | 140 | rc->rc_result = dlm_recover_status(ls); |
133 | goto out; | 141 | goto out; |
134 | } | 142 | } |
@@ -147,7 +155,7 @@ int dlm_rcom_status(struct dlm_ls *ls, int nodeid) | |||
147 | if (error) | 155 | if (error) |
148 | goto out; | 156 | goto out; |
149 | 157 | ||
150 | rc = (struct dlm_rcom *) ls->ls_recover_buf; | 158 | rc = ls->ls_recover_buf; |
151 | 159 | ||
152 | if (rc->rc_result == -ESRCH) { | 160 | if (rc->rc_result == -ESRCH) { |
153 | /* we pretend the remote lockspace exists with 0 status */ | 161 | /* we pretend the remote lockspace exists with 0 status */ |
@@ -201,14 +209,15 @@ int dlm_rcom_names(struct dlm_ls *ls, int nodeid, char *last_name, int last_len) | |||
201 | { | 209 | { |
202 | struct dlm_rcom *rc; | 210 | struct dlm_rcom *rc; |
203 | struct dlm_mhandle *mh; | 211 | struct dlm_mhandle *mh; |
204 | int error = 0, len = sizeof(struct dlm_rcom); | 212 | int error = 0; |
213 | int max_size = dlm_config.ci_buffer_size - sizeof(struct dlm_rcom); | ||
205 | 214 | ||
206 | ls->ls_recover_nodeid = nodeid; | 215 | ls->ls_recover_nodeid = nodeid; |
207 | 216 | ||
208 | if (nodeid == dlm_our_nodeid()) { | 217 | if (nodeid == dlm_our_nodeid()) { |
209 | dlm_copy_master_names(ls, last_name, last_len, | 218 | dlm_copy_master_names(ls, last_name, last_len, |
210 | ls->ls_recover_buf + len, | 219 | ls->ls_recover_buf->rc_buf, |
211 | dlm_config.ci_buffer_size - len, nodeid); | 220 | max_size, nodeid); |
212 | goto out; | 221 | goto out; |
213 | } | 222 | } |
214 | 223 | ||
@@ -299,22 +308,22 @@ static void pack_rcom_lock(struct dlm_rsb *r, struct dlm_lkb *lkb, | |||
299 | { | 308 | { |
300 | memset(rl, 0, sizeof(*rl)); | 309 | memset(rl, 0, sizeof(*rl)); |
301 | 310 | ||
302 | rl->rl_ownpid = lkb->lkb_ownpid; | 311 | rl->rl_ownpid = cpu_to_le32(lkb->lkb_ownpid); |
303 | rl->rl_lkid = lkb->lkb_id; | 312 | rl->rl_lkid = cpu_to_le32(lkb->lkb_id); |
304 | rl->rl_exflags = lkb->lkb_exflags; | 313 | rl->rl_exflags = cpu_to_le32(lkb->lkb_exflags); |
305 | rl->rl_flags = lkb->lkb_flags; | 314 | rl->rl_flags = cpu_to_le32(lkb->lkb_flags); |
306 | rl->rl_lvbseq = lkb->lkb_lvbseq; | 315 | rl->rl_lvbseq = cpu_to_le32(lkb->lkb_lvbseq); |
307 | rl->rl_rqmode = lkb->lkb_rqmode; | 316 | rl->rl_rqmode = lkb->lkb_rqmode; |
308 | rl->rl_grmode = lkb->lkb_grmode; | 317 | rl->rl_grmode = lkb->lkb_grmode; |
309 | rl->rl_status = lkb->lkb_status; | 318 | rl->rl_status = lkb->lkb_status; |
310 | rl->rl_wait_type = lkb->lkb_wait_type; | 319 | rl->rl_wait_type = cpu_to_le16(lkb->lkb_wait_type); |
311 | 320 | ||
312 | if (lkb->lkb_bastaddr) | 321 | if (lkb->lkb_bastfn) |
313 | rl->rl_asts |= AST_BAST; | 322 | rl->rl_asts |= AST_BAST; |
314 | if (lkb->lkb_astaddr) | 323 | if (lkb->lkb_astfn) |
315 | rl->rl_asts |= AST_COMP; | 324 | rl->rl_asts |= AST_COMP; |
316 | 325 | ||
317 | rl->rl_namelen = r->res_length; | 326 | rl->rl_namelen = cpu_to_le16(r->res_length); |
318 | memcpy(rl->rl_name, r->res_name, r->res_length); | 327 | memcpy(rl->rl_name, r->res_name, r->res_length); |
319 | 328 | ||
320 | /* FIXME: might we have an lvb without DLM_LKF_VALBLK set ? | 329 | /* FIXME: might we have an lvb without DLM_LKF_VALBLK set ? |
@@ -348,6 +357,7 @@ int dlm_send_rcom_lock(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
348 | return error; | 357 | return error; |
349 | } | 358 | } |
350 | 359 | ||
360 | /* needs at least dlm_rcom + rcom_lock */ | ||
351 | static void receive_rcom_lock(struct dlm_ls *ls, struct dlm_rcom *rc_in) | 361 | static void receive_rcom_lock(struct dlm_ls *ls, struct dlm_rcom *rc_in) |
352 | { | 362 | { |
353 | struct dlm_rcom *rc; | 363 | struct dlm_rcom *rc; |
@@ -401,7 +411,7 @@ int dlm_send_ls_not_ready(int nodeid, struct dlm_rcom *rc_in) | |||
401 | rc->rc_result = -ESRCH; | 411 | rc->rc_result = -ESRCH; |
402 | 412 | ||
403 | rf = (struct rcom_config *) rc->rc_buf; | 413 | rf = (struct rcom_config *) rc->rc_buf; |
404 | rf->rf_lvblen = -1; | 414 | rf->rf_lvblen = cpu_to_le32(~0U); |
405 | 415 | ||
406 | dlm_rcom_out(rc); | 416 | dlm_rcom_out(rc); |
407 | dlm_lowcomms_commit_buffer(mh); | 417 | dlm_lowcomms_commit_buffer(mh); |
@@ -439,6 +449,8 @@ static int is_old_reply(struct dlm_ls *ls, struct dlm_rcom *rc) | |||
439 | 449 | ||
440 | void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid) | 450 | void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid) |
441 | { | 451 | { |
452 | int lock_size = sizeof(struct dlm_rcom) + sizeof(struct rcom_lock); | ||
453 | |||
442 | if (dlm_recovery_stopped(ls) && (rc->rc_type != DLM_RCOM_STATUS)) { | 454 | if (dlm_recovery_stopped(ls) && (rc->rc_type != DLM_RCOM_STATUS)) { |
443 | log_debug(ls, "ignoring recovery message %x from %d", | 455 | log_debug(ls, "ignoring recovery message %x from %d", |
444 | rc->rc_type, nodeid); | 456 | rc->rc_type, nodeid); |
@@ -462,6 +474,8 @@ void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid) | |||
462 | break; | 474 | break; |
463 | 475 | ||
464 | case DLM_RCOM_LOCK: | 476 | case DLM_RCOM_LOCK: |
477 | if (rc->rc_header.h_length < lock_size) | ||
478 | goto Eshort; | ||
465 | receive_rcom_lock(ls, rc); | 479 | receive_rcom_lock(ls, rc); |
466 | break; | 480 | break; |
467 | 481 | ||
@@ -478,13 +492,18 @@ void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid) | |||
478 | break; | 492 | break; |
479 | 493 | ||
480 | case DLM_RCOM_LOCK_REPLY: | 494 | case DLM_RCOM_LOCK_REPLY: |
495 | if (rc->rc_header.h_length < lock_size) | ||
496 | goto Eshort; | ||
481 | dlm_recover_process_copy(ls, rc); | 497 | dlm_recover_process_copy(ls, rc); |
482 | break; | 498 | break; |
483 | 499 | ||
484 | default: | 500 | default: |
485 | log_error(ls, "receive_rcom bad type %d", rc->rc_type); | 501 | log_error(ls, "receive_rcom bad type %d", rc->rc_type); |
486 | } | 502 | } |
487 | out: | 503 | out: |
488 | return; | 504 | return; |
505 | Eshort: | ||
506 | log_error(ls, "recovery message %x from %d is too short", | ||
507 | rc->rc_type, nodeid); | ||
489 | } | 508 | } |
490 | 509 | ||
diff --git a/fs/dlm/recover.c b/fs/dlm/recover.c index df075dc300fa..80aba5bdd4a4 100644 --- a/fs/dlm/recover.c +++ b/fs/dlm/recover.c | |||
@@ -94,7 +94,7 @@ void dlm_set_recover_status(struct dlm_ls *ls, uint32_t status) | |||
94 | 94 | ||
95 | static int wait_status_all(struct dlm_ls *ls, uint32_t wait_status) | 95 | static int wait_status_all(struct dlm_ls *ls, uint32_t wait_status) |
96 | { | 96 | { |
97 | struct dlm_rcom *rc = (struct dlm_rcom *) ls->ls_recover_buf; | 97 | struct dlm_rcom *rc = ls->ls_recover_buf; |
98 | struct dlm_member *memb; | 98 | struct dlm_member *memb; |
99 | int error = 0, delay; | 99 | int error = 0, delay; |
100 | 100 | ||
@@ -123,7 +123,7 @@ static int wait_status_all(struct dlm_ls *ls, uint32_t wait_status) | |||
123 | 123 | ||
124 | static int wait_status_low(struct dlm_ls *ls, uint32_t wait_status) | 124 | static int wait_status_low(struct dlm_ls *ls, uint32_t wait_status) |
125 | { | 125 | { |
126 | struct dlm_rcom *rc = (struct dlm_rcom *) ls->ls_recover_buf; | 126 | struct dlm_rcom *rc = ls->ls_recover_buf; |
127 | int error = 0, delay = 0, nodeid = ls->ls_low_nodeid; | 127 | int error = 0, delay = 0, nodeid = ls->ls_low_nodeid; |
128 | 128 | ||
129 | for (;;) { | 129 | for (;;) { |
diff --git a/fs/dlm/requestqueue.c b/fs/dlm/requestqueue.c index 0de04f17ccea..daa4183fbb84 100644 --- a/fs/dlm/requestqueue.c +++ b/fs/dlm/requestqueue.c | |||
@@ -20,7 +20,7 @@ | |||
20 | struct rq_entry { | 20 | struct rq_entry { |
21 | struct list_head list; | 21 | struct list_head list; |
22 | int nodeid; | 22 | int nodeid; |
23 | char request[0]; | 23 | struct dlm_message request; |
24 | }; | 24 | }; |
25 | 25 | ||
26 | /* | 26 | /* |
@@ -30,10 +30,10 @@ struct rq_entry { | |||
30 | * lockspace is enabled on some while still suspended on others. | 30 | * lockspace is enabled on some while still suspended on others. |
31 | */ | 31 | */ |
32 | 32 | ||
33 | void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_header *hd) | 33 | void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_message *ms) |
34 | { | 34 | { |
35 | struct rq_entry *e; | 35 | struct rq_entry *e; |
36 | int length = hd->h_length; | 36 | int length = ms->m_header.h_length - sizeof(struct dlm_message); |
37 | 37 | ||
38 | e = kmalloc(sizeof(struct rq_entry) + length, GFP_KERNEL); | 38 | e = kmalloc(sizeof(struct rq_entry) + length, GFP_KERNEL); |
39 | if (!e) { | 39 | if (!e) { |
@@ -42,7 +42,7 @@ void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_header *hd) | |||
42 | } | 42 | } |
43 | 43 | ||
44 | e->nodeid = nodeid; | 44 | e->nodeid = nodeid; |
45 | memcpy(e->request, hd, length); | 45 | memcpy(&e->request, ms, ms->m_header.h_length); |
46 | 46 | ||
47 | mutex_lock(&ls->ls_requestqueue_mutex); | 47 | mutex_lock(&ls->ls_requestqueue_mutex); |
48 | list_add_tail(&e->list, &ls->ls_requestqueue); | 48 | list_add_tail(&e->list, &ls->ls_requestqueue); |
@@ -76,7 +76,7 @@ int dlm_process_requestqueue(struct dlm_ls *ls) | |||
76 | e = list_entry(ls->ls_requestqueue.next, struct rq_entry, list); | 76 | e = list_entry(ls->ls_requestqueue.next, struct rq_entry, list); |
77 | mutex_unlock(&ls->ls_requestqueue_mutex); | 77 | mutex_unlock(&ls->ls_requestqueue_mutex); |
78 | 78 | ||
79 | dlm_receive_message_saved(ls, (struct dlm_message *)e->request); | 79 | dlm_receive_message_saved(ls, &e->request); |
80 | 80 | ||
81 | mutex_lock(&ls->ls_requestqueue_mutex); | 81 | mutex_lock(&ls->ls_requestqueue_mutex); |
82 | list_del(&e->list); | 82 | list_del(&e->list); |
@@ -176,7 +176,7 @@ void dlm_purge_requestqueue(struct dlm_ls *ls) | |||
176 | 176 | ||
177 | mutex_lock(&ls->ls_requestqueue_mutex); | 177 | mutex_lock(&ls->ls_requestqueue_mutex); |
178 | list_for_each_entry_safe(e, safe, &ls->ls_requestqueue, list) { | 178 | list_for_each_entry_safe(e, safe, &ls->ls_requestqueue, list) { |
179 | ms = (struct dlm_message *) e->request; | 179 | ms = &e->request; |
180 | 180 | ||
181 | if (purge_request(ls, ms, e->nodeid)) { | 181 | if (purge_request(ls, ms, e->nodeid)) { |
182 | list_del(&e->list); | 182 | list_del(&e->list); |
diff --git a/fs/dlm/requestqueue.h b/fs/dlm/requestqueue.h index aba34fc05ee4..10ce449b77da 100644 --- a/fs/dlm/requestqueue.h +++ b/fs/dlm/requestqueue.h | |||
@@ -13,7 +13,7 @@ | |||
13 | #ifndef __REQUESTQUEUE_DOT_H__ | 13 | #ifndef __REQUESTQUEUE_DOT_H__ |
14 | #define __REQUESTQUEUE_DOT_H__ | 14 | #define __REQUESTQUEUE_DOT_H__ |
15 | 15 | ||
16 | void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_header *hd); | 16 | void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_message *ms); |
17 | int dlm_process_requestqueue(struct dlm_ls *ls); | 17 | int dlm_process_requestqueue(struct dlm_ls *ls); |
18 | void dlm_wait_requestqueue(struct dlm_ls *ls); | 18 | void dlm_wait_requestqueue(struct dlm_ls *ls); |
19 | void dlm_purge_requestqueue(struct dlm_ls *ls); | 19 | void dlm_purge_requestqueue(struct dlm_ls *ls); |
diff --git a/fs/dlm/user.c b/fs/dlm/user.c index 7cbc6826239b..ebbcf38fd33b 100644 --- a/fs/dlm/user.c +++ b/fs/dlm/user.c | |||
@@ -82,7 +82,7 @@ struct dlm_lock_result32 { | |||
82 | 82 | ||
83 | static void compat_input(struct dlm_write_request *kb, | 83 | static void compat_input(struct dlm_write_request *kb, |
84 | struct dlm_write_request32 *kb32, | 84 | struct dlm_write_request32 *kb32, |
85 | int max_namelen) | 85 | size_t count) |
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]; |
@@ -94,7 +94,8 @@ static void compat_input(struct dlm_write_request *kb, | |||
94 | kb->cmd == DLM_USER_REMOVE_LOCKSPACE) { | 94 | kb->cmd == DLM_USER_REMOVE_LOCKSPACE) { |
95 | kb->i.lspace.flags = kb32->i.lspace.flags; | 95 | kb->i.lspace.flags = kb32->i.lspace.flags; |
96 | kb->i.lspace.minor = kb32->i.lspace.minor; | 96 | kb->i.lspace.minor = kb32->i.lspace.minor; |
97 | strcpy(kb->i.lspace.name, kb32->i.lspace.name); | 97 | memcpy(kb->i.lspace.name, kb32->i.lspace.name, count - |
98 | offsetof(struct dlm_write_request32, i.lspace.name)); | ||
98 | } else if (kb->cmd == DLM_USER_PURGE) { | 99 | } else if (kb->cmd == DLM_USER_PURGE) { |
99 | kb->i.purge.nodeid = kb32->i.purge.nodeid; | 100 | kb->i.purge.nodeid = kb32->i.purge.nodeid; |
100 | kb->i.purge.pid = kb32->i.purge.pid; | 101 | kb->i.purge.pid = kb32->i.purge.pid; |
@@ -112,11 +113,8 @@ static void compat_input(struct dlm_write_request *kb, | |||
112 | kb->i.lock.bastaddr = (void *)(long)kb32->i.lock.bastaddr; | 113 | kb->i.lock.bastaddr = (void *)(long)kb32->i.lock.bastaddr; |
113 | kb->i.lock.lksb = (void *)(long)kb32->i.lock.lksb; | 114 | kb->i.lock.lksb = (void *)(long)kb32->i.lock.lksb; |
114 | memcpy(kb->i.lock.lvb, kb32->i.lock.lvb, DLM_USER_LVB_LEN); | 115 | memcpy(kb->i.lock.lvb, kb32->i.lock.lvb, DLM_USER_LVB_LEN); |
115 | if (kb->i.lock.namelen <= max_namelen) | 116 | memcpy(kb->i.lock.name, kb32->i.lock.name, count - |
116 | memcpy(kb->i.lock.name, kb32->i.lock.name, | 117 | offsetof(struct dlm_write_request32, i.lock.name)); |
117 | kb->i.lock.namelen); | ||
118 | else | ||
119 | kb->i.lock.namelen = max_namelen; | ||
120 | } | 118 | } |
121 | } | 119 | } |
122 | 120 | ||
@@ -197,8 +195,8 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type) | |||
197 | if (lkb->lkb_flags & (DLM_IFL_ORPHAN | DLM_IFL_DEAD)) | 195 | if (lkb->lkb_flags & (DLM_IFL_ORPHAN | DLM_IFL_DEAD)) |
198 | goto out; | 196 | goto out; |
199 | 197 | ||
200 | DLM_ASSERT(lkb->lkb_astparam, dlm_print_lkb(lkb);); | 198 | DLM_ASSERT(lkb->lkb_ua, dlm_print_lkb(lkb);); |
201 | ua = (struct dlm_user_args *)lkb->lkb_astparam; | 199 | ua = lkb->lkb_ua; |
202 | proc = ua->proc; | 200 | proc = ua->proc; |
203 | 201 | ||
204 | if (type == AST_BAST && ua->bastaddr == NULL) | 202 | if (type == AST_BAST && ua->bastaddr == NULL) |
@@ -508,7 +506,7 @@ static ssize_t device_write(struct file *file, const char __user *buf, | |||
508 | #endif | 506 | #endif |
509 | return -EINVAL; | 507 | return -EINVAL; |
510 | 508 | ||
511 | kbuf = kmalloc(count, GFP_KERNEL); | 509 | kbuf = kzalloc(count + 1, GFP_KERNEL); |
512 | if (!kbuf) | 510 | if (!kbuf) |
513 | return -ENOMEM; | 511 | return -ENOMEM; |
514 | 512 | ||
@@ -526,15 +524,14 @@ static ssize_t device_write(struct file *file, const char __user *buf, | |||
526 | if (!kbuf->is64bit) { | 524 | if (!kbuf->is64bit) { |
527 | struct dlm_write_request32 *k32buf; | 525 | struct dlm_write_request32 *k32buf; |
528 | k32buf = (struct dlm_write_request32 *)kbuf; | 526 | k32buf = (struct dlm_write_request32 *)kbuf; |
529 | kbuf = kmalloc(count + (sizeof(struct dlm_write_request) - | 527 | kbuf = kmalloc(count + 1 + (sizeof(struct dlm_write_request) - |
530 | sizeof(struct dlm_write_request32)), GFP_KERNEL); | 528 | sizeof(struct dlm_write_request32)), GFP_KERNEL); |
531 | if (!kbuf) | 529 | if (!kbuf) |
532 | return -ENOMEM; | 530 | return -ENOMEM; |
533 | 531 | ||
534 | if (proc) | 532 | if (proc) |
535 | set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags); | 533 | set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags); |
536 | compat_input(kbuf, k32buf, | 534 | compat_input(kbuf, k32buf, count + 1); |
537 | count - sizeof(struct dlm_write_request32)); | ||
538 | kfree(k32buf); | 535 | kfree(k32buf); |
539 | } | 536 | } |
540 | #endif | 537 | #endif |
@@ -774,7 +771,6 @@ static ssize_t device_read(struct file *file, char __user *buf, size_t count, | |||
774 | { | 771 | { |
775 | struct dlm_user_proc *proc = file->private_data; | 772 | struct dlm_user_proc *proc = file->private_data; |
776 | struct dlm_lkb *lkb; | 773 | struct dlm_lkb *lkb; |
777 | struct dlm_user_args *ua; | ||
778 | DECLARE_WAITQUEUE(wait, current); | 774 | DECLARE_WAITQUEUE(wait, current); |
779 | int error, type=0, bmode=0, removed = 0; | 775 | int error, type=0, bmode=0, removed = 0; |
780 | 776 | ||
@@ -845,8 +841,7 @@ static ssize_t device_read(struct file *file, char __user *buf, size_t count, | |||
845 | } | 841 | } |
846 | spin_unlock(&proc->asts_spin); | 842 | spin_unlock(&proc->asts_spin); |
847 | 843 | ||
848 | ua = (struct dlm_user_args *)lkb->lkb_astparam; | 844 | error = copy_result_to_user(lkb->lkb_ua, |
849 | error = copy_result_to_user(ua, | ||
850 | test_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags), | 845 | test_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags), |
851 | type, bmode, buf, count); | 846 | type, bmode, buf, count); |
852 | 847 | ||
@@ -907,7 +902,7 @@ static struct miscdevice ctl_device = { | |||
907 | .minor = MISC_DYNAMIC_MINOR, | 902 | .minor = MISC_DYNAMIC_MINOR, |
908 | }; | 903 | }; |
909 | 904 | ||
910 | int dlm_user_init(void) | 905 | int __init dlm_user_init(void) |
911 | { | 906 | { |
912 | int error; | 907 | int error; |
913 | 908 | ||
diff --git a/fs/dlm/util.c b/fs/dlm/util.c index 4d9c1f4e1bd1..e36520af7cc0 100644 --- a/fs/dlm/util.c +++ b/fs/dlm/util.c | |||
@@ -131,52 +131,8 @@ void dlm_message_in(struct dlm_message *ms) | |||
131 | ms->m_result = from_dlm_errno(le32_to_cpu(ms->m_result)); | 131 | ms->m_result = from_dlm_errno(le32_to_cpu(ms->m_result)); |
132 | } | 132 | } |
133 | 133 | ||
134 | static void rcom_lock_out(struct rcom_lock *rl) | ||
135 | { | ||
136 | rl->rl_ownpid = cpu_to_le32(rl->rl_ownpid); | ||
137 | rl->rl_lkid = cpu_to_le32(rl->rl_lkid); | ||
138 | rl->rl_remid = cpu_to_le32(rl->rl_remid); | ||
139 | rl->rl_parent_lkid = cpu_to_le32(rl->rl_parent_lkid); | ||
140 | rl->rl_parent_remid = cpu_to_le32(rl->rl_parent_remid); | ||
141 | rl->rl_exflags = cpu_to_le32(rl->rl_exflags); | ||
142 | rl->rl_flags = cpu_to_le32(rl->rl_flags); | ||
143 | rl->rl_lvbseq = cpu_to_le32(rl->rl_lvbseq); | ||
144 | rl->rl_result = cpu_to_le32(rl->rl_result); | ||
145 | rl->rl_wait_type = cpu_to_le16(rl->rl_wait_type); | ||
146 | rl->rl_namelen = cpu_to_le16(rl->rl_namelen); | ||
147 | } | ||
148 | |||
149 | static void rcom_lock_in(struct rcom_lock *rl) | ||
150 | { | ||
151 | rl->rl_ownpid = le32_to_cpu(rl->rl_ownpid); | ||
152 | rl->rl_lkid = le32_to_cpu(rl->rl_lkid); | ||
153 | rl->rl_remid = le32_to_cpu(rl->rl_remid); | ||
154 | rl->rl_parent_lkid = le32_to_cpu(rl->rl_parent_lkid); | ||
155 | rl->rl_parent_remid = le32_to_cpu(rl->rl_parent_remid); | ||
156 | rl->rl_exflags = le32_to_cpu(rl->rl_exflags); | ||
157 | rl->rl_flags = le32_to_cpu(rl->rl_flags); | ||
158 | rl->rl_lvbseq = le32_to_cpu(rl->rl_lvbseq); | ||
159 | rl->rl_result = le32_to_cpu(rl->rl_result); | ||
160 | rl->rl_wait_type = le16_to_cpu(rl->rl_wait_type); | ||
161 | rl->rl_namelen = le16_to_cpu(rl->rl_namelen); | ||
162 | } | ||
163 | |||
164 | static void rcom_config_out(struct rcom_config *rf) | ||
165 | { | ||
166 | rf->rf_lvblen = cpu_to_le32(rf->rf_lvblen); | ||
167 | rf->rf_lsflags = cpu_to_le32(rf->rf_lsflags); | ||
168 | } | ||
169 | |||
170 | static void rcom_config_in(struct rcom_config *rf) | ||
171 | { | ||
172 | rf->rf_lvblen = le32_to_cpu(rf->rf_lvblen); | ||
173 | rf->rf_lsflags = le32_to_cpu(rf->rf_lsflags); | ||
174 | } | ||
175 | |||
176 | void dlm_rcom_out(struct dlm_rcom *rc) | 134 | void dlm_rcom_out(struct dlm_rcom *rc) |
177 | { | 135 | { |
178 | int type = rc->rc_type; | ||
179 | |||
180 | header_out(&rc->rc_header); | 136 | header_out(&rc->rc_header); |
181 | 137 | ||
182 | rc->rc_type = cpu_to_le32(rc->rc_type); | 138 | rc->rc_type = cpu_to_le32(rc->rc_type); |
@@ -184,18 +140,10 @@ void dlm_rcom_out(struct dlm_rcom *rc) | |||
184 | rc->rc_id = cpu_to_le64(rc->rc_id); | 140 | rc->rc_id = cpu_to_le64(rc->rc_id); |
185 | rc->rc_seq = cpu_to_le64(rc->rc_seq); | 141 | rc->rc_seq = cpu_to_le64(rc->rc_seq); |
186 | rc->rc_seq_reply = cpu_to_le64(rc->rc_seq_reply); | 142 | rc->rc_seq_reply = cpu_to_le64(rc->rc_seq_reply); |
187 | |||
188 | if ((type == DLM_RCOM_LOCK) || (type == DLM_RCOM_LOCK_REPLY)) | ||
189 | rcom_lock_out((struct rcom_lock *) rc->rc_buf); | ||
190 | |||
191 | else if (type == DLM_RCOM_STATUS_REPLY) | ||
192 | rcom_config_out((struct rcom_config *) rc->rc_buf); | ||
193 | } | 143 | } |
194 | 144 | ||
195 | void dlm_rcom_in(struct dlm_rcom *rc) | 145 | void dlm_rcom_in(struct dlm_rcom *rc) |
196 | { | 146 | { |
197 | int type; | ||
198 | |||
199 | header_in(&rc->rc_header); | 147 | header_in(&rc->rc_header); |
200 | 148 | ||
201 | rc->rc_type = le32_to_cpu(rc->rc_type); | 149 | rc->rc_type = le32_to_cpu(rc->rc_type); |
@@ -203,13 +151,4 @@ void dlm_rcom_in(struct dlm_rcom *rc) | |||
203 | rc->rc_id = le64_to_cpu(rc->rc_id); | 151 | rc->rc_id = le64_to_cpu(rc->rc_id); |
204 | rc->rc_seq = le64_to_cpu(rc->rc_seq); | 152 | rc->rc_seq = le64_to_cpu(rc->rc_seq); |
205 | rc->rc_seq_reply = le64_to_cpu(rc->rc_seq_reply); | 153 | rc->rc_seq_reply = le64_to_cpu(rc->rc_seq_reply); |
206 | |||
207 | type = rc->rc_type; | ||
208 | |||
209 | if ((type == DLM_RCOM_LOCK) || (type == DLM_RCOM_LOCK_REPLY)) | ||
210 | rcom_lock_in((struct rcom_lock *) rc->rc_buf); | ||
211 | |||
212 | else if (type == DLM_RCOM_STATUS_REPLY) | ||
213 | rcom_config_in((struct rcom_config *) rc->rc_buf); | ||
214 | } | 154 | } |
215 | |||