diff options
-rw-r--r-- | fs/ocfs2/dlm/dlmcommon.h | 6 | ||||
-rw-r--r-- | fs/ocfs2/dlm/dlmmaster.c | 99 |
2 files changed, 94 insertions, 11 deletions
diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h index 3f554711efe5..2f4f5d4edb07 100644 --- a/fs/ocfs2/dlm/dlmcommon.h +++ b/fs/ocfs2/dlm/dlmcommon.h | |||
@@ -180,6 +180,11 @@ struct dlm_assert_master_priv | |||
180 | unsigned ignore_higher:1; | 180 | unsigned ignore_higher:1; |
181 | }; | 181 | }; |
182 | 182 | ||
183 | struct dlm_deref_lockres_priv | ||
184 | { | ||
185 | struct dlm_lock_resource *deref_res; | ||
186 | u8 deref_node; | ||
187 | }; | ||
183 | 188 | ||
184 | struct dlm_work_item | 189 | struct dlm_work_item |
185 | { | 190 | { |
@@ -191,6 +196,7 @@ struct dlm_work_item | |||
191 | struct dlm_request_all_locks_priv ral; | 196 | struct dlm_request_all_locks_priv ral; |
192 | struct dlm_mig_lockres_priv ml; | 197 | struct dlm_mig_lockres_priv ml; |
193 | struct dlm_assert_master_priv am; | 198 | struct dlm_assert_master_priv am; |
199 | struct dlm_deref_lockres_priv dl; | ||
194 | } u; | 200 | } u; |
195 | }; | 201 | }; |
196 | 202 | ||
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 84f36db8ada3..77e4e6169a0d 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c | |||
@@ -102,6 +102,7 @@ static void dlm_assert_master_worker(struct dlm_work_item *item, void *data); | |||
102 | static int dlm_do_assert_master(struct dlm_ctxt *dlm, | 102 | static int dlm_do_assert_master(struct dlm_ctxt *dlm, |
103 | struct dlm_lock_resource *res, | 103 | struct dlm_lock_resource *res, |
104 | void *nodemap, u32 flags); | 104 | void *nodemap, u32 flags); |
105 | static void dlm_deref_lockres_worker(struct dlm_work_item *item, void *data); | ||
105 | 106 | ||
106 | static inline int dlm_mle_equal(struct dlm_ctxt *dlm, | 107 | static inline int dlm_mle_equal(struct dlm_ctxt *dlm, |
107 | struct dlm_master_list_entry *mle, | 108 | struct dlm_master_list_entry *mle, |
@@ -1717,6 +1718,11 @@ int dlm_do_assert_master(struct dlm_ctxt *dlm, | |||
1717 | unsigned int namelen = res->lockname.len; | 1718 | unsigned int namelen = res->lockname.len; |
1718 | 1719 | ||
1719 | BUG_ON(namelen > O2NM_MAX_NAME_LEN); | 1720 | BUG_ON(namelen > O2NM_MAX_NAME_LEN); |
1721 | |||
1722 | spin_lock(&res->spinlock); | ||
1723 | res->state |= DLM_LOCK_RES_SETREF_INPROG; | ||
1724 | spin_unlock(&res->spinlock); | ||
1725 | |||
1720 | again: | 1726 | again: |
1721 | reassert = 0; | 1727 | reassert = 0; |
1722 | 1728 | ||
@@ -1789,6 +1795,11 @@ again: | |||
1789 | if (reassert) | 1795 | if (reassert) |
1790 | goto again; | 1796 | goto again; |
1791 | 1797 | ||
1798 | spin_lock(&res->spinlock); | ||
1799 | res->state &= ~DLM_LOCK_RES_SETREF_INPROG; | ||
1800 | spin_unlock(&res->spinlock); | ||
1801 | wake_up(&res->wq); | ||
1802 | |||
1792 | return ret; | 1803 | return ret; |
1793 | } | 1804 | } |
1794 | 1805 | ||
@@ -2296,6 +2307,9 @@ int dlm_deref_lockres_handler(struct o2net_msg *msg, u32 len, void *data, | |||
2296 | int ret = -EINVAL; | 2307 | int ret = -EINVAL; |
2297 | u8 node; | 2308 | u8 node; |
2298 | unsigned int hash; | 2309 | unsigned int hash; |
2310 | struct dlm_work_item *item; | ||
2311 | int cleared = 0; | ||
2312 | int dispatch = 0; | ||
2299 | 2313 | ||
2300 | if (!dlm_grab(dlm)) | 2314 | if (!dlm_grab(dlm)) |
2301 | return 0; | 2315 | return 0; |
@@ -2326,27 +2340,90 @@ int dlm_deref_lockres_handler(struct o2net_msg *msg, u32 len, void *data, | |||
2326 | spin_unlock(&dlm->spinlock); | 2340 | spin_unlock(&dlm->spinlock); |
2327 | 2341 | ||
2328 | spin_lock(&res->spinlock); | 2342 | spin_lock(&res->spinlock); |
2329 | BUG_ON(res->state & DLM_LOCK_RES_DROPPING_REF); | 2343 | if (res->state & DLM_LOCK_RES_SETREF_INPROG) |
2330 | if (test_bit(node, res->refmap)) { | 2344 | dispatch = 1; |
2331 | ret = 0; | 2345 | else { |
2332 | dlm_lockres_clear_refmap_bit(node, res); | 2346 | BUG_ON(res->state & DLM_LOCK_RES_DROPPING_REF); |
2333 | } else { | 2347 | if (test_bit(node, res->refmap)) { |
2334 | mlog(ML_ERROR, "%s:%.*s: node %u trying to drop ref " | 2348 | dlm_lockres_clear_refmap_bit(node, res); |
2335 | "but it is already dropped!\n", dlm->name, namelen, | 2349 | cleared = 1; |
2336 | name, node); | 2350 | } |
2337 | __dlm_print_one_lock_resource(res); | ||
2338 | } | 2351 | } |
2339 | spin_unlock(&res->spinlock); | 2352 | spin_unlock(&res->spinlock); |
2340 | 2353 | ||
2341 | if (!ret) | 2354 | if (!dispatch) { |
2342 | dlm_lockres_calc_usage(dlm, res); | 2355 | if (cleared) |
2356 | dlm_lockres_calc_usage(dlm, res); | ||
2357 | else { | ||
2358 | mlog(ML_ERROR, "%s:%.*s: node %u trying to drop ref " | ||
2359 | "but it is already dropped!\n", dlm->name, | ||
2360 | res->lockname.len, res->lockname.name, node); | ||
2361 | __dlm_print_one_lock_resource(res); | ||
2362 | } | ||
2363 | ret = 0; | ||
2364 | goto done; | ||
2365 | } | ||
2366 | |||
2367 | item = kzalloc(sizeof(*item), GFP_NOFS); | ||
2368 | if (!item) { | ||
2369 | ret = -ENOMEM; | ||
2370 | mlog_errno(ret); | ||
2371 | goto done; | ||
2372 | } | ||
2373 | |||
2374 | dlm_init_work_item(dlm, item, dlm_deref_lockres_worker, NULL); | ||
2375 | item->u.dl.deref_res = res; | ||
2376 | item->u.dl.deref_node = node; | ||
2377 | |||
2378 | spin_lock(&dlm->work_lock); | ||
2379 | list_add_tail(&item->list, &dlm->work_list); | ||
2380 | spin_unlock(&dlm->work_lock); | ||
2381 | |||
2382 | queue_work(dlm->dlm_worker, &dlm->dispatched_work); | ||
2383 | return 0; | ||
2384 | |||
2343 | done: | 2385 | done: |
2344 | if (res) | 2386 | if (res) |
2345 | dlm_lockres_put(res); | 2387 | dlm_lockres_put(res); |
2346 | dlm_put(dlm); | 2388 | dlm_put(dlm); |
2389 | |||
2347 | return ret; | 2390 | return ret; |
2348 | } | 2391 | } |
2349 | 2392 | ||
2393 | static void dlm_deref_lockres_worker(struct dlm_work_item *item, void *data) | ||
2394 | { | ||
2395 | struct dlm_ctxt *dlm; | ||
2396 | struct dlm_lock_resource *res; | ||
2397 | u8 node; | ||
2398 | u8 cleared = 0; | ||
2399 | |||
2400 | dlm = item->dlm; | ||
2401 | res = item->u.dl.deref_res; | ||
2402 | node = item->u.dl.deref_node; | ||
2403 | |||
2404 | spin_lock(&res->spinlock); | ||
2405 | BUG_ON(res->state & DLM_LOCK_RES_DROPPING_REF); | ||
2406 | if (test_bit(node, res->refmap)) { | ||
2407 | __dlm_wait_on_lockres_flags(res, DLM_LOCK_RES_SETREF_INPROG); | ||
2408 | dlm_lockres_clear_refmap_bit(node, res); | ||
2409 | cleared = 1; | ||
2410 | } | ||
2411 | spin_unlock(&res->spinlock); | ||
2412 | |||
2413 | if (cleared) { | ||
2414 | mlog(0, "%s:%.*s node %u ref dropped in dispatch\n", | ||
2415 | dlm->name, res->lockname.len, res->lockname.name, node); | ||
2416 | dlm_lockres_calc_usage(dlm, res); | ||
2417 | } else { | ||
2418 | mlog(ML_ERROR, "%s:%.*s: node %u trying to drop ref " | ||
2419 | "but it is already dropped!\n", dlm->name, | ||
2420 | res->lockname.len, res->lockname.name, node); | ||
2421 | __dlm_print_one_lock_resource(res); | ||
2422 | } | ||
2423 | |||
2424 | dlm_lockres_put(res); | ||
2425 | } | ||
2426 | |||
2350 | 2427 | ||
2351 | /* | 2428 | /* |
2352 | * DLM_MIGRATE_LOCKRES | 2429 | * DLM_MIGRATE_LOCKRES |