diff options
-rw-r--r-- | fs/ocfs2/dlmglue.c | 59 |
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 | */ |
111 | struct ocfs2_lock_res_ops { | 119 | struct 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 | ||
2233 | typedef void (ocfs2_pre_drop_cb_t)(struct ocfs2_lock_res *, void *); | ||
2234 | |||
2235 | struct drop_lock_cb { | ||
2236 | ocfs2_pre_drop_cb_t *drop_func; | ||
2237 | void *drop_data; | ||
2238 | }; | ||
2239 | |||
2240 | static int ocfs2_drop_lock(struct ocfs2_super *osb, | 2250 | static 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 | ||
2369 | static 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 | |||
2381 | int ocfs2_drop_inode_locks(struct inode *inode) | 2382 | int 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) |