Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3ae1c24e authored by Ed L. Cashin's avatar Ed L. Cashin Committed by Greg Kroah-Hartman
Browse files

[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: default avatar"Ed L. Cashin" <ecashin@coraid.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 50bba752
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@ rm -f $dir/discover
mknod -m 0200 $dir/discover c $MAJOR 3
rm -f $dir/interfaces
mknod -m 0200 $dir/interfaces c $MAJOR 4
rm -f $dir/revalidate
mknod -m 0200 $dir/revalidate c $MAJOR 5

export n_partitions
mkshelf=`echo $0 | sed 's!mkdevs!mkshelf!'`
+1 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
SUBSYSTEM="aoe", KERNEL="discover",	NAME="etherd/%k", GROUP="disk", MODE="0220"
SUBSYSTEM="aoe", KERNEL="err",		NAME="etherd/%k", GROUP="disk", MODE="0440"
SUBSYSTEM="aoe", KERNEL="interfaces",	NAME="etherd/%k", GROUP="disk", MODE="0220"
SUBSYSTEM="aoe", KERNEL="revalidate",	NAME="etherd/%k", GROUP="disk", MODE="0220"

# aoe block devices     
KERNEL="etherd*",       NAME="%k", GROUP="disk"
+7 −5
Original line number Diff line number Diff line
@@ -75,8 +75,9 @@ enum {
	DEVFL_TKILL = (1<<1),	/* flag for timer to know when to kill self */
	DEVFL_EXT = (1<<2),	/* device accepts lba48 commands */
	DEVFL_CLOSEWAIT = (1<<3), /* device is waiting for all closes to revalidate */
	DEVFL_WC_UPDATE = (1<<4), /* this device needs to update write cache status */
	DEVFL_WORKON = (1<<4),
	DEVFL_GDALLOC = (1<<4),	/* need to alloc gendisk */
	DEVFL_PAUSE = (1<<5),
	DEVFL_NEWSIZE = (1<<6),	/* need to update dev size in block layer */

	BUFFL_FAIL = 1,
};
@@ -152,16 +153,17 @@ void aoechr_exit(void);
void aoechr_error(char *);

void aoecmd_work(struct aoedev *d);
void aoecmd_cfg(ushort, unsigned char);
void aoecmd_cfg(ushort aoemajor, unsigned char aoeminor);
void aoecmd_ata_rsp(struct sk_buff *);
void aoecmd_cfg_rsp(struct sk_buff *);
void aoecmd_sleepwork(void *vp);

int aoedev_init(void);
void aoedev_exit(void);
struct aoedev *aoedev_by_aoeaddr(int maj, int min);
struct aoedev *aoedev_by_sysminor_m(ulong sysminor, ulong bufcnt);
void aoedev_downdev(struct aoedev *d);
struct aoedev *aoedev_set(ulong, unsigned char *, struct net_device *, ulong);
int aoedev_busy(void);
int aoedev_isbusy(struct aoedev *d);

int aoenet_init(void);
void aoenet_exit(void);
+9 −13
Original line number Diff line number Diff line
@@ -22,7 +22,9 @@ static ssize_t aoedisk_show_state(struct gendisk * disk, char *page)
	return snprintf(page, PAGE_SIZE,
			"%s%s\n",
			(d->flags & DEVFL_UP) ? "up" : "down",
			(d->flags & DEVFL_CLOSEWAIT) ? ",closewait" : "");
			(d->flags & DEVFL_PAUSE) ? ",paused" :
			(d->nopen && !(d->flags & DEVFL_UP)) ? ",closewait" : "");
	/* I'd rather see nopen exported so we can ditch closewait */
}
static ssize_t aoedisk_show_mac(struct gendisk * disk, char *page)
{
@@ -107,8 +109,7 @@ aoeblk_release(struct inode *inode, struct file *filp)

	spin_lock_irqsave(&d->lock, flags);

	if (--d->nopen == 0 && (d->flags & DEVFL_CLOSEWAIT)) {
		d->flags &= ~DEVFL_CLOSEWAIT;
	if (--d->nopen == 0 && !(d->flags & DEVFL_UP)) {
		spin_unlock_irqrestore(&d->lock, flags);
		aoecmd_cfg(d->aoemajor, d->aoeminor);
		return 0;
@@ -158,14 +159,14 @@ aoeblk_make_request(request_queue_t *q, struct bio *bio)
	}

	list_add_tail(&buf->bufs, &d->bufq);
	aoecmd_work(d);

	aoecmd_work(d);
	sl = d->sendq_hd;
	d->sendq_hd = d->sendq_tl = NULL;

	spin_unlock_irqrestore(&d->lock, flags);

	aoenet_xmit(sl);

	return 0;
}

@@ -205,7 +206,7 @@ aoeblk_gdalloc(void *vp)
		printk(KERN_ERR "aoe: aoeblk_gdalloc: cannot allocate disk "
			"structure for %ld.%ld\n", d->aoemajor, d->aoeminor);
		spin_lock_irqsave(&d->lock, flags);
		d->flags &= ~DEVFL_WORKON;
		d->flags &= ~DEVFL_GDALLOC;
		spin_unlock_irqrestore(&d->lock, flags);
		return;
	}
