aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/aoe/aoedev.c
diff options
context:
space:
mode:
authorEd L. Cashin <ecashin@coraid.com>2006-01-19 13:46:19 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-03-24 01:01:55 -0500
commit3ae1c24e395b2b65326439622223d88d92bfa03a (patch)
treedf1e7e8e63a37ed91407ea5da6535b64f50e64a2 /drivers/block/aoe/aoedev.c
parent50bba752ca0a740a6ba9eb96d61ef7bbdfe405cf (diff)
[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" <ecashin@coraid.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/block/aoe/aoedev.c')
-rw-r--r--drivers/block/aoe/aoedev.c69
1 files changed, 48 insertions, 21 deletions
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c
index ded33ba31acc..ed4258a62df5 100644
--- a/drivers/block/aoe/aoedev.c
+++ b/drivers/block/aoe/aoedev.c
@@ -12,6 +12,24 @@
12static struct aoedev *devlist; 12static struct aoedev *devlist;
13static spinlock_t devlist_lock; 13static spinlock_t devlist_lock;
14 14
15int
16aoedev_isbusy(struct aoedev *d)
17{
18 struct frame *f, *e;
19
20 f = d->frames;
21 e = f + d->nframes;
22 do {
23 if (f->tag != FREETAG) {
24 printk(KERN_DEBUG "aoe: %ld.%ld isbusy\n",
25 d->aoemajor, d->aoeminor);
26 return 1;
27 }
28 } while (++f < e);
29
30 return 0;
31}
32
15struct aoedev * 33struct aoedev *
16aoedev_by_aoeaddr(int maj, int min) 34aoedev_by_aoeaddr(int maj, int min)
17{ 35{
@@ -28,6 +46,18 @@ aoedev_by_aoeaddr(int maj, int min)
28 return d; 46 return d;
29} 47}
30 48
49static void
50dummy_timer(ulong vp)
51{
52 struct aoedev *d;
53
54 d = (struct aoedev *)vp;
55 if (d->flags & DEVFL_TKILL)
56 return;
57 d->timer.expires = jiffies + HZ;
58 add_timer(&d->timer);
59}
60
31/* called with devlist lock held */ 61/* called with devlist lock held */
32static struct aoedev * 62static struct aoedev *
33aoedev_newdev(ulong nframes) 63aoedev_newdev(ulong nframes)
@@ -44,6 +74,8 @@ aoedev_newdev(ulong nframes)
44 return NULL; 74 return NULL;
45 } 75 }
46 76
77 INIT_WORK(&d->work, aoecmd_sleepwork, d);
78
47 d->nframes = nframes; 79 d->nframes = nframes;
48 d->frames = f; 80 d->frames = f;
49 e = f + nframes; 81 e = f + nframes;
@@ -52,6 +84,10 @@ aoedev_newdev(ulong nframes)
52 84
53 spin_lock_init(&d->lock); 85 spin_lock_init(&d->lock);
54 init_timer(&d->timer); 86 init_timer(&d->timer);
87 d->timer.data = (ulong) d;
88 d->timer.function = dummy_timer;
89 d->timer.expires = jiffies + HZ;
90 add_timer(&d->timer);
55 d->bufpool = NULL; /* defer to aoeblk_gdalloc */ 91 d->bufpool = NULL; /* defer to aoeblk_gdalloc */
56 INIT_LIST_HEAD(&d->bufq); 92 INIT_LIST_HEAD(&d->bufq);
57 d->next = devlist; 93 d->next = devlist;
@@ -67,9 +103,6 @@ aoedev_downdev(struct aoedev *d)
67 struct buf *buf; 103 struct buf *buf;
68 struct bio *bio; 104 struct bio *bio;
69 105
70 d->flags |= DEVFL_TKILL;
71 del_timer(&d->timer);
72
73 f = d->frames; 106 f = d->frames;
74 e = f + d->nframes; 107 e = f + d->nframes;
75 for (; f<e; f->tag = FREETAG, f->buf = NULL, f++) { 108 for (; f<e; f->tag = FREETAG, f->buf = NULL, f++) {
@@ -92,16 +125,15 @@ aoedev_downdev(struct aoedev *d)
92 bio_endio(bio, bio->bi_size, -EIO); 125 bio_endio(bio, bio->bi_size, -EIO);
93 } 126 }
94 127
95 if (d->nopen)
96 d->flags |= DEVFL_CLOSEWAIT;
97 if (d->gd) 128 if (d->gd)
98 d->gd->capacity = 0; 129 d->gd->capacity = 0;
99 130
100 d->flags &= ~DEVFL_UP; 131 d->flags &= ~(DEVFL_UP | DEVFL_PAUSE);
101} 132}
102 133
134/* find it or malloc it */
103struct aoedev * 135struct aoedev *
104aoedev_set(ulong sysminor, unsigned char *addr, struct net_device *ifp, ulong bufcnt) 136aoedev_by_sysminor_m(ulong sysminor, ulong bufcnt)
105{ 137{
106 struct aoedev *d; 138 struct aoedev *d;
107 ulong flags; 139 ulong flags;
@@ -112,25 +144,19 @@ aoedev_set(ulong sysminor, unsigned char *addr, struct net_device *ifp, ulong bu
112 if (d->sysminor == sysminor) 144 if (d->sysminor == sysminor)
113 break; 145 break;
114 146
115 if (d == NULL && (d = aoedev_newdev(bufcnt)) == NULL) { 147 if (d == NULL) {
116 spin_unlock_irqrestore(&devlist_lock, flags); 148 d = aoedev_newdev(bufcnt);
117 printk(KERN_INFO "aoe: aoedev_set: aoedev_newdev failure.\n"); 149 if (d == NULL) {
118 return NULL; 150 spin_unlock_irqrestore(&devlist_lock, flags);
119 } /* if newdev, (d->flags & DEVFL_UP) == 0 for below */ 151 printk(KERN_INFO "aoe: aoedev_set: aoedev_newdev failure.\n");
120 152 return NULL;
121 spin_unlock_irqrestore(&devlist_lock, flags); 153 }
122 spin_lock_irqsave(&d->lock, flags);
123
124 d->ifp = ifp;
125 memcpy(d->addr, addr, sizeof d->addr);
126 if ((d->flags & DEVFL_UP) == 0) {
127 aoedev_downdev(d); /* flushes outstanding frames */
128 d->sysminor = sysminor; 154 d->sysminor = sysminor;
129 d->aoemajor = AOEMAJOR(sysminor); 155 d->aoemajor = AOEMAJOR(sysminor);
130 d->aoeminor = AOEMINOR(sysminor); 156 d->aoeminor = AOEMINOR(sysminor);
131 } 157 }
132 158
133 spin_unlock_irqrestore(&d->lock, flags); 159 spin_unlock_irqrestore(&devlist_lock, flags);
134 return d; 160 return d;
135} 161}
136 162
@@ -161,6 +187,7 @@ aoedev_exit(void)
161 187
162 spin_lock_irqsave(&d->lock, flags); 188 spin_lock_irqsave(&d->lock, flags);
163 aoedev_downdev(d); 189 aoedev_downdev(d);
190 d->flags |= DEVFL_TKILL;
164 spin_unlock_irqrestore(&d->lock, flags); 191 spin_unlock_irqrestore(&d->lock, flags);
165 192
166 del_timer_sync(&d->timer); 193 del_timer_sync(&d->timer);