aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2010-02-09 16:41:18 -0500
committerSage Weil <sage@newdream.net>2010-02-11 14:48:52 -0500
commitcbd03635913a86afb7c2cfc0058932956b05b51e (patch)
tree5938439c41509d72af379fcfc770e37fb5527847 /fs
parent29065a513aa4c7e4b46b77cbcd25f814a4ca0bfe (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')
-rw-r--r--fs/ceph/caps.c22
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)