aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2006-08-09 12:20:15 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2006-08-09 17:32:07 -0400
commit4a99c3d9d6663085e28bc7ac8dae1e985c5a6174 (patch)
treecf96b33aaa41411f7c5a5a5ece5862c4d672711f
parentfaa0f2677287a2e7ae796db8b73618ec43715e94 (diff)
[DLM] reject replies to old requests
When recoveries are aborted by other recoveries we can get replies to status or names requests that we've given up on. This can cause problems if we're making another request and receive an old reply. Add a sequence number to status/names requests and reject replies that don't match. A field already exists for the seq number that's used in other message types. Signed-off-by: David Teigland <teigland@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
-rw-r--r--fs/dlm/dlm_internal.h1
-rw-r--r--fs/dlm/rcom.c20
2 files changed, 17 insertions, 4 deletions
diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h
index ec7e401133fd..da7509986699 100644
--- a/fs/dlm/dlm_internal.h
+++ b/fs/dlm/dlm_internal.h
@@ -468,6 +468,7 @@ struct dlm_ls {
468 struct mutex ls_requestqueue_mutex; 468 struct mutex ls_requestqueue_mutex;
469 char *ls_recover_buf; 469 char *ls_recover_buf;
470 int ls_recover_nodeid; /* for debugging */ 470 int ls_recover_nodeid; /* for debugging */
471 uint64_t ls_rcom_seq;
471 struct list_head ls_recover_list; 472 struct list_head ls_recover_list;
472 spinlock_t ls_recover_list_lock; 473 spinlock_t ls_recover_list_lock;
473 int ls_recover_list_count; 474 int ls_recover_list_count;
diff --git a/fs/dlm/rcom.c b/fs/dlm/rcom.c
index 5573d8590e58..64ba4929f90b 100644
--- a/fs/dlm/rcom.c
+++ b/fs/dlm/rcom.c
@@ -108,6 +108,7 @@ int dlm_rcom_status(struct dlm_ls *ls, int nodeid)
108 error = create_rcom(ls, nodeid, DLM_RCOM_STATUS, 0, &rc, &mh); 108 error = create_rcom(ls, nodeid, DLM_RCOM_STATUS, 0, &rc, &mh);
109 if (error) 109 if (error)
110 goto out; 110 goto out;
111 rc->rc_id = ++ls->ls_rcom_seq;
111 112
112 send_rcom(ls, mh, rc); 113 send_rcom(ls, mh, rc);
113 114
@@ -140,19 +141,30 @@ static void receive_rcom_status(struct dlm_ls *ls, struct dlm_rcom *rc_in)
140 sizeof(struct rcom_config), &rc, &mh); 141 sizeof(struct rcom_config), &rc, &mh);
141 if (error) 142 if (error)
142 return; 143 return;
144 rc->rc_id = rc_in->rc_id;
143 rc->rc_result = dlm_recover_status(ls); 145 rc->rc_result = dlm_recover_status(ls);
144 make_config(ls, (struct rcom_config *) rc->rc_buf); 146 make_config(ls, (struct rcom_config *) rc->rc_buf);
145 147
146 send_rcom(ls, mh, rc); 148 send_rcom(ls, mh, rc);
147} 149}
148 150
149static void receive_rcom_status_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in) 151static void receive_sync_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in)
150{ 152{
153 if (rc_in->rc_id != ls->ls_rcom_seq) {
154 log_debug(ls, "reject old reply %d got %llx wanted %llx",
155 rc_in->rc_type, rc_in->rc_id, ls->ls_rcom_seq);
156 return;
157 }
151 memcpy(ls->ls_recover_buf, rc_in, rc_in->rc_header.h_length); 158 memcpy(ls->ls_recover_buf, rc_in, rc_in->rc_header.h_length);
152 set_bit(LSFL_RCOM_READY, &ls->ls_flags); 159 set_bit(LSFL_RCOM_READY, &ls->ls_flags);
153 wake_up(&ls->ls_wait_general); 160 wake_up(&ls->ls_wait_general);
154} 161}
155 162
163static void receive_rcom_status_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in)
164{
165 receive_sync_reply(ls, rc_in);
166}
167
156int dlm_rcom_names(struct dlm_ls *ls, int nodeid, char *last_name, int last_len) 168int dlm_rcom_names(struct dlm_ls *ls, int nodeid, char *last_name, int last_len)
157{ 169{
158 struct dlm_rcom *rc; 170 struct dlm_rcom *rc;
@@ -173,6 +185,7 @@ int dlm_rcom_names(struct dlm_ls *ls, int nodeid, char *last_name, int last_len)
173 if (error) 185 if (error)
174 goto out; 186 goto out;
175 memcpy(rc->rc_buf, last_name, last_len); 187 memcpy(rc->rc_buf, last_name, last_len);
188 rc->rc_id = ++ls->ls_rcom_seq;
176 189
177 send_rcom(ls, mh, rc); 190 send_rcom(ls, mh, rc);
178 191
@@ -209,6 +222,7 @@ static void receive_rcom_names(struct dlm_ls *ls, struct dlm_rcom *rc_in)
209 error = create_rcom(ls, nodeid, DLM_RCOM_NAMES_REPLY, outlen, &rc, &mh); 222 error = create_rcom(ls, nodeid, DLM_RCOM_NAMES_REPLY, outlen, &rc, &mh);
210 if (error) 223 if (error)
211 return; 224 return;
225 rc->rc_id = rc_in->rc_id;
212 226
213 dlm_copy_master_names(ls, rc_in->rc_buf, inlen, rc->rc_buf, outlen, 227 dlm_copy_master_names(ls, rc_in->rc_buf, inlen, rc->rc_buf, outlen,
214 nodeid); 228 nodeid);
@@ -217,9 +231,7 @@ static void receive_rcom_names(struct dlm_ls *ls, struct dlm_rcom *rc_in)
217 231
218static void receive_rcom_names_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in) 232static void receive_rcom_names_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in)
219{ 233{
220 memcpy(ls->ls_recover_buf, rc_in, rc_in->rc_header.h_length); 234 receive_sync_reply(ls, rc_in);
221 set_bit(LSFL_RCOM_READY, &ls->ls_flags);
222 wake_up(&ls->ls_wait_general);
223} 235}
224 236
225int dlm_send_rcom_lookup(struct dlm_rsb *r, int dir_nodeid) 237int dlm_send_rcom_lookup(struct dlm_rsb *r, int dir_nodeid)