diff options
author | Sage Weil <sage@newdream.net> | 2011-11-30 12:47:09 -0500 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2011-12-07 13:46:44 -0500 |
commit | be655596b3de5873f994ddbe205751a5ffb4de39 (patch) | |
tree | cf6e53c6344f87a47ac68d6a6ff4d7dac6e5c25e /fs/ceph/caps.c | |
parent | 51703306b3b9ea7c05728040998521e47358147b (diff) |
ceph: use i_ceph_lock instead of i_lock
We have been using i_lock to protect all kinds of data structures in the
ceph_inode_info struct, including lists of inodes that we need to iterate
over while avoiding races with inode destruction. That requires grabbing
a reference to the inode with the list lock protected, but igrab() now
takes i_lock to check the inode flags.
Changing the list lock ordering would be a painful process.
However, using a ceph-specific i_ceph_lock in the ceph inode instead of
i_lock is a simple mechanical change and avoids the ordering constraints
imposed by igrab().
Reported-by: Amon Ott <a.ott@m-privacy.de>
Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph/caps.c')
-rw-r--r-- | fs/ceph/caps.c | 187 |
1 files changed, 94 insertions, 93 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 0f327c6c9679..8b53193e4f7c 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -309,7 +309,7 @@ void ceph_reservation_status(struct ceph_fs_client *fsc, | |||
309 | /* | 309 | /* |
310 | * Find ceph_cap for given mds, if any. | 310 | * Find ceph_cap for given mds, if any. |
311 | * | 311 | * |
312 | * Called with i_lock held. | 312 | * Called with i_ceph_lock held. |
313 | */ | 313 | */ |
314 | static struct ceph_cap *__get_cap_for_mds(struct ceph_inode_info *ci, int mds) | 314 | static struct ceph_cap *__get_cap_for_mds(struct ceph_inode_info *ci, int mds) |
315 | { | 315 | { |
@@ -332,9 +332,9 @@ struct ceph_cap *ceph_get_cap_for_mds(struct ceph_inode_info *ci, int mds) | |||
332 | { | 332 | { |
333 | struct ceph_cap *cap; | 333 | struct ceph_cap *cap; |
334 | 334 | ||
335 | spin_lock(&ci->vfs_inode.i_lock); | 335 | spin_lock(&ci->i_ceph_lock); |
336 | cap = __get_cap_for_mds(ci, mds); | 336 | cap = __get_cap_for_mds(ci, mds); |
337 | spin_unlock(&ci->vfs_inode.i_lock); | 337 | spin_unlock(&ci->i_ceph_lock); |
338 | return cap; | 338 | return cap; |
339 | } | 339 | } |
340 | 340 | ||
@@ -361,15 +361,16 @@ static int __ceph_get_cap_mds(struct ceph_inode_info *ci) | |||
361 | 361 | ||
362 | int ceph_get_cap_mds(struct inode *inode) | 362 | int ceph_get_cap_mds(struct inode *inode) |
363 | { | 363 | { |
364 | struct ceph_inode_info *ci = ceph_inode(inode); | ||
364 | int mds; | 365 | int mds; |
365 | spin_lock(&inode->i_lock); | 366 | spin_lock(&ci->i_ceph_lock); |
366 | mds = __ceph_get_cap_mds(ceph_inode(inode)); | 367 | mds = __ceph_get_cap_mds(ceph_inode(inode)); |
367 | spin_unlock(&inode->i_lock); | 368 | spin_unlock(&ci->i_ceph_lock); |
368 | return mds; | 369 | return mds; |
369 | } | 370 | } |
370 | 371 | ||
371 | /* | 372 | /* |
372 | * Called under i_lock. | 373 | * Called under i_ceph_lock. |
373 | */ | 374 | */ |
374 | static void __insert_cap_node(struct ceph_inode_info *ci, | 375 | static void __insert_cap_node(struct ceph_inode_info *ci, |
375 | struct ceph_cap *new) | 376 | struct ceph_cap *new) |
@@ -415,7 +416,7 @@ static void __cap_set_timeouts(struct ceph_mds_client *mdsc, | |||
415 | * | 416 | * |
416 | * If I_FLUSH is set, leave the inode at the front of the list. | 417 | * If I_FLUSH is set, leave the inode at the front of the list. |
417 | * | 418 | * |
418 | * Caller holds i_lock | 419 | * Caller holds i_ceph_lock |
419 | * -> we take mdsc->cap_delay_lock | 420 | * -> we take mdsc->cap_delay_lock |
420 | */ | 421 | */ |
421 | static void __cap_delay_requeue(struct ceph_mds_client *mdsc, | 422 | static void __cap_delay_requeue(struct ceph_mds_client *mdsc, |
@@ -457,7 +458,7 @@ static void __cap_delay_requeue_front(struct ceph_mds_client *mdsc, | |||
457 | /* | 458 | /* |
458 | * Cancel delayed work on cap. | 459 | * Cancel delayed work on cap. |
459 | * | 460 | * |
460 | * Caller must hold i_lock. | 461 | * Caller must hold i_ceph_lock. |
461 | */ | 462 | */ |
462 | static void __cap_delay_cancel(struct ceph_mds_client *mdsc, | 463 | static void __cap_delay_cancel(struct ceph_mds_client *mdsc, |
463 | struct ceph_inode_info *ci) | 464 | struct ceph_inode_info *ci) |
@@ -532,14 +533,14 @@ int ceph_add_cap(struct inode *inode, | |||
532 | wanted |= ceph_caps_for_mode(fmode); | 533 | wanted |= ceph_caps_for_mode(fmode); |
533 | 534 | ||
534 | retry: | 535 | retry: |
535 | spin_lock(&inode->i_lock); | 536 | spin_lock(&ci->i_ceph_lock); |
536 | cap = __get_cap_for_mds(ci, mds); | 537 | cap = __get_cap_for_mds(ci, mds); |
537 | if (!cap) { | 538 | if (!cap) { |
538 | if (new_cap) { | 539 | if (new_cap) { |
539 | cap = new_cap; | 540 | cap = new_cap; |
540 | new_cap = NULL; | 541 | new_cap = NULL; |
541 | } else { | 542 | } else { |
542 | spin_unlock(&inode->i_lock); | 543 | spin_unlock(&ci->i_ceph_lock); |
543 | new_cap = get_cap(mdsc, caps_reservation); | 544 | new_cap = get_cap(mdsc, caps_reservation); |
544 | if (new_cap == NULL) | 545 | if (new_cap == NULL) |
545 | return -ENOMEM; | 546 | return -ENOMEM; |
@@ -625,7 +626,7 @@ retry: | |||
625 | 626 | ||
626 | if (fmode >= 0) | 627 | if (fmode >= 0) |
627 | __ceph_get_fmode(ci, fmode); | 628 | __ceph_get_fmode(ci, fmode); |
628 | spin_unlock(&inode->i_lock); | 629 | spin_unlock(&ci->i_ceph_lock); |
629 | wake_up_all(&ci->i_cap_wq); | 630 | wake_up_all(&ci->i_cap_wq); |
630 | return 0; | 631 | return 0; |
631 | } | 632 | } |
@@ -792,7 +793,7 @@ int ceph_caps_revoking(struct ceph_inode_info *ci, int mask) | |||
792 | struct rb_node *p; | 793 | struct rb_node *p; |
793 | int ret = 0; | 794 | int ret = 0; |
794 | 795 | ||
795 | spin_lock(&inode->i_lock); | 796 | spin_lock(&ci->i_ceph_lock); |
796 | for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) { | 797 | for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) { |
797 | cap = rb_entry(p, struct ceph_cap, ci_node); | 798 | cap = rb_entry(p, struct ceph_cap, ci_node); |
798 | if (__cap_is_valid(cap) && | 799 | if (__cap_is_valid(cap) && |
@@ -801,7 +802,7 @@ int ceph_caps_revoking(struct ceph_inode_info *ci, int mask) | |||
801 | break; | 802 | break; |
802 | } | 803 | } |
803 | } | 804 | } |
804 | spin_unlock(&inode->i_lock); | 805 | spin_unlock(&ci->i_ceph_lock); |
805 | dout("ceph_caps_revoking %p %s = %d\n", inode, | 806 | dout("ceph_caps_revoking %p %s = %d\n", inode, |
806 | ceph_cap_string(mask), ret); | 807 | ceph_cap_string(mask), ret); |
807 | return ret; | 808 | return ret; |
@@ -855,7 +856,7 @@ int __ceph_caps_mds_wanted(struct ceph_inode_info *ci) | |||
855 | } | 856 | } |
856 | 857 | ||
857 | /* | 858 | /* |
858 | * called under i_lock | 859 | * called under i_ceph_lock |
859 | */ | 860 | */ |
860 | static int __ceph_is_any_caps(struct ceph_inode_info *ci) | 861 | static int __ceph_is_any_caps(struct ceph_inode_info *ci) |
861 | { | 862 | { |
@@ -865,7 +866,7 @@ static int __ceph_is_any_caps(struct ceph_inode_info *ci) | |||
865 | /* | 866 | /* |
866 | * Remove a cap. Take steps to deal with a racing iterate_session_caps. | 867 | * Remove a cap. Take steps to deal with a racing iterate_session_caps. |
867 | * | 868 | * |
868 | * caller should hold i_lock. | 869 | * caller should hold i_ceph_lock. |
869 | * caller will not hold session s_mutex if called from destroy_inode. | 870 | * caller will not hold session s_mutex if called from destroy_inode. |
870 | */ | 871 | */ |
871 | void __ceph_remove_cap(struct ceph_cap *cap) | 872 | void __ceph_remove_cap(struct ceph_cap *cap) |
@@ -1028,7 +1029,7 @@ static void __queue_cap_release(struct ceph_mds_session *session, | |||
1028 | 1029 | ||
1029 | /* | 1030 | /* |
1030 | * Queue cap releases when an inode is dropped from our cache. Since | 1031 | * Queue cap releases when an inode is dropped from our cache. Since |
1031 | * inode is about to be destroyed, there is no need for i_lock. | 1032 | * inode is about to be destroyed, there is no need for i_ceph_lock. |
1032 | */ | 1033 | */ |
1033 | void ceph_queue_caps_release(struct inode *inode) | 1034 | void ceph_queue_caps_release(struct inode *inode) |
1034 | { | 1035 | { |
@@ -1049,7 +1050,7 @@ void ceph_queue_caps_release(struct inode *inode) | |||
1049 | 1050 | ||
1050 | /* | 1051 | /* |
1051 | * Send a cap msg on the given inode. Update our caps state, then | 1052 | * Send a cap msg on the given inode. Update our caps state, then |
1052 | * drop i_lock and send the message. | 1053 | * drop i_ceph_lock and send the message. |
1053 | * | 1054 | * |
1054 | * Make note of max_size reported/requested from mds, revoked caps | 1055 | * Make note of max_size reported/requested from mds, revoked caps |
1055 | * that have now been implemented. | 1056 | * that have now been implemented. |
@@ -1061,13 +1062,13 @@ void ceph_queue_caps_release(struct inode *inode) | |||
1061 | * Return non-zero if delayed release, or we experienced an error | 1062 | * Return non-zero if delayed release, or we experienced an error |
1062 | * such that the caller should requeue + retry later. | 1063 | * such that the caller should requeue + retry later. |
1063 | * | 1064 | * |
1064 | * called with i_lock, then drops it. | 1065 | * called with i_ceph_lock, then drops it. |
1065 | * caller should hold snap_rwsem (read), s_mutex. | 1066 | * caller should hold snap_rwsem (read), s_mutex. |
1066 | */ | 1067 | */ |
1067 | static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, | 1068 | static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, |
1068 | int op, int used, int want, int retain, int flushing, | 1069 | int op, int used, int want, int retain, int flushing, |
1069 | unsigned *pflush_tid) | 1070 | unsigned *pflush_tid) |
1070 | __releases(cap->ci->vfs_inode->i_lock) | 1071 | __releases(cap->ci->i_ceph_lock) |
1071 | { | 1072 | { |
1072 | struct ceph_inode_info *ci = cap->ci; | 1073 | struct ceph_inode_info *ci = cap->ci; |
1073 | struct inode *inode = &ci->vfs_inode; | 1074 | struct inode *inode = &ci->vfs_inode; |
@@ -1170,7 +1171,7 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, | |||
1170 | xattr_version = ci->i_xattrs.version; | 1171 | xattr_version = ci->i_xattrs.version; |
1171 | } | 1172 | } |
1172 | 1173 | ||
1173 | spin_unlock(&inode->i_lock); | 1174 | spin_unlock(&ci->i_ceph_lock); |
1174 | 1175 | ||
1175 | ret = send_cap_msg(session, ceph_vino(inode).ino, cap_id, | 1176 | ret = send_cap_msg(session, ceph_vino(inode).ino, cap_id, |
1176 | op, keep, want, flushing, seq, flush_tid, issue_seq, mseq, | 1177 | op, keep, want, flushing, seq, flush_tid, issue_seq, mseq, |
@@ -1198,13 +1199,13 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, | |||
1198 | * Unless @again is true, skip cap_snaps that were already sent to | 1199 | * Unless @again is true, skip cap_snaps that were already sent to |
1199 | * the MDS (i.e., during this session). | 1200 | * the MDS (i.e., during this session). |
1200 | * | 1201 | * |
1201 | * Called under i_lock. Takes s_mutex as needed. | 1202 | * Called under i_ceph_lock. Takes s_mutex as needed. |
1202 | */ | 1203 | */ |
1203 | void __ceph_flush_snaps(struct ceph_inode_info *ci, | 1204 | void __ceph_flush_snaps(struct ceph_inode_info *ci, |
1204 | struct ceph_mds_session **psession, | 1205 | struct ceph_mds_session **psession, |
1205 | int again) | 1206 | int again) |
1206 | __releases(ci->vfs_inode->i_lock) | 1207 | __releases(ci->i_ceph_lock) |
1207 | __acquires(ci->vfs_inode->i_lock) | 1208 | __acquires(ci->i_ceph_lock) |
1208 | { | 1209 | { |
1209 | struct inode *inode = &ci->vfs_inode; | 1210 | struct inode *inode = &ci->vfs_inode; |
1210 | int mds; | 1211 | int mds; |
@@ -1261,7 +1262,7 @@ retry: | |||
1261 | session = NULL; | 1262 | session = NULL; |
1262 | } | 1263 | } |
1263 | if (!session) { | 1264 | if (!session) { |
1264 | spin_unlock(&inode->i_lock); | 1265 | spin_unlock(&ci->i_ceph_lock); |
1265 | mutex_lock(&mdsc->mutex); | 1266 | mutex_lock(&mdsc->mutex); |
1266 | session = __ceph_lookup_mds_session(mdsc, mds); | 1267 | session = __ceph_lookup_mds_session(mdsc, mds); |
1267 | mutex_unlock(&mdsc->mutex); | 1268 | mutex_unlock(&mdsc->mutex); |
@@ -1275,7 +1276,7 @@ retry: | |||
1275 | * deletion or migration. retry, and we'll | 1276 | * deletion or migration. retry, and we'll |
1276 | * get a better @mds value next time. | 1277 | * get a better @mds value next time. |
1277 | */ | 1278 | */ |
1278 | spin_lock(&inode->i_lock); | 1279 | spin_lock(&ci->i_ceph_lock); |
1279 | goto retry; | 1280 | goto retry; |
1280 | } | 1281 | } |
1281 | 1282 | ||
@@ -1285,7 +1286,7 @@ retry: | |||
1285 | list_del_init(&capsnap->flushing_item); | 1286 | list_del_init(&capsnap->flushing_item); |
1286 | list_add_tail(&capsnap->flushing_item, | 1287 | list_add_tail(&capsnap->flushing_item, |
1287 | &session->s_cap_snaps_flushing); | 1288 | &session->s_cap_snaps_flushing); |
1288 | spin_unlock(&inode->i_lock); | 1289 | spin_unlock(&ci->i_ceph_lock); |
1289 | 1290 | ||
1290 | dout("flush_snaps %p cap_snap %p follows %lld tid %llu\n", | 1291 | dout("flush_snaps %p cap_snap %p follows %lld tid %llu\n", |
1291 | inode, capsnap, capsnap->follows, capsnap->flush_tid); | 1292 | inode, capsnap, capsnap->follows, capsnap->flush_tid); |
@@ -1302,7 +1303,7 @@ retry: | |||
1302 | next_follows = capsnap->follows + 1; | 1303 | next_follows = capsnap->follows + 1; |
1303 | ceph_put_cap_snap(capsnap); | 1304 | ceph_put_cap_snap(capsnap); |
1304 | 1305 | ||
1305 | spin_lock(&inode->i_lock); | 1306 | spin_lock(&ci->i_ceph_lock); |
1306 | goto retry; | 1307 | goto retry; |
1307 | } | 1308 | } |
1308 | 1309 | ||
@@ -1322,11 +1323,9 @@ out: | |||
1322 | 1323 | ||
1323 | static void ceph_flush_snaps(struct ceph_inode_info *ci) | 1324 | static void ceph_flush_snaps(struct ceph_inode_info *ci) |
1324 | { | 1325 | { |
1325 | struct inode *inode = &ci->vfs_inode; | 1326 | spin_lock(&ci->i_ceph_lock); |
1326 | |||
1327 | spin_lock(&inode->i_lock); | ||
1328 | __ceph_flush_snaps(ci, NULL, 0); | 1327 | __ceph_flush_snaps(ci, NULL, 0); |
1329 | spin_unlock(&inode->i_lock); | 1328 | spin_unlock(&ci->i_ceph_lock); |
1330 | } | 1329 | } |
1331 | 1330 | ||
1332 | /* | 1331 | /* |
@@ -1373,7 +1372,7 @@ int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask) | |||
1373 | * Add dirty inode to the flushing list. Assigned a seq number so we | 1372 | * Add dirty inode to the flushing list. Assigned a seq number so we |
1374 | * can wait for caps to flush without starving. | 1373 | * can wait for caps to flush without starving. |
1375 | * | 1374 | * |
1376 | * Called under i_lock. | 1375 | * Called under i_ceph_lock. |
1377 | */ | 1376 | */ |
1378 | static int __mark_caps_flushing(struct inode *inode, | 1377 | static int __mark_caps_flushing(struct inode *inode, |
1379 | struct ceph_mds_session *session) | 1378 | struct ceph_mds_session *session) |
@@ -1421,9 +1420,9 @@ static int try_nonblocking_invalidate(struct inode *inode) | |||
1421 | struct ceph_inode_info *ci = ceph_inode(inode); | 1420 | struct ceph_inode_info *ci = ceph_inode(inode); |
1422 | u32 invalidating_gen = ci->i_rdcache_gen; | 1421 | u32 invalidating_gen = ci->i_rdcache_gen; |
1423 | 1422 | ||
1424 | spin_unlock(&inode->i_lock); | 1423 | spin_unlock(&ci->i_ceph_lock); |
1425 | invalidate_mapping_pages(&inode->i_data, 0, -1); | 1424 | invalidate_mapping_pages(&inode->i_data, 0, -1); |
1426 | spin_lock(&inode->i_lock); | 1425 | spin_lock(&ci->i_ceph_lock); |
1427 | 1426 | ||
1428 | if (inode->i_data.nrpages == 0 && | 1427 | if (inode->i_data.nrpages == 0 && |
1429 | invalidating_gen == ci->i_rdcache_gen) { | 1428 | invalidating_gen == ci->i_rdcache_gen) { |
@@ -1470,7 +1469,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags, | |||
1470 | if (mdsc->stopping) | 1469 | if (mdsc->stopping) |
1471 | is_delayed = 1; | 1470 | is_delayed = 1; |
1472 | 1471 | ||
1473 | spin_lock(&inode->i_lock); | 1472 | spin_lock(&ci->i_ceph_lock); |
1474 | 1473 | ||
1475 | if (ci->i_ceph_flags & CEPH_I_FLUSH) | 1474 | if (ci->i_ceph_flags & CEPH_I_FLUSH) |
1476 | flags |= CHECK_CAPS_FLUSH; | 1475 | flags |= CHECK_CAPS_FLUSH; |
@@ -1480,7 +1479,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags, | |||
1480 | __ceph_flush_snaps(ci, &session, 0); | 1479 | __ceph_flush_snaps(ci, &session, 0); |
1481 | goto retry_locked; | 1480 | goto retry_locked; |
1482 | retry: | 1481 | retry: |
1483 | spin_lock(&inode->i_lock); | 1482 | spin_lock(&ci->i_ceph_lock); |
1484 | retry_locked: | 1483 | retry_locked: |
1485 | file_wanted = __ceph_caps_file_wanted(ci); | 1484 | file_wanted = __ceph_caps_file_wanted(ci); |
1486 | used = __ceph_caps_used(ci); | 1485 | used = __ceph_caps_used(ci); |
@@ -1634,7 +1633,7 @@ ack: | |||
1634 | if (mutex_trylock(&session->s_mutex) == 0) { | 1633 | if (mutex_trylock(&session->s_mutex) == 0) { |
1635 | dout("inverting session/ino locks on %p\n", | 1634 | dout("inverting session/ino locks on %p\n", |
1636 | session); | 1635 | session); |
1637 | spin_unlock(&inode->i_lock); | 1636 | spin_unlock(&ci->i_ceph_lock); |
1638 | if (took_snap_rwsem) { | 1637 | if (took_snap_rwsem) { |
1639 | up_read(&mdsc->snap_rwsem); | 1638 | up_read(&mdsc->snap_rwsem); |
1640 | took_snap_rwsem = 0; | 1639 | took_snap_rwsem = 0; |
@@ -1648,7 +1647,7 @@ ack: | |||
1648 | if (down_read_trylock(&mdsc->snap_rwsem) == 0) { | 1647 | if (down_read_trylock(&mdsc->snap_rwsem) == 0) { |
1649 | dout("inverting snap/in locks on %p\n", | 1648 | dout("inverting snap/in locks on %p\n", |
1650 | inode); | 1649 | inode); |
1651 | spin_unlock(&inode->i_lock); | 1650 | spin_unlock(&ci->i_ceph_lock); |
1652 | down_read(&mdsc->snap_rwsem); | 1651 | down_read(&mdsc->snap_rwsem); |
1653 | took_snap_rwsem = 1; | 1652 | took_snap_rwsem = 1; |
1654 | goto retry; | 1653 | goto retry; |
@@ -1664,10 +1663,10 @@ ack: | |||
1664 | mds = cap->mds; /* remember mds, so we don't repeat */ | 1663 | mds = cap->mds; /* remember mds, so we don't repeat */ |
1665 | sent++; | 1664 | sent++; |
1666 | 1665 | ||
1667 | /* __send_cap drops i_lock */ | 1666 | /* __send_cap drops i_ceph_lock */ |
1668 | delayed += __send_cap(mdsc, cap, CEPH_CAP_OP_UPDATE, used, want, | 1667 | delayed += __send_cap(mdsc, cap, CEPH_CAP_OP_UPDATE, used, want, |
1669 | retain, flushing, NULL); | 1668 | retain, flushing, NULL); |
1670 | goto retry; /* retake i_lock and restart our cap scan. */ | 1669 | goto retry; /* retake i_ceph_lock and restart our cap scan. */ |
1671 | } | 1670 | } |
1672 | 1671 | ||
1673 | /* | 1672 | /* |
@@ -1681,7 +1680,7 @@ ack: | |||
1681 | else if (!is_delayed || force_requeue) | 1680 | else if (!is_delayed || force_requeue) |
1682 | __cap_delay_requeue(mdsc, ci); | 1681 | __cap_delay_requeue(mdsc, ci); |
1683 | 1682 | ||
1684 | spin_unlock(&inode->i_lock); | 1683 | spin_unlock(&ci->i_ceph_lock); |
1685 | 1684 | ||
1686 | if (queue_invalidate) | 1685 | if (queue_invalidate) |
1687 | ceph_queue_invalidate(inode); | 1686 | ceph_queue_invalidate(inode); |
@@ -1704,7 +1703,7 @@ static int try_flush_caps(struct inode *inode, struct ceph_mds_session *session, | |||
1704 | int flushing = 0; | 1703 | int flushing = 0; |
1705 | 1704 | ||
1706 | retry: | 1705 | retry: |
1707 | spin_lock(&inode->i_lock); | 1706 | spin_lock(&ci->i_ceph_lock); |
1708 | if (ci->i_ceph_flags & CEPH_I_NOFLUSH) { | 1707 | if (ci->i_ceph_flags & CEPH_I_NOFLUSH) { |
1709 | dout("try_flush_caps skipping %p I_NOFLUSH set\n", inode); | 1708 | dout("try_flush_caps skipping %p I_NOFLUSH set\n", inode); |
1710 | goto out; | 1709 | goto out; |
@@ -1716,7 +1715,7 @@ retry: | |||
1716 | int delayed; | 1715 | int delayed; |
1717 | 1716 | ||
1718 | if (!session) { | 1717 | if (!session) { |
1719 | spin_unlock(&inode->i_lock); | 1718 | spin_unlock(&ci->i_ceph_lock); |
1720 | session = cap->session; | 1719 | session = cap->session; |
1721 | mutex_lock(&session->s_mutex); | 1720 | mutex_lock(&session->s_mutex); |
1722 | goto retry; | 1721 | goto retry; |
@@ -1727,18 +1726,18 @@ retry: | |||
1727 | 1726 | ||
1728 | flushing = __mark_caps_flushing(inode, session); | 1727 | flushing = __mark_caps_flushing(inode, session); |
1729 | 1728 | ||
1730 | /* __send_cap drops i_lock */ | 1729 | /* __send_cap drops i_ceph_lock */ |
1731 | delayed = __send_cap(mdsc, cap, CEPH_CAP_OP_FLUSH, used, want, | 1730 | delayed = __send_cap(mdsc, cap, CEPH_CAP_OP_FLUSH, used, want, |
1732 | cap->issued | cap->implemented, flushing, | 1731 | cap->issued | cap->implemented, flushing, |
1733 | flush_tid); | 1732 | flush_tid); |
1734 | if (!delayed) | 1733 | if (!delayed) |
1735 | goto out_unlocked; | 1734 | goto out_unlocked; |
1736 | 1735 | ||
1737 | spin_lock(&inode->i_lock); | 1736 | spin_lock(&ci->i_ceph_lock); |
1738 | __cap_delay_requeue(mdsc, ci); | 1737 | __cap_delay_requeue(mdsc, ci); |
1739 | } | 1738 | } |
1740 | out: | 1739 | out: |
1741 | spin_unlock(&inode->i_lock); | 1740 | spin_unlock(&ci->i_ceph_lock); |
1742 | out_unlocked: | 1741 | out_unlocked: |
1743 | if (session && unlock_session) | 1742 | if (session && unlock_session) |
1744 | mutex_unlock(&session->s_mutex); | 1743 | mutex_unlock(&session->s_mutex); |
@@ -1753,7 +1752,7 @@ static int caps_are_flushed(struct inode *inode, unsigned tid) | |||
1753 | struct ceph_inode_info *ci = ceph_inode(inode); | 1752 | struct ceph_inode_info *ci = ceph_inode(inode); |
1754 | int i, ret = 1; | 1753 | int i, ret = 1; |
1755 | 1754 | ||
1756 | spin_lock(&inode->i_lock); | 1755 | spin_lock(&ci->i_ceph_lock); |
1757 | for (i = 0; i < CEPH_CAP_BITS; i++) | 1756 | for (i = 0; i < CEPH_CAP_BITS; i++) |
1758 | if ((ci->i_flushing_caps & (1 << i)) && | 1757 | if ((ci->i_flushing_caps & (1 << i)) && |
1759 | ci->i_cap_flush_tid[i] <= tid) { | 1758 | ci->i_cap_flush_tid[i] <= tid) { |
@@ -1761,7 +1760,7 @@ static int caps_are_flushed(struct inode *inode, unsigned tid) | |||
1761 | ret = 0; | 1760 | ret = 0; |
1762 | break; | 1761 | break; |
1763 | } | 1762 | } |
1764 | spin_unlock(&inode->i_lock); | 1763 | spin_unlock(&ci->i_ceph_lock); |
1765 | return ret; | 1764 | return ret; |
1766 | } | 1765 | } |
1767 | 1766 | ||
@@ -1868,10 +1867,10 @@ int ceph_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
1868 | struct ceph_mds_client *mdsc = | 1867 | struct ceph_mds_client *mdsc = |
1869 | ceph_sb_to_client(inode->i_sb)->mdsc; | 1868 | ceph_sb_to_client(inode->i_sb)->mdsc; |
1870 | 1869 | ||
1871 | spin_lock(&inode->i_lock); | 1870 | spin_lock(&ci->i_ceph_lock); |
1872 | if (__ceph_caps_dirty(ci)) | 1871 | if (__ceph_caps_dirty(ci)) |
1873 | __cap_delay_requeue_front(mdsc, ci); | 1872 | __cap_delay_requeue_front(mdsc, ci); |
1874 | spin_unlock(&inode->i_lock); | 1873 | spin_unlock(&ci->i_ceph_lock); |
1875 | } | 1874 | } |
1876 | return err; | 1875 | return err; |
1877 | } | 1876 | } |
@@ -1894,7 +1893,7 @@ static void kick_flushing_capsnaps(struct ceph_mds_client *mdsc, | |||
1894 | struct inode *inode = &ci->vfs_inode; | 1893 | struct inode *inode = &ci->vfs_inode; |
1895 | struct ceph_cap *cap; | 1894 | struct ceph_cap *cap; |
1896 | 1895 | ||
1897 | spin_lock(&inode->i_lock); | 1896 | spin_lock(&ci->i_ceph_lock); |
1898 | cap = ci->i_auth_cap; | 1897 | cap = ci->i_auth_cap; |
1899 | if (cap && cap->session == session) { | 1898 | if (cap && cap->session == session) { |
1900 | dout("kick_flushing_caps %p cap %p capsnap %p\n", inode, | 1899 | dout("kick_flushing_caps %p cap %p capsnap %p\n", inode, |
@@ -1904,7 +1903,7 @@ static void kick_flushing_capsnaps(struct ceph_mds_client *mdsc, | |||
1904 | pr_err("%p auth cap %p not mds%d ???\n", inode, | 1903 | pr_err("%p auth cap %p not mds%d ???\n", inode, |
1905 | cap, session->s_mds); | 1904 | cap, session->s_mds); |
1906 | } | 1905 | } |
1907 | spin_unlock(&inode->i_lock); | 1906 | spin_unlock(&ci->i_ceph_lock); |
1908 | } | 1907 | } |
1909 | } | 1908 | } |
1910 | 1909 | ||
@@ -1921,7 +1920,7 @@ void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc, | |||
1921 | struct ceph_cap *cap; | 1920 | struct ceph_cap *cap; |
1922 | int delayed = 0; | 1921 | int delayed = 0; |
1923 | 1922 | ||
1924 | spin_lock(&inode->i_lock); | 1923 | spin_lock(&ci->i_ceph_lock); |
1925 | cap = ci->i_auth_cap; | 1924 | cap = ci->i_auth_cap; |
1926 | if (cap && cap->session == session) { | 1925 | if (cap && cap->session == session) { |
1927 | dout("kick_flushing_caps %p cap %p %s\n", inode, | 1926 | dout("kick_flushing_caps %p cap %p %s\n", inode, |
@@ -1932,14 +1931,14 @@ void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc, | |||
1932 | cap->issued | cap->implemented, | 1931 | cap->issued | cap->implemented, |
1933 | ci->i_flushing_caps, NULL); | 1932 | ci->i_flushing_caps, NULL); |
1934 | if (delayed) { | 1933 | if (delayed) { |
1935 | spin_lock(&inode->i_lock); | 1934 | spin_lock(&ci->i_ceph_lock); |
1936 | __cap_delay_requeue(mdsc, ci); | 1935 | __cap_delay_requeue(mdsc, ci); |
1937 | spin_unlock(&inode->i_lock); | 1936 | spin_unlock(&ci->i_ceph_lock); |
1938 | } | 1937 | } |
1939 | } else { | 1938 | } else { |
1940 | pr_err("%p auth cap %p not mds%d ???\n", inode, | 1939 | pr_err("%p auth cap %p not mds%d ???\n", inode, |
1941 | cap, session->s_mds); | 1940 | cap, session->s_mds); |
1942 | spin_unlock(&inode->i_lock); | 1941 | spin_unlock(&ci->i_ceph_lock); |
1943 | } | 1942 | } |
1944 | } | 1943 | } |
1945 | } | 1944 | } |
@@ -1952,7 +1951,7 @@ static void kick_flushing_inode_caps(struct ceph_mds_client *mdsc, | |||
1952 | struct ceph_cap *cap; | 1951 | struct ceph_cap *cap; |
1953 | int delayed = 0; | 1952 | int delayed = 0; |
1954 | 1953 | ||
1955 | spin_lock(&inode->i_lock); | 1954 | spin_lock(&ci->i_ceph_lock); |
1956 | cap = ci->i_auth_cap; | 1955 | cap = ci->i_auth_cap; |
1957 | dout("kick_flushing_inode_caps %p flushing %s flush_seq %lld\n", inode, | 1956 | dout("kick_flushing_inode_caps %p flushing %s flush_seq %lld\n", inode, |
1958 | ceph_cap_string(ci->i_flushing_caps), ci->i_cap_flush_seq); | 1957 | ceph_cap_string(ci->i_flushing_caps), ci->i_cap_flush_seq); |
@@ -1964,12 +1963,12 @@ static void kick_flushing_inode_caps(struct ceph_mds_client *mdsc, | |||
1964 | cap->issued | cap->implemented, | 1963 | cap->issued | cap->implemented, |
1965 | ci->i_flushing_caps, NULL); | 1964 | ci->i_flushing_caps, NULL); |
1966 | if (delayed) { | 1965 | if (delayed) { |
1967 | spin_lock(&inode->i_lock); | 1966 | spin_lock(&ci->i_ceph_lock); |
1968 | __cap_delay_requeue(mdsc, ci); | 1967 | __cap_delay_requeue(mdsc, ci); |
1969 | spin_unlock(&inode->i_lock); | 1968 | spin_unlock(&ci->i_ceph_lock); |
1970 | } | 1969 | } |
1971 | } else { | 1970 | } else { |
1972 | spin_unlock(&inode->i_lock); | 1971 | spin_unlock(&ci->i_ceph_lock); |
1973 | } | 1972 | } |
1974 | } | 1973 | } |
1975 | 1974 | ||
@@ -1978,7 +1977,7 @@ static void kick_flushing_inode_caps(struct ceph_mds_client *mdsc, | |||
1978 | * Take references to capabilities we hold, so that we don't release | 1977 | * Take references to capabilities we hold, so that we don't release |
1979 | * them to the MDS prematurely. | 1978 | * them to the MDS prematurely. |
1980 | * | 1979 | * |
1981 | * Protected by i_lock. | 1980 | * Protected by i_ceph_lock. |
1982 | */ | 1981 | */ |
1983 | static void __take_cap_refs(struct ceph_inode_info *ci, int got) | 1982 | static void __take_cap_refs(struct ceph_inode_info *ci, int got) |
1984 | { | 1983 | { |
@@ -2016,7 +2015,7 @@ static int try_get_cap_refs(struct ceph_inode_info *ci, int need, int want, | |||
2016 | 2015 | ||
2017 | dout("get_cap_refs %p need %s want %s\n", inode, | 2016 | dout("get_cap_refs %p need %s want %s\n", inode, |
2018 | ceph_cap_string(need), ceph_cap_string(want)); | 2017 | ceph_cap_string(need), ceph_cap_string(want)); |
2019 | spin_lock(&inode->i_lock); | 2018 | spin_lock(&ci->i_ceph_lock); |
2020 | 2019 | ||
2021 | /* make sure file is actually open */ | 2020 | /* make sure file is actually open */ |
2022 | file_wanted = __ceph_caps_file_wanted(ci); | 2021 | file_wanted = __ceph_caps_file_wanted(ci); |
@@ -2077,7 +2076,7 @@ static int try_get_cap_refs(struct ceph_inode_info *ci, int need, int want, | |||
2077 | ceph_cap_string(have), ceph_cap_string(need)); | 2076 | ceph_cap_string(have), ceph_cap_string(need)); |
2078 | } | 2077 | } |
2079 | out: | 2078 | out: |
2080 | spin_unlock(&inode->i_lock); | 2079 | spin_unlock(&ci->i_ceph_lock); |
2081 | dout("get_cap_refs %p ret %d got %s\n", inode, | 2080 | dout("get_cap_refs %p ret %d got %s\n", inode, |
2082 | ret, ceph_cap_string(*got)); | 2081 | ret, ceph_cap_string(*got)); |
2083 | return ret; | 2082 | return ret; |
@@ -2094,7 +2093,7 @@ static void check_max_size(struct inode *inode, loff_t endoff) | |||
2094 | int check = 0; | 2093 | int check = 0; |
2095 | 2094 | ||
2096 | /* do we need to explicitly request a larger max_size? */ | 2095 | /* do we need to explicitly request a larger max_size? */ |
2097 | spin_lock(&inode->i_lock); | 2096 | spin_lock(&ci->i_ceph_lock); |
2098 | if ((endoff >= ci->i_max_size || | 2097 | if ((endoff >= ci->i_max_size || |
2099 | endoff > (inode->i_size << 1)) && | 2098 | endoff > (inode->i_size << 1)) && |
2100 | endoff > ci->i_wanted_max_size) { | 2099 | endoff > ci->i_wanted_max_size) { |
@@ -2103,7 +2102,7 @@ static void check_max_size(struct inode *inode, loff_t endoff) | |||
2103 | ci->i_wanted_max_size = endoff; | 2102 | ci->i_wanted_max_size = endoff; |
2104 | check = 1; | 2103 | check = 1; |
2105 | } | 2104 | } |
2106 | spin_unlock(&inode->i_lock); | 2105 | spin_unlock(&ci->i_ceph_lock); |
2107 | if (check) | 2106 | if (check) |
2108 | ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL); | 2107 | ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL); |
2109 | } | 2108 | } |
@@ -2140,9 +2139,9 @@ retry: | |||
2140 | */ | 2139 | */ |
2141 | void ceph_get_cap_refs(struct ceph_inode_info *ci, int caps) | 2140 | void ceph_get_cap_refs(struct ceph_inode_info *ci, int caps) |
2142 | { | 2141 | { |
2143 | spin_lock(&ci->vfs_inode.i_lock); | 2142 | spin_lock(&ci->i_ceph_lock); |
2144 | __take_cap_refs(ci, caps); | 2143 | __take_cap_refs(ci, caps); |
2145 | spin_unlock(&ci->vfs_inode.i_lock); | 2144 | spin_unlock(&ci->i_ceph_lock); |
2146 | } | 2145 | } |
2147 | 2146 | ||
2148 | /* | 2147 | /* |
@@ -2160,7 +2159,7 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had) | |||
2160 | int last = 0, put = 0, flushsnaps = 0, wake = 0; | 2159 | int last = 0, put = 0, flushsnaps = 0, wake = 0; |
2161 | struct ceph_cap_snap *capsnap; | 2160 | struct ceph_cap_snap *capsnap; |
2162 | 2161 | ||
2163 | spin_lock(&inode->i_lock); | 2162 | spin_lock(&ci->i_ceph_lock); |
2164 | if (had & CEPH_CAP_PIN) | 2163 | if (had & CEPH_CAP_PIN) |
2165 | --ci->i_pin_ref; | 2164 | --ci->i_pin_ref; |
2166 | if (had & CEPH_CAP_FILE_RD) | 2165 | if (had & CEPH_CAP_FILE_RD) |
@@ -2193,7 +2192,7 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had) | |||
2193 | } | 2192 | } |
2194 | } | 2193 | } |
2195 | } | 2194 | } |
2196 | spin_unlock(&inode->i_lock); | 2195 | spin_unlock(&ci->i_ceph_lock); |
2197 | 2196 | ||
2198 | dout("put_cap_refs %p had %s%s%s\n", inode, ceph_cap_string(had), | 2197 | dout("put_cap_refs %p had %s%s%s\n", inode, ceph_cap_string(had), |
2199 | last ? " last" : "", put ? " put" : ""); | 2198 | last ? " last" : "", put ? " put" : ""); |
@@ -2225,7 +2224,7 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, | |||
2225 | int found = 0; | 2224 | int found = 0; |
2226 | struct ceph_cap_snap *capsnap = NULL; | 2225 | struct ceph_cap_snap *capsnap = NULL; |
2227 | 2226 | ||
2228 | spin_lock(&inode->i_lock); | 2227 | spin_lock(&ci->i_ceph_lock); |
2229 | ci->i_wrbuffer_ref -= nr; | 2228 | ci->i_wrbuffer_ref -= nr; |
2230 | last = !ci->i_wrbuffer_ref; | 2229 | last = !ci->i_wrbuffer_ref; |
2231 | 2230 | ||
@@ -2274,7 +2273,7 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, | |||
2274 | } | 2273 | } |
2275 | } | 2274 | } |
2276 | 2275 | ||
2277 | spin_unlock(&inode->i_lock); | 2276 | spin_unlock(&ci->i_ceph_lock); |
2278 | 2277 | ||
2279 | if (last) { | 2278 | if (last) { |
2280 | ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL); | 2279 | ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL); |
@@ -2291,7 +2290,7 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, | |||
2291 | * Handle a cap GRANT message from the MDS. (Note that a GRANT may | 2290 | * Handle a cap GRANT message from the MDS. (Note that a GRANT may |
2292 | * actually be a revocation if it specifies a smaller cap set.) | 2291 | * actually be a revocation if it specifies a smaller cap set.) |
2293 | * | 2292 | * |
2294 | * caller holds s_mutex and i_lock, we drop both. | 2293 | * caller holds s_mutex and i_ceph_lock, we drop both. |
2295 | * | 2294 | * |
2296 | * return value: | 2295 | * return value: |
2297 | * 0 - ok | 2296 | * 0 - ok |
@@ -2302,7 +2301,7 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, | |||
2302 | struct ceph_mds_session *session, | 2301 | struct ceph_mds_session *session, |
2303 | struct ceph_cap *cap, | 2302 | struct ceph_cap *cap, |
2304 | struct ceph_buffer *xattr_buf) | 2303 | struct ceph_buffer *xattr_buf) |
2305 | __releases(inode->i_lock) | 2304 | __releases(ci->i_ceph_lock) |
2306 | { | 2305 | { |
2307 | struct ceph_inode_info *ci = ceph_inode(inode); | 2306 | struct ceph_inode_info *ci = ceph_inode(inode); |
2308 | int mds = session->s_mds; | 2307 | int mds = session->s_mds; |
@@ -2453,7 +2452,7 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, | |||
2453 | } | 2452 | } |
2454 | BUG_ON(cap->issued & ~cap->implemented); | 2453 | BUG_ON(cap->issued & ~cap->implemented); |
2455 | 2454 | ||
2456 | spin_unlock(&inode->i_lock); | 2455 | spin_unlock(&ci->i_ceph_lock); |
2457 | if (writeback) | 2456 | if (writeback) |
2458 | /* | 2457 | /* |
2459 | * queue inode for writeback: we can't actually call | 2458 | * queue inode for writeback: we can't actually call |
@@ -2483,7 +2482,7 @@ static void handle_cap_flush_ack(struct inode *inode, u64 flush_tid, | |||
2483 | struct ceph_mds_caps *m, | 2482 | struct ceph_mds_caps *m, |
2484 | struct ceph_mds_session *session, | 2483 | struct ceph_mds_session *session, |
2485 | struct ceph_cap *cap) | 2484 | struct ceph_cap *cap) |
2486 | __releases(inode->i_lock) | 2485 | __releases(ci->i_ceph_lock) |
2487 | { | 2486 | { |
2488 | struct ceph_inode_info *ci = ceph_inode(inode); | 2487 | struct ceph_inode_info *ci = ceph_inode(inode); |
2489 | struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc; | 2488 | struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc; |
@@ -2539,7 +2538,7 @@ static void handle_cap_flush_ack(struct inode *inode, u64 flush_tid, | |||
2539 | wake_up_all(&ci->i_cap_wq); | 2538 | wake_up_all(&ci->i_cap_wq); |
2540 | 2539 | ||
2541 | out: | 2540 | out: |
2542 | spin_unlock(&inode->i_lock); | 2541 | spin_unlock(&ci->i_ceph_lock); |
2543 | if (drop) | 2542 | if (drop) |
2544 | iput(inode); | 2543 | iput(inode); |
2545 | } | 2544 | } |
@@ -2562,7 +2561,7 @@ static void handle_cap_flushsnap_ack(struct inode *inode, u64 flush_tid, | |||
2562 | dout("handle_cap_flushsnap_ack inode %p ci %p mds%d follows %lld\n", | 2561 | dout("handle_cap_flushsnap_ack inode %p ci %p mds%d follows %lld\n", |
2563 | inode, ci, session->s_mds, follows); | 2562 | inode, ci, session->s_mds, follows); |
2564 | 2563 | ||
2565 | spin_lock(&inode->i_lock); | 2564 | spin_lock(&ci->i_ceph_lock); |
2566 | list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) { | 2565 | list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) { |
2567 | if (capsnap->follows == follows) { | 2566 | if (capsnap->follows == follows) { |
2568 | if (capsnap->flush_tid != flush_tid) { | 2567 | if (capsnap->flush_tid != flush_tid) { |
@@ -2585,7 +2584,7 @@ static void handle_cap_flushsnap_ack(struct inode *inode, u64 flush_tid, | |||
2585 | capsnap, capsnap->follows); | 2584 | capsnap, capsnap->follows); |
2586 | } | 2585 | } |
2587 | } | 2586 | } |
2588 | spin_unlock(&inode->i_lock); | 2587 | spin_unlock(&ci->i_ceph_lock); |
2589 | if (drop) | 2588 | if (drop) |
2590 | iput(inode); | 2589 | iput(inode); |
2591 | } | 2590 | } |
@@ -2598,7 +2597,7 @@ static void handle_cap_flushsnap_ack(struct inode *inode, u64 flush_tid, | |||
2598 | static void handle_cap_trunc(struct inode *inode, | 2597 | static void handle_cap_trunc(struct inode *inode, |
2599 | struct ceph_mds_caps *trunc, | 2598 | struct ceph_mds_caps *trunc, |
2600 | struct ceph_mds_session *session) | 2599 | struct ceph_mds_session *session) |
2601 | __releases(inode->i_lock) | 2600 | __releases(ci->i_ceph_lock) |
2602 | { | 2601 | { |
2603 | struct ceph_inode_info *ci = ceph_inode(inode); | 2602 | struct ceph_inode_info *ci = ceph_inode(inode); |
2604 | int mds = session->s_mds; | 2603 | int mds = session->s_mds; |
@@ -2617,7 +2616,7 @@ static void handle_cap_trunc(struct inode *inode, | |||
2617 | inode, mds, seq, truncate_size, truncate_seq); | 2616 | inode, mds, seq, truncate_size, truncate_seq); |
2618 | queue_trunc = ceph_fill_file_size(inode, issued, | 2617 | queue_trunc = ceph_fill_file_size(inode, issued, |
2619 | truncate_seq, truncate_size, size); | 2618 | truncate_seq, truncate_size, size); |
2620 | spin_unlock(&inode->i_lock); | 2619 | spin_unlock(&ci->i_ceph_lock); |
2621 | 2620 | ||
2622 | if (queue_trunc) | 2621 | if (queue_trunc) |
2623 | ceph_queue_vmtruncate(inode); | 2622 | ceph_queue_vmtruncate(inode); |
@@ -2646,7 +2645,7 @@ static void handle_cap_export(struct inode *inode, struct ceph_mds_caps *ex, | |||
2646 | dout("handle_cap_export inode %p ci %p mds%d mseq %d\n", | 2645 | dout("handle_cap_export inode %p ci %p mds%d mseq %d\n", |
2647 | inode, ci, mds, mseq); | 2646 | inode, ci, mds, mseq); |
2648 | 2647 | ||
2649 | spin_lock(&inode->i_lock); | 2648 | spin_lock(&ci->i_ceph_lock); |
2650 | 2649 | ||
2651 | /* make sure we haven't seen a higher mseq */ | 2650 | /* make sure we haven't seen a higher mseq */ |
2652 | for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) { | 2651 | for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) { |
@@ -2690,7 +2689,7 @@ static void handle_cap_export(struct inode *inode, struct ceph_mds_caps *ex, | |||
2690 | } | 2689 | } |
2691 | /* else, we already released it */ | 2690 | /* else, we already released it */ |
2692 | 2691 | ||
2693 | spin_unlock(&inode->i_lock); | 2692 | spin_unlock(&ci->i_ceph_lock); |
2694 | } | 2693 | } |
2695 | 2694 | ||
2696 | /* | 2695 | /* |
@@ -2745,9 +2744,9 @@ static void handle_cap_import(struct ceph_mds_client *mdsc, | |||
2745 | up_read(&mdsc->snap_rwsem); | 2744 | up_read(&mdsc->snap_rwsem); |
2746 | 2745 | ||
2747 | /* make sure we re-request max_size, if necessary */ | 2746 | /* make sure we re-request max_size, if necessary */ |
2748 | spin_lock(&inode->i_lock); | 2747 | spin_lock(&ci->i_ceph_lock); |
2749 | ci->i_requested_max_size = 0; | 2748 | ci->i_requested_max_size = 0; |
2750 | spin_unlock(&inode->i_lock); | 2749 | spin_unlock(&ci->i_ceph_lock); |
2751 | } | 2750 | } |
2752 | 2751 | ||
2753 | /* | 2752 | /* |
@@ -2762,6 +2761,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, | |||
2762 | struct ceph_mds_client *mdsc = session->s_mdsc; | 2761 | struct ceph_mds_client *mdsc = session->s_mdsc; |
2763 | struct super_block *sb = mdsc->fsc->sb; | 2762 | struct super_block *sb = mdsc->fsc->sb; |
2764 | struct inode *inode; | 2763 | struct inode *inode; |
2764 | struct ceph_inode_info *ci; | ||
2765 | struct ceph_cap *cap; | 2765 | struct ceph_cap *cap; |
2766 | struct ceph_mds_caps *h; | 2766 | struct ceph_mds_caps *h; |
2767 | int mds = session->s_mds; | 2767 | int mds = session->s_mds; |
@@ -2815,6 +2815,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, | |||
2815 | 2815 | ||
2816 | /* lookup ino */ | 2816 | /* lookup ino */ |
2817 | inode = ceph_find_inode(sb, vino); | 2817 | inode = ceph_find_inode(sb, vino); |
2818 | ci = ceph_inode(inode); | ||
2818 | dout(" op %s ino %llx.%llx inode %p\n", ceph_cap_op_name(op), vino.ino, | 2819 | dout(" op %s ino %llx.%llx inode %p\n", ceph_cap_op_name(op), vino.ino, |
2819 | vino.snap, inode); | 2820 | vino.snap, inode); |
2820 | if (!inode) { | 2821 | if (!inode) { |
@@ -2844,16 +2845,16 @@ void ceph_handle_caps(struct ceph_mds_session *session, | |||
2844 | } | 2845 | } |
2845 | 2846 | ||
2846 | /* the rest require a cap */ | 2847 | /* the rest require a cap */ |
2847 | spin_lock(&inode->i_lock); | 2848 | spin_lock(&ci->i_ceph_lock); |
2848 | cap = __get_cap_for_mds(ceph_inode(inode), mds); | 2849 | cap = __get_cap_for_mds(ceph_inode(inode), mds); |
2849 | if (!cap) { | 2850 | if (!cap) { |
2850 | dout(" no cap on %p ino %llx.%llx from mds%d\n", | 2851 | dout(" no cap on %p ino %llx.%llx from mds%d\n", |
2851 | inode, ceph_ino(inode), ceph_snap(inode), mds); | 2852 | inode, ceph_ino(inode), ceph_snap(inode), mds); |
2852 | spin_unlock(&inode->i_lock); | 2853 | spin_unlock(&ci->i_ceph_lock); |
2853 | goto flush_cap_releases; | 2854 | goto flush_cap_releases; |
2854 | } | 2855 | } |
2855 | 2856 | ||
2856 | /* note that each of these drops i_lock for us */ | 2857 | /* note that each of these drops i_ceph_lock for us */ |
2857 | switch (op) { | 2858 | switch (op) { |
2858 | case CEPH_CAP_OP_REVOKE: | 2859 | case CEPH_CAP_OP_REVOKE: |
2859 | case CEPH_CAP_OP_GRANT: | 2860 | case CEPH_CAP_OP_GRANT: |
@@ -2869,7 +2870,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, | |||
2869 | break; | 2870 | break; |
2870 | 2871 | ||
2871 | default: | 2872 | default: |
2872 | spin_unlock(&inode->i_lock); | 2873 | spin_unlock(&ci->i_ceph_lock); |
2873 | pr_err("ceph_handle_caps: unknown cap op %d %s\n", op, | 2874 | pr_err("ceph_handle_caps: unknown cap op %d %s\n", op, |
2874 | ceph_cap_op_name(op)); | 2875 | ceph_cap_op_name(op)); |
2875 | } | 2876 | } |
@@ -2962,13 +2963,13 @@ void ceph_put_fmode(struct ceph_inode_info *ci, int fmode) | |||
2962 | struct inode *inode = &ci->vfs_inode; | 2963 | struct inode *inode = &ci->vfs_inode; |
2963 | int last = 0; | 2964 | int last = 0; |
2964 | 2965 | ||
2965 | spin_lock(&inode->i_lock); | 2966 | spin_lock(&ci->i_ceph_lock); |
2966 | dout("put_fmode %p fmode %d %d -> %d\n", inode, fmode, | 2967 | dout("put_fmode %p fmode %d %d -> %d\n", inode, fmode, |
2967 | ci->i_nr_by_mode[fmode], ci->i_nr_by_mode[fmode]-1); | 2968 | ci->i_nr_by_mode[fmode], ci->i_nr_by_mode[fmode]-1); |
2968 | BUG_ON(ci->i_nr_by_mode[fmode] == 0); | 2969 | BUG_ON(ci->i_nr_by_mode[fmode] == 0); |
2969 | if (--ci->i_nr_by_mode[fmode] == 0) | 2970 | if (--ci->i_nr_by_mode[fmode] == 0) |
2970 | last++; | 2971 | last++; |
2971 | spin_unlock(&inode->i_lock); | 2972 | spin_unlock(&ci->i_ceph_lock); |
2972 | 2973 | ||
2973 | if (last && ci->i_vino.snap == CEPH_NOSNAP) | 2974 | if (last && ci->i_vino.snap == CEPH_NOSNAP) |
2974 | ceph_check_caps(ci, 0, NULL); | 2975 | ceph_check_caps(ci, 0, NULL); |
@@ -2991,7 +2992,7 @@ int ceph_encode_inode_release(void **p, struct inode *inode, | |||
2991 | int used, dirty; | 2992 | int used, dirty; |
2992 | int ret = 0; | 2993 | int ret = 0; |
2993 | 2994 | ||
2994 | spin_lock(&inode->i_lock); | 2995 | spin_lock(&ci->i_ceph_lock); |
2995 | used = __ceph_caps_used(ci); | 2996 | used = __ceph_caps_used(ci); |
2996 | dirty = __ceph_caps_dirty(ci); | 2997 | dirty = __ceph_caps_dirty(ci); |
2997 | 2998 | ||
@@ -3046,7 +3047,7 @@ int ceph_encode_inode_release(void **p, struct inode *inode, | |||
3046 | inode, cap, ceph_cap_string(cap->issued)); | 3047 | inode, cap, ceph_cap_string(cap->issued)); |
3047 | } | 3048 | } |
3048 | } | 3049 | } |
3049 | spin_unlock(&inode->i_lock); | 3050 | spin_unlock(&ci->i_ceph_lock); |
3050 | return ret; | 3051 | return ret; |
3051 | } | 3052 | } |
3052 | 3053 | ||
@@ -3061,7 +3062,7 @@ int ceph_encode_dentry_release(void **p, struct dentry *dentry, | |||
3061 | 3062 | ||
3062 | /* | 3063 | /* |
3063 | * force an record for the directory caps if we have a dentry lease. | 3064 | * force an record for the directory caps if we have a dentry lease. |
3064 | * this is racy (can't take i_lock and d_lock together), but it | 3065 | * this is racy (can't take i_ceph_lock and d_lock together), but it |
3065 | * doesn't have to be perfect; the mds will revoke anything we don't | 3066 | * doesn't have to be perfect; the mds will revoke anything we don't |
3066 | * release. | 3067 | * release. |
3067 | */ | 3068 | */ |