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