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

Commit 1fb32b7b authored by Evgeniy Dushistov's avatar Evgeniy Dushistov Committed by Linus Torvalds
Browse files

[PATCH] ufs: ufs_get_locked_page() race fix

As discussed earlier:
http://lkml.org/lkml/2006/6/28/136


this patch fixes such issue:

`ufs_get_locked_page' takes page from cache
after that `vmtruncate' takes page and deletes it from cache
`ufs_get_locked_page' locks page, and reports about EIO error.

Also because of find_lock_page always return valid page or NULL, we have no
need to check it if page not NULL.

Signed-off-by: default avatarEvgeniy Dushistov <dushistov@mail.ru>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent e91467ec
Loading
Loading
Loading
Loading
+8 −7
Original line number Diff line number Diff line
@@ -257,6 +257,7 @@ struct page *ufs_get_locked_page(struct address_space *mapping,
		page = read_cache_page(mapping, index,
				       (filler_t*)mapping->a_ops->readpage,
				       NULL);

		if (IS_ERR(page)) {
			printk(KERN_ERR "ufs_change_blocknr: "
			       "read_cache_page error: ino %lu, index: %lu\n",
@@ -266,6 +267,13 @@ struct page *ufs_get_locked_page(struct address_space *mapping,

		lock_page(page);

		if (unlikely(page->mapping == NULL)) {
			/* Truncate got there first */
			unlock_page(page);
			page_cache_release(page);
			goto try_again;
		}

		if (!PageUptodate(page) || PageError(page)) {
			unlock_page(page);
			page_cache_release(page);
@@ -275,14 +283,7 @@ struct page *ufs_get_locked_page(struct address_space *mapping,
			       mapping->host->i_ino, index);

			page = ERR_PTR(-EIO);
			goto out;
		}
		}

	if (unlikely(!page->mapping || !page_has_buffers(page))) {
		unlock_page(page);
		page_cache_release(page);
		goto try_again;/*we really need these buffers*/
	}
out:
	return page;