diff --git a/block/blk-core.c b/block/blk-core.c
index 1f61b74..274e05d 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1309,6 +1309,7 @@ void init_request_from_bio(struct request *req, struct bio *bio)
 	req->errors = 0;
 	req->__sector = bio->bi_sector;
 	req->ioprio = bio_prio(bio);
+	req->context = bio->bi_context;
 	blk_rq_bio_prep(req->q, req, bio);
 }
 
diff --git a/block/blk-merge.c b/block/blk-merge.c
index 160035f..ed70d56 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -497,6 +497,9 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
 	if (bio_integrity(bio) != blk_integrity_rq(rq))
 		return false;
 
+	if (bio->bi_context != rq->bio->bi_context)
+		return false;
+
 	return true;
 }
 
diff --git a/fs/mpage.c b/fs/mpage.c
index 0face1c..4889842 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -293,6 +293,12 @@ alloc_new:
 			goto confused;
 	}
 
+	if (page && page->mapping && page->mapping->a_ops &&
+		page->mapping->a_ops->get_context)
+		bio->bi_context = page->mapping->a_ops->get_context(page);
+	else
+		bio->bi_context = 0;
+
 	length = first_hole << blkbits;
 	if (bio_add_page(bio, page, length, 0) < length) {
 		bio = mpage_bio_submit(READ, bio);
@@ -581,6 +587,12 @@ alloc_new:
 			goto confused;
 	}
 
+	if (page && page->mapping && page->mapping->a_ops &&
+		page->mapping->a_ops->get_context)
+		bio->bi_context = page->mapping->a_ops->get_context(page);
+	else
+		bio->bi_context = 0;
+
 	/*
 	 * Must try to add the page before marking the buffer clean or
 	 * the confused fail path above (OOM) will be very confused when
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 4053cbd..f3ac448 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -42,6 +42,7 @@ struct bio {
 
 	unsigned short		bi_vcnt;	/* how many bio_vec's */
 	unsigned short		bi_idx;		/* current index into bvl_vec */
+	unsigned long		bi_context;	/* context of this bio */
 
 	/* Number of segments in this BIO after
 	 * physical address coalescing is performed.
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 2aa2466..0dd9a08 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -167,6 +167,7 @@ struct request {
 	struct list_head timeout_list;
 	unsigned int timeout;
 	int retries;
+	unsigned long context;	/* context of this request */
 
 	/*
 	 * completion callback.
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 13bba17..0776564 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -72,6 +72,8 @@ struct buffer_head {
 	struct list_head b_assoc_buffers; /* associated with another mapping */
 	struct address_space *b_assoc_map;	/* mapping this buffer is
 						   associated with */
+	unsigned long	b_context; /* context for this buffer within the
+							storage device */
 	atomic_t b_count;		/* users using this buffer_head */
 };
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 8de6755..4b379d8 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -626,6 +626,7 @@ struct address_space_operations {
 	int (*is_partially_uptodate) (struct page *, read_descriptor_t *,
 					unsigned long);
 	int (*error_remove_page)(struct address_space *, struct page *);
+	int (*get_context)(struct page *);
 };
 
 extern const struct address_space_operations empty_aops;
