Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 83eaea22 authored by Sage Weil's avatar Sage Weil
Browse files

Revert "ceph: don't truncate dirty pages in invalidate work thread"



This reverts commit c9af9fb6.

We need to block and truncate all pages in order to reliably invalidate
them.  Otherwise, we could:

 - have some uptodate pages in the cache
 - queue an invalidate
 - write(2) locks some pages
 - invalidate_work skips them
 - write(2) only overwrites part of the page
 - page now dirty and uptodate
 -> partial leakage of invalidated data

It's not entirely clear why we started skipping locked pages in the first
place.  I just ran this through fsx and didn't see any problems.

Signed-off-by: default avatarSage Weil <sage@newdream.net>
parent 80db8bea
Loading
Loading
Loading
Loading
+1 −45
Original line number Diff line number Diff line
@@ -9,7 +9,6 @@
#include <linux/namei.h>
#include <linux/writeback.h>
#include <linux/vmalloc.h>
#include <linux/pagevec.h>

#include "super.h"
#include "mds_client.h"
@@ -1363,49 +1362,6 @@ void ceph_queue_invalidate(struct inode *inode)
	}
}

/*
 * invalidate any pages that are not dirty or under writeback.  this
 * includes pages that are clean and mapped.
 */
static void ceph_invalidate_nondirty_pages(struct address_space *mapping)
{
	struct pagevec pvec;
	pgoff_t next = 0;
	int i;

	pagevec_init(&pvec, 0);
	while (pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
		for (i = 0; i < pagevec_count(&pvec); i++) {
			struct page *page = pvec.pages[i];
			pgoff_t index;
			int skip_page =
				(PageDirty(page) || PageWriteback(page));

			if (!skip_page)
				skip_page = !trylock_page(page);

			/*
			 * We really shouldn't be looking at the ->index of an
			 * unlocked page.  But we're not allowed to lock these
			 * pages.  So we rely upon nobody altering the ->index
			 * of this (pinned-by-us) page.
			 */
			index = page->index;
			if (index > next)
				next = index;
			next++;

			if (skip_page)
				continue;

			generic_error_remove_page(mapping, page);
			unlock_page(page);
		}
		pagevec_release(&pvec);
		cond_resched();
	}
}

/*
 * Invalidate inode pages in a worker thread.  (This can't be done
 * in the message handler context.)
@@ -1429,7 +1385,7 @@ static void ceph_invalidate_work(struct work_struct *work)
	orig_gen = ci->i_rdcache_gen;
	spin_unlock(&inode->i_lock);

	ceph_invalidate_nondirty_pages(inode->i_mapping);
	truncate_inode_pages(&inode->i_data, 0);

	spin_lock(&inode->i_lock);
	if (orig_gen == ci->i_rdcache_gen &&