mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-08-18 02:22:47 -07:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/dlm
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/dlm: (21 commits) dlm: static initialization improvements dlm: clean ups dlm: Sanity check namelen before copying it dlm: keep cached master rsbs during recovery dlm: change error message to debug dlm: fix possible use-after-free dlm: limit dir lookup loop dlm: reject normal unlock when lock is waiting for lookup dlm: validate messages before processing dlm: reject messages from non-members dlm: another call to confirm_master in receive_request_reply dlm: recover locks waiting for overlap replies dlm: clear ast_type when removing from astqueue dlm: use fixed errno values in messages dlm: swap bytes for rcom lock reply dlm: align midcomms message buffer dlm: close othercons dlm: use dlm prefix on alloc and free functions dlm: don't print common non-errors dlm: proper prototypes ...
This commit is contained in:
commit
f389e9fcec
17 files changed
+398
-236
No files matched your search
+37
-39
@@ -49,7 +49,7 @@ static struct dlm_direntry *get_free_de(struct dlm_ls *ls, int len)
|
||||
spin_unlock(&ls->ls_recover_list_lock);
|
||||
|
||||
if (!found)
|
||||
de = allocate_direntry(ls, len);
|
||||
de = kzalloc(sizeof(struct dlm_direntry) + len, GFP_KERNEL);
|
||||
return de;
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ void dlm_clear_free_entries(struct dlm_ls *ls)
|
||||
de = list_entry(ls->ls_recover_list.next, struct dlm_direntry,
|
||||
list);
|
||||
list_del(&de->list);
|
||||
free_direntry(de);
|
||||
kfree(de);
|
||||
}
|
||||
spin_unlock(&ls->ls_recover_list_lock);
|
||||
}
|
||||
@@ -171,7 +171,7 @@ void dlm_dir_remove_entry(struct dlm_ls *ls, int nodeid, char *name, int namelen
|
||||
}
|
||||
|
||||
list_del(&de->list);
|
||||
free_direntry(de);
|
||||
kfree(de);
|
||||
out:
|
||||
write_unlock(&ls->ls_dirtbl[bucket].lock);
|
||||
}
|
||||
@@ -302,7 +302,7 @@ static int get_entry(struct dlm_ls *ls, int nodeid, char *name,
|
||||
|
||||
write_unlock(&ls->ls_dirtbl[bucket].lock);
|
||||
|
||||
de = allocate_direntry(ls, namelen);
|
||||
de = kzalloc(sizeof(struct dlm_direntry) + namelen, GFP_KERNEL);
|
||||
if (!de)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -313,7 +313,7 @@ static int get_entry(struct dlm_ls *ls, int nodeid, char *name,
|
||||
write_lock(&ls->ls_dirtbl[bucket].lock);
|
||||
tmp = search_bucket(ls, name, namelen, bucket);
|
||||
if (tmp) {
|
||||
free_direntry(de);
|
||||
kfree(de);
|
||||
de = tmp;
|
||||
} else {
|
||||
list_add_tail(&de->list, &ls->ls_dirtbl[bucket].list);
|
||||
@@ -329,49 +329,47 @@ int dlm_dir_lookup(struct dlm_ls *ls, int nodeid, char *name, int namelen,
|
||||
return get_entry(ls, nodeid, name, namelen, r_nodeid);
|
||||
}
|
||||
|
||||
/* Copy the names of master rsb's into the buffer provided.
|
||||
Only select names whose dir node is the given nodeid. */
|
||||
static struct dlm_rsb *find_rsb_root(struct dlm_ls *ls, char *name, int len)
|
||||
{
|
||||
struct dlm_rsb *r;
|
||||
|
||||
down_read(&ls->ls_root_sem);
|
||||
list_for_each_entry(r, &ls->ls_root_list, res_root_list) {
|
||||
if (len == r->res_length && !memcmp(name, r->res_name, len)) {
|
||||
up_read(&ls->ls_root_sem);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
up_read(&ls->ls_root_sem);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Find the rsb where we left off (or start again), then send rsb names
|
||||
for rsb's we're master of and whose directory node matches the requesting
|
||||
node. inbuf is the rsb name last sent, inlen is the name's length */
|
||||
|
||||
void dlm_copy_master_names(struct dlm_ls *ls, char *inbuf, int inlen,
|
||||
char *outbuf, int outlen, int nodeid)
|
||||
{
|
||||
struct list_head *list;
|
||||
struct dlm_rsb *start_r = NULL, *r = NULL;
|
||||
int offset = 0, start_namelen, error, dir_nodeid;
|
||||
char *start_name;
|
||||
struct dlm_rsb *r;
|
||||
int offset = 0, dir_nodeid;
|
||||
uint16_t be_namelen;
|
||||
|
||||
/*
|
||||
* Find the rsb where we left off (or start again)
|
||||
*/
|
||||
|
||||
start_namelen = inlen;
|
||||
start_name = inbuf;
|
||||
|
||||
if (start_namelen > 1) {
|
||||
/*
|
||||
* We could also use a find_rsb_root() function here that
|
||||
* searched the ls_root_list.
|
||||
*/
|
||||
error = dlm_find_rsb(ls, start_name, start_namelen, R_MASTER,
|
||||
&start_r);
|
||||
DLM_ASSERT(!error && start_r,
|
||||
printk("error %d\n", error););
|
||||
DLM_ASSERT(!list_empty(&start_r->res_root_list),
|
||||
dlm_print_rsb(start_r););
|
||||
dlm_put_rsb(start_r);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send rsb names for rsb's we're master of and whose directory node
|
||||
* matches the requesting node.
|
||||
*/
|
||||
|
||||
down_read(&ls->ls_root_sem);
|
||||
if (start_r)
|
||||
list = start_r->res_root_list.next;
|
||||
else
|
||||
|
||||
if (inlen > 1) {
|
||||
r = find_rsb_root(ls, inbuf, inlen);
|
||||
if (!r) {
|
||||
inbuf[inlen - 1] = '\0';
|
||||
log_error(ls, "copy_master_names from %d start %d %s",
|
||||
nodeid, inlen, inbuf);
|
||||
goto out;
|
||||
}
|
||||
list = r->res_root_list.next;
|
||||
} else {
|
||||
list = ls->ls_root_list.next;
|
||||
}
|
||||
|
||||
for (offset = 0; list != &ls->ls_root_list; list = list->next) {
|
||||
r = list_entry(list, struct dlm_rsb, res_root_list);
|
||||
|
||||
@@ -570,5 +570,21 @@ static inline int dlm_no_directory(struct dlm_ls *ls)
|
||||
return (ls->ls_exflags & DLM_LSFL_NODIR) ? 1 : 0;
|
||||
}
|
||||
|
||||
int dlm_netlink_init(void);
|
||||
void dlm_netlink_exit(void);
|
||||
void dlm_timeout_warn(struct dlm_lkb *lkb);
|
||||
|
||||
#ifdef CONFIG_DLM_DEBUG
|
||||
int dlm_register_debugfs(void);
|
||||
void dlm_unregister_debugfs(void);
|
||||
int dlm_create_debug_file(struct dlm_ls *ls);
|
||||
void dlm_delete_debug_file(struct dlm_ls *ls);
|
||||
#else
|
||||
static inline int dlm_register_debugfs(void) { return 0; }
|
||||
static inline void dlm_unregister_debugfs(void) { }
|
||||
static inline int dlm_create_debug_file(struct dlm_ls *ls) { return 0; }
|
||||
static inline void dlm_delete_debug_file(struct dlm_ls *ls) { }
|
||||
#endif
|
||||
|
||||
#endif /* __DLM_INTERNAL_DOT_H__ */
|
||||
|
||||
+179
-74
File diff suppressed because it is too large.
Load diff
@@ -19,8 +19,6 @@ 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);
|
||||
int dlm_modes_compat(int mode1, int mode2);
|
||||
int dlm_find_rsb(struct dlm_ls *ls, char *name, int namelen,
|
||||
unsigned int flags, struct dlm_rsb **r_ret);
|
||||
void dlm_put_rsb(struct dlm_rsb *r);
|
||||
void dlm_hold_rsb(struct dlm_rsb *r);
|
||||
int dlm_put_lkb(struct dlm_lkb *lkb);
|
||||
|
||||
+4
-12
@@ -24,14 +24,6 @@
|
||||
#include "recover.h"
|
||||
#include "requestqueue.h"
|
||||
|
||||
#ifdef CONFIG_DLM_DEBUG
|
||||
int dlm_create_debug_file(struct dlm_ls *ls);
|
||||
void dlm_delete_debug_file(struct dlm_ls *ls);
|
||||
#else
|
||||
static inline int dlm_create_debug_file(struct dlm_ls *ls) { return 0; }
|
||||
static inline void dlm_delete_debug_file(struct dlm_ls *ls) { }
|
||||
#endif
|
||||
|
||||
static int ls_count;
|
||||
static struct mutex ls_lock;
|
||||
static struct list_head lslist;
|
||||
@@ -684,9 +676,9 @@ static int release_lockspace(struct dlm_ls *ls, int force)
|
||||
dlm_del_ast(lkb);
|
||||
|
||||
if (lkb->lkb_lvbptr && lkb->lkb_flags & DLM_IFL_MSTCPY)
|
||||
free_lvb(lkb->lkb_lvbptr);
|
||||
dlm_free_lvb(lkb->lkb_lvbptr);
|
||||
|
||||
free_lkb(lkb);
|
||||
dlm_free_lkb(lkb);
|
||||
}
|
||||
}
|
||||
dlm_astd_resume();
|
||||
@@ -704,7 +696,7 @@ static int release_lockspace(struct dlm_ls *ls, int force)
|
||||
res_hashchain);
|
||||
|
||||
list_del(&rsb->res_hashchain);
|
||||
free_rsb(rsb);
|
||||
dlm_free_rsb(rsb);
|
||||
}
|
||||
|
||||
head = &ls->ls_rsbtbl[i].toss;
|
||||
@@ -712,7 +704,7 @@ static int release_lockspace(struct dlm_ls *ls, int force)
|
||||
rsb = list_entry(head->next, struct dlm_rsb,
|
||||
res_hashchain);
|
||||
list_del(&rsb->res_hashchain);
|
||||
free_rsb(rsb);
|
||||
dlm_free_rsb(rsb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-1
@@ -864,7 +864,7 @@ static void sctp_init_assoc(struct connection *con)
|
||||
static void tcp_connect_to_sock(struct connection *con)
|
||||
{
|
||||
int result = -EHOSTUNREACH;
|
||||
struct sockaddr_storage saddr;
|
||||
struct sockaddr_storage saddr, src_addr;
|
||||
int addr_len;
|
||||
struct socket *sock;
|
||||
|
||||
@@ -898,6 +898,17 @@ static void tcp_connect_to_sock(struct connection *con)
|
||||
con->connect_action = tcp_connect_to_sock;
|
||||
add_sock(sock, con);
|
||||
|
||||
/* Bind to our cluster-known address connecting to avoid
|
||||
routing problems */
|
||||
memcpy(&src_addr, dlm_local_addr[0], sizeof(src_addr));
|
||||
make_sockaddr(&src_addr, 0, &addr_len);
|
||||
result = sock->ops->bind(sock, (struct sockaddr *) &src_addr,
|
||||
addr_len);
|
||||
if (result < 0) {
|
||||
log_print("could not bind for connect: %d", result);
|
||||
/* This *may* not indicate a critical error */
|
||||
}
|
||||
|
||||
make_sockaddr(&saddr, dlm_config.ci_tcp_port, &addr_len);
|
||||
|
||||
log_print("connecting to %d", con->nodeid);
|
||||
@@ -1426,6 +1437,8 @@ void dlm_lowcomms_stop(void)
|
||||
con = __nodeid2con(i, 0);
|
||||
if (con) {
|
||||
close_connection(con, true);
|
||||
if (con->othercon)
|
||||
kmem_cache_free(con_cache, con->othercon);
|
||||
kmem_cache_free(con_cache, con);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,16 +18,6 @@
|
||||
#include "memory.h"
|
||||
#include "config.h"
|
||||
|
||||
#ifdef CONFIG_DLM_DEBUG
|
||||
int dlm_register_debugfs(void);
|
||||
void dlm_unregister_debugfs(void);
|
||||
#else
|
||||
static inline int dlm_register_debugfs(void) { return 0; }
|
||||
static inline void dlm_unregister_debugfs(void) { }
|
||||
#endif
|
||||
int dlm_netlink_init(void);
|
||||
void dlm_netlink_exit(void);
|
||||
|
||||
static int __init init_dlm(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
/******************************************************************************
|
||||
*******************************************************************************
|
||||
**
|
||||
** Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
|
||||
** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
|
||||
**
|
||||
** This copyrighted material is made available to anyone wishing to use,
|
||||
** modify, copy, or redistribute it subject to the terms and conditions
|
||||
@@ -70,7 +70,7 @@ static void dlm_remove_member(struct dlm_ls *ls, struct dlm_member *memb)
|
||||
ls->ls_num_nodes--;
|
||||
}
|
||||
|
||||
static int dlm_is_member(struct dlm_ls *ls, int nodeid)
|
||||
int dlm_is_member(struct dlm_ls *ls, int nodeid)
|
||||
{
|
||||
struct dlm_member *memb;
|
||||
|
||||
|
||||
+2
-1
@@ -1,7 +1,7 @@
|
||||
/******************************************************************************
|
||||
*******************************************************************************
|
||||
**
|
||||
** Copyright (C) 2005 Red Hat, Inc. All rights reserved.
|
||||
** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
|
||||
**
|
||||
** This copyrighted material is made available to anyone wishing to use,
|
||||
** modify, copy, or redistribute it subject to the terms and conditions
|
||||
@@ -19,6 +19,7 @@ void dlm_clear_members(struct dlm_ls *ls);
|
||||
void dlm_clear_members_gone(struct dlm_ls *ls);
|
||||
int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv,int *neg_out);
|
||||
int dlm_is_removed(struct dlm_ls *ls, int nodeid);
|
||||
int dlm_is_member(struct dlm_ls *ls, int nodeid);
|
||||
|
||||
#endif /* __MEMBER_DOT_H__ */
|
||||
|
||||
+8
-24
@@ -2,7 +2,7 @@
|
||||
*******************************************************************************
|
||||
**
|
||||
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
|
||||
** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
|
||||
** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
**
|
||||
** This copyrighted material is made available to anyone wishing to use,
|
||||
** modify, copy, or redistribute it subject to the terms and conditions
|
||||
@@ -35,7 +35,7 @@ void dlm_memory_exit(void)
|
||||
kmem_cache_destroy(lkb_cache);
|
||||
}
|
||||
|
||||
char *allocate_lvb(struct dlm_ls *ls)
|
||||
char *dlm_allocate_lvb(struct dlm_ls *ls)
|
||||
{
|
||||
char *p;
|
||||
|
||||
@@ -43,7 +43,7 @@ char *allocate_lvb(struct dlm_ls *ls)
|
||||
return p;
|
||||
}
|
||||
|
||||
void free_lvb(char *p)
|
||||
void dlm_free_lvb(char *p)
|
||||
{
|
||||
kfree(p);
|
||||
}
|
||||
@@ -51,7 +51,7 @@ void free_lvb(char *p)
|
||||
/* FIXME: have some minimal space built-in to rsb for the name and
|
||||
kmalloc a separate name if needed, like dentries are done */
|
||||
|
||||
struct dlm_rsb *allocate_rsb(struct dlm_ls *ls, int namelen)
|
||||
struct dlm_rsb *dlm_allocate_rsb(struct dlm_ls *ls, int namelen)
|
||||
{
|
||||
struct dlm_rsb *r;
|
||||
|
||||
@@ -61,14 +61,14 @@ struct dlm_rsb *allocate_rsb(struct dlm_ls *ls, int namelen)
|
||||
return r;
|
||||
}
|
||||
|
||||
void free_rsb(struct dlm_rsb *r)
|
||||
void dlm_free_rsb(struct dlm_rsb *r)
|
||||
{
|
||||
if (r->res_lvbptr)
|
||||
free_lvb(r->res_lvbptr);
|
||||
dlm_free_lvb(r->res_lvbptr);
|
||||
kfree(r);
|
||||
}
|
||||
|
||||
struct dlm_lkb *allocate_lkb(struct dlm_ls *ls)
|
||||
struct dlm_lkb *dlm_allocate_lkb(struct dlm_ls *ls)
|
||||
{
|
||||
struct dlm_lkb *lkb;
|
||||
|
||||
@@ -76,7 +76,7 @@ struct dlm_lkb *allocate_lkb(struct dlm_ls *ls)
|
||||
return lkb;
|
||||
}
|
||||
|
||||
void free_lkb(struct dlm_lkb *lkb)
|
||||
void dlm_free_lkb(struct dlm_lkb *lkb)
|
||||
{
|
||||
if (lkb->lkb_flags & DLM_IFL_USER) {
|
||||
struct dlm_user_args *ua;
|
||||
@@ -90,19 +90,3 @@ void free_lkb(struct dlm_lkb *lkb)
|
||||
kmem_cache_free(lkb_cache, lkb);
|
||||
}
|
||||
|
||||
struct dlm_direntry *allocate_direntry(struct dlm_ls *ls, int namelen)
|
||||
{
|
||||
struct dlm_direntry *de;
|
||||
|
||||
DLM_ASSERT(namelen <= DLM_RESNAME_MAXLEN,
|
||||
printk("namelen = %d\n", namelen););
|
||||
|
||||
de = kzalloc(sizeof(*de) + namelen, GFP_KERNEL);
|
||||
return de;
|
||||
}
|
||||
|
||||
void free_direntry(struct dlm_direntry *de)
|
||||
{
|
||||
kfree(de);
|
||||
}
|
||||
|
||||
+7
-9
@@ -2,7 +2,7 @@
|
||||
*******************************************************************************
|
||||
**
|
||||
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
|
||||
** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
|
||||
** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
**
|
||||
** This copyrighted material is made available to anyone wishing to use,
|
||||
** modify, copy, or redistribute it subject to the terms and conditions
|
||||
@@ -16,14 +16,12 @@
|
||||
|
||||
int dlm_memory_init(void);
|
||||
void dlm_memory_exit(void);
|
||||
struct dlm_rsb *allocate_rsb(struct dlm_ls *ls, int namelen);
|
||||
void free_rsb(struct dlm_rsb *r);
|
||||
struct dlm_lkb *allocate_lkb(struct dlm_ls *ls);
|
||||
void free_lkb(struct dlm_lkb *l);
|
||||
struct dlm_direntry *allocate_direntry(struct dlm_ls *ls, int namelen);
|
||||
void free_direntry(struct dlm_direntry *de);
|
||||
char *allocate_lvb(struct dlm_ls *ls);
|
||||
void free_lvb(char *l);
|
||||
struct dlm_rsb *dlm_allocate_rsb(struct dlm_ls *ls, int namelen);
|
||||
void dlm_free_rsb(struct dlm_rsb *r);
|
||||
struct dlm_lkb *dlm_allocate_lkb(struct dlm_ls *ls);
|
||||
void dlm_free_lkb(struct dlm_lkb *l);
|
||||
char *dlm_allocate_lvb(struct dlm_ls *ls);
|
||||
void dlm_free_lvb(char *l);
|
||||
|
||||
#endif /* __MEMORY_DOT_H__ */
|
||||
|
||||
+9
-6
@@ -2,7 +2,7 @@
|
||||
*******************************************************************************
|
||||
**
|
||||
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
|
||||
** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
|
||||
**
|
||||
** This copyrighted material is made available to anyone wishing to use,
|
||||
** modify, copy, or redistribute it subject to the terms and conditions
|
||||
@@ -58,8 +58,12 @@ static void copy_from_cb(void *dst, const void *base, unsigned offset,
|
||||
int dlm_process_incoming_buffer(int nodeid, const void *base,
|
||||
unsigned offset, unsigned len, unsigned limit)
|
||||
{
|
||||
unsigned char __tmp[DLM_INBUF_LEN];
|
||||
struct dlm_header *msg = (struct dlm_header *) __tmp;
|
||||
union {
|
||||
unsigned char __buf[DLM_INBUF_LEN];
|
||||
/* this is to force proper alignment on some arches */
|
||||
struct dlm_header dlm;
|
||||
} __tmp;
|
||||
struct dlm_header *msg = &__tmp.dlm;
|
||||
int ret = 0;
|
||||
int err = 0;
|
||||
uint16_t msglen;
|
||||
@@ -100,8 +104,7 @@ 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 > sizeof(__tmp) &&
|
||||
msg == (struct dlm_header *) __tmp) {
|
||||
if (msglen > DLM_INBUF_LEN && msg == &__tmp.dlm) {
|
||||
msg = kmalloc(dlm_config.ci_buffer_size, GFP_KERNEL);
|
||||
if (msg == NULL)
|
||||
return ret;
|
||||
@@ -119,7 +122,7 @@ int dlm_process_incoming_buffer(int nodeid, const void *base,
|
||||
dlm_receive_buffer(msg, nodeid);
|
||||
}
|
||||
|
||||
if (msg != (struct dlm_header *) __tmp)
|
||||
if (msg != &__tmp.dlm)
|
||||
kfree(msg);
|
||||
|
||||
return err ? err : ret;
|
||||
|
||||
+5
-20
@@ -2,7 +2,7 @@
|
||||
*******************************************************************************
|
||||
**
|
||||
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
|
||||
** Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
|
||||
** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
|
||||
**
|
||||
** This copyrighted material is made available to anyone wishing to use,
|
||||
** modify, copy, or redistribute it subject to the terms and conditions
|
||||
@@ -197,11 +197,6 @@ static void receive_sync_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in)
|
||||
spin_unlock(&ls->ls_rcom_spin);
|
||||
}
|
||||
|
||||
static void receive_rcom_status_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in)
|
||||
{
|
||||
receive_sync_reply(ls, rc_in);
|
||||
}
|
||||
|
||||
int dlm_rcom_names(struct dlm_ls *ls, int nodeid, char *last_name, int last_len)
|
||||
{
|
||||
struct dlm_rcom *rc;
|
||||
@@ -254,11 +249,6 @@ static void receive_rcom_names(struct dlm_ls *ls, struct dlm_rcom *rc_in)
|
||||
send_rcom(ls, mh, rc);
|
||||
}
|
||||
|
||||
static void receive_rcom_names_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in)
|
||||
{
|
||||
receive_sync_reply(ls, rc_in);
|
||||
}
|
||||
|
||||
int dlm_send_rcom_lookup(struct dlm_rsb *r, int dir_nodeid)
|
||||
{
|
||||
struct dlm_rcom *rc;
|
||||
@@ -381,11 +371,6 @@ static void receive_rcom_lock(struct dlm_ls *ls, struct dlm_rcom *rc_in)
|
||||
send_rcom(ls, mh, rc);
|
||||
}
|
||||
|
||||
static void receive_rcom_lock_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in)
|
||||
{
|
||||
dlm_recover_process_copy(ls, rc_in);
|
||||
}
|
||||
|
||||
/* If the lockspace doesn't exist then still send a status message
|
||||
back; it's possible that it just doesn't have its global_id yet. */
|
||||
|
||||
@@ -481,11 +466,11 @@ void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
|
||||
break;
|
||||
|
||||
case DLM_RCOM_STATUS_REPLY:
|
||||
receive_rcom_status_reply(ls, rc);
|
||||
receive_sync_reply(ls, rc);
|
||||
break;
|
||||
|
||||
case DLM_RCOM_NAMES_REPLY:
|
||||
receive_rcom_names_reply(ls, rc);
|
||||
receive_sync_reply(ls, rc);
|
||||
break;
|
||||
|
||||
case DLM_RCOM_LOOKUP_REPLY:
|
||||
@@ -493,11 +478,11 @@ void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
|
||||
break;
|
||||
|
||||
case DLM_RCOM_LOCK_REPLY:
|
||||
receive_rcom_lock_reply(ls, rc);
|
||||
dlm_recover_process_copy(ls, rc);
|
||||
break;
|
||||
|
||||
default:
|
||||
DLM_ASSERT(0, printk("rc_type=%x\n", rc->rc_type););
|
||||
log_error(ls, "receive_rcom bad type %d", rc->rc_type);
|
||||
}
|
||||
out:
|
||||
return;
|
||||
|
||||
+24
-3
@@ -629,7 +629,7 @@ static void recover_lvb(struct dlm_rsb *r)
|
||||
goto out;
|
||||
|
||||
if (!r->res_lvbptr) {
|
||||
r->res_lvbptr = allocate_lvb(r->res_ls);
|
||||
r->res_lvbptr = dlm_allocate_lvb(r->res_ls);
|
||||
if (!r->res_lvbptr)
|
||||
goto out;
|
||||
}
|
||||
@@ -731,6 +731,20 @@ int dlm_create_root_list(struct dlm_ls *ls)
|
||||
list_add(&r->res_root_list, &ls->ls_root_list);
|
||||
dlm_hold_rsb(r);
|
||||
}
|
||||
|
||||
/* If we're using a directory, add tossed rsbs to the root
|
||||
list; they'll have entries created in the new directory,
|
||||
but no other recovery steps should do anything with them. */
|
||||
|
||||
if (dlm_no_directory(ls)) {
|
||||
read_unlock(&ls->ls_rsbtbl[i].lock);
|
||||
continue;
|
||||
}
|
||||
|
||||
list_for_each_entry(r, &ls->ls_rsbtbl[i].toss, res_hashchain) {
|
||||
list_add(&r->res_root_list, &ls->ls_root_list);
|
||||
dlm_hold_rsb(r);
|
||||
}
|
||||
read_unlock(&ls->ls_rsbtbl[i].lock);
|
||||
}
|
||||
out:
|
||||
@@ -750,6 +764,11 @@ void dlm_release_root_list(struct dlm_ls *ls)
|
||||
up_write(&ls->ls_root_sem);
|
||||
}
|
||||
|
||||
/* If not using a directory, clear the entire toss list, there's no benefit to
|
||||
caching the master value since it's fixed. If we are using a dir, keep the
|
||||
rsb's we're the master of. Recovery will add them to the root list and from
|
||||
there they'll be entered in the rebuilt directory. */
|
||||
|
||||
void dlm_clear_toss_list(struct dlm_ls *ls)
|
||||
{
|
||||
struct dlm_rsb *r, *safe;
|
||||
@@ -759,8 +778,10 @@ void dlm_clear_toss_list(struct dlm_ls *ls)
|
||||
write_lock(&ls->ls_rsbtbl[i].lock);
|
||||
list_for_each_entry_safe(r, safe, &ls->ls_rsbtbl[i].toss,
|
||||
res_hashchain) {
|
||||
list_del(&r->res_hashchain);
|
||||
free_rsb(r);
|
||||
if (dlm_no_directory(ls) || !is_master(r)) {
|
||||
list_del(&r->res_hashchain);
|
||||
dlm_free_rsb(r);
|
||||
}
|
||||
}
|
||||
write_unlock(&ls->ls_rsbtbl[i].lock);
|
||||
}
|
||||
|
||||
+7
-6
@@ -66,6 +66,13 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
|
||||
dlm_astd_suspend();
|
||||
dlm_astd_resume();
|
||||
|
||||
/*
|
||||
* Free non-master tossed rsb's. Master rsb's are kept on toss
|
||||
* list and put on root list to be included in resdir recovery.
|
||||
*/
|
||||
|
||||
dlm_clear_toss_list(ls);
|
||||
|
||||
/*
|
||||
* This list of root rsb's will be the basis of most of the recovery
|
||||
* routines.
|
||||
@@ -73,12 +80,6 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
|
||||
|
||||
dlm_create_root_list(ls);
|
||||
|
||||
/*
|
||||
* Free all the tossed rsb's so we don't have to recover them.
|
||||
*/
|
||||
|
||||
dlm_clear_toss_list(ls);
|
||||
|
||||
/*
|
||||
* Add or remove nodes from the lockspace's ls_nodes list.
|
||||
* Also waits for all nodes to complete dlm_recover_members.
|
||||
|
||||
+18
-11
@@ -24,8 +24,7 @@
|
||||
#include "lvb_table.h"
|
||||
#include "user.h"
|
||||
|
||||
static const char *name_prefix="dlm";
|
||||
static struct miscdevice ctl_device;
|
||||
static const char name_prefix[] = "dlm";
|
||||
static const struct file_operations device_fops;
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
@@ -82,7 +81,8 @@ struct dlm_lock_result32 {
|
||||
};
|
||||
|
||||
static void compat_input(struct dlm_write_request *kb,
|
||||
struct dlm_write_request32 *kb32)
|
||||
struct dlm_write_request32 *kb32,
|
||||
int max_namelen)
|
||||
{
|
||||
kb->version[0] = kb32->version[0];
|
||||
kb->version[1] = kb32->version[1];
|
||||
@@ -112,7 +112,11 @@ 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);
|
||||
memcpy(kb->i.lock.name, kb32->i.lock.name, kb->i.lock.namelen);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,12 +240,12 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type)
|
||||
spin_unlock(&proc->asts_spin);
|
||||
|
||||
if (eol) {
|
||||
spin_lock(&ua->proc->locks_spin);
|
||||
spin_lock(&proc->locks_spin);
|
||||
if (!list_empty(&lkb->lkb_ownqueue)) {
|
||||
list_del_init(&lkb->lkb_ownqueue);
|
||||
dlm_put_lkb(lkb);
|
||||
}
|
||||
spin_unlock(&ua->proc->locks_spin);
|
||||
spin_unlock(&proc->locks_spin);
|
||||
}
|
||||
out:
|
||||
mutex_unlock(&ls->ls_clear_proc_locks);
|
||||
@@ -529,7 +533,8 @@ static ssize_t device_write(struct file *file, const char __user *buf,
|
||||
|
||||
if (proc)
|
||||
set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags);
|
||||
compat_input(kbuf, k32buf);
|
||||
compat_input(kbuf, k32buf,
|
||||
count - sizeof(struct dlm_write_request32));
|
||||
kfree(k32buf);
|
||||
}
|
||||
#endif
|
||||
@@ -896,14 +901,16 @@ static const struct file_operations ctl_device_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static struct miscdevice ctl_device = {
|
||||
.name = "dlm-control",
|
||||
.fops = &ctl_device_fops,
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
};
|
||||
|
||||
int dlm_user_init(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
ctl_device.name = "dlm-control";
|
||||
ctl_device.fops = &ctl_device_fops;
|
||||
ctl_device.minor = MISC_DYNAMIC_MINOR;
|
||||
|
||||
error = misc_register(&ctl_device);
|
||||
if (error)
|
||||
log_print("misc_register failed for control device");
|
||||
|
||||
+66
-16
@@ -1,7 +1,7 @@
|
||||
/******************************************************************************
|
||||
*******************************************************************************
|
||||
**
|
||||
** Copyright (C) 2005 Red Hat, Inc. All rights reserved.
|
||||
** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
|
||||
**
|
||||
** This copyrighted material is made available to anyone wishing to use,
|
||||
** modify, copy, or redistribute it subject to the terms and conditions
|
||||
@@ -14,6 +14,14 @@
|
||||
#include "rcom.h"
|
||||
#include "util.h"
|
||||
|
||||
#define DLM_ERRNO_EDEADLK 35
|
||||
#define DLM_ERRNO_EBADR 53
|
||||
#define DLM_ERRNO_EBADSLT 57
|
||||
#define DLM_ERRNO_EPROTO 71
|
||||
#define DLM_ERRNO_EOPNOTSUPP 95
|
||||
#define DLM_ERRNO_ETIMEDOUT 110
|
||||
#define DLM_ERRNO_EINPROGRESS 115
|
||||
|
||||
static void header_out(struct dlm_header *hd)
|
||||
{
|
||||
hd->h_version = cpu_to_le32(hd->h_version);
|
||||
@@ -30,11 +38,54 @@ static void header_in(struct dlm_header *hd)
|
||||
hd->h_length = le16_to_cpu(hd->h_length);
|
||||
}
|
||||
|
||||
/* higher errno values are inconsistent across architectures, so select
|
||||
one set of values for on the wire */
|
||||
|
||||
static int to_dlm_errno(int err)
|
||||
{
|
||||
switch (err) {
|
||||
case -EDEADLK:
|
||||
return -DLM_ERRNO_EDEADLK;
|
||||
case -EBADR:
|
||||
return -DLM_ERRNO_EBADR;
|
||||
case -EBADSLT:
|
||||
return -DLM_ERRNO_EBADSLT;
|
||||
case -EPROTO:
|
||||
return -DLM_ERRNO_EPROTO;
|
||||
case -EOPNOTSUPP:
|
||||
return -DLM_ERRNO_EOPNOTSUPP;
|
||||
case -ETIMEDOUT:
|
||||
return -DLM_ERRNO_ETIMEDOUT;
|
||||
case -EINPROGRESS:
|
||||
return -DLM_ERRNO_EINPROGRESS;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int from_dlm_errno(int err)
|
||||
{
|
||||
switch (err) {
|
||||
case -DLM_ERRNO_EDEADLK:
|
||||
return -EDEADLK;
|
||||
case -DLM_ERRNO_EBADR:
|
||||
return -EBADR;
|
||||
case -DLM_ERRNO_EBADSLT:
|
||||
return -EBADSLT;
|
||||
case -DLM_ERRNO_EPROTO:
|
||||
return -EPROTO;
|
||||
case -DLM_ERRNO_EOPNOTSUPP:
|
||||
return -EOPNOTSUPP;
|
||||
case -DLM_ERRNO_ETIMEDOUT:
|
||||
return -ETIMEDOUT;
|
||||
case -DLM_ERRNO_EINPROGRESS:
|
||||
return -EINPROGRESS;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
void dlm_message_out(struct dlm_message *ms)
|
||||
{
|
||||
struct dlm_header *hd = (struct dlm_header *) ms;
|
||||
|
||||
header_out(hd);
|
||||
header_out(&ms->m_header);
|
||||
|
||||
ms->m_type = cpu_to_le32(ms->m_type);
|
||||
ms->m_nodeid = cpu_to_le32(ms->m_nodeid);
|
||||
@@ -53,14 +104,12 @@ void dlm_message_out(struct dlm_message *ms)
|
||||
ms->m_rqmode = cpu_to_le32(ms->m_rqmode);
|
||||
ms->m_bastmode = cpu_to_le32(ms->m_bastmode);
|
||||
ms->m_asts = cpu_to_le32(ms->m_asts);
|
||||
ms->m_result = cpu_to_le32(ms->m_result);
|
||||
ms->m_result = cpu_to_le32(to_dlm_errno(ms->m_result));
|
||||
}
|
||||
|
||||
void dlm_message_in(struct dlm_message *ms)
|
||||
{
|
||||
struct dlm_header *hd = (struct dlm_header *) ms;
|
||||
|
||||
header_in(hd);
|
||||
header_in(&ms->m_header);
|
||||
|
||||
ms->m_type = le32_to_cpu(ms->m_type);
|
||||
ms->m_nodeid = le32_to_cpu(ms->m_nodeid);
|
||||
@@ -79,7 +128,7 @@ void dlm_message_in(struct dlm_message *ms)
|
||||
ms->m_rqmode = le32_to_cpu(ms->m_rqmode);
|
||||
ms->m_bastmode = le32_to_cpu(ms->m_bastmode);
|
||||
ms->m_asts = le32_to_cpu(ms->m_asts);
|
||||
ms->m_result = le32_to_cpu(ms->m_result);
|
||||
ms->m_result = from_dlm_errno(le32_to_cpu(ms->m_result));
|
||||
}
|
||||
|
||||
static void rcom_lock_out(struct rcom_lock *rl)
|
||||
@@ -126,10 +175,9 @@ static void rcom_config_in(struct rcom_config *rf)
|
||||
|
||||
void dlm_rcom_out(struct dlm_rcom *rc)
|
||||
{
|
||||
struct dlm_header *hd = (struct dlm_header *) rc;
|
||||
int type = rc->rc_type;
|
||||
|
||||
header_out(hd);
|
||||
header_out(&rc->rc_header);
|
||||
|
||||
rc->rc_type = cpu_to_le32(rc->rc_type);
|
||||
rc->rc_result = cpu_to_le32(rc->rc_result);
|
||||
@@ -137,7 +185,7 @@ void dlm_rcom_out(struct dlm_rcom *rc)
|
||||
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)
|
||||
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)
|
||||
@@ -146,9 +194,9 @@ void dlm_rcom_out(struct dlm_rcom *rc)
|
||||
|
||||
void dlm_rcom_in(struct dlm_rcom *rc)
|
||||
{
|
||||
struct dlm_header *hd = (struct dlm_header *) rc;
|
||||
int type;
|
||||
|
||||
header_in(hd);
|
||||
header_in(&rc->rc_header);
|
||||
|
||||
rc->rc_type = le32_to_cpu(rc->rc_type);
|
||||
rc->rc_result = le32_to_cpu(rc->rc_result);
|
||||
@@ -156,10 +204,12 @@ void dlm_rcom_in(struct dlm_rcom *rc)
|
||||
rc->rc_seq = le64_to_cpu(rc->rc_seq);
|
||||
rc->rc_seq_reply = le64_to_cpu(rc->rc_seq_reply);
|
||||
|
||||
if (rc->rc_type == DLM_RCOM_LOCK)
|
||||
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 (rc->rc_type == DLM_RCOM_STATUS_REPLY)
|
||||
else if (type == DLM_RCOM_STATUS_REPLY)
|
||||
rcom_config_in((struct rcom_config *) rc->rc_buf);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user