]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - fs/btrfs/compression.c
Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
[karo-tx-linux.git] / fs / btrfs / compression.c
index 10e6b282d09d6e8d31b4ac8740d0119ccad3e786..2c0b7b57fcd5525f826f40041da230b5fe212fcf 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/writeback.h>
 #include <linux/bit_spinlock.h>
 #include <linux/slab.h>
+#include <linux/sched/mm.h>
 #include "ctree.h"
 #include "disk-io.h"
 #include "transaction.h"
 #include "extent_io.h"
 #include "extent_map.h"
 
-struct compressed_bio {
-       /* number of bios pending for this compressed extent */
-       refcount_t pending_bios;
-
-       /* the pages with the compressed data on them */
-       struct page **compressed_pages;
-
-       /* inode that owns this data */
-       struct inode *inode;
-
-       /* starting offset in the inode for our pages */
-       u64 start;
-
-       /* number of bytes in the inode we're working on */
-       unsigned long len;
-
-       /* number of bytes on disk */
-       unsigned long compressed_len;
-
-       /* the compression algorithm for this bio */
-       int compress_type;
-
-       /* number of compressed pages in the array */
-       unsigned long nr_pages;
-
-       /* IO errors */
-       int errors;
-       int mirror_num;
-
-       /* for reads, this is the bio we are copying the data into */
-       struct bio *orig_bio;
-
-       /*
-        * the start of a variable length array of checksums only
-        * used by reads
-        */
-       u32 sums;
-};
-
-static int btrfs_decompress_bio(int type, struct page **pages_in,
-                                  u64 disk_start, struct bio *orig_bio,
-                                  size_t srclen);
+static int btrfs_decompress_bio(struct compressed_bio *cb);
 
 static inline int compressed_bio_size(struct btrfs_fs_info *fs_info,
                                      unsigned long disk_size)
@@ -94,12 +54,6 @@ static inline int compressed_bio_size(struct btrfs_fs_info *fs_info,
                (DIV_ROUND_UP(disk_size, fs_info->sectorsize)) * csum_size;
 }
 
-static struct bio *compressed_bio_alloc(struct block_device *bdev,
-                                       u64 first_byte, gfp_t gfp_flags)
-{
-       return btrfs_bio_alloc(bdev, first_byte >> 9, BIO_MAX_PAGES, gfp_flags);
-}
-
 static int check_compressed_csum(struct btrfs_inode *inode,
                                 struct compressed_bio *cb,
                                 u64 disk_start)
@@ -155,7 +109,7 @@ static void end_compressed_bio_read(struct bio *bio)
        unsigned long index;
        int ret;
 
-       if (bio->bi_error)
+       if (bio->bi_status)
                cb->errors = 1;
 
        /* if there are more bios still pending for this compressed
@@ -173,11 +127,8 @@ static void end_compressed_bio_read(struct bio *bio)
        /* ok, we're the last bio for this extent, lets start
         * the decompression.
         */
-       ret = btrfs_decompress_bio(cb->compress_type,
-                                     cb->compressed_pages,
-                                     cb->start,
-                                     cb->orig_bio,
-                                     cb->compressed_len);
+       ret = btrfs_decompress_bio(cb);
+
 csum_failed:
        if (ret)
                cb->errors = 1;
@@ -268,7 +219,7 @@ static void end_compressed_bio_write(struct bio *bio)
        struct page *page;
        unsigned long index;
 
-       if (bio->bi_error)
+       if (bio->bi_status)
                cb->errors = 1;
 
        /* if there are more bios still pending for this compressed
@@ -287,7 +238,7 @@ static void end_compressed_bio_write(struct bio *bio)
                                         cb->start,
                                         cb->start + cb->len - 1,
                                         NULL,
-                                        bio->bi_error ? 0 : 1);
+                                        bio->bi_status ? 0 : 1);
        cb->compressed_pages[0]->mapping = NULL;
 
        end_compressed_writeback(inode, cb);
@@ -320,7 +271,7 @@ out:
  * This also checksums the file bytes and gets things ready for
  * the end io hooks.
  */
