diff options
Diffstat (limited to 'fs/ocfs2/dlmglue.c')
-rw-r--r-- | fs/ocfs2/dlmglue.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index ebc4a49801bd..9e8ed607173b 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c | |||
@@ -119,6 +119,18 @@ struct ocfs2_lock_res_ops { | |||
119 | void (*post_unlock)(struct ocfs2_super *, struct ocfs2_lock_res *); | 119 | void (*post_unlock)(struct ocfs2_super *, struct ocfs2_lock_res *); |
120 | 120 | ||
121 | /* | 121 | /* |
122 | * Allow a lock type to add checks to determine whether it is | ||
123 | * safe to downconvert a lock. Return 0 to re-queue the | ||
124 | * downconvert at a later time, nonzero to continue. | ||
125 | * | ||
126 | * For most locks, the default checks that there are no | ||
127 | * incompatible holders are sufficient. | ||
128 | * | ||
129 | * Called with the lockres spinlock held. | ||
130 | */ | ||
131 | int (*check_downconvert)(struct ocfs2_lock_res *, int); | ||
132 | |||
133 | /* | ||
122 | * LOCK_TYPE_* flags which describe the specific requirements | 134 | * LOCK_TYPE_* flags which describe the specific requirements |
123 | * of a lock type. Descriptions of each individual flag follow. | 135 | * of a lock type. Descriptions of each individual flag follow. |
124 | */ | 136 | */ |
@@ -2657,6 +2669,12 @@ recheck: | |||
2657 | && (lockres->l_flags & OCFS2_LOCK_REFRESHING)) | 2669 | && (lockres->l_flags & OCFS2_LOCK_REFRESHING)) |
2658 | goto leave_requeue; | 2670 | goto leave_requeue; |
2659 | 2671 | ||
2672 | new_level = ocfs2_highest_compat_lock_level(lockres->l_blocking); | ||
2673 | |||
2674 | if (lockres->l_ops->check_downconvert | ||
2675 | && !lockres->l_ops->check_downconvert(lockres, new_level)) | ||
2676 | goto leave_requeue; | ||
2677 | |||
2660 | /* If we get here, then we know that there are no more | 2678 | /* If we get here, then we know that there are no more |
2661 | * incompatible holders (and anyone asking for an incompatible | 2679 | * incompatible holders (and anyone asking for an incompatible |
2662 | * lock is blocked). We can now downconvert the lock */ | 2680 | * lock is blocked). We can now downconvert the lock */ |
@@ -2684,7 +2702,6 @@ recheck: | |||
2684 | 2702 | ||
2685 | downconvert: | 2703 | downconvert: |
2686 | ctl->requeue = 0; | 2704 | ctl->requeue = 0; |
2687 | new_level = ocfs2_highest_compat_lock_level(lockres->l_blocking); | ||
2688 | 2705 | ||
2689 | ocfs2_prepare_downconvert(lockres, new_level); | 2706 | ocfs2_prepare_downconvert(lockres, new_level); |
2690 | spin_unlock_irqrestore(&lockres->l_lock, flags); | 2707 | spin_unlock_irqrestore(&lockres->l_lock, flags); |