From 3ae1c24e395b2b65326439622223d88d92bfa03a Mon Sep 17 00:00:00 2001 From: "Ed L. Cashin" Date: Thu, 19 Jan 2006 13:46:19 -0500 Subject: [PATCH] aoe [2/8]: support dynamic resizing of AoE devices Allow the driver to recognize AoE devices that have changed size. Devices not in use are updated automatically, and devices that are in use are updated at user request. Signed-off-by: "Ed L. Cashin" Signed-off-by: Greg Kroah-Hartman --- drivers/block/aoe/aoedev.c | 69 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 21 deletions(-) (limited to 'drivers/block/aoe/aoedev.c') diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c index ded33ba31ac..ed4258a62df 100644 --- a/drivers/block/aoe/aoedev.c +++ b/drivers/block/aoe/aoedev.c @@ -12,6 +12,24 @@ static struct aoedev *devlist; static spinlock_t devlist_lock; +int +aoedev_isbusy(struct aoedev *d) +{ + struct frame *f, *e; + + f = d->frames; + e = f + d->nframes; + do { + if (f->tag != FREETAG) { + printk(KERN_DEBUG "aoe: %ld.%ld isbusy\n", + d->aoemajor, d->aoeminor); + return 1; + } + } while (++f < e); + + return 0; +} + struct aoedev * aoedev_by_aoeaddr(int maj, int min) { @@ -28,6 +46,18 @@ aoedev_by_aoeaddr(int maj, int min) return d; } +static void +dummy_timer(ulong vp) +{ + struct aoedev *d; + + d = (struct aoedev *)vp; + if (d->flags & DEVFL_TKILL) + return; + d->timer.expires = jiffies + HZ; + add_timer(&d->timer); +} + /* called with devlist lock held */ static struct aoedev * aoedev_newdev(ulong nframes) @@ -44,6 +74,8 @@ aoedev_newdev(ulong nframes) return NULL; } + INIT_WORK(&d->work, aoecmd_sleepwork, d); + d->nframes = nframes; d->frames = f; e = f + nframes; @@ -52,6 +84,10 @@ aoedev_newdev(ulong nframes) spin_lock_init(&d->lock); init_timer(&d->timer); + d->timer.data = (ulong) d; + d->timer.function = dummy_timer; + d->timer.expires = jiffies + HZ; + add_timer(&d->timer); d->bufpool = NULL; /* defer to aoeblk_gdalloc */ INIT_LIST_HEAD(&d->bufq); d->next = devlist; @@ -67,9 +103,6 @@ aoedev_downdev(struct aoedev *d) struct buf *buf; struct bio *bio; - d->flags |= DEVFL_TKILL; - del_timer(&d->timer); - f = d->frames; e = f + d->nframes; for (; ftag = FREETAG, f->buf = NULL, f++) { @@ -92,16 +125,15 @@ aoedev_downdev(struct aoedev *d) bio_endio(bio, bio->bi_size, -EIO); } - if (d->nopen) - d->flags |= DEVFL_CLOSEWAIT; if (d->gd) d->gd->capacity = 0; - d->flags &= ~DEVFL_UP; + d->flags &= ~(DEVFL_UP | DEVFL_PAUSE); } +/* find it or malloc it */ struct aoedev * -aoedev_set(ulong sysminor, unsigned char *addr, struct net_device *ifp, ulong bufcnt) +aoedev_by_sysminor_m(ulong sysminor, ulong bufcnt) { struct aoedev *d; ulong flags; @@ -112,25 +144,19 @@ aoedev_set(ulong sysminor, unsigned char *addr, struct net_device *ifp, ulong bu if (d->sysminor == sysminor) break; - if (d == NULL && (d = aoedev_newdev(bufcnt)) == NULL) { - spin_unlock_irqrestore(&devlist_lock, flags); - printk(KERN_INFO "aoe: aoedev_set: aoedev_newdev failure.\n"); - return NULL; - } /* if newdev, (d->flags & DEVFL_UP) == 0 for below */ - - spin_unlock_irqrestore(&devlist_lock, flags); - spin_lock_irqsave(&d->lock, flags); - - d->ifp = ifp; - memcpy(d->addr, addr, sizeof d->addr); - if ((d->flags & DEVFL_UP) == 0) { - aoedev_downdev(d); /* flushes outstanding frames */ + if (d == NULL) { + d = aoedev_newdev(bufcnt); + if (d == NULL) { + spin_unlock_irqrestore(&devlist_lock, flags); + printk(KERN_INFO "aoe: aoedev_set: aoedev_newdev failure.\n"); + return NULL; + } d->sysminor = sysminor; d->aoemajor = AOEMAJOR(sysminor); d->aoeminor = AOEMINOR(sysminor); } - spin_unlock_irqrestore(&d->lock, flags); + spin_unlock_irqrestore(&devlist_lock, flags); return d; } @@ -161,6 +187,7 @@ aoedev_exit(void) spin_lock_irqsave(&d->lock, flags); aoedev_downdev(d); + d->flags |= DEVFL_TKILL; spin_unlock_irqrestore(&d->lock, flags); del_timer_sync(&d->timer); -- cgit v1.2.3