-int btrfs_submit_compressed_write(struct inode *inode, u64 start,
+blk_status_t btrfs_submit_compressed_write(struct inode *inode, u64 start,
                                 unsigned long len, u64 disk_start,
                                 unsigned long compressed_len,
                                 struct page **compressed_pages,
@@ -335,13 +286,13 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start,
        struct page *page;
        u64 first_byte = disk_start;
        struct block_device *bdev;
-       int ret;
+       blk_status_t ret;
        int skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
 
        WARN_ON(start & ((u64)PAGE_SIZE - 1));
        cb = kmalloc(compressed_bio_size(fs_info, compressed_len), GFP_NOFS);
        if (!cb)
-               return -ENOMEM;
+               return BLK_STS_RESOURCE;
        refcount_set(&cb->pending_bios, 0);
        cb->errors = 0;
        cb->inode = inode;
@@ -355,11 +306,7 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start,
 
        bdev = fs_info->fs_devices->latest_bdev;
 
-       bio = compressed_bio_alloc(bdev, first_byte, GFP_NOFS);
-       if (!bio) {
-               kfree(cb);
-               return -ENOMEM;
-       }
+       bio = btrfs_bio_alloc(bdev, first_byte);
        bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
        bio->bi_private = cb;
        bio->bi_end_io = end_compressed_bio_write;
@@ -368,17 +315,17 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start,
        /* create and submit bios for the compressed pages */
        bytes_left = compressed_len;
        for (pg_index = 0; pg_index < cb->nr_pages; pg_index++) {
+               int submit = 0;
+
                page = compressed_pages[pg_index];
                page->mapping = inode->i_mapping;
                if (bio->bi_iter.bi_size)
-                       ret = io_tree->ops->merge_bio_hook(page, 0,
+                       submit = io_tree->ops->merge_bio_hook(page, 0,
                                                           PAGE_SIZE,
                                                           bio, 0);
-               else
-                       ret = 0;
 
                page->mapping = NULL;
-               if (ret || bio_add_page(bio, page, PAGE_SIZE, 0) <
+               if (submit || bio_add_page(bio, page, PAGE_SIZE, 0) <
                    PAGE_SIZE) {
                        bio_get(bio);
 
@@ -400,14 +347,13 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start,
 
                        ret = btrfs_map_bio(fs_info, bio, 0, 1);
                        if (ret) {
-                               bio->bi_error = ret;
+                               bio->bi_status = ret;
                                bio_endio(bio);
                        }
 
                        bio_put(bio);
 
-                       bio = compressed_bio_alloc(bdev, first_byte, GFP_NOFS);
-                       BUG_ON(!bio);
+                       bio = btrfs_bio_alloc(bdev, first_byte);
                        bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
                        bio->bi_private = cb;
                        bio->bi_end_io = end_compressed_bio_write;
@@ -434,7 +380,7 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start,
 
        ret = btrfs_map_bio(fs_info, bio, 0, 1);
        if (ret) {
-               bio->bi_error = ret;
+               bio->bi_status = ret;
                bio_endio(bio);
        }
 
@@ -569,7 +515,7 @@ next:
  * After the compressed pages are read, we copy the bytes into the
  * bio we were passed and then call the bio end_io calls
  */
-int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
+blk_status_t btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
                                 int mirror_num, unsigned long bio_flags)
 {
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
@@ -586,7 +532,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
        u64 em_len;
        u64 em_start;
        struct extent_map *em;
-       int ret = -ENOMEM;
+       blk_status_t ret = BLK_STS_RESOURCE;
        int faili = 0;
        u32 *sums;
 
@@ -600,7 +546,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
                                   PAGE_SIZE);
        read_unlock(&em_tree->lock);
        if (!em)
-               return -EIO;
+               return BLK_STS_IOERR;
 
        compressed_len = em->block_len;
        cb = kmalloc(compressed_bio_size(fs_info, compressed_len), GFP_NOFS);
@@ -638,7 +584,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
                                                              __GFP_HIGHMEM);
                if (!cb->compressed_pages[pg_index]) {
                        faili = pg_index - 1;
-                       ret = -ENOMEM;
+                       ret = BLK_STS_RESOURCE;
                        goto fail2;
                }
        }
@@ -650,28 +596,26 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
        /* include any pages we added in add_ra-bio_pages */
        cb->len = bio->bi_iter.bi_size;
 
-       comp_bio = compressed_bio_alloc(bdev, cur_disk_byte, GFP_NOFS);
-       if (!comp_bio)
-               goto fail2;
+       comp_bio = btrfs_bio_alloc(bdev, cur_disk_byte);
        bio_set_op_attrs (comp_bio, REQ_OP_READ, 0);
        comp_bio->bi_private = cb;
        comp_bio->bi_end_io = end_compressed_bio_read;
        refcount_set(&cb->pending_bios, 1);
 
        for (pg_index = 0; pg_index < nr_pages; pg_index++) {
+               int submit = 0;
+
                page = cb->compressed_pages[pg_index];
                page->mapping = inode->i_mapping;
                page->index = em_start >> PAGE_SHIFT;
 
                if (comp_bio->bi_iter.bi_size)
-                       ret = tree->ops->merge_bio_hook(page, 0,
+                       submit = tree->ops->merge_bio_hook(page, 0,
                                                        PAGE_SIZE,
                                                        comp_bio, 0);
-               else
-                       ret = 0;
 
                page->mapping = NULL;
-               if (ret || bio_add_page(comp_bio, page, PAGE_SIZE, 0) <
+               if (submit || bio_add_page(comp_bio, page, PAGE_SIZE, 0) <
                    PAGE_SIZE) {
                        bio_get(comp_bio);
 
@@ -697,15 +641,13 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
 
                        ret = btrfs_map_bio(fs_info, comp_bio, mirror_num, 0);
                        if (ret) {
-                               comp_bio->bi_error = ret;
+                               comp_bio->bi_status = ret;
                                bio_endio(comp_bio);
                        }
 
                        bio_put(comp_bio);
 
-                       comp_bio = compressed_bio_alloc(bdev, cur_disk_byte,
-                                                       GFP_NOFS);
-                       BUG_ON(!comp_bio);
+                       comp_bio = btrfs_bio_alloc(bdev, cur_disk_byte);
                        bio_set_op_attrs(comp_bio, REQ_OP_READ, 0);
                        comp_bio->bi_private = cb;
                        comp_bio->bi_end_io = end_compressed_bio_read;
@@ -726,7 +668,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
 
        ret = btrfs_map_bio(fs_info, comp_bio, mirror_num, 0);
        if (ret) {
-               comp_bio->bi_error = ret;
+               comp_bio->bi_status = ret;
                bio_endio(comp_bio);
        }
 
@@ -801,6 +743,7 @@ static struct list_head *find_workspace(int type)
        struct list_head *workspace;
        int cpus = num_online_cpus();
        int idx = type - 1;
+       unsigned nofs_flag;
 
        struct list_head *idle_ws       = &btrfs_comp_ws[idx].idle_ws;
        spinlock_t *ws_lock             = &btrfs_comp_ws[idx].ws_lock;
@@ -830,7 +773,15 @@ again:
        atomic_inc(total_ws);
        spin_unlock(ws_lock);
 
+       /*
+        * Allocation helpers call vmalloc that can't use GFP_NOFS, so we have
+        * to turn it off here because we might get called from the restricted
+        * context of btrfs_compress_bio/btrfs_compress_pages
+        */
+       nofs_flag = memalloc_nofs_save();
        workspace = btrfs_compress_op[idx]->alloc_workspace();
+       memalloc_nofs_restore(nofs_flag);
+
        if (IS_ERR(workspace)) {
                atomic_dec(total_ws);
                wake_up(ws_wait);
@@ -961,19 +912,16 @@ int btrfs_compress_pages(int type, struct address_space *mapping,
  * be contiguous.  They all correspond to the range of bytes covered by
  * the compressed extent.
  */
-static int btrfs_decompress_bio(int type, struct page **pages_in,
-                                  u64 disk_start, struct bio *orig_bio,
-                                  size_t srclen)
+static int btrfs_decompress_bio(struct compressed_bio *cb)
 {
        struct list_head *workspace;
        int ret;
+       int type = cb->compress_type;
 
        workspace = find_workspace(type);
-
-       ret = btrfs_compress_op[type-1]->decompress_bio(workspace, pages_in,
-                                                        disk_start, orig_bio,
-                                                        srclen);
+       ret = btrfs_compress_op[type - 1]->decompress_bio(workspace, cb);
        free_workspace(type, workspace);
+
        return ret;
 }