aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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) {