projects
/
cascardo
/
linux.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
[GFS2] Journaled file write/unstuff bug
[cascardo/linux.git]
/
fs
/
dlm
/
requestqueue.c
diff --git
a/fs/dlm/requestqueue.c
b/fs/dlm/requestqueue.c
index
7b2b089
..
65008d7
100644
(file)
--- a/
fs/dlm/requestqueue.c
+++ b/
fs/dlm/requestqueue.c
@@
-30,26
+30,36
@@
struct rq_entry {
* lockspace is enabled on some while still suspended on others.
*/
* lockspace is enabled on some while still suspended on others.
*/
-
void
dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_header *hd)
+
int
dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_header *hd)
{
struct rq_entry *e;
int length = hd->h_length;
{
struct rq_entry *e;
int length = hd->h_length;
-
- if (dlm_is_removed(ls, nodeid))
- return;
+ int rv = 0;
e = kmalloc(sizeof(struct rq_entry) + length, GFP_KERNEL);
if (!e) {
log_print("dlm_add_requestqueue: out of memory\n");
e = kmalloc(sizeof(struct rq_entry) + length, GFP_KERNEL);
if (!e) {
log_print("dlm_add_requestqueue: out of memory\n");
- return;
+ return
0
;
}
e->nodeid = nodeid;
memcpy(e->request, hd, length);
}
e->nodeid = nodeid;
memcpy(e->request, hd, length);
+ /* We need to check dlm_locking_stopped() after taking the mutex to
+ avoid a race where dlm_recoverd enables locking and runs
+ process_requestqueue between our earlier dlm_locking_stopped check
+ and this addition to the requestqueue. */
+
mutex_lock(&ls->ls_requestqueue_mutex);
mutex_lock(&ls->ls_requestqueue_mutex);
- list_add_tail(&e->list, &ls->ls_requestqueue);
+ if (dlm_locking_stopped(ls))
+ list_add_tail(&e->list, &ls->ls_requestqueue);
+ else {
+ log_debug(ls, "dlm_add_requestqueue skip from %d", nodeid);
+ kfree(e);
+ rv = -EAGAIN;
+ }
mutex_unlock(&ls->ls_requestqueue_mutex);
mutex_unlock(&ls->ls_requestqueue_mutex);
+ return rv;
}
int dlm_process_requestqueue(struct dlm_ls *ls)
}
int dlm_process_requestqueue(struct dlm_ls *ls)
@@
-120,6
+130,10
@@
static int purge_request(struct dlm_ls *ls, struct dlm_message *ms, int nodeid)
{
uint32_t type = ms->m_type;
{
uint32_t type = ms->m_type;
+ /* the ls is being cleaned up and freed by release_lockspace */
+ if (!ls->ls_count)
+ return 1;
+
if (dlm_is_removed(ls, nodeid))
return 1;
if (dlm_is_removed(ls, nodeid))
return 1;