diff options
Diffstat (limited to 'fs/gfs2/glock.c')
-rw-r--r-- | fs/gfs2/glock.c | 92 |
1 files changed, 44 insertions, 48 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 87778857f099..08a8beb152e6 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -541,21 +541,6 @@ out_locked: | |||
541 | spin_unlock(&gl->gl_spin); | 541 | spin_unlock(&gl->gl_spin); |
542 | } | 542 | } |
543 | 543 | ||
544 | static unsigned int gfs2_lm_lock(struct gfs2_sbd *sdp, void *lock, | ||
545 | unsigned int req_state, | ||
546 | unsigned int flags) | ||
547 | { | ||
548 | int ret = LM_OUT_ERROR; | ||
549 | |||
550 | if (!sdp->sd_lockstruct.ls_ops->lm_lock) | ||
551 | return req_state == LM_ST_UNLOCKED ? 0 : req_state; | ||
552 | |||
553 | if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) | ||
554 | ret = sdp->sd_lockstruct.ls_ops->lm_lock(lock, | ||
555 | req_state, flags); | ||
556 | return ret; | ||
557 | } | ||
558 | |||
559 | /** | 544 | /** |
560 | * do_xmote - Calls the DLM to change the state of a lock | 545 | * do_xmote - Calls the DLM to change the state of a lock |
561 | * @gl: The lock state | 546 | * @gl: The lock state |
@@ -575,13 +560,14 @@ __acquires(&gl->gl_spin) | |||
575 | 560 | ||
576 | lck_flags &= (LM_FLAG_TRY | LM_FLAG_TRY_1CB | LM_FLAG_NOEXP | | 561 | lck_flags &= (LM_FLAG_TRY | LM_FLAG_TRY_1CB | LM_FLAG_NOEXP | |
577 | LM_FLAG_PRIORITY); | 562 | LM_FLAG_PRIORITY); |
578 | BUG_ON(gl->gl_state == target); | 563 | GLOCK_BUG_ON(gl, gl->gl_state == target); |
579 | BUG_ON(gl->gl_state == gl->gl_target); | 564 | GLOCK_BUG_ON(gl, gl->gl_state == gl->gl_target); |
580 | if ((target == LM_ST_UNLOCKED || target == LM_ST_DEFERRED) && | 565 | if ((target == LM_ST_UNLOCKED || target == LM_ST_DEFERRED) && |
581 | glops->go_inval) { | 566 | glops->go_inval) { |
582 | set_bit(GLF_INVALIDATE_IN_PROGRESS, &gl->gl_flags); | 567 | set_bit(GLF_INVALIDATE_IN_PROGRESS, &gl->gl_flags); |
583 | do_error(gl, 0); /* Fail queued try locks */ | 568 | do_error(gl, 0); /* Fail queued try locks */ |
584 | } | 569 | } |
570 | gl->gl_req = target; | ||
585 | spin_unlock(&gl->gl_spin); | 571 | spin_unlock(&gl->gl_spin); |
586 | if (glops->go_xmote_th) | 572 | if (glops->go_xmote_th) |
587 | glops->go_xmote_th(gl); | 573 | glops->go_xmote_th(gl); |
@@ -594,15 +580,17 @@ __acquires(&gl->gl_spin) | |||
594 | gl->gl_state == LM_ST_DEFERRED) && | 580 | gl->gl_state == LM_ST_DEFERRED) && |
595 | !(lck_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB))) | 581 | !(lck_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB))) |
596 | lck_flags |= LM_FLAG_TRY_1CB; | 582 | lck_flags |= LM_FLAG_TRY_1CB; |
597 | ret = gfs2_lm_lock(sdp, gl, target, lck_flags); | ||
598 | 583 | ||
599 | if (!(ret & LM_OUT_ASYNC)) { | 584 | if (sdp->sd_lockstruct.ls_ops->lm_lock) { |
600 | finish_xmote(gl, ret); | 585 | /* lock_dlm */ |
586 | ret = sdp->sd_lockstruct.ls_ops->lm_lock(gl, target, lck_flags); | ||
587 | GLOCK_BUG_ON(gl, ret); | ||
588 | } else { /* lock_nolock */ | ||
589 | finish_xmote(gl, target); | ||
601 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) | 590 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) |
602 | gfs2_glock_put(gl); | 591 | gfs2_glock_put(gl); |
603 | } else { | ||
604 | GLOCK_BUG_ON(gl, ret != LM_OUT_ASYNC); | ||
605 | } | 592 | } |
593 | |||
606 | spin_lock(&gl->gl_spin); | 594 | spin_lock(&gl->gl_spin); |
607 | } | 595 | } |
608 | 596 | ||
@@ -686,21 +674,20 @@ static void delete_work_func(struct work_struct *work) | |||
686 | { | 674 | { |
687 | struct gfs2_glock *gl = container_of(work, struct gfs2_glock, gl_delete); | 675 | struct gfs2_glock *gl = container_of(work, struct gfs2_glock, gl_delete); |
688 | struct gfs2_sbd *sdp = gl->gl_sbd; | 676 | struct gfs2_sbd *sdp = gl->gl_sbd; |
689 | struct gfs2_inode *ip = NULL; | 677 | struct gfs2_inode *ip; |
690 | struct inode *inode; | 678 | struct inode *inode; |
691 | u64 no_addr = 0; | 679 | u64 no_addr = gl->gl_name.ln_number; |
680 | |||
681 | ip = gl->gl_object; | ||
682 | /* Note: Unsafe to dereference ip as we don't hold right refs/locks */ | ||
692 | 683 | ||
693 | spin_lock(&gl->gl_spin); | ||
694 | ip = (struct gfs2_inode *)gl->gl_object; | ||
695 | if (ip) | 684 | if (ip) |
696 | no_addr = ip->i_no_addr; | ||
697 | spin_unlock(&gl->gl_spin); | ||
698 | if (ip) { | ||
699 | inode = gfs2_ilookup(sdp->sd_vfs, no_addr); | 685 | inode = gfs2_ilookup(sdp->sd_vfs, no_addr); |
700 | if (inode) { | 686 | else |
701 | d_prune_aliases(inode); | 687 | inode = gfs2_lookup_by_inum(sdp, no_addr, NULL, GFS2_BLKST_UNLINKED); |
702 | iput(inode); | 688 | if (inode && !IS_ERR(inode)) { |
703 | } | 689 | d_prune_aliases(inode); |
690 | iput(inode); | ||
704 | } | 691 | } |
705 | gfs2_glock_put(gl); | 692 | gfs2_glock_put(gl); |
706 | } | 693 | } |
@@ -952,17 +939,22 @@ int gfs2_glock_wait(struct gfs2_holder *gh) | |||
952 | 939 | ||
953 | void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...) | 940 | void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...) |
954 | { | 941 | { |
942 | struct va_format vaf; | ||
955 | va_list args; | 943 | va_list args; |
956 | 944 | ||
957 | va_start(args, fmt); | 945 | va_start(args, fmt); |
946 | |||
958 | if (seq) { | 947 | if (seq) { |
959 | struct gfs2_glock_iter *gi = seq->private; | 948 | struct gfs2_glock_iter *gi = seq->private; |
960 | vsprintf(gi->string, fmt, args); | 949 | vsprintf(gi->string, fmt, args); |
961 | seq_printf(seq, gi->string); | 950 | seq_printf(seq, gi->string); |
962 | } else { | 951 | } else { |
963 | printk(KERN_ERR " "); | 952 | vaf.fmt = fmt; |
964 | vprintk(fmt, args); | 953 | vaf.va = &args; |
954 | |||
955 | printk(KERN_ERR " %pV", &vaf); | ||
965 | } | 956 | } |
957 | |||
966 | va_end(args); | 958 | va_end(args); |
967 | } | 959 | } |
968 | 960 | ||
@@ -1362,24 +1354,28 @@ static int gfs2_should_freeze(const struct gfs2_glock *gl) | |||
1362 | * @gl: Pointer to the glock | 1354 | * @gl: Pointer to the glock |
1363 | * @ret: The return value from the dlm | 1355 | * @ret: The return value from the dlm |
1364 | * | 1356 | * |
1357 | * The gl_reply field is under the gl_spin lock so that it is ok | ||
1358 | * to use a bitfield shared with other glock state fields. | ||
1365 | */ | 1359 | */ |
1366 | 1360 | ||
1367 | void gfs2_glock_complete(struct gfs2_glock *gl, int ret) | 1361 | void gfs2_glock_complete(struct gfs2_glock *gl, int ret) |
1368 | { | 1362 | { |
1369 | struct lm_lockstruct *ls = &gl->gl_sbd->sd_lockstruct; | 1363 | struct lm_lockstruct *ls = &gl->gl_sbd->sd_lockstruct; |
1370 | 1364 | ||
1365 | spin_lock(&gl->gl_spin); | ||
1371 | gl->gl_reply = ret; | 1366 | gl->gl_reply = ret; |
1372 | 1367 | ||
1373 | if (unlikely(test_bit(DFL_BLOCK_LOCKS, &ls->ls_flags))) { | 1368 | if (unlikely(test_bit(DFL_BLOCK_LOCKS, &ls->ls_flags))) { |
1374 | spin_lock(&gl->gl_spin); | ||
1375 | if (gfs2_should_freeze(gl)) { | 1369 | if (gfs2_should_freeze(gl)) { |
1376 | set_bit(GLF_FROZEN, &gl->gl_flags); | 1370 | set_bit(GLF_FROZEN, &gl->gl_flags); |
1377 | spin_unlock(&gl->gl_spin); | 1371 | spin_unlock(&gl->gl_spin); |
1378 | return; | 1372 | return; |
1379 | } | 1373 | } |
1380 | spin_unlock(&gl->gl_spin); | ||
1381 | } | 1374 | } |
1375 | |||
1376 | spin_unlock(&gl->gl_spin); | ||
1382 | set_bit(GLF_REPLY_PENDING, &gl->gl_flags); | 1377 | set_bit(GLF_REPLY_PENDING, &gl->gl_flags); |
1378 | smp_wmb(); | ||
1383 | gfs2_glock_hold(gl); | 1379 | gfs2_glock_hold(gl); |
1384 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) | 1380 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) |
1385 | gfs2_glock_put(gl); | 1381 | gfs2_glock_put(gl); |
@@ -1627,18 +1623,17 @@ static const char *hflags2str(char *buf, unsigned flags, unsigned long iflags) | |||
1627 | static int dump_holder(struct seq_file *seq, const struct gfs2_holder *gh) | 1623 | static int dump_holder(struct seq_file *seq, const struct gfs2_holder *gh) |
1628 | { | 1624 | { |
1629 | struct task_struct *gh_owner = NULL; | 1625 | struct task_struct *gh_owner = NULL; |
1630 | char buffer[KSYM_SYMBOL_LEN]; | ||
1631 | char flags_buf[32]; | 1626 | char flags_buf[32]; |
1632 | 1627 | ||
1633 | sprint_symbol(buffer, gh->gh_ip); | ||
1634 | if (gh->gh_owner_pid) | 1628 | if (gh->gh_owner_pid) |
1635 | gh_owner = pid_task(gh->gh_owner_pid, PIDTYPE_PID); | 1629 | gh_owner = pid_task(gh->gh_owner_pid, PIDTYPE_PID); |
1636 | gfs2_print_dbg(seq, " H: s:%s f:%s e:%d p:%ld [%s] %s\n", | 1630 | gfs2_print_dbg(seq, " H: s:%s f:%s e:%d p:%ld [%s] %pS\n", |
1637 | state2str(gh->gh_state), | 1631 | state2str(gh->gh_state), |
1638 | hflags2str(flags_buf, gh->gh_flags, gh->gh_iflags), | 1632 | hflags2str(flags_buf, gh->gh_flags, gh->gh_iflags), |
1639 | gh->gh_error, | 1633 | gh->gh_error, |
1640 | gh->gh_owner_pid ? (long)pid_nr(gh->gh_owner_pid) : -1, | 1634 | gh->gh_owner_pid ? (long)pid_nr(gh->gh_owner_pid) : -1, |
1641 | gh_owner ? gh_owner->comm : "(ended)", buffer); | 1635 | gh_owner ? gh_owner->comm : "(ended)", |
1636 | (void *)gh->gh_ip); | ||
1642 | return 0; | 1637 | return 0; |
1643 | } | 1638 | } |
1644 | 1639 | ||
@@ -1783,12 +1778,13 @@ int __init gfs2_glock_init(void) | |||
1783 | } | 1778 | } |
1784 | #endif | 1779 | #endif |
1785 | 1780 | ||
1786 | glock_workqueue = alloc_workqueue("glock_workqueue", WQ_RESCUER | | 1781 | glock_workqueue = alloc_workqueue("glock_workqueue", WQ_MEM_RECLAIM | |
1787 | WQ_HIGHPRI | WQ_FREEZEABLE, 0); | 1782 | WQ_HIGHPRI | WQ_FREEZEABLE, 0); |
1788 | if (IS_ERR(glock_workqueue)) | 1783 | if (IS_ERR(glock_workqueue)) |
1789 | return PTR_ERR(glock_workqueue); | 1784 | return PTR_ERR(glock_workqueue); |
1790 | gfs2_delete_workqueue = alloc_workqueue("delete_workqueue", WQ_RESCUER | | 1785 | gfs2_delete_workqueue = alloc_workqueue("delete_workqueue", |
1791 | WQ_FREEZEABLE, 0); | 1786 | WQ_MEM_RECLAIM | WQ_FREEZEABLE, |
1787 | 0); | ||
1792 | if (IS_ERR(gfs2_delete_workqueue)) { | 1788 | if (IS_ERR(gfs2_delete_workqueue)) { |
1793 | destroy_workqueue(glock_workqueue); | 1789 | destroy_workqueue(glock_workqueue); |
1794 | return PTR_ERR(gfs2_delete_workqueue); | 1790 | return PTR_ERR(gfs2_delete_workqueue); |