Merge branch 'for-linus-4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/mason...
[linux-2.6-microblaze.git] / fs / btrfs / disk-io.c
index f556c37..9ebd34f 100644 (file)
@@ -703,7 +703,7 @@ static int btree_io_failed_hook(struct page *page, int failed_mirror)
        return -EIO;    /* we fixed nothing */
 }
 
-static void end_workqueue_bio(struct bio *bio, int err)
+static void end_workqueue_bio(struct bio *bio)
 {
        struct btrfs_end_io_wq *end_io_wq = bio->bi_private;
        struct btrfs_fs_info *fs_info;
@@ -711,7 +711,7 @@ static void end_workqueue_bio(struct bio *bio, int err)
        btrfs_work_func_t func;
 
        fs_info = end_io_wq->info;
-       end_io_wq->error = err;
+       end_io_wq->error = bio->bi_error;
 
        if (bio->bi_rw & REQ_WRITE) {
                if (end_io_wq->metadata == BTRFS_WQ_ENDIO_METADATA) {
@@ -808,7 +808,8 @@ static void run_one_async_done(struct btrfs_work *work)
 
        /* If an error occured we just want to clean up the bio and move on */
        if (async->error) {
-               bio_endio(async->bio, async->error);
+               async->bio->bi_error = async->error;
+               bio_endio(async->bio);
                return;
        }
 
@@ -908,8 +909,10 @@ static int __btree_submit_bio_done(struct inode *inode, int rw, struct bio *bio,
         * submission context.  Just jump into btrfs_map_bio
         */
        ret = btrfs_map_bio(BTRFS_I(inode)->root, rw, bio, mirror_num, 1);
-       if (ret)
-               bio_endio(bio, ret);
+       if (ret) {
+               bio->bi_error = ret;
+               bio_endio(bio);
+       }
        return ret;
 }
 
@@ -960,10 +963,13 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
                                          __btree_submit_bio_done);
        }
 
-       if (ret) {
+       if (ret)
+               goto out_w_error;
+       return 0;
+
 out_w_error:
-               bio_endio(bio, ret);
-       }
+       bio->bi_error = ret;
+       bio_endio(bio);
        return ret;
 }
 
@@ -1724,6 +1730,7 @@ static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi)
        bdi->ra_pages = VM_MAX_READAHEAD * 1024 / PAGE_CACHE_SIZE;
        bdi->congested_fn       = btrfs_congested_fn;
        bdi->congested_data     = info;
+       bdi->capabilities |= BDI_CAP_CGROUP_WRITEBACK;
        return 0;
 }
 
@@ -1735,16 +1742,15 @@ static void end_workqueue_fn(struct btrfs_work *work)
 {
        struct bio *bio;
        struct btrfs_end_io_wq *end_io_wq;
-       int error;
 
        end_io_wq = container_of(work, struct btrfs_end_io_wq, work);
        bio = end_io_wq->bio;
 
-       error = end_io_wq->error;
+       bio->bi_error = end_io_wq->error;
        bio->bi_private = end_io_wq->private;
        bio->bi_end_io = end_io_wq->end_io;
        kmem_cache_free(btrfs_end_io_wq_cache, end_io_wq);
-       bio_endio(bio, error);
+       bio_endio(bio);
 }
 
 static int cleaner_kthread(void *arg)
@@ -2608,7 +2614,6 @@ int open_ctree(struct super_block *sb,
 
 
        mutex_init(&fs_info->ordered_operations_mutex);
-       mutex_init(&fs_info->ordered_extent_flush_mutex);
        mutex_init(&fs_info->tree_log_mutex);
        mutex_init(&fs_info->chunk_mutex);
        mutex_init(&fs_info->transaction_kthread_mutex);
@@ -2950,8 +2955,9 @@ retry_root_backup:
        if (fs_info->fs_devices->missing_devices >
             fs_info->num_tolerated_disk_barrier_failures &&
            !(sb->s_flags & MS_RDONLY)) {
-               printk(KERN_WARNING "BTRFS: "
-                       "too many missing devices, writeable mount is not allowed\n");
+               pr_warn("BTRFS: missing devices(%llu) exceeds the limit(%d), writeable mount is not allowed\n",
+                       fs_info->fs_devices->missing_devices,
+                       fs_info->num_tolerated_disk_barrier_failures);
                goto fail_sysfs;
        }
 
@@ -3324,10 +3330,8 @@ static int write_dev_supers(struct btrfs_device *device,
  * endio for the write_dev_flush, this will wake anyone waiting
  * for the barrier when it is done
  */
-static void btrfs_end_empty_barrier(struct bio *bio, int err)
+static void btrfs_end_empty_barrier(struct bio *bio)
 {
-       if (err)
-               clear_bit(BIO_UPTODATE, &bio->bi_flags);
        if (bio->bi_private)
                complete(bio->bi_private);
        bio_put(bio);
@@ -3355,8 +3359,8 @@ static int write_dev_flush(struct btrfs_device *device, int wait)
 
                wait_for_completion(&device->flush_wait);
 
-               if (!bio_flagged(bio, BIO_UPTODATE)) {
-                       ret = -EIO;
+               if (bio->bi_error) {
+                       ret = bio->bi_error;
                        btrfs_dev_stat_inc_and_print(device,
                                BTRFS_DEV_STAT_FLUSH_ERRS);
                }
@@ -3760,6 +3764,15 @@ void close_ctree(struct btrfs_root *root)
        cancel_work_sync(&fs_info->async_reclaim_work);
 
        if (!(fs_info->sb->s_flags & MS_RDONLY)) {
+               /*
+                * If the cleaner thread is stopped and there are
+                * block groups queued for removal, the deletion will be
+                * skipped when we quit the cleaner thread.
+                */
+               mutex_lock(&root->fs_info->cleaner_mutex);
+               btrfs_delete_unused_bgs(root->fs_info);
+               mutex_unlock(&root->fs_info->cleaner_mutex);
+
                ret = btrfs_commit_super(root);
                if (ret)
                        btrfs_err(fs_info, "commit super ret %d", ret);