aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2')
-rw-r--r--fs/ocfs2/dlmglue.c59
1 files changed, 28 insertions, 31 deletions
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 182ff2476ccf..de887063dcfc 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -107,6 +107,14 @@ static void ocfs2_dentry_post_unlock(struct ocfs2_super *osb,
107 * OCFS2 Lock Resource Operations 107 * OCFS2 Lock Resource Operations
108 * 108 *
109 * These fine tune the behavior of the generic dlmglue locking infrastructure. 109 * These fine tune the behavior of the generic dlmglue locking infrastructure.
110 *
111 * The most basic of lock types can point ->l_priv to their respective
112 * struct ocfs2_super and allow the default actions to manage things.
113 *
114 * Right now, each lock type also needs to implement an init function,
115 * and trivial lock/unlock wrappers. ocfs2_simple_drop_lockres()
116 * should be called when the lock is no longer needed (i.e., object
117 * destruction time).
110 */ 118 */
111struct ocfs2_lock_res_ops { 119struct ocfs2_lock_res_ops {
112 /* 120 /*
@@ -115,6 +123,15 @@ struct ocfs2_lock_res_ops {
115 */ 123 */
116 struct ocfs2_super * (*get_osb)(struct ocfs2_lock_res *); 124 struct ocfs2_super * (*get_osb)(struct ocfs2_lock_res *);
117 125
126 /*
127 * Optionally called in the downconvert (or "vote") thread
128 * after a successful downconvert. The lockres will not be
129 * referenced after this callback is called, so it is safe to
130 * free memory, etc.
131 *
132 * The exact semantics of when this is called are controlled
133 * by ->downconvert_worker()
134 */
118 void (*post_unlock)(struct ocfs2_super *, struct ocfs2_lock_res *); 135 void (*post_unlock)(struct ocfs2_super *, struct ocfs2_lock_res *);
119 136
120 /* 137 /*
@@ -2230,16 +2247,8 @@ complete_unlock:
2230 mlog_exit_void(); 2247 mlog_exit_void();
2231} 2248}
2232 2249
2233typedef void (ocfs2_pre_drop_cb_t)(struct ocfs2_lock_res *, void *);
2234
2235struct drop_lock_cb {
2236 ocfs2_pre_drop_cb_t *drop_func;
2237 void *drop_data;
2238};
2239
2240static int ocfs2_drop_lock(struct ocfs2_super *osb, 2250static int ocfs2_drop_lock(struct ocfs2_super *osb,
2241 struct ocfs2_lock_res *lockres, 2251 struct ocfs2_lock_res *lockres)
2242 struct drop_lock_cb *dcb)
2243{ 2252{
2244 enum dlm_status status; 2253 enum dlm_status status;
2245 unsigned long flags; 2254 unsigned long flags;
@@ -2274,8 +2283,12 @@ static int ocfs2_drop_lock(struct ocfs2_super *osb,
2274 spin_lock_irqsave(&lockres->l_lock, flags); 2283 spin_lock_irqsave(&lockres->l_lock, flags);
2275 } 2284 }
2276 2285
2277 if (dcb) 2286 if (lockres->l_ops->flags & LOCK_TYPE_USES_LVB) {
2278 dcb->drop_func(lockres, dcb->drop_data); 2287 if (lockres->l_flags & OCFS2_LOCK_ATTACHED &&
2288 lockres->l_level == LKM_EXMODE &&
2289 !(lockres->l_flags & OCFS2_LOCK_NEEDS_REFRESH))
2290 lockres->l_ops->set_lvb(lockres);
2291 }
2279 2292
2280 if (lockres->l_flags & OCFS2_LOCK_BUSY) 2293 if (lockres->l_flags & OCFS2_LOCK_BUSY)
2281 mlog(ML_ERROR, "destroying busy lock: \"%s\"\n", 2294 mlog(ML_ERROR, "destroying busy lock: \"%s\"\n",
@@ -2355,7 +2368,7 @@ void ocfs2_simple_drop_lockres(struct ocfs2_super *osb,
2355 int ret; 2368 int ret;
2356 2369
2357 ocfs2_mark_lockres_freeing(lockres); 2370 ocfs2_mark_lockres_freeing(lockres);
2358 ret = ocfs2_drop_lock(osb, lockres, NULL); 2371 ret = ocfs2_drop_lock(osb, lockres);
2359 if (ret) 2372 if (ret)
2360 mlog_errno(ret); 2373 mlog_errno(ret);
2361} 2374}
@@ -2366,22 +2379,9 @@ static void ocfs2_drop_osb_locks(struct ocfs2_super *osb)
2366 ocfs2_simple_drop_lockres(osb, &osb->osb_rename_lockres); 2379 ocfs2_simple_drop_lockres(osb, &osb->osb_rename_lockres);
2367} 2380}
2368 2381
2369static void ocfs2_meta_pre_drop(struct ocfs2_lock_res *lockres, void *data)
2370{
2371 struct inode *inode = data;
2372
2373 /* the metadata lock requires a bit more work as we have an
2374 * LVB to worry about. */
2375 if (lockres->l_flags & OCFS2_LOCK_ATTACHED &&
2376 lockres->l_level == LKM_EXMODE &&
2377 !(lockres->l_flags & OCFS2_LOCK_NEEDS_REFRESH))
2378 __ocfs2_stuff_meta_lvb(inode);
2379}
2380
2381int ocfs2_drop_inode_locks(struct inode *inode) 2382int ocfs2_drop_inode_locks(struct inode *inode)
2382{ 2383{
2383 int status, err; 2384 int status, err;
2384 struct drop_lock_cb meta_dcb = { ocfs2_meta_pre_drop, inode, };
2385 2385
2386 mlog_entry_void(); 2386 mlog_entry_void();
2387 2387
@@ -2389,24 +2389,21 @@ int ocfs2_drop_inode_locks(struct inode *inode)
2389 * ocfs2_clear_inode has done it for us. */ 2389 * ocfs2_clear_inode has done it for us. */
2390 2390
2391 err = ocfs2_drop_lock(OCFS2_SB(inode->i_sb), 2391 err = ocfs2_drop_lock(OCFS2_SB(inode->i_sb),
2392 &OCFS2_I(inode)->ip_data_lockres, 2392 &OCFS2_I(inode)->ip_data_lockres);
2393 NULL);
2394 if (err < 0) 2393 if (err < 0)
2395 mlog_errno(err); 2394 mlog_errno(err);
2396 2395
2397 status = err; 2396 status = err;
2398 2397
2399 err = ocfs2_drop_lock(OCFS2_SB(inode->i_sb), 2398 err = ocfs2_drop_lock(OCFS2_SB(inode->i_sb),
2400 &OCFS2_I(inode)->ip_meta_lockres, 2399 &OCFS2_I(inode)->ip_meta_lockres);
2401 &meta_dcb);
2402 if (err < 0) 2400 if (err < 0)
2403 mlog_errno(err); 2401 mlog_errno(err);
2404 if (err < 0 && !status) 2402 if (err < 0 && !status)
2405 status = err; 2403 status = err;
2406 2404
2407 err = ocfs2_drop_lock(OCFS2_SB(inode->i_sb), 2405 err = ocfs2_drop_lock(OCFS2_SB(inode->i_sb),
2408 &OCFS2_I(inode)->ip_rw_lockres, 2406 &OCFS2_I(inode)->ip_rw_lockres);
2409 NULL);
2410 if (err < 0) 2407 if (err < 0)
2411 mlog_errno(err); 2408 mlog_errno(err);
2412 if (err < 0 && !status) 2409 if (err < 0 && !status)