aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@hq.newdream.net>2010-02-18 19:10:11 -0500
committerSage Weil <sage@newdream.net>2010-02-19 17:40:51 -0500
commitc9af9fb68e01eb2c2165e1bc45cfeeed510c64e6 (patch)
tree9af8caecd66c6557c5ada6a38d4b2ff9be180d35
parente63dc5c780ba32d6d8b3662eecce2b8d96489b41 (diff)
ceph: don't truncate dirty pages in invalidate work thread
Instead of truncating the whole range of pages, we skip those pages that are dirty or in the middle of writeback. Those pages will be cleared later when the writeback completes. Signed-off-by: Yehuda Sadeh <yehuda@hq.newdream.net> Signed-off-by: Sage Weil <sage@newdream.net>
-rw-r--r--fs/ceph/inode.c46
1 files changed, 45 insertions, 1 deletions
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index d7d5d4923772..7abe1aed819b 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -10,6 +10,7 @@
10#include <linux/namei.h> 10#include <linux/namei.h>
11#include <linux/writeback.h> 11#include <linux/writeback.h>
12#include <linux/vmalloc.h> 12#include <linux/vmalloc.h>
13#include <linux/pagevec.h>
13 14
14#include "super.h" 15#include "super.h"
15#include "decode.h" 16#include "decode.h"
@@ -1280,6 +1281,49 @@ void ceph_queue_invalidate(struct inode *inode)
1280} 1281}
1281 1282
1282/* 1283/*
1284 * invalidate any pages that are not dirty or under writeback. this
1285 * includes pages that are clean and mapped.
1286 */
1287static void ceph_invalidate_nondirty_pages(struct address_space *mapping)
1288{
1289 struct pagevec pvec;
1290 pgoff_t next = 0;
1291 int i;
1292
1293 pagevec_init(&pvec, 0);
1294 while (pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
1295 for (i = 0; i < pagevec_count(&pvec); i++) {
1296 struct page *page = pvec.pages[i];
1297 pgoff_t index;
1298 int skip_page =
1299 (PageDirty(page) || PageWriteback(page));
1300
1301 if (!skip_page)
1302 skip_page = !trylock_page(page);
1303
1304 /*
1305 * We really shouldn't be looking at the ->index of an
1306 * unlocked page. But we're not allowed to lock these
1307 * pages. So we rely upon nobody altering the ->index
1308 * of this (pinned-by-us) page.
1309 */
1310 index = page->index;
1311 if (index > next)
1312 next = index;
1313 next++;
1314
1315 if (skip_page)
1316 continue;
1317
1318 generic_error_remove_page(mapping, page);
1319 unlock_page(page);
1320 }
1321 pagevec_release(&pvec);
1322 cond_resched();
1323 }
1324}
1325
1326/*
1283 * Invalidate inode pages in a worker thread. (This can't be done 1327 * Invalidate inode pages in a worker thread. (This can't be done
1284 * in the message handler context.) 1328 * in the message handler context.)
1285 */ 1329 */
@@ -1305,7 +1349,7 @@ static void ceph_invalidate_work(struct work_struct *work)
1305 orig_gen = ci->i_rdcache_gen; 1349 orig_gen = ci->i_rdcache_gen;
1306 spin_unlock(&inode->i_lock); 1350 spin_unlock(&inode->i_lock);
1307 1351
1308 truncate_inode_pages(&inode->i_data, 0); 1352 ceph_invalidate_nondirty_pages(inode->i_mapping);
1309 1353
1310 spin_lock(&inode->i_lock); 1354 spin_lock(&inode->i_lock);
1311 if (orig_gen == ci->i_rdcache_gen) { 1355 if (orig_gen == ci->i_rdcache_gen) {