aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/caps.c
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2010-02-17 13:43:37 -0500
committerSage Weil <sage@newdream.net>2010-02-19 17:33:18 -0500
commit5ecad6fd7bfd30b3eaea51345f546b81de7a6473 (patch)
tree98447fd009cc03e5125ffc51b4caac07123e0f70 /fs/ceph/caps.c
parent2c27c9a57c93a0757b9b4b0e7dc1abeaf1db1ce2 (diff)
ceph: fix check for invalidate_mapping_pages success
We need to know whether there was any page left behind, and not the return value (the total number of pages invalidated). Look at the mapping to see if we were successful or not. Move it all into a helper to simplify the two callers. Signed-off-by: Yehuda Sadeh <yehuda@hq.newdream.net> Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph/caps.c')
-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 }