[PATCH 6/6] pnfs-block: mark IO error with NFS_LAYOUT_{RW|RO}_FAILED

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

 



From: Peng Tao <bergwolf@xxxxxxxxx>

Signed-off-by: Peng Tao <peng_tao@xxxxxxx>
---
 fs/nfs/blocklayout/blocklayout.c |   90 ++++++++++++++-----------------------
 fs/nfs/blocklayout/blocklayout.h |    5 --
 2 files changed, 34 insertions(+), 61 deletions(-)

diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c
index 804eee6..65daed9 100644
--- a/fs/nfs/blocklayout/blocklayout.c
+++ b/fs/nfs/blocklayout/blocklayout.c
@@ -143,35 +143,40 @@ static struct bio *bl_submit_bio(int rw, struct bio *bio)
 	return NULL;
 }
 
-static inline void bl_done_with_rpage(struct page *page, const int ok)
+static void bl_set_lo_fail(struct pnfs_layout_segment *lseg)
 {
-	if (ok) {
-		ClearPagePnfsErr(page);
-		SetPageUptodate(page);
+	if (lseg->pls_range.iomode == IOMODE_RW) {
+		dprintk("%s Setting layout IOMODE_RW fail bit\n", __func__);
+		set_bit(lo_fail_bit(IOMODE_RW), &lseg->pls_layout->plh_flags);
 	} else {
-		ClearPageUptodate(page);
-		SetPageError(page);
-		SetPagePnfsErr(page);
+		dprintk("%s Setting layout IOMODE_READ fail bit\n", __func__);
+		set_bit(lo_fail_bit(IOMODE_READ), &lseg->pls_layout->plh_flags);
 	}
-	/* Page is unlocked via rpc_release.  Should really be done here. */
 }
 
 /* This is basically copied from mpage_end_io_read */
 static void bl_end_io_read(struct bio *bio, int err)
 {
-	void *data = bio->bi_private;
+	struct parallel_io *par = bio->bi_private;
 	const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
 	struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
+	struct nfs_read_data *rdata = (struct nfs_read_data *)par->data;
 
 	do {
 		struct page *page = bvec->bv_page;
 
 		if (--bvec >= bio->bi_io_vec)
 			prefetchw(&bvec->bv_page->flags);
-		bl_done_with_rpage(page, uptodate);
+		if (uptodate)
+			SetPageUptodate(page);
 	} while (bvec >= bio->bi_io_vec);
+	if (!uptodate) {
+		if (!rdata->pnfs_error)
+			rdata->pnfs_error = -EIO;
+		bl_set_lo_fail(rdata->lseg);
+	}
 	bio_put(bio);
-	put_parallel(data);
+	put_parallel(par);
 }
 
 static void bl_read_cleanup(struct work_struct *work)
@@ -219,13 +224,7 @@ static enum pnfs_try_status bl_read_pagelist(struct nfs_read_data *rdata)
 		dprintk("%s dont_like_caller failed\n", __func__);
 		goto use_mds;
 	}
-	if ((rdata->npages == 1) && PagePnfsErr(rdata->req->wb_page)) {
-		/* We want to fall back to mds in case of read_page
-		 * after error on read_pages.
-		 */
-		dprintk("%s PG_pnfserr set\n", __func__);
-		goto use_mds;
-	}
+
 	par = alloc_parallel(rdata);
 	if (!par)
 		goto use_mds;
@@ -246,9 +245,8 @@ static enum pnfs_try_status bl_read_pagelist(struct nfs_read_data *rdata)
 			be = find_get_extent(BLK_LSEG2EXT(rdata->lseg),
 					     isect, &cow_read);
 			if (!be) {
-				/* Error out this page */
-				bl_done_with_rpage(pages[i], 0);
-				break;
+				rdata->pnfs_error = -EIO;
+				goto out;
 			}
 			extent_length = be->be_length -
 			    (isect - be->be_f_offset);
@@ -263,10 +261,9 @@ static enum pnfs_try_status bl_read_pagelist(struct nfs_read_data *rdata)
 			bio = bl_submit_bio(READ, bio);
 			/* Fill hole w/ zeroes w/o accessing device */
 			dprintk("%s Zeroing page for hole\n", __func__);
-			zero_user(pages[i], 0,
-				  min_t(int, PAGE_CACHE_SIZE, count));
+			zero_user_segment(pages[i], 0, PAGE_CACHE_SIZE);
 			print_page(pages[i]);
