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.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 9e8ed607173b..faa6f57db703 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -131,6 +131,17 @@ struct ocfs2_lock_res_ops {
131 int (*check_downconvert)(struct ocfs2_lock_res *, int); 131 int (*check_downconvert)(struct ocfs2_lock_res *, int);
132 132
133 /* 133 /*
134 * Allows a lock type to populate the lock value block. This
135 * is called on downconvert, and when we drop a lock.
136 *
137 * Locks that want to use this should set LOCK_TYPE_USES_LVB
138 * in the flags field.
139 *
140 * Called with the lockres spinlock held.
141 */
142 void (*set_lvb)(struct ocfs2_lock_res *);
143
144 /*
134 * LOCK_TYPE_* flags which describe the specific requirements 145 * LOCK_TYPE_* flags which describe the specific requirements
135 * of a lock type. Descriptions of each individual flag follow. 146 * of a lock type. Descriptions of each individual flag follow.
136 */ 147 */
@@ -148,7 +159,8 @@ struct ocfs2_lock_res_ops {
148#define LOCK_TYPE_REQUIRES_REFRESH 0x1 159#define LOCK_TYPE_REQUIRES_REFRESH 0x1
149 160
150/* 161/*
151 * Indicate that a lock type makes use of the lock value block. 162 * Indicate that a lock type makes use of the lock value block. The
163 * ->set_lvb lock type callback must be defined.
152 */ 164 */
153#define LOCK_TYPE_USES_LVB 0x2 165#define LOCK_TYPE_USES_LVB 0x2
154 166
@@ -2629,6 +2641,7 @@ static int ocfs2_generic_unblock_lock(struct ocfs2_super *osb,
2629 int blocking; 2641 int blocking;
2630 int new_level; 2642 int new_level;
2631 int ret = 0; 2643 int ret = 0;
2644 int set_lvb = 0;
2632 2645
2633 mlog_entry_void(); 2646 mlog_entry_void();
2634 2647
@@ -2703,9 +2716,23 @@ recheck:
2703downconvert: 2716downconvert:
2704 ctl->requeue = 0; 2717 ctl->requeue = 0;
2705 2718
2719 if (lockres->l_ops->flags & LOCK_TYPE_USES_LVB) {
2720 if (lockres->l_level == LKM_EXMODE)
2721 set_lvb = 1;
2722
2723 /*
2724 * We only set the lvb if the lock has been fully
2725 * refreshed - otherwise we risk setting stale
2726 * data. Otherwise, there's no need to actually clear
2727 * out the lvb here as it's value is still valid.
2728 */
2729 if (set_lvb && !(lockres->l_flags & OCFS2_LOCK_NEEDS_REFRESH))
2730 lockres->l_ops->set_lvb(lockres);
2731 }
2732
2706 ocfs2_prepare_downconvert(lockres, new_level); 2733 ocfs2_prepare_downconvert(lockres, new_level);
2707 spin_unlock_irqrestore(&lockres->l_lock, flags); 2734 spin_unlock_irqrestore(&lockres->l_lock, flags);
2708 ret = ocfs2_downconvert_lock(osb, lockres, new_level, 0); 2735 ret = ocfs2_downconvert_lock(osb, lockres, new_level, set_lvb);
2709leave: 2736leave:
2710 mlog_exit(ret); 2737 mlog_exit(ret);
2711 return ret; 2738 return ret;