return level;
}
+/* Wrapper around find_get_page(), with extra error message. */
+int btrfs_compress_find_get_page(struct address_space *mapping, u64 start,
+ struct page **in_page_ret)
+{
+ struct page *in_page;
+
+ /*
+ * The compressed write path should have the page locked already, thus
+ * we only need to grab one reference of the page cache.
+ */
+ in_page = find_get_page(mapping, start >> PAGE_SHIFT);
+ if (unlikely(!in_page)) {
+ struct btrfs_inode *inode = BTRFS_I(mapping->host);
+
+ btrfs_crit(inode->root->fs_info,
+ "failed to get page cache, root %lld ino %llu file offset %llu",
+ inode->root->root_key.objectid, btrfs_ino(inode), start);
+ return -ENOENT;
+ }
+ *in_page_ret = in_page;
+ return 0;
+}
+
/*
* Given an address space and start and length, compress the bytes into @pages
* that are allocated on demand.
int btrfs_compress_heuristic(struct inode *inode, u64 start, u64 end);
+int btrfs_compress_find_get_page(struct address_space *mapping, u64 start,
+ struct page **in_page_ret);
+
int zlib_compress_pages(struct list_head *ws, struct address_space *mapping,
u64 start, struct page **pages, unsigned long *out_pages,
unsigned long *total_in, unsigned long *total_out);
/* Get the input page first */
if (!page_in) {
- page_in = find_get_page(mapping, cur_in >> PAGE_SHIFT);
- ASSERT(page_in);
+ ret = btrfs_compress_find_get_page(mapping, cur_in, &page_in);
+ if (ret < 0)
+ goto out;
}
/* Compress at most one sector of data each time */
if (data_in) {
kunmap_local(data_in);
put_page(in_page);
+ data_in = NULL;
}
- in_page = find_get_page(mapping,
- start >> PAGE_SHIFT);
+ ret = btrfs_compress_find_get_page(mapping,
+ start, &in_page);
+ if (ret < 0)
+ goto out;
data_in = kmap_local_page(in_page);
copy_page(workspace->buf + i * PAGE_SIZE,
data_in);
if (data_in) {
kunmap_local(data_in);
put_page(in_page);
+ data_in = NULL;
}
- in_page = find_get_page(mapping,
- start >> PAGE_SHIFT);
+ ret = btrfs_compress_find_get_page(mapping,
+ start, &in_page);
+ if (ret < 0)
+ goto out;
data_in = kmap_local_page(in_page);
start += PAGE_SIZE;
workspace->strm.next_in = data_in;
}
/* map in the first page of input data */
- in_page = find_get_page(mapping, start >> PAGE_SHIFT);
+ ret = btrfs_compress_find_get_page(mapping, start, &in_page);
+ if (ret < 0)
+ goto out;
workspace->in_buf.src = kmap_local_page(in_page);
workspace->in_buf.pos = 0;
workspace->in_buf.size = min_t(size_t, len, PAGE_SIZE);
if (workspace->in_buf.pos == workspace->in_buf.size) {
tot_in += PAGE_SIZE;
kunmap_local(workspace->in_buf.src);
+ workspace->in_buf.src = NULL;
put_page(in_page);
start += PAGE_SIZE;
len -= PAGE_SIZE;
- in_page = find_get_page(mapping, start >> PAGE_SHIFT);
+ ret = btrfs_compress_find_get_page(mapping, start, &in_page);
+ if (ret < 0)
+ goto out;
workspace->in_buf.src = kmap_local_page(in_page);
workspace->in_buf.pos = 0;
workspace->in_buf.size = min_t(size_t, len, PAGE_SIZE);