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 <mpatla...@parallels.com> Acked-by: Andrew Vagin <ava...@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 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel