void aoedev_exit(void) { struct aoedev *d; ulong flags; while ((d = devlist)) { devlist = d->next; spin_lock_irqsave(&d->lock, flags); aoedev_downdev(d); d->flags |= DEVFL_TKILL; spin_unlock_irqrestore(&d->lock, flags); del_timer_sync(&d->timer); aoedev_freedev(d); } }
int aoedev_flush(const char __user *str, size_t cnt) { ulong flags; struct aoedev *d, **dd; struct aoedev *rmd = NULL; char buf[16]; int all = 0; if (cnt >= 3) { if (cnt > sizeof buf) cnt = sizeof buf; if (copy_from_user(buf, str, cnt)) return -EFAULT; all = !strncmp(buf, "all", 3); } flush_scheduled_work(); spin_lock_irqsave(&devlist_lock, flags); dd = &devlist; while ((d = *dd)) { spin_lock(&d->lock); if ((!all && (d->flags & DEVFL_UP)) || (d->flags & (DEVFL_GDALLOC|DEVFL_NEWSIZE)) || d->nopen) { spin_unlock(&d->lock); dd = &d->next; continue; } *dd = d->next; aoedev_downdev(d); d->flags |= DEVFL_TKILL; spin_unlock(&d->lock); d->next = rmd; rmd = d; } spin_unlock_irqrestore(&devlist_lock, flags); while ((d = rmd)) { rmd = d->next; del_timer_sync(&d->timer); aoedev_freedev(d); /* must be able to sleep */ } return 0; }
void aoedev_exit(void) { struct aoedev *d; ulong flags; flush_scheduled_work(); while ((d = devlist)) { devlist = d->next; spin_lock_irqsave(&d->lock, flags); aoedev_downdev(d); spin_unlock_irqrestore(&d->lock, flags); del_timer_sync(&d->timer); aoedev_freedev(d); } }