aoe  87
About: AoE (ATA over Ethernet) Protocol Driver (Linux kernel 4.8.x and greater are not supported).
  Fossies Dox: aoe-87.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

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