1 /* Copyright (c) 2012 Coraid, Inc. See COPYING for GPL terms. */ 2 /* 3 * aoeblk.c 4 * block device routines 5 */ 6 7 #include <linux/kernel.h> 8 #include <linux/hdreg.h> 9 #include <linux/blkdev.h> 10 #include <linux/backing-dev.h> 11 #include <linux/fs.h> 12 #include <linux/ioctl.h> 13 #include <linux/slab.h> 14 #include <linux/ratelimit.h> 15 #include <linux/genhd.h> 16 #include <linux/netdevice.h> 17 #include <linux/mutex.h> 18 #include <linux/export.h> 19 #include "aoe.h" 20 21 static DEFINE_MUTEX(aoeblk_mutex); 22 static struct kmem_cache *buf_pool_cache; 23 24 static ssize_t aoedisk_show_state(struct device *dev, 25 struct device_attribute *attr, char *page) 26 { 27 struct gendisk *disk = dev_to_disk(dev); 28 struct aoedev *d = disk->private_data; 29 30 return snprintf(page, PAGE_SIZE, 31 "%s%s\n", 32 (d->flags & DEVFL_UP) ? "up" : "down", 33 (d->flags & DEVFL_KICKME) ? ",kickme" : 34 (d->nopen && !(d->flags & DEVFL_UP)) ? ",closewait" : ""); 35 /* I'd rather see nopen exported so we can ditch closewait */ 36 } 37 static ssize_t aoedisk_show_mac(struct device *dev, 38 struct device_attribute *attr, char *page) 39 { 40 struct gendisk *disk = dev_to_disk(dev); 41 struct aoedev *d = disk->private_data; 42 struct aoetgt *t = d->targets[0]; 43 44 if (t == NULL) 45 return snprintf(page, PAGE_SIZE, "none\n"); 46 return snprintf(page, PAGE_SIZE, "%pm\n", t->addr); 47 } 48 static ssize_t aoedisk_show_netif(struct device *dev, 49 struct device_attribute *attr, char *page) 50 { 51 struct gendisk *disk = dev_to_disk(dev); 52 struct aoedev *d = disk->private_data; 53 struct net_device *nds[8], **nd, **nnd, **ne; 54 struct aoetgt **t, **te; 55 struct aoeif *ifp, *e; 56 char *p; 57 58 memset(nds, 0, sizeof nds); 59 nd = nds; 60 ne = nd + ARRAY_SIZE(nds); 61 t = d->targets; 62 te = t + NTARGETS; 63 for (; t < te && *t; t++) { 64 ifp = (*t)->ifs; 65 e = ifp + NAOEIFS; 66 for (; ifp < e && ifp->nd; ifp++) { 67 for (nnd = nds; nnd < nd; nnd++) 68 if (*nnd == ifp->nd) 69 break; 70 if (nnd == nd && nd != ne) 71 *nd++ = ifp->nd; 72 } 73 } 74 75 ne = nd; 76 nd = nds; 77 if (*nd == NULL) 78 return snprintf(page, PAGE_SIZE, "none\n"); 79 for (p = page; nd < ne; nd++) 80 p += snprintf(p, PAGE_SIZE - (p-page), "%s%s", 81 p == page ? "" : ",", (*nd)->name); 82 p += snprintf(p, PAGE_SIZE - (p-page), "\n"); 83 return p-page; 84 } 85 /* firmware version */ 86 static ssize_t aoedisk_show_fwver(struct device *dev, 87 struct device_attribute *attr, char *page) 88 { 89 struct gendisk *disk = dev_to_disk(dev); 90 struct aoedev *d = disk->private_data; 91 92 return snprintf(page, PAGE_SIZE, "0x%04x\n", (unsigned int) d->fw_ver); 93 } 94 95 static DEVICE_ATTR(state, S_IRUGO, aoedisk_show_state, NULL); 96 static DEVICE_ATTR(mac, S_IRUGO, aoedisk_show_mac, NULL); 97 static DEVICE_ATTR(netif, S_IRUGO, aoedisk_show_netif, NULL); 98 static struct device_attribute dev_attr_firmware_version = { 99 .attr = { .name = "firmware-version", .mode = S_IRUGO }, 100 .show = aoedisk_show_fwver, 101 }; 102 103 static struct attribute *aoe_attrs[] = { 104 &dev_attr_state.attr, 105 &dev_attr_mac.attr, 106 &dev_attr_netif.attr, 107 &dev_attr_firmware_version.attr, 108 NULL, 109 }; 110 111 static const struct attribute_group attr_group = { 112 .attrs = aoe_attrs, 113 }; 114 115 static int 116 aoedisk_add_sysfs(struct aoedev *d) 117 { 118 return sysfs_create_group(&disk_to_dev(d->gd)->kobj, &attr_group); 119 } 120 void 121 aoedisk_rm_sysfs(struct aoedev *d) 122 { 123 sysfs_remove_group(&disk_to_dev(d->gd)->kobj, &attr_group); 124 } 125 126 static int 127 aoeblk_open(struct block_device *bdev, fmode_t mode) 128 { 129 struct aoedev *d = bdev->bd_disk->private_data; 130 ulong flags; 131 132 mutex_lock(&aoeblk_mutex); 133 spin_lock_irqsave(&d->lock, flags); 134 if (d->flags & DEVFL_UP) { 135 d->nopen++; 136 spin_unlock_irqrestore(&d->lock, flags); 137 mutex_unlock(&aoeblk_mutex); 138 return 0; 139 } 140 spin_unlock_irqrestore(&d->lock, flags); 141 mutex_unlock(&aoeblk_mutex); 142 return -ENODEV; 143 } 144 145 static int 146 aoeblk_release(struct gendisk *disk, fmode_t mode) 147 { 148 struct aoedev *d = disk->private_data; 149 ulong flags; 150 151 spin_lock_irqsave(&d->lock, flags); 152 153 if (--d->nopen == 0) { 154 spin_unlock_irqrestore(&d->lock, flags); 155 aoecmd_cfg(d->aoemajor, d->aoeminor); 156 return 0; 157 } 158 spin_unlock_irqrestore(&d->lock, flags); 159 160 return 0; 161 } 162 163 static void 164 aoeblk_request(struct request_queue *q) 165 { 166 struct aoedev *d; 167 struct request *rq; 168 169 d = q->queuedata; 170 if ((d->flags & DEVFL_UP) == 0) { 171 pr_info_ratelimited("aoe: device %ld.%d is not up\n", 172 d->aoemajor, d->aoeminor); 173 while ((rq = blk_peek_request(q))) { 174 blk_start_request(rq); 175 aoe_end_request(d, rq, 1); 176 } 177 return; 178 } 179 aoecmd_work(d); 180 } 181 182 static int 183 aoeblk_getgeo(struct block_device *bdev, struct hd_geometry *geo) 184 { 185 struct aoedev *d = bdev->bd_disk->private_data; 186 187 if ((d->flags & DEVFL_UP) == 0) { 188 printk(KERN_ERR "aoe: disk not up\n"); 189 return -ENODEV; 190 } 191 192 geo->cylinders = d->geo.cylinders; 193 geo->heads = d->geo.heads; 194 geo->sectors = d->geo.sectors; 195 return 0; 196 } 197 198 static const struct block_device_operations aoe_bdops = { 199 .open = aoeblk_open, 200 .release = aoeblk_release, 201 .getgeo = aoeblk_getgeo, 202 .owner = THIS_MODULE, 203 }; 204 205 /* alloc_disk and add_disk can sleep */ 206 void 207 aoeblk_gdalloc(void *vp) 208 { 209 struct aoedev *d = vp; 210 struct gendisk *gd; 211 mempool_t *mp; 212 struct request_queue *q; 213 enum { KB = 1024, MB = KB * KB, READ_AHEAD = 2 * MB, }; 214 ulong flags; 215 216 gd = alloc_disk(AOE_PARTITIONS); 217 if (gd == NULL) { 218 pr_err("aoe: cannot allocate disk structure for %ld.%d\n", 219 d->aoemajor, d->aoeminor); 220 goto err; 221 } 222 223 mp = mempool_create(MIN_BUFS, mempool_alloc_slab, mempool_free_slab, 224 buf_pool_cache); 225 if (mp == NULL) { 226 printk(KERN_ERR "aoe: cannot allocate bufpool for %ld.%d\n", 227 d->aoemajor, d->aoeminor); 228 goto err_disk; 229 } 230 q = blk_init_queue(aoeblk_request, &d->lock); 231 if (q == NULL) { 232 pr_err("aoe: cannot allocate block queue for %ld.%d\n", 233 d->aoemajor, d->aoeminor); 234 mempool_destroy(mp); 235 goto err_disk; 236 } 237 238 d->blkq = blk_alloc_queue(GFP_KERNEL); 239 if (!d->blkq) 240 goto err_mempool; 241 d->blkq->backing_dev_info.name = "aoe"; 242 if (bdi_init(&d->blkq->backing_dev_info)) 243 goto err_blkq; 244 spin_lock_irqsave(&d->lock, flags); 245 blk_queue_max_hw_sectors(d->blkq, BLK_DEF_MAX_SECTORS); 246 q->backing_dev_info.ra_pages = READ_AHEAD / PAGE_CACHE_SIZE; 247 d->bufpool = mp; 248 d->blkq = gd->queue = q; 249 q->queuedata = d; 250 d->gd = gd; 251 gd->major = AOE_MAJOR; 252 gd->first_minor = d->sysminor; 253 gd->fops = &aoe_bdops; 254 gd->private_data = d; 255 set_capacity(gd, d->ssize); 256 snprintf(gd->disk_name, sizeof gd->disk_name, "etherd/e%ld.%d", 257 d->aoemajor, d->aoeminor); 258 259 d->flags &= ~DEVFL_GDALLOC; 260 d->flags |= DEVFL_UP; 261 262 spin_unlock_irqrestore(&d->lock, flags); 263 264 add_disk(gd); 265 aoedisk_add_sysfs(d); 266 return; 267 268 err_blkq: 269 blk_cleanup_queue(d->blkq); 270 d->blkq = NULL; 271 err_mempool: 272 mempool_destroy(d->bufpool); 273 err_disk: 274 put_disk(gd); 275 err: 276 spin_lock_irqsave(&d->lock, flags); 277 d->flags &= ~DEVFL_GDALLOC; 278 spin_unlock_irqrestore(&d->lock, flags); 279 } 280 281 void 282 aoeblk_exit(void) 283 { 284 kmem_cache_destroy(buf_pool_cache); 285 } 286 287 int __init 288 aoeblk_init(void) 289 { 290 buf_pool_cache = kmem_cache_create("aoe_bufs", 291 sizeof(struct buf), 292 0, 0, NULL); 293 if (buf_pool_cache == NULL) 294 return -ENOMEM; 295 296 return 0; 297 } 298 299