]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge branch 'for-linus-4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/mason...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 5 Sep 2015 22:14:43 +0000 (15:14 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 5 Sep 2015 22:14:43 +0000 (15:14 -0700)
Pull btrfs updates from Chris Mason:
 "This has Jeff Mahoney's long standing trim patch that fixes corners
  where trims were missing.  Omar has some raid5/6 fixes, especially for
  using scrub and device replace when devices are missing.

  Zhao Lie continues cleaning and fixing things, this series fixes some
  really hard to hit corners in xfstests.  I had to pull it last merge
  window due to some deadlocks, but those are now resolved.

  I added support for Tejun's new blkio controllers.  It seems to work
  well for single devices, we'll expand to multi-device as well"

* 'for-linus-4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: (47 commits)
  btrfs: fix compile when block cgroups are not enabled
  Btrfs: fix file read corruption after extent cloning and fsync
  Btrfs: check if previous transaction aborted to avoid fs corruption
  btrfs: use __GFP_NOFAIL in alloc_btrfs_bio
  btrfs: Prevent from early transaction abort
  btrfs: Remove unused arguments in tree-log.c
  btrfs: Remove useless condition in start_log_trans()
  Btrfs: add support for blkio controllers
  Btrfs: remove unused mutex from struct 'btrfs_fs_info'
  Btrfs: fix parity scrub of RAID 5/6 with missing device
  Btrfs: fix device replace of a missing RAID 5/6 device
  Btrfs: add RAID 5/6 BTRFS_RBIO_REBUILD_MISSING operation
  Btrfs: count devices correctly in readahead during RAID 5/6 replace
  Btrfs: remove misleading handling of missing device scrub
  btrfs: fix clone / extent-same deadlocks
  Btrfs: fix defrag to merge tail file extent
  Btrfs: fix warning in backref walking
  btrfs: Add WARN_ON() for double lock in btrfs_tree_lock()
  btrfs: Remove root argument in extent_data_ref_count()
  btrfs: Fix wrong comment of btrfs_alloc_tree_block()
  ...

1  2 
fs/btrfs/disk-io.c
fs/btrfs/extent_io.c
fs/btrfs/inode.c
fs/btrfs/raid56.c
fs/btrfs/scrub.c
fs/btrfs/super.c
fs/btrfs/volumes.c

Simple merge
Simple merge
index f924d9a6270075d785ebbd41b617ffc219fa0493,bda3c41dc9d5afa5912f35f2ec5543e81fdabde6..237da012f7d09e3ac0e4c4aabef8224a5d5a06f1
  static struct bio *btrfs_dio_bio_alloc(struct block_device *bdev,
                                       u64 first_sector, gfp_t gfp_flags)
  {
-       return btrfs_bio_alloc(bdev, first_sector, BIO_MAX_PAGES, gfp_flags);
 -      int nr_vecs = bio_get_nr_vecs(bdev);
+       struct bio *bio;
 -      bio = btrfs_bio_alloc(bdev, first_sector, nr_vecs, gfp_flags);
++      bio = btrfs_bio_alloc(bdev, first_sector, BIO_MAX_PAGES, gfp_flags);
+       if (bio)
+               bio_associate_current(bio);
+       return bio;
  }
  
  static inline int btrfs_lookup_and_bind_dio_csum(struct btrfs_root *root,
index 0a02e24900aa149469a84acaf6ee8a5db8bd0848,6fe2613ef288dcc746ce9ce1e557c1f54aa9ddda..fcf7265ca46fd84a65b647619f4e07ba996d7a9f
@@@ -1960,7 -1975,9 +1971,9 @@@ cleanup_io
                else
                        clear_bit(RBIO_CACHE_READY_BIT, &rbio->flags);
  
 -              rbio_orig_end_io(rbio, err, err == 0);
++              rbio_orig_end_io(rbio, err);
+       } else if (rbio->operation == BTRFS_RBIO_REBUILD_MISSING) {
 -              rbio_orig_end_io(rbio, err, err == 0);
 +              rbio_orig_end_io(rbio, err);
        } else if (err == 0) {
                rbio->faila = -1;
                rbio->failb = -1;
@@@ -2096,8 -2114,9 +2109,9 @@@ out
        return 0;
  
  cleanup:
-       if (rbio->operation == BTRFS_RBIO_READ_REBUILD)
+       if (rbio->operation == BTRFS_RBIO_READ_REBUILD ||
+           rbio->operation == BTRFS_RBIO_REBUILD_MISSING)
 -              rbio_orig_end_io(rbio, -EIO, 0);
 +              rbio_orig_end_io(rbio, -EIO);
        return -EIO;
  }
  
index 9c146d8307b51266c643be0e3fdab7f6a45a765a,c69c75e7b841e167b83c3992b42ef207d0f10bc5..9a11db0c47ee7bc1b51d8f79226a9a25f7a3b8eb
@@@ -2165,6 -2174,134 +2161,134 @@@ again
        return 0;
  }
  
 -static void scrub_missing_raid56_end_io(struct bio *bio, int error)
