aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/glock.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2006-04-26 13:21:55 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2006-04-26 13:21:55 -0400
commit5965b1f4792a1a9364b4e1ed6be8778a50eb981b (patch)
tree77773aca2301eb2e11dc455e7152823bf3bde361 /fs/gfs2/glock.c
parent3a2a9c96ac129d17aad1a5c46988ad28f72564b0 (diff)
[GFS2] Don't do recursive locking in glock layer
This patch changes the last user of recursive locking so that it no longer needs this feature and removes it from the glock layer. This makes the glock code a lot simpler and easier to understand. Its also a prerequsite to adding support for the AOP_TRUNCATED_PAGE return code (or at least it is if you don't want your brain to melt in the process) I've left in a couple of checks just in case there is some place else in the code which is still using this feature that I didn't spot yet, but they can probably be removed long term. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/glock.c')
-rw-r--r--fs/gfs2/glock.c162
1 files changed, 6 insertions, 156 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 32cc4005307d..0f317155915d 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -450,86 +450,6 @@ void gfs2_holder_put(struct gfs2_holder *gh)
450} 450}
451 451
452/** 452/**
453 * handle_recurse - put other holder structures (marked recursive)
454 * into the holders list
455 * @gh: the holder structure
456 *
457 */
458
459static void handle_recurse(struct gfs2_holder *gh)
460{
461 struct gfs2_glock *gl = gh->gh_gl;
462 struct gfs2_sbd *sdp = gl->gl_sbd;
463 struct gfs2_holder *tmp_gh, *safe;
464 int found = 0;
465
466 BUG_ON(!spin_is_locked(&gl->gl_spin));
467
468 printk(KERN_INFO "recursion %016llx, %u\n", gl->gl_name.ln_number,
469 gl->gl_name.ln_type);
470
471 if (gfs2_assert_warn(sdp, gh->gh_owner))
472 return;
473
474 list_for_each_entry_safe(tmp_gh, safe, &gl->gl_waiters3, gh_list) {
475 if (tmp_gh->gh_owner != gh->gh_owner)
476 continue;
477
478 gfs2_assert_warn(sdp,
479 test_bit(HIF_RECURSE, &tmp_gh->gh_iflags));
480
481 list_move_tail(&tmp_gh->gh_list, &gl->gl_holders);
482 tmp_gh->gh_error = 0;
483 set_bit(HIF_HOLDER, &tmp_gh->gh_iflags);
484
485 complete(&tmp_gh->gh_wait);
486
487 found = 1;
488 }
489
490 gfs2_assert_warn(sdp, found);
491}
492
493/**
494 * do_unrecurse - a recursive holder was just dropped of the waiters3 list
495 * @gh: the holder
496 *
497 * If there is only one other recursive holder, clear its HIF_RECURSE bit.
498 * If there is more than one, leave them alone.
499 *
500 */
501
502static void do_unrecurse(struct gfs2_holder *gh)
503{
504 struct gfs2_glock *gl = gh->gh_gl;
505 struct gfs2_sbd *sdp = gl->gl_sbd;
506 struct gfs2_holder *tmp_gh, *last_gh = NULL;
507 int found = 0;
508
509 BUG_ON(!spin_is_locked(&gl->gl_spin));
510
511 if (gfs2_assert_warn(sdp, gh->gh_owner))
512 return;
513
514 list_for_each_entry(tmp_gh, &gl->gl_waiters3, gh_list) {
515 if (tmp_gh->gh_owner != gh->gh_owner)
516 continue;
517
518 gfs2_assert_warn(sdp,
519 test_bit(HIF_RECURSE, &tmp_gh->gh_iflags));
520
521 if (found)
522 return;
523
524 found = 1;
525 last_gh = tmp_gh;
526 }
527
528 if (!gfs2_assert_warn(sdp, found))
529 clear_bit(HIF_RECURSE, &last_gh->gh_iflags);
530}
531
532/**
533 * rq_mutex - process a mutex request in the queue 453 * rq_mutex - process a mutex request in the queue
534 * @gh: the glock holder 454 * @gh: the glock holder
535 * 455 *
@@ -562,7 +482,6 @@ static int rq_promote(struct gfs2_holder *gh)
562 struct gfs2_glock *gl = gh->gh_gl; 482 struct gfs2_glock *gl = gh->gh_gl;
563 struct gfs2_sbd *sdp = gl->gl_sbd; 483 struct gfs2_sbd *sdp = gl->gl_sbd;
564 struct gfs2_glock_operations *glops = gl->gl_ops; 484 struct gfs2_glock_operations *glops = gl->gl_ops;
565 int recurse;
566 485
567 if (!relaxed_state_ok(gl->gl_state, gh->gh_state, gh->gh_flags)) { 486 if (!relaxed_state_ok(gl->gl_state, gh->gh_state, gh->gh_flags)) {
568 if (list_empty(&gl->gl_holders)) { 487 if (list_empty(&gl->gl_holders)) {
@@ -588,7 +507,6 @@ static int rq_promote(struct gfs2_holder *gh)
588 if (list_empty(&gl->gl_holders)) { 507 if (list_empty(&gl->gl_holders)) {
589 set_bit(HIF_FIRST, &gh->gh_iflags); 508 set_bit(HIF_FIRST, &gh->gh_iflags);
590 set_bit(GLF_LOCK, &gl->gl_flags); 509 set_bit(GLF_LOCK, &gl->gl_flags);
591 recurse = 0;
592 } else { 510 } else {
593 struct gfs2_holder *next_gh; 511 struct gfs2_holder *next_gh;
594 if (gh->gh_flags & GL_LOCAL_EXCL) 512 if (gh->gh_flags & GL_LOCAL_EXCL)
@@ -597,16 +515,12 @@ static int rq_promote(struct gfs2_holder *gh)
597 gh_list); 515 gh_list);
598 if (next_gh->gh_flags & GL_LOCAL_EXCL) 516 if (next_gh->gh_flags & GL_LOCAL_EXCL)
599 return 1; 517 return 1;
600 recurse = test_bit(HIF_RECURSE, &gh->gh_iflags);
601 } 518 }
602 519
603 list_move_tail(&gh->gh_list, &gl->gl_holders); 520 list_move_tail(&gh->gh_list, &gl->gl_holders);
604 gh->gh_error = 0; 521 gh->gh_error = 0;
605 set_bit(HIF_HOLDER, &gh->gh_iflags); 522 set_bit(HIF_HOLDER, &gh->gh_iflags);
606 523
607 if (recurse)
608 handle_recurse(gh);
609
610 complete(&gh->gh_wait); 524 complete(&gh->gh_wait);
611 525
612 return 0; 526 return 0;
@@ -897,8 +811,6 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret)
897 spin_lock(&gl->gl_spin); 811 spin_lock(&gl->gl_spin);
898 list_del_init(&gh->gh_list); 812 list_del_init(&gh->gh_list);
899 gh->gh_error = -EIO; 813 gh->gh_error = -EIO;
900 if (test_bit(HIF_RECURSE, &gh->gh_iflags))
901 do_unrecurse(gh);
902 spin_unlock(&gl->gl_spin); 814 spin_unlock(&gl->gl_spin);
903 815
904 } else if (test_bit(HIF_DEMOTE, &gh->gh_iflags)) { 816 } else if (test_bit(HIF_DEMOTE, &gh->gh_iflags)) {
@@ -922,8 +834,6 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret)
922 spin_lock(&gl->gl_spin); 834 spin_lock(&gl->gl_spin);
923 list_del_init(&gh->gh_list); 835 list_del_init(&gh->gh_list);
924 gh->gh_error = GLR_CANCELED; 836 gh->gh_error = GLR_CANCELED;
925 if (test_bit(HIF_RECURSE, &gh->gh_iflags))
926 do_unrecurse(gh);
927 spin_unlock(&gl->gl_spin); 837 spin_unlock(&gl->gl_spin);
928 838
929 } else if (relaxed_state_ok(gl->gl_state, gh->gh_state, gh->gh_flags)) { 839 } else if (relaxed_state_ok(gl->gl_state, gh->gh_state, gh->gh_flags)) {
@@ -941,8 +851,6 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret)
941 spin_lock(&gl->gl_spin); 851 spin_lock(&gl->gl_spin);
942 list_del_init(&gh->gh_list); 852 list_del_init(&gh->gh_list);
943 gh->gh_error = GLR_TRYFAILED; 853 gh->gh_error = GLR_TRYFAILED;
944 if (test_bit(HIF_RECURSE, &gh->gh_iflags))
945 do_unrecurse(gh);
946 spin_unlock(&gl->gl_spin); 854 spin_unlock(&gl->gl_spin);
947 855
948 } else { 856 } else {
@@ -1161,8 +1069,6 @@ static int glock_wait_internal(struct gfs2_holder *gh)
1161 !list_empty(&gh->gh_list)) { 1069 !list_empty(&gh->gh_list)) {
1162 list_del_init(&gh->gh_list); 1070 list_del_init(&gh->gh_list);
1163 gh->gh_error = GLR_TRYFAILED; 1071 gh->gh_error = GLR_TRYFAILED;
1164 if (test_bit(HIF_RECURSE, &gh->gh_iflags))
1165 do_unrecurse(gh);
1166 run_queue(gl); 1072 run_queue(gl);
1167 spin_unlock(&gl->gl_spin); 1073 spin_unlock(&gl->gl_spin);
1168 return gh->gh_error; 1074 return gh->gh_error;
@@ -1191,9 +1097,6 @@ static int glock_wait_internal(struct gfs2_holder *gh)
1191 if (gh->gh_error) { 1097 if (gh->gh_error) {
1192 spin_lock(&gl->gl_spin); 1098 spin_lock(&gl->gl_spin);
1193 list_del_init(&gh->gh_list); 1099 list_del_init(&gh->gh_list);
1194 if (test_and_clear_bit(HIF_RECURSE,
1195 &gh->gh_iflags))
1196 do_unrecurse(gh);
1197 spin_unlock(&gl->gl_spin); 1100 spin_unlock(&gl->gl_spin);
1198 } 1101 }
1199 } 1102 }
@@ -1202,8 +1105,6 @@ static int glock_wait_internal(struct gfs2_holder *gh)
1202 gl->gl_req_gh = NULL; 1105 gl->gl_req_gh = NULL;
1203 gl->gl_req_bh = NULL; 1106 gl->gl_req_bh = NULL;
1204 clear_bit(GLF_LOCK, &gl->gl_flags); 1107 clear_bit(GLF_LOCK, &gl->gl_flags);
1205 if (test_bit(HIF_RECURSE, &gh->gh_iflags))
1206 handle_recurse(gh);
1207 run_queue(gl); 1108 run_queue(gl);
1208 spin_unlock(&gl->gl_spin); 1109 spin_unlock(&gl->gl_spin);
1209 } 1110 }
@@ -1225,40 +1126,6 @@ find_holder_by_owner(struct list_head *head, struct task_struct *owner)
1225} 1126}
1226 1127
1227/** 1128/**
1228 * recurse_check -
1229 *
1230 * Make sure the new holder is compatible with the pre-existing one.
1231 *
1232 */
1233
1234static int recurse_check(struct gfs2_holder *existing, struct gfs2_holder *new,
1235 unsigned int state)
1236{
1237 struct gfs2_sbd *sdp = existing->gh_gl->gl_sbd;
1238
1239 if (gfs2_assert_warn(sdp, (new->gh_flags & LM_FLAG_ANY) ||
1240 !(existing->gh_flags & LM_FLAG_ANY)))
1241 goto fail;
1242
1243 if (gfs2_assert_warn(sdp, (existing->gh_flags & GL_LOCAL_EXCL) ||
1244 !(new->gh_flags & GL_LOCAL_EXCL)))
1245 goto fail;
1246
1247 if (gfs2_assert_warn(sdp, relaxed_state_ok(state, new->gh_state,
1248 new->gh_flags)))
1249 goto fail;
1250
1251 return 0;
1252
1253fail:
1254 print_symbol(KERN_WARNING "GFS2: Existing holder from %s\n",
1255 existing->gh_ip);
1256 print_symbol(KERN_WARNING "GFS2: New holder from %s\n", new->gh_ip);
1257 set_bit(HIF_ABORTED, &new->gh_iflags);
1258 return -EINVAL;
1259}
1260
1261/**
1262 * add_to_queue - Add a holder to the wait queue (but look for recursion) 1129 * add_to_queue - Add a holder to the wait queue (but look for recursion)
1263 * @gh: the holder structure to add 1130 * @gh: the holder structure to add
1264 * 1131 *
@@ -1271,37 +1138,20 @@ static void add_to_queue(struct gfs2_holder *gh)
1271 1138
1272 BUG_ON(!gh->gh_owner); 1139 BUG_ON(!gh->gh_owner);
1273 1140
1274 if (!gh->gh_owner)
1275 goto out;
1276
1277 existing = find_holder_by_owner(&gl->gl_holders, gh->gh_owner); 1141 existing = find_holder_by_owner(&gl->gl_holders, gh->gh_owner);
1278 if (existing) { 1142 if (existing) {
1279 if (recurse_check(existing, gh, gl->gl_state)) 1143 print_symbol(KERN_WARNING "original: %s\n", existing->gh_ip);
1280 return; 1144 print_symbol(KERN_WARNING "new: %s\n", gh->gh_ip);
1281 1145 BUG();
1282 list_add_tail(&gh->gh_list, &gl->gl_holders);
1283 set_bit(HIF_HOLDER, &gh->gh_iflags);
1284
1285 gh->gh_error = 0;
1286 complete(&gh->gh_wait);
1287
1288 return;
1289 } 1146 }
1290 1147
1291 existing = find_holder_by_owner(&gl->gl_waiters3, gh->gh_owner); 1148 existing = find_holder_by_owner(&gl->gl_waiters3, gh->gh_owner);
1292 if (existing) { 1149 if (existing) {
1293 if (recurse_check(existing, gh, existing->gh_state)) 1150 print_symbol(KERN_WARNING "original: %s\n", existing->gh_ip);
1294 return; 1151 print_symbol(KERN_WARNING "new: %s\n", gh->gh_ip);
1295 1152 BUG();
1296 set_bit(HIF_RECURSE, &gh->gh_iflags);
1297 set_bit(HIF_RECURSE, &existing->gh_iflags);
1298
1299 list_add_tail(&gh->gh_list, &gl->gl_waiters3);
1300
1301 return;
1302 } 1153 }
1303 1154
1304 out:
1305 if (gh->gh_flags & LM_FLAG_PRIORITY) 1155 if (gh->gh_flags & LM_FLAG_PRIORITY)
1306 list_add(&gh->gh_list, &gl->gl_waiters3); 1156 list_add(&gh->gh_list, &gl->gl_waiters3);
1307 else 1157 else