diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-08 09:33:02 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-08 09:33:02 -0800 |
commit | b5eb9513f7c1bee862ada22bf1489f53752686bd (patch) | |
tree | 707404a45b1ca8809fa8607c5d9d96ca9c657db7 | |
parent | dde0013782dbd09e1cc68ca03860f3a62b03cb34 (diff) | |
parent | 30727174b6273c67fa96fb818fe5bdde1ad70e5c (diff) | |
download | linux-b5eb9513f7c1bee862ada22bf1489f53752686bd.tar.bz2 |
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)
-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) dlm_user_add_ast(lkb, type); return; } - DLM_ASSERT(lkb->lkb_astaddr != DLM_FAKE_USER_AST, dlm_print_lkb(lkb);); spin_lock(&ast_queue_lock); if (!(lkb->lkb_ast_type & (AST_COMP | AST_BAST))) { @@ -58,8 +57,8 @@ static void process_asts(void) struct dlm_ls *ls = NULL; struct dlm_rsb *r = NULL; struct dlm_lkb *lkb; - void (*cast) (long param); - void (*bast) (long param, int mode); + void (*cast) (void *astparam); + void (*bast) (void *astparam, int mode); int type = 0, found, bmode; for (;;) { @@ -83,8 +82,8 @@ static void process_asts(void) if (!found) break; - cast = lkb->lkb_astaddr; - bast = lkb->lkb_bastaddr; + cast = lkb->lkb_astfn; + bast = lkb->lkb_bastfn; bmode = lkb->lkb_bastmode; 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 = { }, }; -int dlm_config_init(void) +int __init dlm_config_init(void) { config_group_init(&clusters_root.subsys.su_group); 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) static void print_lock(struct seq_file *s, struct dlm_lkb *lkb, struct dlm_rsb *r) { - struct dlm_user_args *ua; unsigned int waiting = 0; uint64_t xid = 0; if (lkb->lkb_flags & DLM_IFL_USER) { - ua = (struct dlm_user_args *) lkb->lkb_astparam; - if (ua) - xid = ua->xid; + if (lkb->lkb_ua) + xid = lkb->lkb_ua->xid; } if (lkb->lkb_timestamp) @@ -543,7 +541,7 @@ void dlm_delete_debug_file(struct dlm_ls *ls) debugfs_remove(ls->ls_debug_locks_dentry); } -int dlm_register_debugfs(void) +int __init dlm_register_debugfs(void) { mutex_init(&debug_buf_lock); 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) last_len = 0; for (;;) { + int left; error = dlm_recovery_stopped(ls); if (error) goto out_free; @@ -235,12 +236,21 @@ int dlm_recover_directory(struct dlm_ls *ls) * pick namelen/name pairs out of received buffer */ - b = ls->ls_recover_buf + sizeof(struct dlm_rcom); + b = ls->ls_recover_buf->rc_buf; + left = ls->ls_recover_buf->rc_header.h_length; + left -= sizeof(struct dlm_rcom); for (;;) { - memcpy(&namelen, b, sizeof(uint16_t)); - namelen = be16_to_cpu(namelen); - b += sizeof(uint16_t); + __be16 v; + + error = -EINVAL; + if (left < sizeof(__be16)) + goto out_free; + + memcpy(&v, b, sizeof(__be16)); + namelen = be16_to_cpu(v); + b += sizeof(__be16); + left -= sizeof(__be16); /* namelen of 0xFFFFF marks end of names for this node; namelen of 0 marks end of the @@ -251,6 +261,12 @@ int dlm_recover_directory(struct dlm_ls *ls) if (!namelen) break; + if (namelen > left) + goto out_free; + + if (namelen > DLM_RESNAME_MAXLEN) + goto out_free; + error = -ENOMEM; de = get_free_de(ls, namelen); if (!de) @@ -262,6 +278,7 @@ int dlm_recover_directory(struct dlm_ls *ls) memcpy(de->name, b, namelen); memcpy(last_name, b, namelen); b += namelen; + left -= namelen; add_entry_to_hash(ls, de); count++; @@ -302,6 +319,9 @@ static int get_entry(struct dlm_ls *ls, int nodeid, char *name, write_unlock(&ls->ls_dirtbl[bucket].lock); + if (namelen > DLM_RESNAME_MAXLEN) + return -EINVAL; + de = kzalloc(sizeof(struct dlm_direntry) + namelen, GFP_KERNEL); if (!de) 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 { \ } \ } -#define DLM_FAKE_USER_AST ERR_PTR(-EINVAL) - struct dlm_direntry { struct list_head list; @@ -146,9 +144,9 @@ struct dlm_recover { struct dlm_args { uint32_t flags; - void *astaddr; - long astparam; - void *bastaddr; + void (*astfn) (void *astparam); + void *astparam; + void (*bastfn) (void *astparam, int mode); int mode; struct dlm_lksb *lksb; unsigned long timeout; @@ -253,9 +251,12 @@ struct dlm_lkb { char *lkb_lvbptr; struct dlm_lksb *lkb_lksb; /* caller's status block */ - void *lkb_astaddr; /* caller's ast function */ - void *lkb_bastaddr; /* caller's bast function */ - long lkb_astparam; /* caller's ast arg */ + void (*lkb_astfn) (void *astparam); + void (*lkb_bastfn) (void *astparam, int mode); + union { + void *lkb_astparam; /* caller's ast arg */ + struct dlm_user_args *lkb_ua; + }; }; @@ -403,28 +404,34 @@ struct dlm_rcom { char rc_buf[0]; }; +union dlm_packet { + struct dlm_header header; /* common to other two */ + struct dlm_message message; + struct dlm_rcom rcom; +}; + struct rcom_config { - uint32_t rf_lvblen; - uint32_t rf_lsflags; - uint64_t rf_unused; + __le32 rf_lvblen; + __le32 rf_lsflags; + __le64 rf_unused; }; struct rcom_lock { - uint32_t rl_ownpid; - uint32_t rl_lkid; - uint32_t rl_remid; - uint32_t rl_parent_lkid; - uint32_t rl_parent_remid; - uint32_t rl_exflags; - uint32_t rl_flags; - uint32_t rl_lvbseq; - int rl_result; + __le32 rl_ownpid; + __le32 rl_lkid; + __le32 rl_remid; + __le32 rl_parent_lkid; + __le32 rl_parent_remid; + __le32 rl_exflags; + __le32 rl_flags; + __le32 rl_lvbseq; + __le32 rl_result; int8_t rl_rqmode; int8_t rl_grmode; int8_t rl_status; int8_t rl_asts; - uint16_t rl_wait_type; - uint16_t rl_namelen; + __le16 rl_wait_type; + __le16 rl_namelen; char rl_name[DLM_RESNAME_MAXLEN]; char rl_lvb[0]; }; @@ -494,7 +501,7 @@ struct dlm_ls { struct rw_semaphore ls_recv_active; /* block dlm_recv */ struct list_head ls_requestqueue;/* queue remote requests */ struct mutex ls_requestqueue_mutex; - char *ls_recover_buf; + struct dlm_rcom *ls_recover_buf; int ls_recover_nodeid; /* for debugging */ uint64_t ls_rcom_seq; 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, { struct dlm_rsb *r, *tmp; uint32_t hash, bucket; - int error = 0; + int error = -EINVAL; + + if (namelen > DLM_RESNAME_MAXLEN) + goto out; if (dlm_no_directory(ls)) flags |= R_CREATE; + error = 0; hash = jhash(name, namelen, 0); bucket = hash & (ls->ls_rsbtbl_size - 1); @@ -1222,6 +1226,8 @@ static void set_lvb_lock_pc(struct dlm_rsb *r, struct dlm_lkb *lkb, b = dlm_lvb_operations[lkb->lkb_grmode + 1][lkb->lkb_rqmode + 1]; if (b == 1) { int len = receive_extralen(ms); + if (len > DLM_RESNAME_MAXLEN) + len = DLM_RESNAME_MAXLEN; memcpy(lkb->lkb_lvbptr, ms->m_extra, len); lkb->lkb_lvbseq = ms->m_lvbseq; } @@ -1775,7 +1781,7 @@ static void grant_pending_locks(struct dlm_rsb *r) */ list_for_each_entry_safe(lkb, s, &r->res_grantqueue, lkb_statequeue) { - if (lkb->lkb_bastaddr && lock_requires_bast(lkb, high, cw)) { + if (lkb->lkb_bastfn && lock_requires_bast(lkb, high, cw)) { if (cw && high == DLM_LOCK_PR) queue_bast(r, lkb, DLM_LOCK_CW); else @@ -1805,7 +1811,7 @@ static void send_bast_queue(struct dlm_rsb *r, struct list_head *head, struct dlm_lkb *gr; list_for_each_entry(gr, head, lkb_statequeue) { - if (gr->lkb_bastaddr && modes_require_bast(gr, lkb)) { + if (gr->lkb_bastfn && modes_require_bast(gr, lkb)) { queue_bast(r, gr, lkb->lkb_rqmode); gr->lkb_highbast = lkb->lkb_rqmode; } @@ -1960,8 +1966,11 @@ static void confirm_master(struct dlm_rsb *r, int error) } static int set_lock_args(int mode, struct dlm_lksb *lksb, uint32_t flags, - int namelen, unsigned long timeout_cs, void *ast, - void *astarg, void *bast, struct dlm_args *args) + int namelen, unsigned long timeout_cs, + void (*ast) (void *astparam), + void *astparam, + void (*bast) (void *astparam, int mode), + struct dlm_args *args) { int rv = -EINVAL; @@ -2011,9 +2020,9 @@ static int set_lock_args(int mode, struct dlm_lksb *lksb, uint32_t flags, an active lkb cannot be modified before locking the rsb */ args->flags = flags; - args->astaddr = ast; - args->astparam = (long) astarg; - args->bastaddr = bast; + args->astfn = ast; + args->astparam = astparam; + args->bastfn = bast; args->timeout = timeout_cs; args->mode = mode; args->lksb = lksb; @@ -2032,7 +2041,7 @@ static int set_unlock_args(uint32_t flags, void *astarg, struct dlm_args *args) return -EINVAL; args->flags = flags; - args->astparam = (long) astarg; + args->astparam = astarg; return 0; } @@ -2062,9 +2071,9 @@ static int validate_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb, lkb->lkb_exflags = args->flags; lkb->lkb_sbflags = 0; - lkb->lkb_astaddr = args->astaddr; + lkb->lkb_astfn = args->astfn; lkb->lkb_astparam = args->astparam; - lkb->lkb_bastaddr = args->bastaddr; + lkb->lkb_bastfn = args->bastfn; lkb->lkb_rqmode = args->mode; lkb->lkb_lksb = args->lksb; lkb->lkb_lvbptr = args->lksb->sb_lvbptr; @@ -2711,9 +2720,9 @@ static void send_args(struct dlm_rsb *r, struct dlm_lkb *lkb, /* m_result and m_bastmode are set from function args, not from lkb fields */ - if (lkb->lkb_bastaddr) + if (lkb->lkb_bastfn) ms->m_asts |= AST_BAST; - if (lkb->lkb_astaddr) + if (lkb->lkb_astfn) ms->m_asts |= AST_COMP; /* 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, if (!lkb->lkb_lvbptr) return -ENOMEM; len = receive_extralen(ms); + if (len > DLM_RESNAME_MAXLEN) + len = DLM_RESNAME_MAXLEN; memcpy(lkb->lkb_lvbptr, ms->m_extra, len); } return 0; } +static void fake_bastfn(void *astparam, int mode) +{ + log_print("fake_bastfn should not be called"); +} + +static void fake_astfn(void *astparam) +{ + log_print("fake_astfn should not be called"); +} + static int receive_request_args(struct dlm_ls *ls, struct dlm_lkb *lkb, struct dlm_message *ms) { @@ -3002,8 +3023,9 @@ static int receive_request_args(struct dlm_ls *ls, struct dlm_lkb *lkb, lkb->lkb_remid = ms->m_lkid; lkb->lkb_grmode = DLM_LOCK_IV; lkb->lkb_rqmode = ms->m_rqmode; - lkb->lkb_bastaddr = (void *) (long) (ms->m_asts & AST_BAST); - lkb->lkb_astaddr = (void *) (long) (ms->m_asts & AST_COMP); + + lkb->lkb_bastfn = (ms->m_asts & AST_BAST) ? &fake_bastfn : NULL; + lkb->lkb_astfn = (ms->m_asts & AST_COMP) ? &fake_astfn : NULL; if (lkb->lkb_exflags & DLM_LKF_VALBLK) { /* 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, int nodeid) { if (dlm_locking_stopped(ls)) { - dlm_add_requestqueue(ls, nodeid, (struct dlm_header *) ms); + dlm_add_requestqueue(ls, nodeid, ms); } else { dlm_wait_requestqueue(ls); _receive_message(ls, ms); @@ -3822,21 +3844,20 @@ void dlm_receive_message_saved(struct dlm_ls *ls, struct dlm_message *ms) standard locking activity) or an RCOM (recovery message sent as part of lockspace recovery). */ -void dlm_receive_buffer(struct dlm_header *hd, int nodeid) +void dlm_receive_buffer(union dlm_packet *p, int nodeid) { - struct dlm_message *ms = (struct dlm_message *) hd; - struct dlm_rcom *rc = (struct dlm_rcom *) hd; + struct dlm_header *hd = &p->header; struct dlm_ls *ls; int type = 0; switch (hd->h_cmd) { case DLM_MSG: - dlm_message_in(ms); - type = ms->m_type; + dlm_message_in(&p->message); + type = p->message.m_type; break; case DLM_RCOM: - dlm_rcom_in(rc); - type = rc->rc_type; + dlm_rcom_in(&p->rcom); + type = p->rcom.rc_type; break; default: 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) hd->h_lockspace, nodeid, hd->h_cmd, type); if (hd->h_cmd == DLM_RCOM && type == DLM_RCOM_STATUS) - dlm_send_ls_not_ready(nodeid, rc); + dlm_send_ls_not_ready(nodeid, &p->rcom); return; } @@ -3865,9 +3886,9 @@ void dlm_receive_buffer(struct dlm_header *hd, int nodeid) down_read(&ls->ls_recv_active); if (hd->h_cmd == DLM_MSG) - dlm_receive_message(ls, ms, nodeid); + dlm_receive_message(ls, &p->message, nodeid); else - dlm_receive_rcom(ls, rc, nodeid); + dlm_receive_rcom(ls, &p->rcom, nodeid); up_read(&ls->ls_recv_active); dlm_put_lockspace(ls); @@ -4267,32 +4288,34 @@ static struct dlm_lkb *search_remid(struct dlm_rsb *r, int nodeid, return NULL; } +/* needs at least dlm_rcom + rcom_lock */ static int receive_rcom_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb, struct dlm_rsb *r, struct dlm_rcom *rc) { struct rcom_lock *rl = (struct rcom_lock *) rc->rc_buf; - int lvblen; lkb->lkb_nodeid = rc->rc_header.h_nodeid; - lkb->lkb_ownpid = rl->rl_ownpid; - lkb->lkb_remid = rl->rl_lkid; - lkb->lkb_exflags = rl->rl_exflags; - lkb->lkb_flags = rl->rl_flags & 0x0000FFFF; + lkb->lkb_ownpid = le32_to_cpu(rl->rl_ownpid); + lkb->lkb_remid = le32_to_cpu(rl->rl_lkid); + lkb->lkb_exflags = le32_to_cpu(rl->rl_exflags); + lkb->lkb_flags = le32_to_cpu(rl->rl_flags) & 0x0000FFFF; lkb->lkb_flags |= DLM_IFL_MSTCPY; - lkb->lkb_lvbseq = rl->rl_lvbseq; + lkb->lkb_lvbseq = le32_to_cpu(rl->rl_lvbseq); lkb->lkb_rqmode = rl->rl_rqmode; lkb->lkb_grmode = rl->rl_grmode; /* don't set lkb_status because add_lkb wants to itself */ - lkb->lkb_bastaddr = (void *) (long) (rl->rl_asts & AST_BAST); - lkb->lkb_astaddr = (void *) (long) (rl->rl_asts & AST_COMP); + lkb->lkb_bastfn = (rl->rl_asts & AST_BAST) ? &fake_bastfn : NULL; + lkb->lkb_astfn = (rl->rl_asts & AST_COMP) ? &fake_astfn : NULL; if (lkb->lkb_exflags & DLM_LKF_VALBLK) { + int lvblen = rc->rc_header.h_length - sizeof(struct dlm_rcom) - + sizeof(struct rcom_lock); + if (lvblen > ls->ls_lvblen) + return -EINVAL; lkb->lkb_lvbptr = dlm_allocate_lvb(ls); if (!lkb->lkb_lvbptr) return -ENOMEM; - lvblen = rc->rc_header.h_length - sizeof(struct dlm_rcom) - - sizeof(struct rcom_lock); memcpy(lkb->lkb_lvbptr, rl->rl_lvb, lvblen); } @@ -4300,7 +4323,8 @@ static int receive_rcom_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb, The real granted mode of these converting locks cannot be determined until all locks have been rebuilt on the rsb (recover_conversion) */ - if (rl->rl_wait_type == DLM_MSG_CONVERT && middle_conversion(lkb)) { + if (rl->rl_wait_type == cpu_to_le16(DLM_MSG_CONVERT) && + middle_conversion(lkb)) { rl->rl_status = DLM_LKSTS_CONVERT; lkb->lkb_grmode = DLM_LOCK_IV; 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, the given values and send back our lkid. We send back our lkid by sending back the rcom_lock struct we got but with the remid field filled in. */ +/* needs at least dlm_rcom + rcom_lock */ int dlm_recover_master_copy(struct dlm_ls *ls, struct dlm_rcom *rc) { 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) goto out; } - error = find_rsb(ls, rl->rl_name, rl->rl_namelen, R_MASTER, &r); + error = find_rsb(ls, rl->rl_name, le16_to_cpu(rl->rl_namelen), + R_MASTER, &r); if (error) goto out; lock_rsb(r); - lkb = search_remid(r, rc->rc_header.h_nodeid, rl->rl_lkid); + lkb = search_remid(r, rc->rc_header.h_nodeid, le32_to_cpu(rl->rl_lkid)); if (lkb) { error = -EEXIST; goto out_remid; @@ -4356,18 +4382,20 @@ int dlm_recover_master_copy(struct dlm_ls *ls, struct dlm_rcom *rc) out_remid: /* this is the new value returned to the lock holder for saving in its process-copy lkb */ - rl->rl_remid = lkb->lkb_id; + rl->rl_remid = cpu_to_le32(lkb->lkb_id); out_unlock: unlock_rsb(r); put_rsb(r); out: if (error) - log_debug(ls, "recover_master_copy %d %x", error, rl->rl_lkid); - rl->rl_result = error; + log_debug(ls, "recover_master_copy %d %x", error, + le32_to_cpu(rl->rl_lkid)); + rl->rl_result = cpu_to_le32(error); return error; } +/* needs at least dlm_rcom + rcom_lock */ int dlm_recover_process_copy(struct dlm_ls *ls, struct dlm_rcom *rc) { 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) struct dlm_lkb *lkb; int error; - error = find_lkb(ls, rl->rl_lkid, &lkb); + error = find_lkb(ls, le32_to_cpu(rl->rl_lkid), &lkb); if (error) { - log_error(ls, "recover_process_copy no lkid %x", rl->rl_lkid); + log_error(ls, "recover_process_copy no lkid %x", + le32_to_cpu(rl->rl_lkid)); return error; } DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb);); - error = rl->rl_result; + error = le32_to_cpu(rl->rl_result); r = lkb->lkb_resource; hold_rsb(r); @@ -4402,7 +4431,7 @@ int dlm_recover_process_copy(struct dlm_ls *ls, struct dlm_rcom *rc) log_debug(ls, "master copy exists %x", lkb->lkb_id); /* fall through */ case 0: - lkb->lkb_remid = rl->rl_remid; + lkb->lkb_remid = le32_to_cpu(rl->rl_remid); break; default: 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, lock and that lkb_astparam is the dlm_user_args structure. */ error = set_lock_args(mode, &ua->lksb, flags, namelen, timeout_cs, - DLM_FAKE_USER_AST, ua, DLM_FAKE_USER_AST, &args); + fake_astfn, ua, fake_bastfn, &args); lkb->lkb_flags |= DLM_IFL_USER; ua->old_mode = DLM_LOCK_IV; @@ -4504,7 +4533,7 @@ int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, /* user can change the params on its lock when it converts it, or add an lvb that didn't exist before */ - ua = (struct dlm_user_args *)lkb->lkb_astparam; + ua = lkb->lkb_ua; if (flags & DLM_LKF_VALBLK && !ua->lksb.sb_lvbptr) { 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, ua->old_mode = lkb->lkb_grmode; error = set_lock_args(mode, &ua->lksb, flags, 0, timeout_cs, - DLM_FAKE_USER_AST, ua, DLM_FAKE_USER_AST, &args); + fake_astfn, ua, fake_bastfn, &args); if (error) goto out_put; @@ -4555,7 +4584,7 @@ int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, if (error) goto out; - ua = (struct dlm_user_args *)lkb->lkb_astparam; + ua = lkb->lkb_ua; if (lvb_in && ua->lksb.sb_lvbptr) 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, if (error) goto out; - ua = (struct dlm_user_args *)lkb->lkb_astparam; + ua = lkb->lkb_ua; if (ua_tmp->castparam) ua->castparam = ua_tmp->castparam; 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) if (error) goto out; - ua = (struct dlm_user_args *)lkb->lkb_astparam; + ua = lkb->lkb_ua; error = set_unlock_args(flags, ua, &args); if (error) @@ -4681,7 +4710,6 @@ int dlm_user_deadlock(struct dlm_ls *ls, uint32_t flags, uint32_t lkid) static int orphan_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb) { - struct dlm_user_args *ua = (struct dlm_user_args *)lkb->lkb_astparam; struct dlm_args args; int error; @@ -4690,7 +4718,7 @@ static int orphan_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb) list_add_tail(&lkb->lkb_ownqueue, &ls->ls_orphans); mutex_unlock(&ls->ls_orphans_mutex); - set_unlock_args(0, ua, &args); + set_unlock_args(0, lkb->lkb_ua, &args); error = cancel_lock(ls, lkb, &args); if (error == -DLM_ECANCEL) @@ -4703,11 +4731,10 @@ static int orphan_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb) static int unlock_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb) { - struct dlm_user_args *ua = (struct dlm_user_args *)lkb->lkb_astparam; struct dlm_args args; int error; - set_unlock_args(DLM_LKF_FORCEUNLOCK, ua, &args); + set_unlock_args(DLM_LKF_FORCEUNLOCK, lkb->lkb_ua, &args); error = unlock_lock(ls, lkb, &args); 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); void dlm_dump_rsb(struct dlm_rsb *r); void dlm_print_lkb(struct dlm_lkb *lkb); void dlm_receive_message_saved(struct dlm_ls *ls, struct dlm_message *ms); -void dlm_receive_buffer(struct dlm_header *hd, int nodeid); +void dlm_receive_buffer(union dlm_packet *p, int nodeid); int dlm_modes_compat(int mode1, int mode2); void dlm_put_rsb(struct dlm_rsb *r); 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) } -int dlm_lockspace_init(void) +int __init dlm_lockspace_init(void) { ls_count = 0; 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 @@ static struct kmem_cache *lkb_cache; -int dlm_memory_init(void) +int __init dlm_memory_init(void) { int ret = 0; @@ -80,7 +80,7 @@ void dlm_free_lkb(struct dlm_lkb *lkb) { if (lkb->lkb_flags & DLM_IFL_USER) { struct dlm_user_args *ua; - ua = (struct dlm_user_args *)lkb->lkb_astparam; + ua = lkb->lkb_ua; if (ua) { if (ua->lksb.sb_lvbptr) 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, union { unsigned char __buf[DLM_INBUF_LEN]; /* this is to force proper alignment on some arches */ - struct dlm_header dlm; + union dlm_packet p; } __tmp; - struct dlm_header *msg = &__tmp.dlm; + union dlm_packet *p = &__tmp.p; int ret = 0; int err = 0; uint16_t msglen; @@ -75,15 +75,22 @@ int dlm_process_incoming_buffer(int nodeid, const void *base, message may wrap around the end of the buffer back to the start, so we need to use a temp buffer and copy_from_cb. */ - copy_from_cb(msg, base, offset, sizeof(struct dlm_header), + copy_from_cb(p, base, offset, sizeof(struct dlm_header), limit); - msglen = le16_to_cpu(msg->h_length); - lockspace = msg->h_lockspace; + msglen = le16_to_cpu(p->header.h_length); + lockspace = p->header.h_lockspace; err = -EINVAL; if (msglen < sizeof(struct dlm_header)) break; + if (p->header.h_cmd == DLM_MSG) { + if (msglen < sizeof(struct dlm_message)) + break; + } else { + if (msglen < sizeof(struct dlm_rcom)) + break; + } err = -E2BIG; if (msglen > dlm_config.ci_buffer_size) { 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, in the buffer on the stack (which should work for most ordinary messages). */ - if (msglen > DLM_INBUF_LEN && msg == &__tmp.dlm) { - msg = kmalloc(dlm_config.ci_buffer_size, GFP_KERNEL); - if (msg == NULL) + if (msglen > sizeof(__tmp) && p == &__tmp.p) { + p = kmalloc(dlm_config.ci_buffer_size, GFP_KERNEL); + if (p == NULL) return ret; } - copy_from_cb(msg, base, offset, msglen, limit); + copy_from_cb(p, base, offset, msglen, limit); - BUG_ON(lockspace != msg->h_lockspace); + BUG_ON(lockspace != p->header.h_lockspace); ret += msglen; offset += msglen; offset &= (limit - 1); len -= msglen; - dlm_receive_buffer(msg, nodeid); + dlm_receive_buffer(p, nodeid); } - if (msg != &__tmp.dlm) - kfree(msg); + if (p != &__tmp.p) + kfree(p); return err ? err : ret; } 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 = { .doit = user_cmd, }; -int dlm_netlink_init(void) +int __init dlm_netlink_init(void) { int rv; @@ -95,7 +95,7 @@ int dlm_netlink_init(void) return rv; } -void dlm_netlink_exit(void) +void __exit dlm_netlink_exit(void) { genl_unregister_ops(&family, &dlm_nl_ops); genl_unregister_family(&family); @@ -104,7 +104,6 @@ void dlm_netlink_exit(void) static void fill_data(struct dlm_lock_data *data, struct dlm_lkb *lkb) { struct dlm_rsb *r = lkb->lkb_resource; - struct dlm_user_args *ua = (struct dlm_user_args *) lkb->lkb_astparam; memset(data, 0, sizeof(struct dlm_lock_data)); @@ -117,8 +116,8 @@ static void fill_data(struct dlm_lock_data *data, struct dlm_lkb *lkb) data->grmode = lkb->lkb_grmode; data->rqmode = lkb->lkb_rqmode; data->timestamp = lkb->lkb_timestamp; - if (ua) - data->xid = ua->xid; + if (lkb->lkb_ua) + data->xid = lkb->lkb_ua->xid; if (r) { data->lockspace_id = r->res_ls->ls_global_id; 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, static void make_config(struct dlm_ls *ls, struct rcom_config *rf) { - rf->rf_lvblen = ls->ls_lvblen; - rf->rf_lsflags = ls->ls_exflags; + rf->rf_lvblen = cpu_to_le32(ls->ls_lvblen); + rf->rf_lsflags = cpu_to_le32(ls->ls_exflags); } static int check_config(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid) { struct rcom_config *rf = (struct rcom_config *) rc->rc_buf; + size_t conf_size = sizeof(struct dlm_rcom) + sizeof(struct rcom_config); if ((rc->rc_header.h_version & 0xFFFF0000) != DLM_HEADER_MAJOR) { 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) return -EPROTO; } - if (rf->rf_lvblen != ls->ls_lvblen || - rf->rf_lsflags != ls->ls_exflags) { + if (rc->rc_header.h_length < conf_size) { + log_error(ls, "config too short: %d nodeid %d", + rc->rc_header.h_length, nodeid); + return -EPROTO; + } + + if (le32_to_cpu(rf->rf_lvblen) != ls->ls_lvblen || + le32_to_cpu(rf->rf_lsflags) != ls->ls_exflags) { log_error(ls, "config mismatch: %d,%x nodeid %d: %d,%x", - ls->ls_lvblen, ls->ls_exflags, - nodeid, rf->rf_lvblen, rf->rf_lsflags); + ls->ls_lvblen, ls->ls_exflags, nodeid, + le32_to_cpu(rf->rf_lvblen), + le32_to_cpu(rf->rf_lsflags)); return -EPROTO; } return 0; @@ -128,7 +136,7 @@ int dlm_rcom_status(struct dlm_ls *ls, int nodeid) ls->ls_recover_nodeid = nodeid; if (nodeid == dlm_our_nodeid()) { - rc = (struct dlm_rcom *) ls->ls_recover_buf; + rc = ls->ls_recover_buf; rc->rc_result = dlm_recover_status(ls); goto out; } @@ -147,7 +155,7 @@ int dlm_rcom_status(struct dlm_ls *ls, int nodeid) if (error) goto out; - rc = (struct dlm_rcom *) ls->ls_recover_buf; + rc = ls->ls_recover_buf; if (rc->rc_result == -ESRCH) { /* 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) { struct dlm_rcom *rc; struct dlm_mhandle *mh; - int error = 0, len = sizeof(struct dlm_rcom); + int error = 0; + int max_size = dlm_config.ci_buffer_size - sizeof(struct dlm_rcom); ls->ls_recover_nodeid = nodeid; if (nodeid == dlm_our_nodeid()) { dlm_copy_master_names(ls, last_name, last_len, - ls->ls_recover_buf + len, - dlm_config.ci_buffer_size - len, nodeid); + ls->ls_recover_buf->rc_buf, + max_size, nodeid); goto out; } @@ -299,22 +308,22 @@ static void pack_rcom_lock(struct dlm_rsb *r, struct dlm_lkb *lkb, { memset(rl, 0, sizeof(*rl)); - rl->rl_ownpid = lkb->lkb_ownpid; - rl->rl_lkid = lkb->lkb_id; - rl->rl_exflags = lkb->lkb_exflags; - rl->rl_flags = lkb->lkb_flags; - rl->rl_lvbseq = lkb->lkb_lvbseq; + rl->rl_ownpid = cpu_to_le32(lkb->lkb_ownpid); + rl->rl_lkid = cpu_to_le32(lkb->lkb_id); + rl->rl_exflags = cpu_to_le32(lkb->lkb_exflags); + rl->rl_flags = cpu_to_le32(lkb->lkb_flags); + rl->rl_lvbseq = cpu_to_le32(lkb->lkb_lvbseq); rl->rl_rqmode = lkb->lkb_rqmode; rl->rl_grmode = lkb->lkb_grmode; rl->rl_status = lkb->lkb_status; - rl->rl_wait_type = lkb->lkb_wait_type; + rl->rl_wait_type = cpu_to_le16(lkb->lkb_wait_type); - if (lkb->lkb_bastaddr) + if (lkb->lkb_bastfn) rl->rl_asts |= AST_BAST; - if (lkb->lkb_astaddr) + if (lkb->lkb_astfn) rl->rl_asts |= AST_COMP; - rl->rl_namelen = r->res_length; + rl->rl_namelen = cpu_to_le16(r->res_length); memcpy(rl->rl_name, r->res_name, r->res_length); /* 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) return error; } +/* needs at least dlm_rcom + rcom_lock */ static void receive_rcom_lock(struct dlm_ls *ls, struct dlm_rcom *rc_in) { struct dlm_rcom *rc; @@ -401,7 +411,7 @@ int dlm_send_ls_not_ready(int nodeid, struct dlm_rcom *rc_in) rc->rc_result = -ESRCH; rf = (struct rcom_config *) rc->rc_buf; - rf->rf_lvblen = -1; + rf->rf_lvblen = cpu_to_le32(~0U); dlm_rcom_out(rc); dlm_lowcomms_commit_buffer(mh); @@ -439,6 +449,8 @@ static int is_old_reply(struct dlm_ls *ls, struct dlm_rcom *rc) void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid) { + int lock_size = sizeof(struct dlm_rcom) + sizeof(struct rcom_lock); + if (dlm_recovery_stopped(ls) && (rc->rc_type != DLM_RCOM_STATUS)) { log_debug(ls, "ignoring recovery message %x from %d", rc->rc_type, nodeid); @@ -462,6 +474,8 @@ void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid) break; case DLM_RCOM_LOCK: + if (rc->rc_header.h_length < lock_size) + goto Eshort; receive_rcom_lock(ls, rc); break; @@ -478,13 +492,18 @@ void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid) break; case DLM_RCOM_LOCK_REPLY: + if (rc->rc_header.h_length < lock_size) + goto Eshort; dlm_recover_process_copy(ls, rc); break; default: log_error(ls, "receive_rcom bad type %d", rc->rc_type); } - out: +out: return; +Eshort: + log_error(ls, "recovery message %x from %d is too short", + rc->rc_type, nodeid); } 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) static int wait_status_all(struct dlm_ls *ls, uint32_t wait_status) { - struct dlm_rcom *rc = (struct dlm_rcom *) ls->ls_recover_buf; + struct dlm_rcom *rc = ls->ls_recover_buf; struct dlm_member *memb; int error = 0, delay; @@ -123,7 +123,7 @@ static int wait_status_all(struct dlm_ls *ls, uint32_t wait_status) static int wait_status_low(struct dlm_ls *ls, uint32_t wait_status) { - struct dlm_rcom *rc = (struct dlm_rcom *) ls->ls_recover_buf; + struct dlm_rcom *rc = ls->ls_recover_buf; int error = 0, delay = 0, nodeid = ls->ls_low_nodeid; 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 @@ struct rq_entry { struct list_head list; int nodeid; - char request[0]; + struct dlm_message request; }; /* @@ -30,10 +30,10 @@ struct rq_entry { * lockspace is enabled on some while still suspended on others. */ -void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_header *hd) +void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_message *ms) { struct rq_entry *e; - int length = hd->h_length; + int length = ms->m_header.h_length - sizeof(struct dlm_message); e = kmalloc(sizeof(struct rq_entry) + length, GFP_KERNEL); if (!e) { @@ -42,7 +42,7 @@ void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_header *hd) } e->nodeid = nodeid; - memcpy(e->request, hd, length); + memcpy(&e->request, ms, ms->m_header.h_length); mutex_lock(&ls->ls_requestqueue_mutex); list_add_tail(&e->list, &ls->ls_requestqueue); @@ -76,7 +76,7 @@ int dlm_process_requestqueue(struct dlm_ls *ls) e = list_entry(ls->ls_requestqueue.next, struct rq_entry, list); mutex_unlock(&ls->ls_requestqueue_mutex); - dlm_receive_message_saved(ls, (struct dlm_message *)e->request); + dlm_receive_message_saved(ls, &e->request); mutex_lock(&ls->ls_requestqueue_mutex); list_del(&e->list); @@ -176,7 +176,7 @@ void dlm_purge_requestqueue(struct dlm_ls *ls) mutex_lock(&ls->ls_requestqueue_mutex); list_for_each_entry_safe(e, safe, &ls->ls_requestqueue, list) { - ms = (struct dlm_message *) e->request; + ms = &e->request; if (purge_request(ls, ms, e->nodeid)) { 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 @@ #ifndef __REQUESTQUEUE_DOT_H__ #define __REQUESTQUEUE_DOT_H__ -void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_header *hd); +void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_message *ms); int dlm_process_requestqueue(struct dlm_ls *ls); void dlm_wait_requestqueue(struct dlm_ls *ls); 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 { static void compat_input(struct dlm_write_request *kb, struct dlm_write_request32 *kb32, - int max_namelen) + size_t count) { kb->version[0] = kb32->version[0]; kb->version[1] = kb32->version[1]; @@ -94,7 +94,8 @@ static void compat_input(struct dlm_write_request *kb, kb->cmd == DLM_USER_REMOVE_LOCKSPACE) { kb->i.lspace.flags = kb32->i.lspace.flags; kb->i.lspace.minor = kb32->i.lspace.minor; - strcpy(kb->i.lspace.name, kb32->i.lspace.name); + memcpy(kb->i.lspace.name, kb32->i.lspace.name, count - + offsetof(struct dlm_write_request32, i.lspace.name)); } else if (kb->cmd == DLM_USER_PURGE) { kb->i.purge.nodeid = kb32->i.purge.nodeid; kb->i.purge.pid = kb32->i.purge.pid; @@ -112,11 +113,8 @@ static void compat_input(struct dlm_write_request *kb, kb->i.lock.bastaddr = (void *)(long)kb32->i.lock.bastaddr; kb->i.lock.lksb = (void *)(long)kb32->i.lock.lksb; memcpy(kb->i.lock.lvb, kb32->i.lock.lvb, DLM_USER_LVB_LEN); - if (kb->i.lock.namelen <= max_namelen) - memcpy(kb->i.lock.name, kb32->i.lock.name, - kb->i.lock.namelen); - else - kb->i.lock.namelen = max_namelen; + memcpy(kb->i.lock.name, kb32->i.lock.name, count - + offsetof(struct dlm_write_request32, i.lock.name)); } } @@ -197,8 +195,8 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type) if (lkb->lkb_flags & (DLM_IFL_ORPHAN | DLM_IFL_DEAD)) goto out; - DLM_ASSERT(lkb->lkb_astparam, dlm_print_lkb(lkb);); - ua = (struct dlm_user_args *)lkb->lkb_astparam; + DLM_ASSERT(lkb->lkb_ua, dlm_print_lkb(lkb);); + ua = lkb->lkb_ua; proc = ua->proc; if (type == AST_BAST && ua->bastaddr == NULL) @@ -508,7 +506,7 @@ static ssize_t device_write(struct file *file, const char __user *buf, #endif return -EINVAL; - kbuf = kmalloc(count, GFP_KERNEL); + kbuf = kzalloc(count + 1, GFP_KERNEL); if (!kbuf) return -ENOMEM; @@ -526,15 +524,14 @@ static ssize_t device_write(struct file *file, const char __user *buf, if (!kbuf->is64bit) { struct dlm_write_request32 *k32buf; k32buf = (struct dlm_write_request32 *)kbuf; - kbuf = kmalloc(count + (sizeof(struct dlm_write_request) - + kbuf = kmalloc(count + 1 + (sizeof(struct dlm_write_request) - sizeof(struct dlm_write_request32)), GFP_KERNEL); if (!kbuf) return -ENOMEM; if (proc) set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags); - compat_input(kbuf, k32buf, - count - sizeof(struct dlm_write_request32)); + compat_input(kbuf, k32buf, count + 1); kfree(k32buf); } #endif @@ -774,7 +771,6 @@ static ssize_t device_read(struct file *file, char __user *buf, size_t count, { struct dlm_user_proc *proc = file->private_data; struct dlm_lkb *lkb; - struct dlm_user_args *ua; DECLARE_WAITQUEUE(wait, current); int error, type=0, bmode=0, removed = 0; @@ -845,8 +841,7 @@ static ssize_t device_read(struct file *file, char __user *buf, size_t count, } spin_unlock(&proc->asts_spin); - ua = (struct dlm_user_args *)lkb->lkb_astparam; - error = copy_result_to_user(ua, + error = copy_result_to_user(lkb->lkb_ua, test_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags), type, bmode, buf, count); @@ -907,7 +902,7 @@ static struct miscdevice ctl_device = { .minor = MISC_DYNAMIC_MINOR, }; -int dlm_user_init(void) +int __init dlm_user_init(void) { int error; 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) ms->m_result = from_dlm_errno(le32_to_cpu(ms->m_result)); } -static void rcom_lock_out(struct rcom_lock *rl) -{ - rl->rl_ownpid = cpu_to_le32(rl->rl_ownpid); - rl->rl_lkid = cpu_to_le32(rl->rl_lkid); - rl->rl_remid = cpu_to_le32(rl->rl_remid); - rl->rl_parent_lkid = cpu_to_le32(rl->rl_parent_lkid); - rl->rl_parent_remid = cpu_to_le32(rl->rl_parent_remid); - rl->rl_exflags = cpu_to_le32(rl->rl_exflags); - rl->rl_flags = cpu_to_le32(rl->rl_flags); - rl->rl_lvbseq = cpu_to_le32(rl->rl_lvbseq); - rl->rl_result = cpu_to_le32(rl->rl_result); - rl->rl_wait_type = cpu_to_le16(rl->rl_wait_type); - rl->rl_namelen = cpu_to_le16(rl->rl_namelen); -} - -static void rcom_lock_in(struct rcom_lock *rl) -{ - rl->rl_ownpid = le32_to_cpu(rl->rl_ownpid); - rl->rl_lkid = le32_to_cpu(rl->rl_lkid); - rl->rl_remid = le32_to_cpu(rl->rl_remid); - rl->rl_parent_lkid = le32_to_cpu(rl->rl_parent_lkid); - rl->rl_parent_remid = le32_to_cpu(rl->rl_parent_remid); - rl->rl_exflags = le32_to_cpu(rl->rl_exflags); - rl->rl_flags = le32_to_cpu(rl->rl_flags); - rl->rl_lvbseq = le32_to_cpu(rl->rl_lvbseq); - rl->rl_result = le32_to_cpu(rl->rl_result); - rl->rl_wait_type = le16_to_cpu(rl->rl_wait_type); - rl->rl_namelen = le16_to_cpu(rl->rl_namelen); -} - -static void rcom_config_out(struct rcom_config *rf) -{ - rf->rf_lvblen = cpu_to_le32(rf->rf_lvblen); - rf->rf_lsflags = cpu_to_le32(rf->rf_lsflags); -} - -static void rcom_config_in(struct rcom_config *rf) -{ - rf->rf_lvblen = le32_to_cpu(rf->rf_lvblen); - rf->rf_lsflags = le32_to_cpu(rf->rf_lsflags); -} - void dlm_rcom_out(struct dlm_rcom *rc) { - int type = rc->rc_type; - header_out(&rc->rc_header); rc->rc_type = cpu_to_le32(rc->rc_type); @@ -184,18 +140,10 @@ void dlm_rcom_out(struct dlm_rcom *rc) rc->rc_id = cpu_to_le64(rc->rc_id); rc->rc_seq = cpu_to_le64(rc->rc_seq); rc->rc_seq_reply = cpu_to_le64(rc->rc_seq_reply); - - if ((type == DLM_RCOM_LOCK) || (type == DLM_RCOM_LOCK_REPLY)) - rcom_lock_out((struct rcom_lock *) rc->rc_buf); - - else if (type == DLM_RCOM_STATUS_REPLY) - rcom_config_out((struct rcom_config *) rc->rc_buf); } void dlm_rcom_in(struct dlm_rcom *rc) { - int type; - header_in(&rc->rc_header); rc->rc_type = le32_to_cpu(rc->rc_type); @@ -203,13 +151,4 @@ void dlm_rcom_in(struct dlm_rcom *rc) rc->rc_id = le64_to_cpu(rc->rc_id); rc->rc_seq = le64_to_cpu(rc->rc_seq); rc->rc_seq_reply = le64_to_cpu(rc->rc_seq_reply); - - type = rc->rc_type; - - if ((type == DLM_RCOM_LOCK) || (type == DLM_RCOM_LOCK_REPLY)) - rcom_lock_in((struct rcom_lock *) rc->rc_buf); - - else if (type == DLM_RCOM_STATUS_REPLY) - rcom_config_in((struct rcom_config *) rc->rc_buf); } - |