Re: [PATCH] cramfs corruption after BLKFLSBUF on loop device

Andrew Morton
2006-06-02T09:07:07Z

On Fri, 2 Jun 2006 10:43:27 +0200
Olaf Hering <olh@suse.de> wrote:

> On Thu, Jun 01, Andrew Morton wrote:
>
>
> > > Do you want it like that?
> > >
> > > lock_page(page);
> > > if (PageUptodate(page)) {
> > > SetPageDirty(page);
> > > mb();
> > > return page;
> > > }
> >
> > Not really ;) It's hacky. It'd be better to take a lock.
>
> Which lock exactly?

Ah, sorry, there isn't such a lock. I was just carrying on.

> I'm not sure how to proceed from here.

I'd suggest you run SetPagePrivate() and SetPageChecked() on the locked
page and implement a_ops.releasepage(), which will fail if PageChecked(),
and will succeed otherwise:

/*
* cramfs_releasepage() will fail if cramfs_read() set PG_checked. This
* is so that invalidate_inode_pages() cannot zap the page while
* cramfs_read() is trying to get at its contents.
*/
cramfs_releasepage(...)
{
if (PageChecked(page))
return 0;
return 1;
}

cramfs_read(...)
{
lock_page(page);
SetPagePrivate(page);
SetPageChecked(page);
read_mapping_page(...);
lock_page(page);
if (page->mapping == NULL) {
/* truncate got there first */
unlock_page(page);
bale();
}
memcpy();
ClearPageChecked(page);
ClearPagePrivate(page);
unlock_page(page);
}

PG_checked is a filesystem-private flag. It'll soon be renamed to
PG_fs_misc.