-			bl_done_with_rpage(pages[i], 1);
+			SetPageUptodate(pages[i]);
 		} else {
 			struct pnfs_block_extent *be_read;
 
@@ -277,9 +274,8 @@ static enum pnfs_try_status bl_read_pagelist(struct nfs_read_data *rdata)
 					    bio_alloc(GFP_NOIO,
 						      rdata->npages - i);
 					if (!bio) {
-						/* Error out this page */
-						bl_done_with_rpage(pages[i], 0);
-						break;
+						rdata->pnfs_error = -ENOMEM;
+						goto out;
 					}
 					bio->bi_sector = isect -
 					    be_read->be_f_offset +
@@ -302,6 +298,7 @@ static enum pnfs_try_status bl_read_pagelist(struct nfs_read_data *rdata)
 	} else {
 		rdata->res.count = (isect << 9) - f_offset;
 	}
+out:
 	put_extent(be);
 	put_extent(cow_read);
 	bl_submit_bio(READ, bio);
@@ -337,22 +334,6 @@ static void mark_extents_written(struct pnfs_block_layout *bl,
 	}
 }
 
-static inline void bl_done_with_wpage(struct page *page, const int ok)
-{
-	if (!ok) {
-		SetPageError(page);
-		SetPagePnfsErr(page);
-		/* This is an inline copy of nfs_zap_mapping */
-		/* This is oh so fishy, and needs deep thought */
-		if (page->mapping->nrpages != 0) {
-			struct inode *inode = page->mapping->host;
-			spin_lock(&inode->i_lock);
-			NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA;
-			spin_unlock(&inode->i_lock);
-		}
-	}
-}
-
 static void bl_end_io_write_zero(struct bio *bio, int err)
 {
 	struct parallel_io *par = bio->bi_private;
@@ -365,13 +346,15 @@ static void bl_end_io_write_zero(struct bio *bio, int err)
 
 		if (--bvec >= bio->bi_io_vec)
 			prefetchw(&bvec->bv_page->flags);
-		bl_done_with_wpage(page, uptodate);
 		/* This is the zeroing page we added */
 		end_page_writeback(page);
 		page_cache_release(page);
 	} while (bvec >= bio->bi_io_vec);
-	if (!uptodate && !wdata->pnfs_error)
-		wdata->pnfs_error = -EIO;
+	if (!uptodate) {
+		if (!wdata->pnfs_error)
+			wdata->pnfs_error = -EIO;
+		bl_set_lo_fail(wdata->lseg);
+	}
 	bio_put(bio);
 	put_parallel(par);
 }
@@ -380,18 +363,13 @@ static void bl_end_io_write(struct bio *bio, int err)
 {
 	struct parallel_io *par = bio->bi_private;
 	const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
-	struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
 	struct nfs_write_data *wdata = (struct nfs_write_data *)par->data;
 
-	do {
-		struct page *page = bvec->bv_page;
-
-		if (--bvec >= bio->bi_io_vec)
-			prefetchw(&bvec->bv_page->flags);
-		bl_done_with_wpage(page, uptodate);
-	} while (bvec >= bio->bi_io_vec);
-	if (!uptodate && !wdata->pnfs_error)
-		wdata->pnfs_error = -EIO;
+	if (!uptodate) {
+		if (!wdata->pnfs_error)
+			wdata->pnfs_error = -EIO;
+		bl_set_lo_fail(wdata->lseg);
+	}
 	bio_put(bio);
 	put_parallel(par);
 }
diff --git a/fs/nfs/blocklayout/blocklayout.h b/fs/nfs/blocklayout/blocklayout.h
index d923acc..e2b2a50 100644
--- a/fs/nfs/blocklayout/blocklayout.h
+++ b/fs/nfs/blocklayout/blocklayout.h
@@ -37,11 +37,6 @@
 
 #define PAGE_CACHE_SECTORS (PAGE_CACHE_SIZE >> 9)
 
-#define PG_pnfserr PG_owner_priv_1
-#define PagePnfsErr(page)	test_bit(PG_pnfserr, &(page)->flags)
-#define SetPagePnfsErr(page)	set_bit(PG_pnfserr, &(page)->flags)
-#define ClearPagePnfsErr(page)	clear_bit(PG_pnfserr, &(page)->flags)
-
 struct block_mount_id {
 	spinlock_t			bm_lock;    /* protects list */
 	struct list_head		bm_devlist; /* holds pnfs_block_dev */
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux