[Devel] [PATCH rh7 06/38] ploop: report holes in pio_direct (v2)

Andrey Smetanin asmetanin at virtuozzo.com
Fri May 15 09:48:07 PDT 2015


We have not implemented the support of sparce files yet. Let's at least
print a message more descriptive than common:

[ 3460.838071] ploop_set_error=-22 on ploop44006

Changed in v2:
 - used ploop_msg_once for reporting partially uninitialized extent

https://jira.sw.ru/browse/PSBM-20770

Signed-off-by: Maxim Patlasov <MPatlasov at parallels.com>
Acked-by: Andrew Vagin <avagin at parallels.com>
---
 drivers/block/ploop/dev.c           | 13 +++++++++++++
 drivers/block/ploop/io_direct.c     | 18 +++++++++---------
 drivers/block/ploop/io_direct_map.c | 25 ++++++++++++++++---------
 drivers/block/ploop/io_direct_map.h |  4 ++--
 include/linux/ploop/ploop.h         |  4 ++++
 5 files changed, 44 insertions(+), 20 deletions(-)

diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c
index 8556af2..353fb35 100644
--- a/drivers/block/ploop/dev.c
+++ b/drivers/block/ploop/dev.c
@@ -92,7 +92,20 @@ void ploop_format_put(struct ploop_delta_ops * ops)
 	module_put(ops->owner);
 }
 
