^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* Copyright (c) 2013 Coraid, Inc. See COPYING for GPL terms. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * aoeblk.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * block device routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/hdreg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/blk-mq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/backing-dev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/ratelimit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/genhd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <scsi/sg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "aoe.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) static DEFINE_MUTEX(aoeblk_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static struct kmem_cache *buf_pool_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static struct dentry *aoe_debugfs_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /* GPFS needs a larger value than the default. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static int aoe_maxsectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) module_param(aoe_maxsectors, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) MODULE_PARM_DESC(aoe_maxsectors,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) "When nonzero, set the maximum number of sectors per I/O request");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static ssize_t aoedisk_show_state(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct device_attribute *attr, char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct aoedev *d = disk->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) return snprintf(page, PAGE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) "%s%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) (d->flags & DEVFL_UP) ? "up" : "down",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) (d->flags & DEVFL_KICKME) ? ",kickme" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) (d->nopen && !(d->flags & DEVFL_UP)) ? ",closewait" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* I'd rather see nopen exported so we can ditch closewait */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static ssize_t aoedisk_show_mac(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct device_attribute *attr, char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct aoedev *d = disk->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct aoetgt *t = d->targets[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if (t == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) return snprintf(page, PAGE_SIZE, "none\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return snprintf(page, PAGE_SIZE, "%pm\n", t->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static ssize_t aoedisk_show_netif(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct device_attribute *attr, char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct aoedev *d = disk->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct net_device *nds[8], **nd, **nnd, **ne;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct aoetgt **t, **te;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct aoeif *ifp, *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) memset(nds, 0, sizeof nds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) nd = nds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) ne = nd + ARRAY_SIZE(nds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) t = d->targets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) te = t + d->ntargets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) for (; t < te && *t; t++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) ifp = (*t)->ifs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) e = ifp + NAOEIFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) for (; ifp < e && ifp->nd; ifp++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) for (nnd = nds; nnd < nd; nnd++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (*nnd == ifp->nd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (nnd == nd && nd != ne)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) *nd++ = ifp->nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) ne = nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) nd = nds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (*nd == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return snprintf(page, PAGE_SIZE, "none\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) for (p = page; nd < ne; nd++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) p += scnprintf(p, PAGE_SIZE - (p-page), "%s%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) p == page ? "" : ",", (*nd)->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) p += scnprintf(p, PAGE_SIZE - (p-page), "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return p-page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /* firmware version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static ssize_t aoedisk_show_fwver(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct device_attribute *attr, char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct aoedev *d = disk->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return snprintf(page, PAGE_SIZE, "0x%04x\n", (unsigned int) d->fw_ver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static ssize_t aoedisk_show_payload(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct device_attribute *attr, char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct aoedev *d = disk->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return snprintf(page, PAGE_SIZE, "%lu\n", d->maxbcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static int aoedisk_debugfs_show(struct seq_file *s, void *ignored)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct aoedev *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct aoetgt **t, **te;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct aoeif *ifp, *ife;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) char c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) d = s->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) seq_printf(s, "rttavg: %d rttdev: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) d->rttavg >> RTTSCALE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) d->rttdev >> RTTDSCALE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) seq_printf(s, "nskbpool: %d\n", skb_queue_len(&d->skbpool));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) seq_printf(s, "kicked: %ld\n", d->kicked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) seq_printf(s, "maxbcnt: %ld\n", d->maxbcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) seq_printf(s, "ref: %ld\n", d->ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) spin_lock_irqsave(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) t = d->targets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) te = t + d->ntargets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) for (; t < te && *t; t++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) c = '\t';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) seq_printf(s, "falloc: %ld\n", (*t)->falloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) seq_printf(s, "ffree: %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) list_empty(&(*t)->ffree) ? NULL : (*t)->ffree.next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) seq_printf(s, "%pm:%d:%d:%d\n", (*t)->addr, (*t)->nout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) (*t)->maxout, (*t)->nframes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) seq_printf(s, "\tssthresh:%d\n", (*t)->ssthresh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) seq_printf(s, "\ttaint:%d\n", (*t)->taint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) seq_printf(s, "\tr:%d\n", (*t)->rpkts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) seq_printf(s, "\tw:%d\n", (*t)->wpkts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) ifp = (*t)->ifs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) ife = ifp + ARRAY_SIZE((*t)->ifs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) for (; ifp->nd && ifp < ife; ifp++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) seq_printf(s, "%c%s", c, ifp->nd->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) c = ',';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) seq_puts(s, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) spin_unlock_irqrestore(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static int aoe_debugfs_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return single_open(file, aoedisk_debugfs_show, inode->i_private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static DEVICE_ATTR(state, 0444, aoedisk_show_state, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static DEVICE_ATTR(mac, 0444, aoedisk_show_mac, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static DEVICE_ATTR(netif, 0444, aoedisk_show_netif, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static struct device_attribute dev_attr_firmware_version = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) .attr = { .name = "firmware-version", .mode = 0444 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) .show = aoedisk_show_fwver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static DEVICE_ATTR(payload, 0444, aoedisk_show_payload, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static struct attribute *aoe_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) &dev_attr_state.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) &dev_attr_mac.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) &dev_attr_netif.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) &dev_attr_firmware_version.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) &dev_attr_payload.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static const struct attribute_group aoe_attr_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) .attrs = aoe_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static const struct attribute_group *aoe_attr_groups[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) &aoe_attr_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static const struct file_operations aoe_debugfs_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) .open = aoe_debugfs_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) .read = seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) .llseek = seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) .release = single_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) aoedisk_add_debugfs(struct aoedev *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (aoe_debugfs_dir == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) p = strchr(d->gd->disk_name, '/');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (p == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) p = d->gd->disk_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) BUG_ON(*p == '\0');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) d->debugfs = debugfs_create_file(p, 0444, aoe_debugfs_dir, d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) &aoe_debugfs_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) aoedisk_rm_debugfs(struct aoedev *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) debugfs_remove(d->debugfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) d->debugfs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) aoeblk_open(struct block_device *bdev, fmode_t mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) struct aoedev *d = bdev->bd_disk->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) ulong flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (!virt_addr_valid(d)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) pr_crit("aoe: invalid device pointer in %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (!(d->flags & DEVFL_UP) || d->flags & DEVFL_TKILL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) mutex_lock(&aoeblk_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) spin_lock_irqsave(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (d->flags & DEVFL_UP && !(d->flags & DEVFL_TKILL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) d->nopen++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) spin_unlock_irqrestore(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) mutex_unlock(&aoeblk_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) spin_unlock_irqrestore(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) mutex_unlock(&aoeblk_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) aoeblk_release(struct gendisk *disk, fmode_t mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct aoedev *d = disk->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) ulong flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) spin_lock_irqsave(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (--d->nopen == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) spin_unlock_irqrestore(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) aoecmd_cfg(d->aoemajor, d->aoeminor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) spin_unlock_irqrestore(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static blk_status_t aoeblk_queue_rq(struct blk_mq_hw_ctx *hctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) const struct blk_mq_queue_data *bd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct aoedev *d = hctx->queue->queuedata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) spin_lock_irq(&d->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if ((d->flags & DEVFL_UP) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) pr_info_ratelimited("aoe: device %ld.%d is not up\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) d->aoemajor, d->aoeminor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) spin_unlock_irq(&d->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) blk_mq_start_request(bd->rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) return BLK_STS_IOERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) list_add_tail(&bd->rq->queuelist, &d->rq_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) aoecmd_work(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) spin_unlock_irq(&d->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return BLK_STS_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) aoeblk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) struct aoedev *d = bdev->bd_disk->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if ((d->flags & DEVFL_UP) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) printk(KERN_ERR "aoe: disk not up\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) geo->cylinders = d->geo.cylinders;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) geo->heads = d->geo.heads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) geo->sectors = d->geo.sectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) aoeblk_ioctl(struct block_device *bdev, fmode_t mode, uint cmd, ulong arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct aoedev *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (!arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) d = bdev->bd_disk->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if ((d->flags & DEVFL_UP) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) pr_err("aoe: disk not up\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (cmd == HDIO_GET_IDENTITY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (!copy_to_user((void __user *) arg, &d->ident,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) sizeof(d->ident)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /* udev calls scsi_id, which uses SG_IO, resulting in noise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (cmd != SG_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) pr_info("aoe: unknown ioctl 0x%x\n", cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static const struct block_device_operations aoe_bdops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) .open = aoeblk_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) .release = aoeblk_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) .ioctl = aoeblk_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) .compat_ioctl = blkdev_compat_ptr_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) .getgeo = aoeblk_getgeo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) static const struct blk_mq_ops aoeblk_mq_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) .queue_rq = aoeblk_queue_rq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) /* alloc_disk and add_disk can sleep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) aoeblk_gdalloc(void *vp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct aoedev *d = vp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct gendisk *gd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) mempool_t *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct request_queue *q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct blk_mq_tag_set *set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) ulong flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) int late = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) spin_lock_irqsave(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (d->flags & DEVFL_GDALLOC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) && !(d->flags & DEVFL_TKILL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) && !(d->flags & DEVFL_GD_NOW))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) d->flags |= DEVFL_GD_NOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) late = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) spin_unlock_irqrestore(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (late)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) gd = alloc_disk(AOE_PARTITIONS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (gd == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) pr_err("aoe: cannot allocate disk structure for %ld.%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) d->aoemajor, d->aoeminor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) mp = mempool_create(MIN_BUFS, mempool_alloc_slab, mempool_free_slab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) buf_pool_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (mp == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) printk(KERN_ERR "aoe: cannot allocate bufpool for %ld.%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) d->aoemajor, d->aoeminor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) goto err_disk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) set = &d->tag_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) set->ops = &aoeblk_mq_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) set->cmd_size = sizeof(struct aoe_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) set->nr_hw_queues = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) set->queue_depth = 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) set->numa_node = NUMA_NO_NODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) set->flags = BLK_MQ_F_SHOULD_MERGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) err = blk_mq_alloc_tag_set(set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) pr_err("aoe: cannot allocate tag set for %ld.%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) d->aoemajor, d->aoeminor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) goto err_mempool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) q = blk_mq_init_queue(set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (IS_ERR(q)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) pr_err("aoe: cannot allocate block queue for %ld.%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) d->aoemajor, d->aoeminor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) blk_mq_free_tag_set(set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) goto err_mempool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) spin_lock_irqsave(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) WARN_ON(!(d->flags & DEVFL_GD_NOW));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) WARN_ON(!(d->flags & DEVFL_GDALLOC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) WARN_ON(d->flags & DEVFL_TKILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) WARN_ON(d->gd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) WARN_ON(d->flags & DEVFL_UP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) blk_queue_max_hw_sectors(q, BLK_DEF_MAX_SECTORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) blk_queue_io_opt(q, SZ_2M);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) d->bufpool = mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) d->blkq = gd->queue = q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) q->queuedata = d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) d->gd = gd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (aoe_maxsectors)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) blk_queue_max_hw_sectors(q, aoe_maxsectors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) gd->major = AOE_MAJOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) gd->first_minor = d->sysminor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) gd->fops = &aoe_bdops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) gd->private_data = d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) set_capacity(gd, d->ssize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) snprintf(gd->disk_name, sizeof gd->disk_name, "etherd/e%ld.%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) d->aoemajor, d->aoeminor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) d->flags &= ~DEVFL_GDALLOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) d->flags |= DEVFL_UP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) spin_unlock_irqrestore(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) device_add_disk(NULL, gd, aoe_attr_groups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) aoedisk_add_debugfs(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) spin_lock_irqsave(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) WARN_ON(!(d->flags & DEVFL_GD_NOW));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) d->flags &= ~DEVFL_GD_NOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) spin_unlock_irqrestore(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) err_mempool:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) mempool_destroy(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) err_disk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) put_disk(gd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) spin_lock_irqsave(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) d->flags &= ~DEVFL_GD_NOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) schedule_work(&d->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) spin_unlock_irqrestore(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) aoeblk_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) debugfs_remove_recursive(aoe_debugfs_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) aoe_debugfs_dir = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) kmem_cache_destroy(buf_pool_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) aoeblk_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) buf_pool_cache = kmem_cache_create("aoe_bufs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) sizeof(struct buf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 0, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (buf_pool_cache == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) aoe_debugfs_dir = debugfs_create_dir("aoe", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)