Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[DLM] add lock timeouts and warnings [2/6]

New features: lock timeouts and time warnings. If the DLM_LKF_TIMEOUT
flag is set, then the request/conversion will be canceled after waiting
the specified number of centiseconds (specified per lock). This feature
is only available for locks requested through libdlm (can be enabled for
kernel dlm users if there's a use for it.)

If the new DLM_LSFL_TIMEWARN flag is set when creating the lockspace, then
a warning message will be sent to userspace (using genetlink) after a
request/conversion has been waiting for a given number of centiseconds
(configurable per node). The time warnings will be used in the future
to do deadlock detection in userspace.

Signed-off-by: David Teigland <teigland@redhat.com>
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>

authored by

David Teigland and committed by
Steven Whitehouse
3ae1acf9 85e86edf

+409 -12
+1
fs/dlm/Makefile
··· 8 8 member.o \ 9 9 memory.o \ 10 10 midcomms.o \ 11 + netlink.o \ 11 12 lowcomms.o \ 12 13 rcom.o \ 13 14 recover.o \
+7 -1
fs/dlm/config.c
··· 90 90 unsigned int cl_scan_secs; 91 91 unsigned int cl_log_debug; 92 92 unsigned int cl_protocol; 93 + unsigned int cl_timewarn_cs; 93 94 }; 94 95 95 96 enum { ··· 104 103 CLUSTER_ATTR_SCAN_SECS, 105 104 CLUSTER_ATTR_LOG_DEBUG, 106 105 CLUSTER_ATTR_PROTOCOL, 106 + CLUSTER_ATTR_TIMEWARN_CS, 107 107 }; 108 108 109 109 struct cluster_attribute { ··· 164 162 CLUSTER_ATTR(scan_secs, 1); 165 163 CLUSTER_ATTR(log_debug, 0); 166 164 CLUSTER_ATTR(protocol, 0); 165 + CLUSTER_ATTR(timewarn_cs, 1); 167 166 168 167 static struct configfs_attribute *cluster_attrs[] = { 169 168 [CLUSTER_ATTR_TCP_PORT] = &cluster_attr_tcp_port.attr, ··· 177 174 [CLUSTER_ATTR_SCAN_SECS] = &cluster_attr_scan_secs.attr, 178 175 [CLUSTER_ATTR_LOG_DEBUG] = &cluster_attr_log_debug.attr, 179 176 [CLUSTER_ATTR_PROTOCOL] = &cluster_attr_protocol.attr, 177 + [CLUSTER_ATTR_TIMEWARN_CS] = &cluster_attr_timewarn_cs.attr, 180 178 NULL, 181 179 }; 182 180 ··· 920 916 #define DEFAULT_SCAN_SECS 5 921 917 #define DEFAULT_LOG_DEBUG 0 922 918 #define DEFAULT_PROTOCOL 0 919 + #define DEFAULT_TIMEWARN_CS 500 /* 5 sec = 500 centiseconds */ 923 920 924 921 struct dlm_config_info dlm_config = { 925 922 .ci_tcp_port = DEFAULT_TCP_PORT, ··· 932 927 .ci_toss_secs = DEFAULT_TOSS_SECS, 933 928 .ci_scan_secs = DEFAULT_SCAN_SECS, 934 929 .ci_log_debug = DEFAULT_LOG_DEBUG, 935 - .ci_protocol = DEFAULT_PROTOCOL 930 + .ci_protocol = DEFAULT_PROTOCOL, 931 + .ci_timewarn_cs = DEFAULT_TIMEWARN_CS 936 932 }; 937 933
+1
fs/dlm/config.h
··· 27 27 int ci_scan_secs; 28 28 int ci_log_debug; 29 29 int ci_protocol; 30 + int ci_timewarn_cs; 30 31 }; 31 32 32 33 extern struct dlm_config_info dlm_config;
+10
fs/dlm/dlm_internal.h
··· 213 213 #define DLM_IFL_OVERLAP_UNLOCK 0x00080000 214 214 #define DLM_IFL_OVERLAP_CANCEL 0x00100000 215 215 #define DLM_IFL_ENDOFLIFE 0x00200000 216 + #define DLM_IFL_WATCH_TIMEWARN 0x00400000 216 217 #define DLM_IFL_USER 0x00000001 217 218 #define DLM_IFL_ORPHAN 0x00000002 219 + #define DLM_IFL_TIMEOUT_CANCEL 0x00000004 218 220 219 221 struct dlm_lkb { 220 222 struct dlm_rsb *lkb_resource; /* the rsb */ ··· 245 243 struct list_head lkb_wait_reply; /* waiting for remote reply */ 246 244 struct list_head lkb_astqueue; /* need ast to be sent */ 247 245 struct list_head lkb_ownqueue; /* list of locks for a process */ 246 + struct list_head lkb_time_list; 247 + unsigned long lkb_timestamp; 248 + unsigned long lkb_timeout_cs; 248 249 249 250 char *lkb_lvbptr; 250 251 struct dlm_lksb *lkb_lksb; /* caller's status block */ ··· 452 447 struct mutex ls_orphans_mutex; 453 448 struct list_head ls_orphans; 454 449 450 + struct mutex ls_timeout_mutex; 451 + struct list_head ls_timeout; 452 + 455 453 struct list_head ls_nodes; /* current nodes in ls */ 456 454 struct list_head ls_nodes_gone; /* dead node list, recovery */ 457 455 int ls_num_nodes; /* number of nodes in ls */ ··· 480 472 struct task_struct *ls_recoverd_task; 481 473 struct mutex ls_recoverd_active; 482 474 spinlock_t ls_recover_lock; 475 + unsigned long ls_recover_begin; /* jiffies timestamp */ 483 476 uint32_t ls_recover_status; /* DLM_RS_ */ 484 477 uint64_t ls_recover_seq; 485 478 struct dlm_recover *ls_recover_args; ··· 510 501 #define LSFL_RCOM_READY 3 511 502 #define LSFL_RCOM_WAIT 4 512 503 #define LSFL_UEVENT_WAIT 5 504 + #define LSFL_TIMEWARN 6 513 505 514 506 /* much of this is just saving user space pointers associated with the 515 507 lock that we pass back to the user lib with an ast */
+144 -2
fs/dlm/lock.c
··· 82 82 static int send_lookup(struct dlm_rsb *r, struct dlm_lkb *lkb); 83 83 static int send_remove(struct dlm_rsb *r); 84 84 static int _request_lock(struct dlm_rsb *r, struct dlm_lkb *lkb); 85 + static int _cancel_lock(struct dlm_rsb *r, struct dlm_lkb *lkb); 85 86 static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb, 86 87 struct dlm_message *ms); 87 88 static int receive_extralen(struct dlm_message *ms); 88 89 static void do_purge(struct dlm_ls *ls, int nodeid, int pid); 90 + static void del_timeout(struct dlm_lkb *lkb); 91 + void dlm_timeout_warn(struct dlm_lkb *lkb); 89 92 90 93 /* 91 94 * Lock compatibilty matrix - thanks Steve ··· 289 286 if (is_master_copy(lkb)) 290 287 return; 291 288 289 + del_timeout(lkb); 290 + 292 291 DLM_ASSERT(lkb->lkb_lksb, dlm_print_lkb(lkb);); 292 + 293 + /* if the operation was a cancel, then return -DLM_ECANCEL, if a 294 + timeout caused the cancel then return -ETIMEDOUT */ 295 + if (rv == -DLM_ECANCEL && (lkb->lkb_flags & DLM_IFL_TIMEOUT_CANCEL)) { 296 + lkb->lkb_flags &= ~DLM_IFL_TIMEOUT_CANCEL; 297 + rv = -ETIMEDOUT; 298 + } 293 299 294 300 lkb->lkb_lksb->sb_status = rv; 295 301 lkb->lkb_lksb->sb_flags = lkb->lkb_sbflags; ··· 593 581 kref_init(&lkb->lkb_ref); 594 582 INIT_LIST_HEAD(&lkb->lkb_ownqueue); 595 583 INIT_LIST_HEAD(&lkb->lkb_rsb_lookup); 584 + INIT_LIST_HEAD(&lkb->lkb_time_list); 596 585 597 586 get_random_bytes(&bucket, sizeof(bucket)); 598 587 bucket &= (ls->ls_lkbtbl_size - 1); ··· 1004 991 break; 1005 992 cond_resched(); 1006 993 } 994 + } 995 + 996 + static void add_timeout(struct dlm_lkb *lkb) 997 + { 998 + struct dlm_ls *ls = lkb->lkb_resource->res_ls; 999 + 1000 + if (is_master_copy(lkb)) 1001 + return; 1002 + 1003 + if (lkb->lkb_exflags & DLM_LKF_TIMEOUT) 1004 + goto add_it; 1005 + 1006 + if (test_bit(LSFL_TIMEWARN, &ls->ls_flags) && 1007 + !(lkb->lkb_exflags & DLM_LKF_NODLCKWT)) { 1008 + lkb->lkb_flags |= DLM_IFL_WATCH_TIMEWARN; 1009 + goto add_it; 1010 + } 1011 + return; 1012 + 1013 + add_it: 1014 + DLM_ASSERT(list_empty(&lkb->lkb_time_list), dlm_print_lkb(lkb);); 1015 + mutex_lock(&ls->ls_timeout_mutex); 1016 + hold_lkb(lkb); 1017 + lkb->lkb_timestamp = jiffies; 1018 + list_add_tail(&lkb->lkb_time_list, &ls->ls_timeout); 1019 + mutex_unlock(&ls->ls_timeout_mutex); 1020 + } 1021 + 1022 + static void del_timeout(struct dlm_lkb *lkb) 1023 + { 1024 + struct dlm_ls *ls = lkb->lkb_resource->res_ls; 1025 + 1026 + mutex_lock(&ls->ls_timeout_mutex); 1027 + if (!list_empty(&lkb->lkb_time_list)) { 1028 + list_del_init(&lkb->lkb_time_list); 1029 + unhold_lkb(lkb); 1030 + } 1031 + mutex_unlock(&ls->ls_timeout_mutex); 1032 + } 1033 + 1034 + /* FIXME: is it safe to look at lkb_exflags, lkb_flags, lkb_timestamp, and 1035 + lkb_lksb_timeout without lock_rsb? Note: we can't lock timeout_mutex 1036 + and then lock rsb because of lock ordering in add_timeout. We may need 1037 + to specify some special timeout-related bits in the lkb that are just to 1038 + be accessed under the timeout_mutex. */ 1039 + 1040 + void dlm_scan_timeout(struct dlm_ls *ls) 1041 + { 1042 + struct dlm_rsb *r; 1043 + struct dlm_lkb *lkb; 1044 + int do_cancel, do_warn; 1045 + 1046 + for (;;) { 1047 + if (dlm_locking_stopped(ls)) 1048 + break; 1049 + 1050 + do_cancel = 0; 1051 + do_warn = 0; 1052 + mutex_lock(&ls->ls_timeout_mutex); 1053 + list_for_each_entry(lkb, &ls->ls_timeout, lkb_time_list) { 1054 + 1055 + if ((lkb->lkb_exflags & DLM_LKF_TIMEOUT) && 1056 + time_after_eq(jiffies, lkb->lkb_timestamp + 1057 + lkb->lkb_timeout_cs * HZ/100)) 1058 + do_cancel = 1; 1059 + 1060 + if ((lkb->lkb_flags & DLM_IFL_WATCH_TIMEWARN) && 1061 + time_after_eq(jiffies, lkb->lkb_timestamp + 1062 + dlm_config.ci_timewarn_cs * HZ/100)) 1063 + do_warn = 1; 1064 + 1065 + if (!do_cancel && !do_warn) 1066 + continue; 1067 + hold_lkb(lkb); 1068 + break; 1069 + } 1070 + mutex_unlock(&ls->ls_timeout_mutex); 1071 + 1072 + if (!do_cancel && !do_warn) 1073 + break; 1074 + 1075 + r = lkb->lkb_resource; 1076 + hold_rsb(r); 1077 + lock_rsb(r); 1078 + 1079 + if (do_warn) { 1080 + /* clear flag so we only warn once */ 1081 + lkb->lkb_flags &= ~DLM_IFL_WATCH_TIMEWARN; 1082 + if (!(lkb->lkb_exflags & DLM_LKF_TIMEOUT)) 1083 + del_timeout(lkb); 1084 + dlm_timeout_warn(lkb); 1085 + } 1086 + 1087 + if (do_cancel) { 1088 + lkb->lkb_flags &= ~DLM_IFL_WATCH_TIMEWARN; 1089 + lkb->lkb_flags |= DLM_IFL_TIMEOUT_CANCEL; 1090 + del_timeout(lkb); 1091 + _cancel_lock(r, lkb); 1092 + } 1093 + 1094 + unlock_rsb(r); 1095 + unhold_rsb(r); 1096 + dlm_put_lkb(lkb); 1097 + } 1098 + } 1099 + 1100 + /* This is only called by dlm_recoverd, and we rely on dlm_ls_stop() stopping 1101 + dlm_recoverd before checking/setting ls_recover_begin. */ 1102 + 1103 + void dlm_adjust_timeouts(struct dlm_ls *ls) 1104 + { 1105 + struct dlm_lkb *lkb; 1106 + long adj = jiffies - ls->ls_recover_begin; 1107 + 1108 + ls->ls_recover_begin = 0; 1109 + mutex_lock(&ls->ls_timeout_mutex); 1110 + list_for_each_entry(lkb, &ls->ls_timeout, lkb_time_list) 1111 + lkb->lkb_timestamp += adj; 1112 + mutex_unlock(&ls->ls_timeout_mutex); 1007 1113 } 1008 1114 1009 1115 /* lkb is master or local copy */ ··· 2034 1902 if (is_overlap(lkb)) 2035 1903 goto out; 2036 1904 1905 + /* don't let scand try to do a cancel */ 1906 + del_timeout(lkb); 1907 + 2037 1908 if (lkb->lkb_flags & DLM_IFL_RESEND) { 2038 1909 lkb->lkb_flags |= DLM_IFL_OVERLAP_CANCEL; 2039 1910 rv = -EBUSY; ··· 2067 1932 2068 1933 if (is_overlap_unlock(lkb)) 2069 1934 goto out; 1935 + 1936 + /* don't let scand try to do a cancel */ 1937 + del_timeout(lkb); 2070 1938 2071 1939 if (lkb->lkb_flags & DLM_IFL_RESEND) { 2072 1940 lkb->lkb_flags |= DLM_IFL_OVERLAP_UNLOCK; ··· 2131 1993 error = -EINPROGRESS; 2132 1994 add_lkb(r, lkb, DLM_LKSTS_WAITING); 2133 1995 send_blocking_asts(r, lkb); 1996 + add_timeout(lkb); 2134 1997 goto out; 2135 1998 } 2136 1999 ··· 2179 2040 del_lkb(r, lkb); 2180 2041 add_lkb(r, lkb, DLM_LKSTS_CONVERT); 2181 2042 send_blocking_asts(r, lkb); 2043 + add_timeout(lkb); 2182 2044 goto out; 2183 2045 } 2184 2046 ··· 3250 3110 lkb->lkb_remid = ms->m_lkid; 3251 3111 if (is_altmode(lkb)) 3252 3112 munge_altmode(lkb, ms); 3253 - if (result) 3113 + if (result) { 3254 3114 add_lkb(r, lkb, DLM_LKSTS_WAITING); 3255 - else { 3115 + add_timeout(lkb); 3116 + } else { 3256 3117 grant_lock_pc(r, lkb, ms); 3257 3118 queue_cast(r, lkb, 0); 3258 3119 } ··· 3319 3178 munge_demoted(lkb, ms); 3320 3179 del_lkb(r, lkb); 3321 3180 add_lkb(r, lkb, DLM_LKSTS_CONVERT); 3181 + add_timeout(lkb); 3322 3182 break; 3323 3183 3324 3184 case 0:
+3 -1
fs/dlm/lock.h
··· 1 1 /****************************************************************************** 2 2 ******************************************************************************* 3 3 ** 4 - ** Copyright (C) 2005 Red Hat, Inc. All rights reserved. 4 + ** Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved. 5 5 ** 6 6 ** This copyrighted material is made available to anyone wishing to use, 7 7 ** modify, copy, or redistribute it subject to the terms and conditions ··· 26 26 void dlm_scan_rsbs(struct dlm_ls *ls); 27 27 int dlm_lock_recovery_try(struct dlm_ls *ls); 28 28 void dlm_unlock_recovery(struct dlm_ls *ls); 29 + void dlm_scan_timeout(struct dlm_ls *ls); 30 + void dlm_adjust_timeouts(struct dlm_ls *ls); 29 31 30 32 int dlm_purge_locks(struct dlm_ls *ls); 31 33 void dlm_purge_mstcpy_locks(struct dlm_rsb *r);
+9 -1
fs/dlm/lockspace.c
··· 237 237 list_for_each_entry(ls, &lslist, ls_list) { 238 238 if (dlm_lock_recovery_try(ls)) { 239 239 dlm_scan_rsbs(ls); 240 + dlm_scan_timeout(ls); 240 241 dlm_unlock_recovery(ls); 241 242 } 242 243 } ··· 422 421 goto out; 423 422 memcpy(ls->ls_name, name, namelen); 424 423 ls->ls_namelen = namelen; 425 - ls->ls_exflags = flags; 426 424 ls->ls_lvblen = lvblen; 427 425 ls->ls_count = 0; 428 426 ls->ls_flags = 0; 427 + 428 + /* ls_exflags are forced to match among nodes, and we don't 429 + need to require all nodes to have TIMEWARN active */ 430 + if (flags & DLM_LSFL_TIMEWARN) 431 + set_bit(LSFL_TIMEWARN, &ls->ls_flags); 432 + ls->ls_exflags = (flags & ~DLM_LSFL_TIMEWARN); 429 433 430 434 size = dlm_config.ci_rsbtbl_size; 431 435 ls->ls_rsbtbl_size = size; ··· 471 465 mutex_init(&ls->ls_waiters_mutex); 472 466 INIT_LIST_HEAD(&ls->ls_orphans); 473 467 mutex_init(&ls->ls_orphans_mutex); 468 + INIT_LIST_HEAD(&ls->ls_timeout); 469 + mutex_init(&ls->ls_timeout_mutex); 474 470 475 471 INIT_LIST_HEAD(&ls->ls_nodes); 476 472 INIT_LIST_HEAD(&ls->ls_nodes_gone);
+10 -1
fs/dlm/main.c
··· 2 2 ******************************************************************************* 3 3 ** 4 4 ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 5 - ** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. 5 + ** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. 6 6 ** 7 7 ** This copyrighted material is made available to anyone wishing to use, 8 8 ** modify, copy, or redistribute it subject to the terms and conditions ··· 25 25 static inline int dlm_register_debugfs(void) { return 0; } 26 26 static inline void dlm_unregister_debugfs(void) { } 27 27 #endif 28 + int dlm_netlink_init(void); 29 + void dlm_netlink_exit(void); 28 30 29 31 static int __init init_dlm(void) 30 32 { ··· 52 50 if (error) 53 51 goto out_debug; 54 52 53 + error = dlm_netlink_init(); 54 + if (error) 55 + goto out_user; 56 + 55 57 printk("DLM (built %s %s) installed\n", __DATE__, __TIME__); 56 58 57 59 return 0; 58 60 61 + out_user: 62 + dlm_user_exit(); 59 63 out_debug: 60 64 dlm_unregister_debugfs(); 61 65 out_config: ··· 76 68 77 69 static void __exit exit_dlm(void) 78 70 { 71 + dlm_netlink_exit(); 79 72 dlm_user_exit(); 80 73 dlm_config_exit(); 81 74 dlm_memory_exit();
+4 -1
fs/dlm/member.c
··· 1 1 /****************************************************************************** 2 2 ******************************************************************************* 3 3 ** 4 - ** Copyright (C) 2005 Red Hat, Inc. All rights reserved. 4 + ** Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved. 5 5 ** 6 6 ** This copyrighted material is made available to anyone wishing to use, 7 7 ** modify, copy, or redistribute it subject to the terms and conditions ··· 284 284 dlm_recoverd_suspend(ls); 285 285 ls->ls_recover_status = 0; 286 286 dlm_recoverd_resume(ls); 287 + 288 + if (!ls->ls_recover_begin) 289 + ls->ls_recover_begin = jiffies; 287 290 return 0; 288 291 } 289 292
+155
fs/dlm/netlink.c
··· 1 + /* 2 + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. 3 + * 4 + * This copyrighted material is made available to anyone wishing to use, 5 + * modify, copy, or redistribute it subject to the terms and conditions 6 + * of the GNU General Public License v.2. 7 + */ 8 + 9 + #include <net/genetlink.h> 10 + #include <linux/dlm.h> 11 + #include <linux/dlm_netlink.h> 12 + 13 + #include "dlm_internal.h" 14 + 15 + static uint32_t dlm_nl_seqnum; 16 + static uint32_t listener_nlpid; 17 + 18 + static struct genl_family family = { 19 + .id = GENL_ID_GENERATE, 20 + .name = DLM_GENL_NAME, 21 + .version = DLM_GENL_VERSION, 22 + }; 23 + 24 + static int prepare_data(u8 cmd, struct sk_buff **skbp, size_t size) 25 + { 26 + struct sk_buff *skb; 27 + void *data; 28 + 29 + skb = genlmsg_new(size, GFP_KERNEL); 30 + if (!skb) 31 + return -ENOMEM; 32 + 33 + /* add the message headers */ 34 + data = genlmsg_put(skb, 0, dlm_nl_seqnum++, &family, 0, cmd); 35 + if (!data) { 36 + nlmsg_free(skb); 37 + return -EINVAL; 38 + } 39 + 40 + *skbp = skb; 41 + return 0; 42 + } 43 + 44 + static struct dlm_lock_data *mk_data(struct sk_buff *skb) 45 + { 46 + struct nlattr *ret; 47 + 48 + ret = nla_reserve(skb, DLM_TYPE_LOCK, sizeof(struct dlm_lock_data)); 49 + if (!ret) 50 + return NULL; 51 + return nla_data(ret); 52 + } 53 + 54 + static int send_data(struct sk_buff *skb) 55 + { 56 + struct genlmsghdr *genlhdr = nlmsg_data((struct nlmsghdr *)skb->data); 57 + void *data = genlmsg_data(genlhdr); 58 + int rv; 59 + 60 + rv = genlmsg_end(skb, data); 61 + if (rv < 0) { 62 + nlmsg_free(skb); 63 + return rv; 64 + } 65 + 66 + return genlmsg_unicast(skb, listener_nlpid); 67 + } 68 + 69 + static int user_cmd(struct sk_buff *skb, struct genl_info *info) 70 + { 71 + listener_nlpid = info->snd_pid; 72 + printk("user_cmd nlpid %u\n", listener_nlpid); 73 + return 0; 74 + } 75 + 76 + static struct genl_ops dlm_nl_ops = { 77 + .cmd = DLM_CMD_HELLO, 78 + .doit = user_cmd, 79 + }; 80 + 81 + int dlm_netlink_init(void) 82 + { 83 + int rv; 84 + 85 + rv = genl_register_family(&family); 86 + if (rv) 87 + return rv; 88 + 89 + rv = genl_register_ops(&family, &dlm_nl_ops); 90 + if (rv < 0) 91 + goto err; 92 + return 0; 93 + err: 94 + genl_unregister_family(&family); 95 + return rv; 96 + } 97 + 98 + void dlm_netlink_exit(void) 99 + { 100 + genl_unregister_ops(&family, &dlm_nl_ops); 101 + genl_unregister_family(&family); 102 + } 103 + 104 + static void fill_data(struct dlm_lock_data *data, struct dlm_lkb *lkb) 105 + { 106 + struct dlm_rsb *r = lkb->lkb_resource; 107 + struct dlm_user_args *ua = (struct dlm_user_args *) lkb->lkb_astparam; 108 + 109 + memset(data, 0, sizeof(struct dlm_lock_data)); 110 + 111 + data->version = DLM_LOCK_DATA_VERSION; 112 + data->nodeid = lkb->lkb_nodeid; 113 + data->ownpid = lkb->lkb_ownpid; 114 + data->id = lkb->lkb_id; 115 + data->remid = lkb->lkb_remid; 116 + data->status = lkb->lkb_status; 117 + data->grmode = lkb->lkb_grmode; 118 + data->rqmode = lkb->lkb_rqmode; 119 + data->timestamp = lkb->lkb_timestamp; 120 + if (ua) 121 + data->xid = ua->xid; 122 + if (r) { 123 + data->lockspace_id = r->res_ls->ls_global_id; 124 + data->resource_namelen = r->res_length; 125 + memcpy(data->resource_name, r->res_name, r->res_length); 126 + } 127 + } 128 + 129 + void dlm_timeout_warn(struct dlm_lkb *lkb) 130 + { 131 + struct dlm_lock_data *data; 132 + struct sk_buff *send_skb; 133 + size_t size; 134 + int rv; 135 + 136 + log_debug(lkb->lkb_resource->res_ls, "timeout_warn %x", lkb->lkb_id); 137 + 138 + size = nla_total_size(sizeof(struct dlm_lock_data)) + 139 + nla_total_size(0); /* why this? */ 140 + 141 + rv = prepare_data(DLM_CMD_TIMEOUT, &send_skb, size); 142 + if (rv < 0) 143 + return; 144 + 145 + data = mk_data(send_skb); 146 + if (!data) { 147 + nlmsg_free(send_skb); 148 + return; 149 + } 150 + 151 + fill_data(data, lkb); 152 + 153 + send_data(send_skb); 154 + } 155 +
+3 -1
fs/dlm/recoverd.c
··· 2 2 ******************************************************************************* 3 3 ** 4 4 ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 5 - ** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. 5 + ** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. 6 6 ** 7 7 ** This copyrighted material is made available to anyone wishing to use, 8 8 ** modify, copy, or redistribute it subject to the terms and conditions ··· 189 189 } 190 190 191 191 dlm_clear_members_gone(ls); 192 + 193 + dlm_adjust_timeouts(ls); 192 194 193 195 error = enable_locking(ls, rv->seq); 194 196 if (error) {
+1 -1
fs/dlm/user.c
··· 348 348 return -EPERM; 349 349 350 350 error = dlm_new_lockspace(params->name, strlen(params->name), 351 - &lockspace, 0, DLM_USER_LVB_LEN); 351 + &lockspace, params->flags, DLM_USER_LVB_LEN); 352 352 if (error) 353 353 return error; 354 354
+1
include/linux/Kbuild
··· 49 49 header-y += const.h 50 50 header-y += cycx_cfm.h 51 51 header-y += dlm_device.h 52 + header-y += dlm_netlink.h 52 53 header-y += dm-ioctl.h 53 54 header-y += dn.h 54 55 header-y += dqblk_v1.h
+4 -3
include/linux/dlm.h
··· 2 2 ******************************************************************************* 3 3 ** 4 4 ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 5 - ** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. 5 + ** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. 6 6 ** 7 7 ** This copyrighted material is made available to anyone wishing to use, 8 8 ** modify, copy, or redistribute it subject to the terms and conditions ··· 149 149 #define DLM_LKF_ALTPR 0x00008000 150 150 #define DLM_LKF_ALTCW 0x00010000 151 151 #define DLM_LKF_FORCEUNLOCK 0x00020000 152 + #define DLM_LKF_TIMEOUT 0x00040000 152 153 153 154 /* 154 155 * Some return codes that are not in errno.h ··· 200 199 char * sb_lvbptr; 201 200 }; 202 201 202 + #define DLM_LSFL_NODIR 0x00000001 203 + #define DLM_LSFL_TIMEWARN 0x00000002 203 204 204 205 #ifdef __KERNEL__ 205 - 206 - #define DLM_LSFL_NODIR 0x00000001 207 206 208 207 /* 209 208 * dlm_new_lockspace
+56
include/linux/dlm_netlink.h
··· 1 + /* 2 + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. 3 + * 4 + * This copyrighted material is made available to anyone wishing to use, 5 + * modify, copy, or redistribute it subject to the terms and conditions 6 + * of the GNU General Public License v.2. 7 + */ 8 + 9 + #ifndef _DLM_NETLINK_H 10 + #define _DLM_NETLINK_H 11 + 12 + enum { 13 + DLM_STATUS_WAITING = 1, 14 + DLM_STATUS_GRANTED = 2, 15 + DLM_STATUS_CONVERT = 3, 16 + }; 17 + 18 + #define DLM_LOCK_DATA_VERSION 1 19 + 20 + struct dlm_lock_data { 21 + uint16_t version; 22 + uint32_t lockspace_id; 23 + int nodeid; 24 + int ownpid; 25 + uint32_t id; 26 + uint32_t remid; 27 + uint64_t xid; 28 + int8_t status; 29 + int8_t grmode; 30 + int8_t rqmode; 31 + unsigned long timestamp; 32 + int resource_namelen; 33 + char resource_name[DLM_RESNAME_MAXLEN]; 34 + }; 35 + 36 + enum { 37 + DLM_CMD_UNSPEC = 0, 38 + DLM_CMD_HELLO, /* user->kernel */ 39 + DLM_CMD_TIMEOUT, /* kernel->user */ 40 + __DLM_CMD_MAX, 41 + }; 42 + 43 + #define DLM_CMD_MAX (__DLM_CMD_MAX - 1) 44 + 45 + enum { 46 + DLM_TYPE_UNSPEC = 0, 47 + DLM_TYPE_LOCK, 48 + __DLM_TYPE_MAX, 49 + }; 50 + 51 + #define DLM_TYPE_MAX (__DLM_TYPE_MAX - 1) 52 + 53 + #define DLM_GENL_VERSION 0x1 54 + #define DLM_GENL_NAME "DLM" 55 + 56 + #endif /* _DLM_NETLINK_H */