drivers/block/aoe/aoedev.c
Source file repositories/reference/linux-study-clean/drivers/block/aoe/aoedev.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/block/aoe/aoedev.c- Extension
.c- Size
- 11556 bytes
- Lines
- 544
- Domain
- Driver Families
- Bucket
- drivers/block
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/hdreg.hlinux/blk-mq.hlinux/netdevice.hlinux/delay.hlinux/slab.hlinux/bitmap.hlinux/kdev_t.hlinux/moduleparam.hlinux/string.haoe.h
Detected Declarations
enum flush_parmsfunction minor_get_dynfunction minor_get_staticfunction minor_getfunction minor_freefunction aoedev_putfunction dummy_timerfunction aoe_failipfunction downdev_framefunction aoedev_downdevfunction user_reqfunction freedevfunction flushfunction aoedev_flushfunction skbfreefunction skbpoolfreefunction aoedev_by_aoeaddrfunction freetgtfunction aoedev_exitfunction aoedev_init
Annotated Snippet
if (exiting) {
/* unconditionally take each device down */
} else if (specified) {
if (!user_req(buf, cnt, d))
goto cont;
} else if ((!all && (d->flags & DEVFL_UP))
|| d->flags & skipflags
|| d->nopen
|| d->ref)
goto cont;
spin_unlock(&d->lock);
spin_unlock_irqrestore(&devlist_lock, flags);
aoedev_downdev(d);
d->flags |= DEVFL_TKILL;
goto restart1;
cont:
spin_unlock(&d->lock);
}
spin_unlock_irqrestore(&devlist_lock, flags);
/* pass two: call freedev, which might sleep,
* for aoedevs marked with DEVFL_TKILL
*/
restart2:
spin_lock_irqsave(&devlist_lock, flags);
for (d = devlist; d; d = d->next) {
spin_lock(&d->lock);
if (d->flags & DEVFL_TKILL
&& !(d->flags & DEVFL_FREEING)) {
spin_unlock(&d->lock);
spin_unlock_irqrestore(&devlist_lock, flags);
freedev(d);
goto restart2;
}
spin_unlock(&d->lock);
}
/* pass three: remove aoedevs marked with DEVFL_FREED */
for (dd = &devlist, d = *dd; d; d = *dd) {
struct aoedev *doomed = NULL;
spin_lock(&d->lock);
if (d->flags & DEVFL_FREED) {
*dd = d->next;
doomed = d;
} else {
dd = &d->next;
}
spin_unlock(&d->lock);
if (doomed)
kfree(doomed->targets);
kfree(doomed);
}
spin_unlock_irqrestore(&devlist_lock, flags);
return 0;
}
int
aoedev_flush(const char __user *str, size_t cnt)
{
return flush(str, cnt, NOT_EXITING);
}
/* This has been confirmed to occur once with Tms=3*1000 due to the
* driver changing link and not processing its transmit ring. The
* problem is hard enough to solve by returning an error that I'm
* still punting on "solving" this.
*/
static void
skbfree(struct sk_buff *skb)
{
enum { Sms = 250, Tms = 30 * 1000};
int i = Tms / Sms;
if (skb == NULL)
return;
while (atomic_read(&skb_shinfo(skb)->dataref) != 1 && i-- > 0)
msleep(Sms);
if (i < 0) {
printk(KERN_ERR
"aoe: %s holds ref: %s\n",
skb->dev ? skb->dev->name : "netif",
"cannot free skb -- memory leaked.");
return;
}
skb->truesize -= skb->data_len;
skb_shinfo(skb)->nr_frags = skb->data_len = 0;
skb_trim(skb, 0);
Annotation
- Immediate include surface: `linux/hdreg.h`, `linux/blk-mq.h`, `linux/netdevice.h`, `linux/delay.h`, `linux/slab.h`, `linux/bitmap.h`, `linux/kdev_t.h`, `linux/moduleparam.h`.
- Detected declarations: `enum flush_parms`, `function minor_get_dyn`, `function minor_get_static`, `function minor_get`, `function minor_free`, `function aoedev_put`, `function dummy_timer`, `function aoe_failip`, `function downdev_frame`, `function aoedev_downdev`.
- Atlas domain: Driver Families / drivers/block.
- Implementation status: source implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.