++static void scrub_missing_raid56_end_io(struct bio *bio)
+ {
+       struct scrub_block *sblock = bio->bi_private;
+       struct btrfs_fs_info *fs_info = sblock->sctx->dev_root->fs_info;
 -      if (error)
++      if (bio->bi_error)
+               sblock->no_io_error_seen = 0;
+       btrfs_queue_work(fs_info->scrub_workers, &sblock->work);
+ }
+ static void scrub_missing_raid56_worker(struct btrfs_work *work)
+ {
+       struct scrub_block *sblock = container_of(work, struct scrub_block, work);
+       struct scrub_ctx *sctx = sblock->sctx;
+       struct btrfs_fs_info *fs_info = sctx->dev_root->fs_info;
+       unsigned int is_metadata;
+       unsigned int have_csum;
+       u8 *csum;
+       u64 generation;
+       u64 logical;
+       struct btrfs_device *dev;
+       is_metadata = !(sblock->pagev[0]->flags & BTRFS_EXTENT_FLAG_DATA);
+       have_csum = sblock->pagev[0]->have_csum;
+       csum = sblock->pagev[0]->csum;
+       generation = sblock->pagev[0]->generation;
+       logical = sblock->pagev[0]->logical;
+       dev = sblock->pagev[0]->dev;
+       if (sblock->no_io_error_seen) {
+               scrub_recheck_block_checksum(fs_info, sblock, is_metadata,
+                                            have_csum, csum, generation,
+                                            sctx->csum_size);
+       }
+       if (!sblock->no_io_error_seen) {
+               spin_lock(&sctx->stat_lock);
+               sctx->stat.read_errors++;
+               spin_unlock(&sctx->stat_lock);
+               printk_ratelimited_in_rcu(KERN_ERR
+                       "BTRFS: I/O error rebulding logical %llu for dev %s\n",
+                       logical, rcu_str_deref(dev->name));
+       } else if (sblock->header_error || sblock->checksum_error) {
+               spin_lock(&sctx->stat_lock);
+               sctx->stat.uncorrectable_errors++;
+               spin_unlock(&sctx->stat_lock);
+               printk_ratelimited_in_rcu(KERN_ERR
+                       "BTRFS: failed to rebuild valid logical %llu for dev %s\n",
+                       logical, rcu_str_deref(dev->name));
+       } else {
+               scrub_write_block_to_dev_replace(sblock);
+       }
+       scrub_block_put(sblock);
+       if (sctx->is_dev_replace &&
+           atomic_read(&sctx->wr_ctx.flush_all_writes)) {
+               mutex_lock(&sctx->wr_ctx.wr_lock);
+               scrub_wr_submit(sctx);
+               mutex_unlock(&sctx->wr_ctx.wr_lock);
+       }
+       scrub_pending_bio_dec(sctx);
+ }
+ static void scrub_missing_raid56_pages(struct scrub_block *sblock)
+ {
+       struct scrub_ctx *sctx = sblock->sctx;
+       struct btrfs_fs_info *fs_info = sctx->dev_root->fs_info;
+       u64 length = sblock->page_count * PAGE_SIZE;
+       u64 logical = sblock->pagev[0]->logical;
+       struct btrfs_bio *bbio;
+       struct bio *bio;
+       struct btrfs_raid_bio *rbio;
+       int ret;
+       int i;
+       ret = btrfs_map_sblock(fs_info, REQ_GET_READ_MIRRORS, logical, &length,
+                              &bbio, 0, 1);
+       if (ret || !bbio || !bbio->raid_map)
+               goto bbio_out;
+       if (WARN_ON(!sctx->is_dev_replace ||
+                   !(bbio->map_type & BTRFS_BLOCK_GROUP_RAID56_MASK))) {
+               /*
+                * We shouldn't be scrubbing a missing device. Even for dev
+                * replace, we should only get here for RAID 5/6. We either
+                * managed to mount something with no mirrors remaining or
+                * there's a bug in scrub_remap_extent()/btrfs_map_block().
+                */
+               goto bbio_out;
+       }
+       bio = btrfs_io_bio_alloc(GFP_NOFS, 0);
+       if (!bio)
+               goto bbio_out;
+       bio->bi_iter.bi_sector = logical >> 9;
+       bio->bi_private = sblock;
+       bio->bi_end_io = scrub_missing_raid56_end_io;
+       rbio = raid56_alloc_missing_rbio(sctx->dev_root, bio, bbio, length);
+       if (!rbio)
+               goto rbio_out;
+       for (i = 0; i < sblock->page_count; i++) {
+               struct scrub_page *spage = sblock->pagev[i];
+               raid56_add_scrub_pages(rbio, spage->page, spage->logical);
+       }
+       btrfs_init_work(&sblock->work, btrfs_scrub_helper,
+                       scrub_missing_raid56_worker, NULL, NULL);
+       scrub_block_get(sblock);
+       scrub_pending_bio_inc(sctx);
+       raid56_submit_missing_rbio(rbio);
+       return;
+ rbio_out:
+       bio_put(bio);
+ bbio_out:
+       btrfs_put_bbio(bbio);
+       spin_lock(&sctx->stat_lock);
+       sctx->stat.malloc_errors++;
+       spin_unlock(&sctx->stat_lock);
+ }
  static int scrub_pages(struct scrub_ctx *sctx, u64 logical, u64 len,
                       u64 physical, struct btrfs_device *dev, u64 flags,
                       u64 gen, int mirror_num, u8 *csum, int force,
Simple merge
Simple merge