@@ -218,7 +219,7 @@ aoeblk_gdalloc(void *vp)
			"for %ld.%ld\n", d->aoemajor, d->aoeminor);
		put_disk(gd);
		spin_lock_irqsave(&d->lock, flags);
		d->flags &= ~DEVFL_WORKON;
		d->flags &= ~DEVFL_GDALLOC;
		spin_unlock_irqrestore(&d->lock, flags);
		return;
	}
@@ -235,18 +236,13 @@ aoeblk_gdalloc(void *vp)

	gd->queue = &d->blkq;
	d->gd = gd;
	d->flags &= ~DEVFL_WORKON;
	d->flags &= ~DEVFL_GDALLOC;
	d->flags |= DEVFL_UP;

	spin_unlock_irqrestore(&d->lock, flags);

	add_disk(gd);
	aoedisk_add_sysfs(d);
	
	printk(KERN_INFO "aoe: %012llx e%lu.%lu v%04x has %llu "
		"sectors\n", (unsigned long long)mac_addr(d->addr),
		d->aoemajor, d->aoeminor,
		d->fw_ver, (long long)d->ssize);
}

void
+37 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ enum {
	MINOR_ERR = 2,
	MINOR_DISCOVER,
	MINOR_INTERFACES,
	MINOR_REVALIDATE,
	MSGSZ = 2048,
	NARGS = 10,
	NMSG = 100,		/* message backlog to retain */
@@ -41,6 +42,7 @@ static struct aoe_chardev chardevs[] = {
	{ MINOR_ERR, "err" },
	{ MINOR_DISCOVER, "discover" },
	{ MINOR_INTERFACES, "interfaces" },
	{ MINOR_REVALIDATE, "revalidate" },
};

static int
@@ -62,6 +64,39 @@ interfaces(const char __user *str, size_t size)
	return 0;
}

static int
revalidate(const char __user *str, size_t size)
{
	int major, minor, n;
	ulong flags;
	struct aoedev *d;
	char buf[16];

	if (size >= sizeof buf)
		return -EINVAL;
	buf[sizeof buf - 1] = '\0';
	if (copy_from_user(buf, str, size))
		return -EFAULT;

	/* should be e%d.%d format */
	n = sscanf(buf, "e%d.%d", &major, &minor);
	if (n != 2) {
		printk(KERN_ERR "aoe: %s: invalid device specification\n",
			__FUNCTION__);
		return -EINVAL;
	}
	d = aoedev_by_aoeaddr(major, minor);
	if (!d)
		return -EINVAL;

	spin_lock_irqsave(&d->lock, flags);
	d->flags |= DEVFL_PAUSE;
	spin_unlock_irqrestore(&d->lock, flags);
	aoecmd_cfg(major, minor);

	return 0;
}

void
aoechr_error(char *msg)
{
@@ -114,6 +149,8 @@ aoechr_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offp
	case MINOR_INTERFACES:
		ret = interfaces(buf, cnt);
		break;
	case MINOR_REVALIDATE:
		ret = revalidate(buf, cnt);
	}
	if (ret == 0)
		ret = cnt;
Loading