[PATCH 29/40] btrfs: do not allocate a btrfs_bio for low-level bios

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The bios submitted from btrfs_map_bio don't interact with the rest
of btrfs.  The only btrfs_bio field is the device.  Add a bbio
backpointer pointer to struct btrfs_bio_stripe so that the private
data can point to the stripe and just use a normal bio allocation
for them.

Signed-off-by: Christoph Hellwig <hch@xxxxxx>
---
 fs/btrfs/extent_io.c | 13 -------------
 fs/btrfs/extent_io.h |  1 -
 fs/btrfs/volumes.c   | 21 +++++++++++----------
 fs/btrfs/volumes.h   |  5 ++++-
 4 files changed, 15 insertions(+), 25 deletions(-)

diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 116a65787e314..bfd91ed27bd14 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -3149,19 +3149,6 @@ struct bio *btrfs_bio_alloc(struct inode *inode, unsigned int nr_iovecs,
 	return bio;
 }
 
-struct bio *btrfs_bio_clone(struct block_device *bdev, struct bio *bio)
-{
-	struct btrfs_bio *bbio;
-	struct bio *new;
-
-	/* Bio allocation backed by a bioset does not fail */
-	new = bio_alloc_clone(bdev, bio, GFP_NOFS, &btrfs_bioset);
-	bbio = btrfs_bio(new);
-	btrfs_bio_init(btrfs_bio(new), btrfs_bio(bio)->inode);
-	bbio->iter = bio->bi_iter;
-	return new;
-}
-
 struct bio *btrfs_bio_clone_partial(struct inode *inode, struct bio *orig,
 		u64 offset, u64 size)
 {
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index d5f3d9692ea29..3f0cb1ef5fdff 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -279,7 +279,6 @@ void extent_clear_unlock_delalloc(struct btrfs_inode *inode, u64 start, u64 end,
 				  u32 bits_to_clear, unsigned long page_ops);
 struct bio *btrfs_bio_alloc(struct inode *inode, unsigned int nr_iovecs,
 		unsigned int opf);
-struct bio *btrfs_bio_clone(struct block_device *bdev, struct bio *bio);
 struct bio *btrfs_bio_clone_partial(struct inode *inode, struct bio *orig,
 		u64 offset, u64 size);
 
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index cec3f6b9f5c21..7392b9f2a3323 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -6749,23 +6749,21 @@ static void btrfs_end_bbio(struct btrfs_bio *bbio, bool async)
 
 static void btrfs_end_bio(struct bio *bio)
 {
-	struct btrfs_bio *bbio = bio->bi_private;
+	struct btrfs_bio_stripe *stripe = bio->bi_private;
+	struct btrfs_bio *bbio = stripe->bbio;
 
 	if (bio->bi_status) {
 		atomic_inc(&bbio->error);
 		if (bio->bi_status == BLK_STS_IOERR ||
 		    bio->bi_status == BLK_STS_TARGET) {
-			struct btrfs_device *dev = btrfs_bio(bio)->device;
-
-			ASSERT(dev->bdev);
 			if (btrfs_op(bio) == BTRFS_MAP_WRITE)
-				btrfs_dev_stat_inc_and_print(dev,
+				btrfs_dev_stat_inc_and_print(stripe->dev,
 						BTRFS_DEV_STAT_WRITE_ERRS);
 			else if (!(bio->bi_opf & REQ_RAHEAD))
-				btrfs_dev_stat_inc_and_print(dev,
+				btrfs_dev_stat_inc_and_print(stripe->dev,
 						BTRFS_DEV_STAT_READ_ERRS);
 			if (bio->bi_opf & REQ_PREFLUSH)
-				btrfs_dev_stat_inc_and_print(dev,
+				btrfs_dev_stat_inc_and_print(stripe->dev,
 						BTRFS_DEV_STAT_FLUSH_ERRS);
 		}
 	}
@@ -6796,14 +6794,17 @@ static void submit_stripe_bio(struct btrfs_bio *bbio, int dev_nr, bool clone)
 	}
 
 	if (clone) {
-		bio = btrfs_bio_clone(dev->bdev, &bbio->bio);
+		bio = bio_alloc_clone(dev->bdev, &bbio->bio, GFP_NOFS,
+				      &fs_bio_set);
 	} else {
 		bio = &bbio->bio;
 		bio_set_dev(bio, dev->bdev);
+		btrfs_bio(bio)->device = dev;
 	}
 
-	bio->bi_private = bbio;
-	btrfs_bio(bio)->device = dev;
+	bbio->stripes[dev_nr].bbio = bbio;
+	bio->bi_private = &bbio->stripes[dev_nr];
+
 	bio->bi_end_io = btrfs_end_bio;
 	bio->bi_iter.bi_sector = physical >> 9;
 	/*
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index cd71cd33a9df2..5b0e7602434b0 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -325,7 +325,10 @@ enum btrfs_endio_type {
 
 struct btrfs_bio_stripe {
 	struct btrfs_device *dev;
-	u64 physical;
+	union {
+		u64 physical;			/* block mapping */
+		struct btrfs_bio *bbio;		/* for end I/O */
+	};
 };
 
 /*
-- 
2.30.2




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux