Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.8-rc3 134 lines 3.1 kB view raw
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * RDMA Network Block Driver 4 * 5 * Copyright (c) 2014 - 2018 ProfitBricks GmbH. All rights reserved. 6 * Copyright (c) 2018 - 2019 1&1 IONOS Cloud GmbH. All rights reserved. 7 * Copyright (c) 2019 - 2020 1&1 IONOS SE. All rights reserved. 8 */ 9#undef pr_fmt 10#define pr_fmt(fmt) KBUILD_MODNAME " L" __stringify(__LINE__) ": " fmt 11 12#include "rnbd-srv-dev.h" 13#include "rnbd-log.h" 14 15struct rnbd_dev *rnbd_dev_open(const char *path, fmode_t flags, 16 struct bio_set *bs) 17{ 18 struct rnbd_dev *dev; 19 int ret; 20 21 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 22 if (!dev) 23 return ERR_PTR(-ENOMEM); 24 25 dev->blk_open_flags = flags; 26 dev->bdev = blkdev_get_by_path(path, flags, THIS_MODULE); 27 ret = PTR_ERR_OR_ZERO(dev->bdev); 28 if (ret) 29 goto err; 30 31 dev->blk_open_flags = flags; 32 bdevname(dev->bdev, dev->name); 33 dev->ibd_bio_set = bs; 34 35 return dev; 36 37err: 38 kfree(dev); 39 return ERR_PTR(ret); 40} 41 42void rnbd_dev_close(struct rnbd_dev *dev) 43{ 44 blkdev_put(dev->bdev, dev->blk_open_flags); 45 kfree(dev); 46} 47 48static void rnbd_dev_bi_end_io(struct bio *bio) 49{ 50 struct rnbd_dev_blk_io *io = bio->bi_private; 51 52 rnbd_endio(io->priv, blk_status_to_errno(bio->bi_status)); 53 bio_put(bio); 54} 55 56/** 57 * rnbd_bio_map_kern - map kernel address into bio 58 * @data: pointer to buffer to map 59 * @bs: bio_set to use. 60 * @len: length in bytes 61 * @gfp_mask: allocation flags for bio allocation 62 * 63 * Map the kernel address into a bio suitable for io to a block 64 * device. Returns an error pointer in case of error. 65 */ 66static struct bio *rnbd_bio_map_kern(void *data, struct bio_set *bs, 67 unsigned int len, gfp_t gfp_mask) 68{ 69 unsigned long kaddr = (unsigned long)data; 70 unsigned long end = (kaddr + len + PAGE_SIZE - 1) >> PAGE_SHIFT; 71 unsigned long start = kaddr >> PAGE_SHIFT; 72 const int nr_pages = end - start; 73 int offset, i; 74 struct bio *bio; 75 76 bio = bio_alloc_bioset(gfp_mask, nr_pages, bs); 77 if (!bio) 78 return ERR_PTR(-ENOMEM); 79 80 offset = offset_in_page(kaddr); 81 for (i = 0; i < nr_pages; i++) { 82 unsigned int bytes = PAGE_SIZE - offset; 83 84 if (len <= 0) 85 break; 86 87 if (bytes > len) 88 bytes = len; 89 90 if (bio_add_page(bio, virt_to_page(data), bytes, 91 offset) < bytes) { 92 /* we don't support partial mappings */ 93 bio_put(bio); 94 return ERR_PTR(-EINVAL); 95 } 96 97 data += bytes; 98 len -= bytes; 99 offset = 0; 100 } 101 102 bio->bi_end_io = bio_put; 103 return bio; 104} 105 106int rnbd_dev_submit_io(struct rnbd_dev *dev, sector_t sector, void *data, 107 size_t len, u32 bi_size, enum rnbd_io_flags flags, 108 short prio, void *priv) 109{ 110 struct rnbd_dev_blk_io *io; 111 struct bio *bio; 112 113 /* Generate bio with pages pointing to the rdma buffer */ 114 bio = rnbd_bio_map_kern(data, dev->ibd_bio_set, len, GFP_KERNEL); 115 if (IS_ERR(bio)) 116 return PTR_ERR(bio); 117 118 io = container_of(bio, struct rnbd_dev_blk_io, bio); 119 120 io->dev = dev; 121 io->priv = priv; 122 123 bio->bi_end_io = rnbd_dev_bi_end_io; 124 bio->bi_private = io; 125 bio->bi_opf = rnbd_to_bio_flags(flags); 126 bio->bi_iter.bi_sector = sector; 127 bio->bi_iter.bi_size = bi_size; 128 bio_set_prio(bio, prio); 129 bio_set_dev(bio, dev->bdev); 130 131 submit_bio(bio); 132 133 return 0; 134}