/*
 * This tries to keep block devices away from devfs as much as possible.
 */
#include <linux/fs.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/vmalloc.h>
#include <linux/genhd.h>
#include <linux/bitops.h>
#include <linux/mutex.h>


struct unique_numspace {
	u32		  num_free;          /*  Num free in bits       */
	u32		  length;            /*  Array length in bytes  */
	unsigned long	  *bits;
	struct semaphore  mutex;
};

static DEFINE_MUTEX(numspace_mutex);

static int expand_numspace(struct unique_numspace *s)
{
	u32 length;
	void *bits;

	if (s->length < 16)
		length = 16;
	else
		length = s->length << 1;

	bits = vmalloc(length);
	if (!bits)
		return -ENOMEM;
	if (s->bits) {
		memcpy(bits, s->bits, s->length);
		vfree(s->bits);
	}
		
	s->num_free = (length - s->length) << 3;
	s->bits = bits;
	memset(bits + s->length, 0, length - s->length);
	s->length = length;

	return 0;
}

static int alloc_unique_number(struct unique_numspace *s)
{
	int rval = 0;

	mutex_lock(&numspace_mutex);
	if (s->num_free < 1)
		rval = expand_numspace(s);
	if (!rval) {
		rval = find_first_zero_bit(s->bits, s->length << 3);
		--s->num_free;
		__set_bit(rval, s->bits);
	}
	mutex_unlock(&numspace_mutex);

	return rval;
}

static void dealloc_unique_number(struct unique_numspace *s, int number)
{
	int old_val;

	if (number >= 0) {
		mutex_lock(&numspace_mutex);
		old_val = __test_and_clear_bit(number, s->bits);
		if (old_val)
			++s->num_free;
		mutex_unlock(&numspace_mutex);
	}
}

static struct unique_numspace disc_numspace;
static struct unique_numspace cdrom_numspace;

void devfs_add_partitioned(struct gendisk *disk)
{
	char dirname[64], symlink[16];

	devfs_mk_dir(disk->devfs_name);
	devfs_mk_bdev(MKDEV(disk->major, disk->first_minor),
			S_IFBLK|S_IRUSR|S_IWUSR,
			"%s/disc", disk->devfs_name);

	disk->number = alloc_unique_number(&disc_numspace);

	sprintf(symlink, "discs/disc%d", disk->number);
	sprintf(dirname, "../%s", disk->devfs_name);
	devfs_mk_symlink(symlink, dirname);

}

void devfs_add_disk(struct gendisk *disk)
{
	devfs_mk_bdev(MKDEV(disk->major, disk->first_minor),
			(disk->flags & GENHD_FL_CD) ?
				S_IFBLK|S_IRUGO|S_IWUGO :
				S_IFBLK|S_IRUSR|S_IWUSR,
			"%s", disk->devfs_name);

	if (disk->flags & GENHD_FL_CD) {
		char dirname[64], symlink[16];

		disk->number = alloc_unique_number(&cdrom_numspace);

		sprintf(symlink, "cdroms/cdrom%d", disk->number);
		sprintf(dirname, "../%s", disk->devfs_name);
		devfs_mk_symlink(symlink, dirname);
	}
}

void devfs_remove_disk(struct gendisk *disk)
{
	if (disk->minors != 1) {
		devfs_remove("discs/disc%d", disk->number);
		dealloc_unique_number(&disc_numspace, disk->number);
		devfs_remove("%s/disc", disk->devfs_name);
	}
	if (disk->flags & GENHD_FL_CD) {
		devfs_remove("cdroms/cdrom%d", disk->number);
		dealloc_unique_number(&cdrom_numspace, disk->number);
	}
	devfs_remove(disk->devfs_name);
}


