diff options
author | Paul Mackerras <paulus@samba.org> | 2007-04-29 22:38:01 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-04-29 22:38:01 -0400 |
commit | 49e1900d4cc2e7bcecb681fe60f0990bec2dcce8 (patch) | |
tree | 253801ebf57e0a23856a2c7be129c2c178f62fdf /fs/ocfs2/dlmglue.c | |
parent | 34f6d749c0a328817d5e36274e53121c1db734dc (diff) | |
parent | b9099ff63c75216d6ca10bce5a1abcd9293c27e6 (diff) |
Merge branch 'linux-2.6' into for-2.6.22
Diffstat (limited to 'fs/ocfs2/dlmglue.c')
-rw-r--r-- | fs/ocfs2/dlmglue.c | 143 |
1 files changed, 126 insertions, 17 deletions
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index e335541727f9..27e43b0c0eae 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) |
@@ -1387,8 +1495,7 @@ static void ocfs2_refresh_inode_from_lvb(struct inode *inode) | |||
1387 | if (S_ISLNK(inode->i_mode) && !oi->ip_clusters) | 1495 | if (S_ISLNK(inode->i_mode) && !oi->ip_clusters) |
1388 | inode->i_blocks = 0; | 1496 | inode->i_blocks = 0; |
1389 | else | 1497 | else |
1390 | inode->i_blocks = | 1498 | inode->i_blocks = ocfs2_inode_sector_count(inode); |
1391 | ocfs2_align_bytes_to_sectors(i_size_read(inode)); | ||
1392 | 1499 | ||
1393 | inode->i_uid = be32_to_cpu(lvb->lvb_iuid); | 1500 | inode->i_uid = be32_to_cpu(lvb->lvb_iuid); |
1394 | inode->i_gid = be32_to_cpu(lvb->lvb_igid); | 1501 | inode->i_gid = be32_to_cpu(lvb->lvb_igid); |
@@ -1479,12 +1586,15 @@ static int ocfs2_meta_lock_update(struct inode *inode, | |||
1479 | { | 1586 | { |
1480 | int status = 0; | 1587 | int status = 0; |
1481 | struct ocfs2_inode_info *oi = OCFS2_I(inode); | 1588 | struct ocfs2_inode_info *oi = OCFS2_I(inode); |
1482 | struct ocfs2_lock_res *lockres = NULL; | 1589 | struct ocfs2_lock_res *lockres = &oi->ip_meta_lockres; |
1483 | struct ocfs2_dinode *fe; | 1590 | struct ocfs2_dinode *fe; |
1484 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 1591 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
1485 | 1592 | ||
1486 | mlog_entry_void(); | 1593 | mlog_entry_void(); |
1487 | 1594 | ||
1595 | if (ocfs2_mount_local(osb)) | ||
1596 | goto bail; | ||
1597 | |||
1488 | spin_lock(&oi->ip_lock); | 1598 | spin_lock(&oi->ip_lock); |
1489 | if (oi->ip_flags & OCFS2_INODE_DELETED) { | 1599 | if (oi->ip_flags & OCFS2_INODE_DELETED) { |
1490 | mlog(0, "Orphaned inode %llu was deleted while we " | 1600 | mlog(0, "Orphaned inode %llu was deleted while we " |
@@ -1496,22 +1606,16 @@ static int ocfs2_meta_lock_update(struct inode *inode, | |||
1496 | } | 1606 | } |
1497 | spin_unlock(&oi->ip_lock); | 1607 | spin_unlock(&oi->ip_lock); |
1498 | 1608 | ||
1499 | if (!ocfs2_mount_local(osb)) { | 1609 | if (!ocfs2_should_refresh_lock_res(lockres)) |
1500 | lockres = &oi->ip_meta_lockres; | 1610 | goto bail; |
1501 | |||
1502 | if (!ocfs2_should_refresh_lock_res(lockres)) | ||
1503 | goto bail; | ||
1504 | } | ||
1505 | 1611 | ||
1506 | /* This will discard any caching information we might have had | 1612 | /* This will discard any caching information we might have had |
1507 | * for the inode metadata. */ | 1613 | * for the inode metadata. */ |
1508 | ocfs2_metadata_cache_purge(inode); | 1614 | ocfs2_metadata_cache_purge(inode); |
1509 | 1615 | ||
1510 | /* will do nothing for inode types that don't use the extent | ||
1511 | * map (directories, bitmap files, etc) */ | ||
1512 | ocfs2_extent_map_trunc(inode, 0); | 1616 | ocfs2_extent_map_trunc(inode, 0); |
1513 | 1617 | ||
1514 | if (lockres && ocfs2_meta_lvb_is_trustable(inode, lockres)) { | 1618 | if (ocfs2_meta_lvb_is_trustable(inode, lockres)) { |
1515 | mlog(0, "Trusting LVB on inode %llu\n", | 1619 | mlog(0, "Trusting LVB on inode %llu\n", |
1516 | (unsigned long long)oi->ip_blkno); | 1620 | (unsigned long long)oi->ip_blkno); |
1517 | ocfs2_refresh_inode_from_lvb(inode); | 1621 | ocfs2_refresh_inode_from_lvb(inode); |
@@ -1558,8 +1662,7 @@ static int ocfs2_meta_lock_update(struct inode *inode, | |||
1558 | 1662 | ||
1559 | status = 0; | 1663 | status = 0; |
1560 | bail_refresh: | 1664 | bail_refresh: |
1561 | if (lockres) | 1665 | ocfs2_complete_lock_res_refresh(lockres, status); |
1562 | ocfs2_complete_lock_res_refresh(lockres, status); | ||
1563 | bail: | 1666 | bail: |
1564 | mlog_exit(status); | 1667 | mlog_exit(status); |
1565 | return status; | 1668 | return status; |
@@ -1630,7 +1733,6 @@ int ocfs2_meta_lock_full(struct inode *inode, | |||
1630 | wait_event(osb->recovery_event, | 1733 | wait_event(osb->recovery_event, |
1631 | ocfs2_node_map_is_empty(osb, &osb->recovery_map)); | 1734 | ocfs2_node_map_is_empty(osb, &osb->recovery_map)); |
1632 | 1735 | ||
1633 | acquired = 0; | ||
1634 | lockres = &OCFS2_I(inode)->ip_meta_lockres; | 1736 | lockres = &OCFS2_I(inode)->ip_meta_lockres; |
1635 | level = ex ? LKM_EXMODE : LKM_PRMODE; | 1737 | level = ex ? LKM_EXMODE : LKM_PRMODE; |
1636 | dlm_flags = 0; | 1738 | dlm_flags = 0; |
@@ -2458,13 +2560,20 @@ int ocfs2_drop_inode_locks(struct inode *inode) | |||
2458 | * ocfs2_clear_inode has done it for us. */ | 2560 | * ocfs2_clear_inode has done it for us. */ |
2459 | 2561 | ||
2460 | err = ocfs2_drop_lock(OCFS2_SB(inode->i_sb), | 2562 | err = ocfs2_drop_lock(OCFS2_SB(inode->i_sb), |
2461 | &OCFS2_I(inode)->ip_data_lockres); | 2563 | &OCFS2_I(inode)->ip_open_lockres); |
2462 | if (err < 0) | 2564 | if (err < 0) |
2463 | mlog_errno(err); | 2565 | mlog_errno(err); |
2464 | 2566 | ||
2465 | status = err; | 2567 | status = err; |
2466 | 2568 | ||
2467 | err = ocfs2_drop_lock(OCFS2_SB(inode->i_sb), | 2569 | err = ocfs2_drop_lock(OCFS2_SB(inode->i_sb), |
2570 | &OCFS2_I(inode)->ip_data_lockres); | ||
2571 | if (err < 0) | ||
2572 | mlog_errno(err); | ||
2573 | if (err < 0 && !status) | ||
2574 | status = err; | ||
2575 | |||
2576 | err = ocfs2_drop_lock(OCFS2_SB(inode->i_sb), | ||
2468 | &OCFS2_I(inode)->ip_meta_lockres); | 2577 | &OCFS2_I(inode)->ip_meta_lockres); |
2469 | if (err < 0) | 2578 | if (err < 0) |
2470 | mlog_errno(err); | 2579 | mlog_errno(err); |