@@ -4362,33 +4362,28 @@ int extent_invalidatepage(struct extent_io_tree *tree,
* are locked or under IO and drops the related state bits if it is safe
* to drop the page.
*/
-static int try_release_extent_state(struct extent_io_tree *tree,
+static bool try_release_extent_state(struct extent_io_tree *tree,
struct page *page, gfp_t mask)
{
u64 start = page_offset(page);
u64 end = start + PAGE_SIZE - 1;
- int ret = 1;
if (test_range_bit(tree, start, end, EXTENT_LOCKED, 0, NULL)) {
- ret = 0;
- } else {
- /*
- * at this point we can safely clear everything except the
- * locked bit and the nodatasum bit
- */
- ret = __clear_extent_bit(tree, start, end,
- ~(EXTENT_LOCKED | EXTENT_NODATASUM),
- 0, 0, NULL, mask, NULL);
-
- /* if clear_extent_bit failed for enomem reasons,
- * we can't allow the release to continue.
- */
- if (ret < 0)
- ret = 0;
- else
- ret = 1;
+ if (!gfpflags_allow_blocking(mask))
+ return false;
+ wait_extent_bit(tree, start, end, EXTENT_LOCKED);
}
- return ret;
+ /*
+ * At this point we can safely clear everything except the locked and
+ * nodatasum bits. If clear_extent_bit failed due to -ENOMEM,
+ * don't allow release.
+ */
+ if (__clear_extent_bit(tree, start, end,
+ ~(EXTENT_LOCKED | EXTENT_NODATASUM), 0, 0,
+ NULL, mask, NULL) < 0)
+ return false;
+
+ return true;
}
/*
@@ -4396,7 +4391,7 @@ static int try_release_extent_state(struct extent_io_tree *tree,
* in the range corresponding to the page, both state records and extent
* map records are removed
*/
-int try_release_extent_mapping(struct page *page, gfp_t mask)
+bool try_release_extent_mapping(struct page *page, gfp_t mask)
{
struct extent_map *em;
u64 start = page_offset(page);
@@ -263,7 +263,7 @@ void extent_io_tree_init(struct btrfs_fs_info *fs_info,
struct extent_io_tree *tree, unsigned int owner,
void *private_data);
void extent_io_tree_release(struct extent_io_tree *tree);
-int try_release_extent_mapping(struct page *page, gfp_t mask);
+bool try_release_extent_mapping(struct page *page, gfp_t mask);
int try_release_extent_buffer(struct page *page);
int lock_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
struct extent_state **cached);
@@ -8787,8 +8787,8 @@ btrfs_readpages(struct file *file, struct address_space *mapping,
static int __btrfs_releasepage(struct page *page, gfp_t gfp_flags)
{
- int ret = try_release_extent_mapping(page, gfp_flags);
- if (ret == 1) {
+ bool ret = try_release_extent_mapping(page, gfp_flags);
+ if (ret) {
ClearPagePrivate(page);
set_page_private(page, 0);
put_page(page);