diff options
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) |
