From: Kiyoshi Ueda <[email-masked]>

Add gfp_mask parameter to bio_integrity_clone().

Stricter gfp_mask might be required for clone allocation.
For example, request-based dm may clone bio in interrupt context
so it has to use GFP_ATOMIC.

Signed-off-by: Kiyoshi Ueda <[email-masked]>
Signed-off-by: Jun'ichi Nomura <[email-masked]>
Cc: Martin K. Petersen <[email-masked]>
Cc: Jens Axboe <[email-masked]>
Cc: Alasdair G Kergon <[email-masked]>

[This patch to go upstream via Jens]

---
 fs/bio-integrity.c  |    5 +++--
 fs/bio.c            |    2 +-
 include/linux/bio.h |    4 ++--
 3 files changed, 6 insertions(+), 5 deletions(-)

Index: linux-2.6.29-rc7/fs/bio-integrity.c
===================================================================
--- linux-2.6.29-rc7.orig/fs/bio-integrity.c	2009-02-25 13:42:16.000000000 +0000
+++ linux-2.6.29-rc7/fs/bio-integrity.c	2009-03-05 12:10:18.000000000 +0000
@@ -685,19 +685,20 @@ EXPORT_SYMBOL(bio_integrity_split);
  * bio_integrity_clone - Callback for cloning bios with integrity metadata
  * @bio:	New bio
  * @bio_src:	Original bio
+ * @gfp_mask:	Memory allocation mask
  * @bs:		bio_set to allocate bip from
  *
  * Description:	Called to allocate a bip when cloning a bio
  */
 int bio_integrity_clone(struct bio *bio, struct bio *bio_src,
-			struct bio_set *bs)
+			gfp_t gfp_mask, struct bio_set *bs)
 {
 	struct bio_integrity_payload *bip_src = bio_src->bi_integrity;
 	struct bio_integrity_payload *bip;
 
 	BUG_ON(bip_src == NULL);
 
-	bip = bio_integrity_alloc_bioset(bio, GFP_NOIO, bip_src->bip_vcnt, bs);
+	bip = bio_integrity_alloc_bioset(bio, gfp_mask, bip_src->bip_vcnt, bs);
 
 	if (bip == NULL)
 		return -EIO;
Index: linux-2.6.29-rc7/fs/bio.c
===================================================================
--- linux-2.6.29-rc7.orig/fs/bio.c	2009-03-05 12:07:21.000000000 +0000
+++ linux-2.6.29-rc7/fs/bio.c	2009-03-05 12:10:18.000000000 +0000
@@ -463,7 +463,7 @@ struct bio *bio_clone(struct bio *bio, g
 	if (bio_integrity(bio)) {
 		int ret;
 
-		ret = bio_integrity_clone(b, bio, fs_bio_set);
+		ret = bio_integrity_clone(b, bio, gfp_mask, fs_bio_set);
 
 		if (ret < 0)
 			return NULL;
Index: linux-2.6.29-rc7/include/linux/bio.h
===================================================================
--- linux-2.6.29-rc7.orig/include/linux/bio.h	2009-02-25 13:42:16.000000000 +0000
+++ linux-2.6.29-rc7/include/linux/bio.h	2009-03-05 12:10:18.000000000 +0000
@@ -531,7 +531,7 @@ extern void bio_integrity_endio(struct b
 extern void bio_integrity_advance(struct bio *, unsigned int);
 extern void bio_integrity_trim(struct bio *, unsigned int, unsigned int);
 extern void bio_integrity_split(struct bio *, struct bio_pair *, int);
-extern int bio_integrity_clone(struct bio *, struct bio *, struct bio_set *);
+extern int bio_integrity_clone(struct bio *, struct bio *, gfp_t, struct bio_set *);
 extern int bioset_integrity_create(struct bio_set *, int);
 extern void bioset_integrity_free(struct bio_set *);
 extern void bio_integrity_init_slab(void);
@@ -542,7 +542,7 @@ extern void bio_integrity_init_slab(void
 #define bioset_integrity_create(a, b)	(0)
 #define bio_integrity_prep(a)		(0)
 #define bio_integrity_enabled(a)	(0)
-#define bio_integrity_clone(a, b, c)	(0)
+#define bio_integrity_clone(a, b, c, d)	(0)
 #define bioset_integrity_free(a)	do { } while (0)
 #define bio_integrity_free(a, b)	do { } while (0)
 #define bio_integrity_endio(a, b)	do { } while (0)