diff options
author | Sage Weil <sage@newdream.net> | 2010-02-09 16:41:18 -0500 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2010-02-11 14:48:52 -0500 |
commit | cbd03635913a86afb7c2cfc0058932956b05b51e (patch) | |
tree | 5938439c41509d72af379fcfc770e37fb5527847 /fs/ceph/caps.c | |
parent | 29065a513aa4c7e4b46b77cbcd25f814a4ca0bfe (diff) |
ceph: cap revocation fixes
Try to invalidate pages in ceph_check_caps() if FILE_CACHE is being
revoked. If we fail, queue an immediate async invalidate if FILE_CACHE
is being revoked. (If it's not being revoked, we just queue the caps
for later evaluation later, as per the old behavior.)
Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph/caps.c')
-rw-r--r-- | fs/ceph/caps.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 847ae64346fe..822f7d3632fe 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -1374,12 +1374,13 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags, | |||
1374 | int file_wanted, used; | 1374 | int file_wanted, used; |
1375 | int took_snap_rwsem = 0; /* true if mdsc->snap_rwsem held */ | 1375 | int took_snap_rwsem = 0; /* true if mdsc->snap_rwsem held */ |
1376 | int drop_session_lock = session ? 0 : 1; | 1376 | int drop_session_lock = session ? 0 : 1; |
1377 | int want, retain, revoking, flushing = 0; | 1377 | int issued, implemented, want, retain, revoking, flushing = 0; |
1378 | int mds = -1; /* keep track of how far we've gone through i_caps list | 1378 | int mds = -1; /* keep track of how far we've gone through i_caps list |
1379 | to avoid an infinite loop on retry */ | 1379 | to avoid an infinite loop on retry */ |
1380 | struct rb_node *p; | 1380 | struct rb_node *p; |
1381 | int tried_invalidate = 0; | 1381 | int tried_invalidate = 0; |
1382 | int delayed = 0, sent = 0, force_requeue = 0, num; | 1382 | int delayed = 0, sent = 0, force_requeue = 0, num; |
1383 | int queue_invalidate = 0; | ||
1383 | int is_delayed = flags & CHECK_CAPS_NODELAY; | 1384 | int is_delayed = flags & CHECK_CAPS_NODELAY; |
1384 | 1385 | ||
1385 | /* if we are unmounting, flush any unused caps immediately. */ | 1386 | /* if we are unmounting, flush any unused caps immediately. */ |
@@ -1401,6 +1402,8 @@ retry_locked: | |||
1401 | file_wanted = __ceph_caps_file_wanted(ci); | 1402 | file_wanted = __ceph_caps_file_wanted(ci); |
1402 | used = __ceph_caps_used(ci); | 1403 | used = __ceph_caps_used(ci); |
1403 | want = file_wanted | used; | 1404 | want = file_wanted | used; |
1405 | issued = __ceph_caps_issued(ci, &implemented); | ||
1406 | revoking = implemented & ~issued; | ||
1404 | 1407 | ||
1405 | retain = want | CEPH_CAP_PIN; | 1408 | retain = want | CEPH_CAP_PIN; |
1406 | if (!mdsc->stopping && inode->i_nlink > 0) { | 1409 | if (!mdsc->stopping && inode->i_nlink > 0) { |
@@ -1419,11 +1422,11 @@ retry_locked: | |||
1419 | } | 1422 | } |
1420 | 1423 | ||
1421 | dout("check_caps %p file_want %s used %s dirty %s flushing %s" | 1424 | dout("check_caps %p file_want %s used %s dirty %s flushing %s" |
1422 | " issued %s retain %s %s%s%s\n", inode, | 1425 | " issued %s revoking %s retain %s %s%s%s\n", inode, |
1423 | ceph_cap_string(file_wanted), | 1426 | ceph_cap_string(file_wanted), |
1424 | ceph_cap_string(used), ceph_cap_string(ci->i_dirty_caps), | 1427 | ceph_cap_string(used), ceph_cap_string(ci->i_dirty_caps), |
1425 | ceph_cap_string(ci->i_flushing_caps), | 1428 | ceph_cap_string(ci->i_flushing_caps), |
1426 | ceph_cap_string(__ceph_caps_issued(ci, NULL)), | 1429 | ceph_cap_string(issued), ceph_cap_string(revoking), |
1427 | ceph_cap_string(retain), | 1430 | ceph_cap_string(retain), |
1428 | (flags & CHECK_CAPS_AUTHONLY) ? " AUTHONLY" : "", | 1431 | (flags & CHECK_CAPS_AUTHONLY) ? " AUTHONLY" : "", |
1429 | (flags & CHECK_CAPS_NODELAY) ? " NODELAY" : "", | 1432 | (flags & CHECK_CAPS_NODELAY) ? " NODELAY" : "", |
@@ -1437,7 +1440,8 @@ retry_locked: | |||
1437 | if ((!is_delayed || mdsc->stopping) && | 1440 | if ((!is_delayed || mdsc->stopping) && |
1438 | ci->i_wrbuffer_ref == 0 && /* no dirty pages... */ | 1441 | ci->i_wrbuffer_ref == 0 && /* no dirty pages... */ |
1439 | ci->i_rdcache_gen && /* may have cached pages */ | 1442 | ci->i_rdcache_gen && /* may have cached pages */ |
1440 | file_wanted == 0 && /* no open files */ | 1443 | (file_wanted == 0 || /* no open files */ |
1444 | (revoking & CEPH_CAP_FILE_CACHE)) && /* or revoking cache */ | ||
1441 | !ci->i_truncate_pending && | 1445 | !ci->i_truncate_pending && |
1442 | !tried_invalidate) { | 1446 | !tried_invalidate) { |
1443 | u32 invalidating_gen = ci->i_rdcache_gen; | 1447 | u32 invalidating_gen = ci->i_rdcache_gen; |
@@ -1451,6 +1455,10 @@ retry_locked: | |||
1451 | /* success. */ | 1455 | /* success. */ |
1452 | ci->i_rdcache_gen = 0; | 1456 | ci->i_rdcache_gen = 0; |
1453 | ci->i_rdcache_revoking = 0; | 1457 | ci->i_rdcache_revoking = 0; |
1458 | } else if (revoking & CEPH_CAP_FILE_CACHE) { | ||
1459 | dout("check_caps queuing invalidate\n"); | ||
1460 | queue_invalidate = 1; | ||
1461 | ci->i_rdcache_revoking = ci->i_rdcache_gen; | ||
1454 | } else { | 1462 | } else { |
1455 | dout("check_caps failed to invalidate pages\n"); | 1463 | dout("check_caps failed to invalidate pages\n"); |
1456 | /* we failed to invalidate pages. check these | 1464 | /* we failed to invalidate pages. check these |
@@ -1476,7 +1484,7 @@ retry_locked: | |||
1476 | 1484 | ||
1477 | revoking = cap->implemented & ~cap->issued; | 1485 | revoking = cap->implemented & ~cap->issued; |
1478 | if (revoking) | 1486 | if (revoking) |
1479 | dout("mds%d revoking %s\n", cap->mds, | 1487 | dout(" mds%d revoking %s\n", cap->mds, |
1480 | ceph_cap_string(revoking)); | 1488 | ceph_cap_string(revoking)); |
1481 | 1489 | ||
1482 | if (cap == ci->i_auth_cap && | 1490 | if (cap == ci->i_auth_cap && |
@@ -1591,6 +1599,10 @@ ack: | |||
1591 | 1599 | ||
1592 | spin_unlock(&inode->i_lock); | 1600 | spin_unlock(&inode->i_lock); |
1593 | 1601 | ||
1602 | if (queue_invalidate) | ||
1603 | if (ceph_queue_page_invalidation(inode)) | ||
1604 | igrab(inode); | ||
1605 | |||
1594 | if (session && drop_session_lock) | 1606 | if (session && drop_session_lock) |
1595 | mutex_unlock(&session->s_mutex); | 1607 | mutex_unlock(&session->s_mutex); |
1596 | if (took_snap_rwsem) | 1608 | if (took_snap_rwsem) |