diff options
Diffstat (limited to 'fs/ocfs2/dlmglue.c')
-rw-r--r-- | fs/ocfs2/dlmglue.c | 119 |
1 files changed, 117 insertions, 2 deletions
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 31d519a6dbd2..ca4f0e0e7587 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c | |||
@@ -225,11 +225,17 @@ static struct ocfs2_lock_res_ops ocfs2_dentry_lops = { | |||
225 | .flags = 0, | 225 | .flags = 0, |
226 | }; | 226 | }; |
227 | 227 | ||
228 | static struct ocfs2_lock_res_ops ocfs2_inode_open_lops = { | ||
229 | .get_osb = ocfs2_get_inode_osb, | ||
230 | .flags = 0, | ||
231 | }; | ||
232 | |||
228 | static inline int ocfs2_is_inode_lock(struct ocfs2_lock_res *lockres) | 233 | static inline int ocfs2_is_inode_lock(struct ocfs2_lock_res *lockres) |
229 | { | 234 | { |
230 | return lockres->l_type == OCFS2_LOCK_TYPE_META || | 235 | return lockres->l_type == OCFS2_LOCK_TYPE_META || |
231 | lockres->l_type == OCFS2_LOCK_TYPE_DATA || | 236 | lockres->l_type == OCFS2_LOCK_TYPE_DATA || |
232 | lockres->l_type == OCFS2_LOCK_TYPE_RW; | 237 | lockres->l_type == OCFS2_LOCK_TYPE_RW || |
238 | lockres->l_type == OCFS2_LOCK_TYPE_OPEN; | ||
233 | } | 239 | } |
234 | 240 | ||
235 | static inline struct inode *ocfs2_lock_res_inode(struct ocfs2_lock_res *lockres) | 241 | static inline struct inode *ocfs2_lock_res_inode(struct ocfs2_lock_res *lockres) |
@@ -373,6 +379,9 @@ void ocfs2_inode_lock_res_init(struct ocfs2_lock_res *res, | |||
373 | case OCFS2_LOCK_TYPE_DATA: | 379 | case OCFS2_LOCK_TYPE_DATA: |
374 | ops = &ocfs2_inode_data_lops; | 380 | ops = &ocfs2_inode_data_lops; |
375 | break; | 381 | break; |
382 | case OCFS2_LOCK_TYPE_OPEN: | ||
383 | ops = &ocfs2_inode_open_lops; | ||
384 | break; | ||
376 | default: | 385 | default: |
377 | mlog_bug_on_msg(1, "type: %d\n", type); | 386 | mlog_bug_on_msg(1, "type: %d\n", type); |
378 | ops = NULL; /* thanks, gcc */ | 387 | ops = NULL; /* thanks, gcc */ |
@@ -1129,6 +1138,12 @@ int ocfs2_create_new_inode_locks(struct inode *inode) | |||
1129 | goto bail; | 1138 | goto bail; |
1130 | } | 1139 | } |
1131 | 1140 | ||
1141 | ret = ocfs2_create_new_lock(osb, &OCFS2_I(inode)->ip_open_lockres, 0, 0); | ||
1142 | if (ret) { | ||
1143 | mlog_errno(ret); | ||
1144 | goto bail; | ||
1145 | } | ||
1146 | |||
1132 | bail: | 1147 | bail: |
1133 | mlog_exit(ret); | 1148 | mlog_exit(ret); |
1134 | return ret; | 1149 | return ret; |
@@ -1182,6 +1197,99 @@ void ocfs2_rw_unlock(struct inode *inode, int write) | |||
1182 | mlog_exit_void(); | 1197 | mlog_exit_void(); |
1183 | } | 1198 | } |
1184 | 1199 | ||
1200 | /* | ||
1201 | * ocfs2_open_lock always get PR mode lock. | ||
1202 | */ | ||
1203 | int ocfs2_open_lock(struct inode *inode) | ||
1204 | { | ||
1205 | int status = 0; | ||
1206 | struct ocfs2_lock_res *lockres; | ||
1207 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
1208 | |||
1209 | BUG_ON(!inode); | ||
1210 | |||
1211 | mlog_entry_void(); | ||
1212 | |||
1213 | mlog(0, "inode %llu take PRMODE open lock\n", | ||
1214 | (unsigned long long)OCFS2_I(inode)->ip_blkno); | ||
1215 | |||
1216 | if (ocfs2_mount_local(osb)) | ||
1217 | goto out; | ||
1218 | |||
1219 | lockres = &OCFS2_I(inode)->ip_open_lockres; | ||
1220 | |||
1221 | status = ocfs2_cluster_lock(OCFS2_SB(inode->i_sb), lockres, | ||
1222 | LKM_PRMODE, 0, 0); | ||
1223 | if (status < 0) | ||
1224 | mlog_errno(status); | ||
1225 | |||
1226 | out: | ||
1227 | mlog_exit(status); | ||
1228 | return status; | ||
1229 | } | ||
1230 | |||
1231 | int ocfs2_try_open_lock(struct inode *inode, int write) | ||
1232 | { | ||
1233 | int status = 0, level; | ||
1234 | struct ocfs2_lock_res *lockres; | ||
1235 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
1236 | |||
1237 | BUG_ON(!inode); | ||
1238 | |||
1239 | mlog_entry_void(); | ||
1240 | |||
1241 | mlog(0, "inode %llu try to take %s open lock\n", | ||
1242 | (unsigned long long)OCFS2_I(inode)->ip_blkno, | ||
1243 | write ? "EXMODE" : "PRMODE"); | ||
1244 | |||
1245 | if (ocfs2_mount_local(osb)) | ||
1246 | goto out; | ||
1247 | |||
1248 | lockres = &OCFS2_I(inode)->ip_open_lockres; | ||
1249 | |||
1250 | level = write ? LKM_EXMODE : LKM_PRMODE; | ||
1251 | |||
1252 | /* | ||
1253 | * The file system may already holding a PRMODE/EXMODE open lock. | ||
1254 | * Since we pass LKM_NOQUEUE, the request won't block waiting on | ||
1255 | * other nodes and the -EAGAIN will indicate to the caller that | ||
1256 | * this inode is still in use. | ||
1257 | */ | ||
1258 | status = ocfs2_cluster_lock(OCFS2_SB(inode->i_sb), lockres, | ||
1259 | level, LKM_NOQUEUE, 0); | ||
1260 | |||
1261 | out: | ||
1262 | mlog_exit(status); | ||
1263 | return status; | ||
1264 | } | ||
1265 | |||
1266 | /* | ||
1267 | * ocfs2_open_unlock unlock PR and EX mode open locks. | ||
1268 | */ | ||
1269 | void ocfs2_open_unlock(struct inode *inode) | ||
1270 | { | ||
1271 | struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_open_lockres; | ||
1272 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
1273 | |||
1274 | mlog_entry_void(); | ||
1275 | |||
1276 | mlog(0, "inode %llu drop open lock\n", | ||
1277 | (unsigned long long)OCFS2_I(inode)->ip_blkno); | ||
1278 | |||
1279 | if (ocfs2_mount_local(osb)) | ||
1280 | goto out; | ||
1281 | |||
1282 | if(lockres->l_ro_holders) | ||
1283 | ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, | ||
1284 | LKM_PRMODE); | ||
1285 | if(lockres->l_ex_holders) | ||
1286 | ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, | ||
1287 | LKM_EXMODE); | ||
1288 | |||
1289 | out: | ||
1290 | mlog_exit_void(); | ||
1291 | } | ||
1292 | |||
1185 | int ocfs2_data_lock_full(struct inode *inode, | 1293 | int ocfs2_data_lock_full(struct inode *inode, |
1186 | int write, | 1294 | int write, |
1187 | int arg_flags) | 1295 | int arg_flags) |
@@ -2455,13 +2563,20 @@ int ocfs2_drop_inode_locks(struct inode *inode) | |||
2455 | * ocfs2_clear_inode has done it for us. */ | 2563 | * ocfs2_clear_inode has done it for us. */ |
2456 | 2564 | ||
2457 | err = ocfs2_drop_lock(OCFS2_SB(inode->i_sb), | 2565 | err = ocfs2_drop_lock(OCFS2_SB(inode->i_sb), |
2458 | &OCFS2_I(inode)->ip_data_lockres); | 2566 | &OCFS2_I(inode)->ip_open_lockres); |
2459 | if (err < 0) | 2567 | if (err < 0) |
2460 | mlog_errno(err); | 2568 | mlog_errno(err); |
2461 | 2569 | ||
2462 | status = err; | 2570 | status = err; |
2463 | 2571 | ||
2464 | err = ocfs2_drop_lock(OCFS2_SB(inode->i_sb), | 2572 | err = ocfs2_drop_lock(OCFS2_SB(inode->i_sb), |
2573 | &OCFS2_I(inode)->ip_data_lockres); | ||
2574 | if (err < 0) | ||
2575 | mlog_errno(err); | ||
2576 | if (err < 0 && !status) | ||
2577 | status = err; | ||
2578 | |||
2579 | err = ocfs2_drop_lock(OCFS2_SB(inode->i_sb), | ||
2465 | &OCFS2_I(inode)->ip_meta_lockres); | 2580 | &OCFS2_I(inode)->ip_meta_lockres); |
2466 | if (err < 0) | 2581 | if (err < 0) |
2467 | mlog_errno(err); | 2582 | mlog_errno(err); |