aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ceph/caps.c82
1 files changed, 50 insertions, 32 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 4958a2ef3e04..e1e6df0f549e 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -1362,6 +1362,41 @@ static int __mark_caps_flushing(struct inode *inode,
1362} 1362}
1363 1363
1364/* 1364/*
1365 * try to invalidate mapping pages without blocking.
1366 */
1367static int mapping_is_empty(struct address_space *mapping)
1368{
1369 struct page *page = find_get_page(mapping, 0);
1370
1371 if (!page)
1372 return 1;
1373
1374 put_page(page);
1375 return 0;
1376}
1377
1378static int try_nonblocking_invalidate(struct inode *inode)
1379{
1380 struct ceph_inode_info *ci = ceph_inode(inode);
1381 u32 invalidating_gen = ci->i_rdcache_gen;
1382
1383 spin_unlock(&inode->i_lock);
1384 invalidate_mapping_pages(&inode->i_data, 0, -1);
1385 spin_lock(&inode->i_lock);
1386
1387 if (mapping_is_empty(&inode->i_data) &&
1388 invalidating_gen == ci->i_rdcache_gen) {
1389 /* success. */
1390 dout("try_nonblocking_invalidate %p success\n", inode);
1391 ci->i_rdcache_gen = 0;
1392 ci->i_rdcache_revoking = 0;
1393 return 0;
1394 }
1395 dout("try_nonblocking_invalidate %p failed\n", inode);
1396 return -1;
1397}
1398
1399/*
1365 * Swiss army knife function to examine currently used and wanted 1400 * Swiss army knife function to examine currently used and wanted
1366 * versus held caps. Release, flush, ack revoked caps to mds as 1401 * versus held caps. Release, flush, ack revoked caps to mds as
1367 * appropriate. 1402 * appropriate.
@@ -1451,27 +1486,19 @@ retry_locked:
1451 (file_wanted == 0 || /* no open files */ 1486 (file_wanted == 0 || /* no open files */
1452 (revoking & CEPH_CAP_FILE_CACHE)) && /* or revoking cache */ 1487 (revoking & CEPH_CAP_FILE_CACHE)) && /* or revoking cache */
1453 !tried_invalidate) { 1488 !tried_invalidate) {
1454 u32 invalidating_gen = ci->i_rdcache_gen;
1455 int ret;
1456
1457 dout("check_caps trying to invalidate on %p\n", inode); 1489 dout("check_caps trying to invalidate on %p\n", inode);
1458 spin_unlock(&inode->i_lock); 1490 if (try_nonblocking_invalidate(inode) < 0) {
1459 ret = invalidate_mapping_pages(&inode->i_data, 0, -1); 1491 if (revoking & CEPH_CAP_FILE_CACHE) {
1460 spin_lock(&inode->i_lock); 1492 dout("check_caps queuing invalidate\n");
1461 if (ret == 0 && invalidating_gen == ci->i_rdcache_gen) { 1493 queue_invalidate = 1;
1462 /* success. */ 1494 ci->i_rdcache_revoking = ci->i_rdcache_gen;
1463 ci->i_rdcache_gen = 0; 1495 } else {
1464 ci->i_rdcache_revoking = 0; 1496 dout("check_caps failed to invalidate pages\n");
1465 } else if (revoking & CEPH_CAP_FILE_CACHE) { 1497 /* we failed to invalidate pages. check these
1466 dout("check_caps queuing invalidate\n"); 1498 caps again later. */
1467 queue_invalidate = 1; 1499 force_requeue = 1;
1468 ci->i_rdcache_revoking = ci->i_rdcache_gen; 1500 __cap_set_timeouts(mdsc, ci);
1469 } else { 1501 }
1470 dout("check_caps failed to invalidate pages\n");
1471 /* we failed to invalidate pages. check these
1472 caps again later. */
1473 force_requeue = 1;
1474 __cap_set_timeouts(mdsc, ci);
1475 } 1502 }
1476 tried_invalidate = 1; 1503 tried_invalidate = 1;
1477 goto retry_locked; 1504 goto retry_locked;
@@ -2184,7 +2211,6 @@ static int handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
2184 int revoked_rdcache = 0; 2211 int revoked_rdcache = 0;
2185 int queue_invalidate = 0; 2212 int queue_invalidate = 0;
2186 int tried_invalidate = 0; 2213 int tried_invalidate = 0;
2187 int ret;
2188 2214
2189 dout("handle_cap_grant inode %p cap %p mds%d seq %d %s\n", 2215 dout("handle_cap_grant inode %p cap %p mds%d seq %d %s\n",
2190 inode, cap, mds, seq, ceph_cap_string(newcaps)); 2216 inode, cap, mds, seq, ceph_cap_string(newcaps));
@@ -2199,24 +2225,16 @@ static int handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
2199restart: 2225restart:
2200 if (((cap->issued & ~newcaps) & CEPH_CAP_FILE_CACHE) && 2226 if (((cap->issued & ~newcaps) & CEPH_CAP_FILE_CACHE) &&
2201 !ci->i_wrbuffer_ref && !tried_invalidate) { 2227 !ci->i_wrbuffer_ref && !tried_invalidate) {
2202 dout("CACHE invalidation\n");
2203 spin_unlock(&inode->i_lock);
2204 tried_invalidate = 1; 2228 tried_invalidate = 1;
2205 2229 if (try_nonblocking_invalidate(inode) == 0) {
2206 ret = invalidate_mapping_pages(&inode->i_data, 0, -1); 2230 revoked_rdcache = 1;
2207 spin_lock(&inode->i_lock); 2231 } else {
2208 if (ret < 0) {
2209 /* there were locked pages.. invalidate later 2232 /* there were locked pages.. invalidate later
2210 in a separate thread. */ 2233 in a separate thread. */
2211 if (ci->i_rdcache_revoking != ci->i_rdcache_gen) { 2234 if (ci->i_rdcache_revoking != ci->i_rdcache_gen) {
2212 queue_invalidate = 1; 2235 queue_invalidate = 1;
2213 ci->i_rdcache_revoking = ci->i_rdcache_gen; 2236 ci->i_rdcache_revoking = ci->i_rdcache_gen;
2214 } 2237 }
2215 } else {
2216 /* we successfully invalidated those pages */
2217 revoked_rdcache = 1;
2218 ci->i_rdcache_gen = 0;
2219 ci->i_rdcache_revoking = 0;
2220 } 2238 }
2221 goto restart; 2239 goto restart;
2222 } 2240 }