Maxim Patlasov <[email protected]> writes:

> Ploop will use the helper to make private "snapshot" copy of CBT mask.
>
> Signed-off-by: Maxim Patlasov <[email protected]>
ACK
> ---
>  block/blk-cbt.c        |   59 
> ++++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/blkdev.h |    2 ++
>  2 files changed, 61 insertions(+)
>
> diff --git a/block/blk-cbt.c b/block/blk-cbt.c
> index 4bf9666..850fd7e 100644
> --- a/block/blk-cbt.c
> +++ b/block/blk-cbt.c
> @@ -278,6 +278,65 @@ err_cbt:
>       return ERR_PTR(-ENOMEM);
>  }
>  
> +int blk_cbt_map_copy_once(struct request_queue *q, struct page ***map_ptr,
> +                       blkcnt_t *block_max, blkcnt_t *block_bits)
> +{
> +     struct cbt_info *cbt;
> +     struct page **map;
> +     unsigned long npages;
> +     unsigned long i;
> +
> +     mutex_lock(&cbt_mutex);
> +     cbt = q->cbt;
> +
> +     BUG_ON(!cbt);
> +     BUG_ON(!cbt->map);
> +     BUG_ON(!cbt->block_max);
> +
> +     cbt_flush_cache(cbt);
> +
> +     npages = NR_PAGES(cbt->block_max);
> +     map = vmalloc(npages * sizeof(void*));
> +     if (!map)
> +             goto fail;
> +
> +     memset(map, 0, npages * sizeof(void*));
> +
> +     for (i = 0; i < npages; i++) {
> +             struct page *page = cbt->map[i];
> +
> +             BUG_ON(page == CBT_PAGE_MISSED);
> +
> +             if (page) {
> +                     map[i] = alloc_page(GFP_KERNEL|__GFP_ZERO);
> +                     if (!map[i])
> +                             goto fail_pages;
> +
> +                     spin_lock_page(page);
> +                     memcpy(page_address(map[i]), page_address(page),
> +                            PAGE_SIZE);
> +                     memset(page_address(page), 0, PAGE_SIZE);
> +                     unlock_page(page);
> +             }
> +     }
> +     mutex_unlock(&cbt_mutex);
> +
> +     *map_ptr = map;
> +     *block_max = cbt->block_max;
> +     *block_bits = cbt->block_bits;
> +     return 0;
> +
> +fail_pages:
> +     while (--i >= 0) {
> +             if (map[i])
> +                     __free_page(map[i]);
> +     }
> +fail:
> +     vfree(map);
> +     mutex_unlock(&cbt_mutex);
> +     return -ENOMEM;
> +}
> +EXPORT_SYMBOL(blk_cbt_map_copy_once);
>  
>  void blk_cbt_update_size(struct block_device *bdev)
>  {
> diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
> index 9dc69cb..7ae962a 100644
> --- a/include/linux/blkdev.h
> +++ b/include/linux/blkdev.h
> @@ -1651,6 +1651,8 @@ extern void blk_cbt_update_size(struct block_device 
> *bdev);
>  extern void blk_cbt_release(struct request_queue *q);
>  extern void blk_cbt_bio_queue(struct request_queue *q, struct bio *bio);
>  extern int blk_cbt_ioctl(struct block_device *bdev, unsigned cmd, char 
> __user *arg);
> +extern int blk_cbt_map_copy_once(struct request_queue *q, struct page 
> ***map_ptr,
> +                              blkcnt_t *block_max, blkcnt_t *block_bits);
>  #else /* CONFIG_BLK_DEV_CBT */
>  static inline void blk_cbt_update_size(struct block_device *bdev)
>  {

Attachment: signature.asc
Description: PGP signature

_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to