aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/dlmglue.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/dlmglue.c')
-rw-r--r--fs/ocfs2/dlmglue.c19
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
2685downconvert: 2703downconvert:
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);