[PATCH 2/2] fs: support direct IO in a multi-device FS

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

 



From: Qiuyang Sun <sunqiuyang@xxxxxxxxxx>

Don't use the bdev pointer in struct buffer_head for dio_bio_alloc(),
since it may have been changed to another device in the FS in
get_more_blocks().

Signed-off-by: Qiuyang Sun <sunqiuyang@xxxxxxxxxx>
---
 fs/direct-io.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/fs/direct-io.c b/fs/direct-io.c
index 722d17c..6cd6029 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -99,6 +99,7 @@ struct dio_submit {
 	unsigned cur_page_offset;	/* Offset into it, in bytes */
 	unsigned cur_page_len;		/* Nr of bytes at cur_page_offset */
 	sector_t cur_page_block;	/* Where it starts */
+	struct block_device *cur_page_dev;
 	loff_t cur_page_fs_offset;	/* Offset in file */
 
 	struct iov_iter *iter;
@@ -729,7 +730,7 @@ static int get_more_blocks(struct dio *dio, struct dio_submit *sdio,
  * There is no bio.  Make one now.
  */
 static inline int dio_new_bio(struct dio *dio, struct dio_submit *sdio,
-		sector_t start_sector, struct buffer_head *map_bh)
+		sector_t start_sector)
 {
 	sector_t sector;
 	int ret, nr_pages;
@@ -740,7 +741,7 @@ static inline int dio_new_bio(struct dio *dio, struct dio_submit *sdio,
 	sector = start_sector << (sdio->blkbits - 9);
 	nr_pages = min(sdio->pages_in_io, BIO_MAX_PAGES);
 	BUG_ON(nr_pages <= 0);
-	dio_bio_alloc(dio, sdio, map_bh->b_bdev, sector, nr_pages);
+	dio_bio_alloc(dio, sdio, sdio->cur_page_dev, sector, nr_pages);
 	sdio->boundary = 0;
 out:
 	return ret;
@@ -785,8 +786,7 @@ static inline int dio_bio_add_page(struct dio_submit *sdio)
  * The caller of this function is responsible for removing cur_page from the
  * dio, and for dropping the refcount which came from that presence.
  */
-static inline int dio_send_cur_page(struct dio *dio, struct dio_submit *sdio,
-		struct buffer_head *map_bh)
+static inline int dio_send_cur_page(struct dio *dio, struct dio_submit *sdio)
 {
 	int ret = 0;
 
@@ -815,14 +815,14 @@ static inline int dio_send_cur_page(struct dio *dio, struct dio_submit *sdio,
 	}
 
 	if (sdio->bio == NULL) {
-		ret = dio_new_bio(dio, sdio, sdio->cur_page_block, map_bh);
+		ret = dio_new_bio(dio, sdio, sdio->cur_page_block);
 		if (ret)
 			goto out;
 	}
 
 	if (dio_bio_add_page(sdio) != 0) {
 		dio_bio_submit(dio, sdio);
-		ret = dio_new_bio(dio, sdio, sdio->cur_page_block, map_bh);
+		ret = dio_new_bio(dio, sdio, sdio->cur_page_block);
 		if (ret == 0) {
 			ret = dio_bio_add_page(sdio);
 			BUG_ON(ret != 0);
@@ -878,7 +878,7 @@ static inline int dio_send_cur_page(struct dio *dio, struct dio_submit *sdio,
 	 * If there's a deferred page already there then send it.
 	 */
 	if (sdio->cur_page) {
-		ret = dio_send_cur_page(dio, sdio, map_bh);
+		ret = dio_send_cur_page(dio, sdio);
 		put_page(sdio->cur_page);
 		sdio->cur_page = NULL;
 		if (ret)
@@ -890,6 +890,7 @@ static inline int dio_send_cur_page(struct dio *dio, struct dio_submit *sdio,
 	sdio->cur_page_offset = offset;
 	sdio->cur_page_len = len;
 	sdio->cur_page_block = blocknr;
+	sdio->cur_page_dev = map_bh->b_bdev;
 	sdio->cur_page_fs_offset = sdio->block_in_file << sdio->blkbits;
 out:
 	/*
@@ -897,7 +898,7 @@ static inline int dio_send_cur_page(struct dio *dio, struct dio_submit *sdio,
 	 * avoid metadata seeks.
 	 */
 	if (sdio->boundary) {
-		ret = dio_send_cur_page(dio, sdio, map_bh);
+		ret = dio_send_cur_page(dio, sdio);
 		if (sdio->bio)
 			dio_bio_submit(dio, sdio);
 		put_page(sdio->cur_page);
@@ -1348,7 +1349,7 @@ static inline int drop_refcount(struct dio *dio)
 	if (sdio.cur_page) {
 		ssize_t ret2;
 
-		ret2 = dio_send_cur_page(dio, &sdio, &map_bh);
+		ret2 = dio_send_cur_page(dio, &sdio);
 		if (retval == 0)
 			retval = ret2;
 		put_page(sdio.cur_page);
-- 
1.8.3.1




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

  Powered by Linux