@@ -118,6 +118,18 @@ struct ocfs2_lock_res_ops {
118
118
int (* unblock )(struct ocfs2_lock_res * , struct ocfs2_unblock_ctl * );
119
119
void (* post_unlock )(struct ocfs2_super * , struct ocfs2_lock_res * );
120
120
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
+
121
133
/*
122
134
* LOCK_TYPE_* flags which describe the specific requirements
123
135
* of a lock type. Descriptions of each individual flag follow.
@@ -2657,6 +2669,12 @@ static int ocfs2_generic_unblock_lock(struct ocfs2_super *osb,
2657
2669
&& (lockres -> l_flags & OCFS2_LOCK_REFRESHING ))
2658
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
2678
/* If we get here, then we know that there are no more
2661
2679
* incompatible holders (and anyone asking for an incompatible
2662
2680
* lock is blocked). We can now downconvert the lock */
@@ -2684,7 +2702,6 @@ static int ocfs2_generic_unblock_lock(struct ocfs2_super *osb,
2684
2702
2685
2703
downconvert :
2686
2704
ctl -> requeue = 0 ;
2687
- new_level = ocfs2_highest_compat_lock_level (lockres -> l_blocking );
2688
2705
2689
2706
ocfs2_prepare_downconvert (lockres , new_level );
2690
2707
spin_unlock_irqrestore (& lockres -> l_lock , flags );
0 commit comments