+void ploop_msg_once(struct ploop_device *plo, const char *fmt, ...)
+{
+	va_list args;
+
+	if (test_and_set_bit(PLOOP_S_ONCE, &plo->state))
+		return;
 
+	va_start(args, fmt);
+	printk("ploop(%d): ", plo->index);
+	vprintk(fmt, args);
+	printk("\n");
+	va_end(args);
+}
+EXPORT_SYMBOL(ploop_msg_once);
 
 static void mitigation_timeout(unsigned long data)
 {
diff --git a/drivers/block/ploop/io_direct.c b/drivers/block/ploop/io_direct.c
index a9910ba..17dbf6c 100644
--- a/drivers/block/ploop/io_direct.c
+++ b/drivers/block/ploop/io_direct.c
@@ -114,7 +114,7 @@ dio_submit(struct ploop_io *io, struct ploop_request * preq,
 	sec = sbl->head->bi_sector;
 	sec = ((sector_t)iblk << preq->plo->cluster_log) | (sec & ((1<<preq->plo->cluster_log) - 1));
 
-	em = extent_lookup_create(io->files.em_tree, sec, size);
+	em = extent_lookup_create(io, sec, size);
 	if (IS_ERR(em))
 		goto out_em_err;
 
@@ -127,7 +127,7 @@ dio_submit(struct ploop_io *io, struct ploop_request * preq,
 		extent_put(em);
 
 		while (sec < end) {
-			em = extent_lookup_create(io->files.em_tree, sec, end - sec);
+			em = extent_lookup_create(io, sec, end - sec);
 			if (IS_ERR(em))
 				goto out_em_err;
 			if (em->block_start != BLOCK_UNINIT)
@@ -171,7 +171,7 @@ dio_submit(struct ploop_io *io, struct ploop_request * preq,
 
 		if (sec >= em->end) {
 			extent_put(em);
-			em = extent_lookup_create(io->files.em_tree, sec, size);
+			em = extent_lookup_create(io, sec, size);
 			if (IS_ERR(em))
 				goto out_em_err;
 			if (write && em->block_start == BLOCK_UNINIT)
@@ -255,7 +255,7 @@ write_unint:
 write_unint_fail:
 	extent_put(em);
 	err = -EIO;
-	printk(KERN_ERR "A part of cluster is in uninitialized extent.\n");
+	ploop_msg_once(io->plo, "A part of cluster is in uninitialized extent.");
 	goto out;
 
 out_em_err:
@@ -547,7 +547,7 @@ dio_submit_pad(struct ploop_io *io, struct ploop_request * preq,
 
 		if (sec >= em->end) {
 			extent_put(em);
-			em = extent_lookup_create(io->files.em_tree, sec, end_sec - sec);
+			em = extent_lookup_create(io, sec, end_sec - sec);
 			if (IS_ERR(em))
 				goto out_em_err;
 		}
@@ -625,7 +625,7 @@ static struct extent_map * dio_fallocate(struct ploop_io *io, u32 iblk, int nr)
 {
 	struct extent_map * em;
 	mutex_lock(&io->files.inode->i_mutex);
-	em = map_extent_get_block(io->files.em_tree,
+	em = map_extent_get_block(io,
 				  io->files.mapping,
 				  (sector_t)iblk << io->plo->cluster_log,
 				  1 << io->plo->cluster_log,
@@ -1008,7 +1008,7 @@ dio_sync_io(struct ploop_io * io, int rw, struct page * page,
 		if (!em || sec >= em->end) {
 			if (em)
 				extent_put(em);
-			em = extent_lookup_create(io->files.em_tree, sec, len>>9);
+			em = extent_lookup_create(io, sec, len>>9);
 			if (IS_ERR(em))
 				goto out_em_err;
 		}
@@ -1129,7 +1129,7 @@ dio_sync_iovec(struct ploop_io * io, int rw, struct page ** pvec,
 		if (!em || sec >= em->end) {
 			if (em)
 				extent_put(em);
-			em = extent_lookup_create(io->files.em_tree, sec, len>>9);
+			em = extent_lookup_create(io, sec, len>>9);
 			if (IS_ERR(em))
 				goto out_em_err;
 		}
@@ -1359,7 +1359,7 @@ dio_io_page(struct ploop_io * io, unsigned long rw,
 		if (!em || sec >= em->end) {
 			if (em)
 				extent_put(em);
-			em = extent_lookup_create(io->files.em_tree, sec, len>>9);
+			em = extent_lookup_create(io, sec, len>>9);
 			if (IS_ERR(em))
 				goto out_em_err;
 		}
diff --git a/drivers/block/ploop/io_direct_map.c b/drivers/block/ploop/io_direct_map.c
index 2ddf93a..6b0886c 100644
--- a/drivers/block/ploop/io_direct_map.c
+++ b/drivers/block/ploop/io_direct_map.c
@@ -631,10 +631,11 @@ again:
 	return em;
 }
 
-static struct extent_map *__map_extent_bmap(struct extent_map_tree *tree,
+static struct extent_map *__map_extent_bmap(struct ploop_io *io,
 				       struct address_space *mapping,
 				       sector_t start, sector_t len, gfp_t gfp_mask)
 {
+	struct extent_map_tree *tree = io->files.em_tree;
 	struct inode *inode = mapping->host;
 	struct extent_map *em;
 	struct fiemap_extent_info fieinfo;
@@ -684,6 +685,8 @@ again:
 	}
 
 	if (fieinfo.fi_extents_mapped != 1) {
+		ploop_msg_once(io->plo, "a hole in image file detected (%d)",
+			       fieinfo.fi_extents_mapped);
 		extent_put(em);
 		return ERR_PTR(-EINVAL);
 	}
@@ -705,11 +708,13 @@ again:
 	return em;
 }
 
-static struct extent_map *__map_extent(struct extent_map_tree *tree,
+static struct extent_map *__map_extent(struct ploop_io *io,
 				       struct address_space *mapping,
 				       sector_t start, sector_t len, int create,
 				       gfp_t gfp_mask, get_block_t get_block)
 {
+	struct extent_map_tree *tree = io->files.em_tree;
+
 	if (tree->_get_extent)
 		return __map_extent_get_extent(tree, mapping, start, len, create,
 					       gfp_mask);
@@ -717,10 +722,10 @@ static struct extent_map *__map_extent(struct extent_map_tree *tree,
 		/* create flag not supported by bmap implementation */
 		return ERR_PTR(-EINVAL);
 
-	return __map_extent_bmap(tree, mapping, start,len, gfp_mask);
+	return __map_extent_bmap(io, mapping, start,len, gfp_mask);
 }
 
-struct extent_map *map_extent_get_block(struct extent_map_tree *tree,
+struct extent_map *map_extent_get_block(struct ploop_io *io,
 					struct address_space *mapping,
 					sector_t start, sector_t len, int create,
 					gfp_t gfp_mask, get_block_t get_block)
@@ -729,7 +734,7 @@ struct extent_map *map_extent_get_block(struct extent_map_tree *tree,
 	sector_t last;
 	sector_t map_ahead_len = 0;
 
-	em = __map_extent(tree, mapping, start, len, create,
+	em = __map_extent(io, mapping, start, len, create,
 			  gfp_mask, get_block);
 
 	/*
@@ -746,7 +751,7 @@ struct extent_map *map_extent_get_block(struct extent_map_tree *tree,
 	do {
 		last = em->end;
 		extent_put(em);
-		em = __map_extent(tree, mapping, last, len, create,
+		em = __map_extent(io, mapping, last, len, create,
 				  gfp_mask, get_block);
 		if (IS_ERR(em) || !em)
 			break;
@@ -759,17 +764,19 @@ struct extent_map *map_extent_get_block(struct extent_map_tree *tree,
 	    start + len > em->end) {
 		if (em && !IS_ERR(em))
 			extent_put(em);
-		em = __map_extent(tree, mapping, start, len, create,
+		em = __map_extent(io, mapping, start, len, create,
 				  gfp_mask, get_block);
 	}
 	return em;
 }
 
 
-struct extent_map *extent_lookup_create(struct extent_map_tree *tree,
+struct extent_map *extent_lookup_create(struct ploop_io *io,
 					sector_t start, sector_t len)
 {
-	return map_extent_get_block(tree, tree->mapping,
+	struct extent_map_tree *tree = io->files.em_tree;
+
+	return map_extent_get_block(io, tree->mapping,
 				    start, len, 0, mapping_gfp_mask(tree->mapping),
 				    NULL);
 }
diff --git a/drivers/block/ploop/io_direct_map.h b/drivers/block/ploop/io_direct_map.h
index 79e00e3..fa0face 100644
--- a/drivers/block/ploop/io_direct_map.h
+++ b/drivers/block/ploop/io_direct_map.h
@@ -38,13 +38,13 @@ static inline sector_t extent_map_block_end(struct extent_map *em)
 	return em->block_start + (em->end - em->start);
 }
 
-struct extent_map *extent_lookup_create(struct extent_map_tree *tree,
+struct extent_map *extent_lookup_create(struct ploop_io *io,
 					sector_t start, sector_t len);
 struct extent_map *extent_lookup(struct extent_map_tree *tree,
 				 sector_t start);
 void extent_put(struct extent_map *em);
 
-struct extent_map *map_extent_get_block(struct extent_map_tree *tree,
+struct extent_map *map_extent_get_block(struct ploop_io *io,
 					struct address_space *mapping,
 					sector_t start, sector_t len, int create,
 					gfp_t gfp_mask, get_block_t get_block);
diff --git a/include/linux/ploop/ploop.h b/include/linux/ploop/ploop.h
index 92ec3e1..ea86ce6 100644
--- a/include/linux/ploop/ploop.h
+++ b/include/linux/ploop/ploop.h
@@ -52,6 +52,7 @@ enum {
 				   free blocks loaded */
 	PLOOP_S_LOCKED,	        /* ploop is locked by userspace
 				   (for minor mgmt only) */
+	PLOOP_S_ONCE,	        /* An event (e.g. printk once) happened */
 };
 
 struct ploop_snapdata
@@ -760,6 +761,9 @@ int ploop_maintenance_wait(struct ploop_device * plo);
 
 extern int max_map_pages;
 
+extern void ploop_msg_once(struct ploop_device *plo, const char *, ...)
+	__attribute__ ((format (printf, 2, 3)));
+
 /* Define PLOOP_TRACE to get full trace of ploop state machine.
  */
 #undef PLOOP_TRACE
-- 
1.9.3




More information about the Devel mailing list