Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 110494
b: refs/heads/master
c: 3e1a7ff
h: refs/heads/master
v: v3
  • Loading branch information
Tejun Heo authored and Jens Axboe committed Oct 9, 2008
1 parent c38dce7 commit 6499c75
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 24 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 689d6fac40b41c7bf154f362deaf442548e4dc81
refs/heads/master: 3e1a7ff8a0a7b948f2684930166954f9e8e776fe
25 changes: 24 additions & 1 deletion trunk/block/genhd.c
Original file line number Diff line number Diff line change
Expand Up @@ -478,14 +478,37 @@ static int exact_lock(dev_t devt, void *data)
*
* This function registers the partitioning information in @disk
* with the kernel.
*
* FIXME: error handling
*/
void add_disk(struct gendisk *disk)
{
struct backing_dev_info *bdi;
dev_t devt;
int retval;

/* minors == 0 indicates to use ext devt from part0 and should
* be accompanied with EXT_DEVT flag. Make sure all
* parameters make sense.
*/
WARN_ON(disk->minors && !(disk->major || disk->first_minor));
WARN_ON(!disk->minors && !(disk->flags & GENHD_FL_EXT_DEVT));

disk->flags |= GENHD_FL_UP;
disk_to_dev(disk)->devt = MKDEV(disk->major, disk->first_minor);

retval = blk_alloc_devt(&disk->part0, &devt);
if (retval) {
WARN_ON(1);
return;
}
disk_to_dev(disk)->devt = devt;

/* ->major and ->first_minor aren't supposed to be
* dereferenced from here on, but set them just in case.
*/
disk->major = MAJOR(devt);
disk->first_minor = MINOR(devt);

blk_register_region(disk_devt(disk), disk->minors, NULL,
exact_match, exact_lock, disk);
register_disk(disk);
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/ide/ide-disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
#if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT)
#define IDE_DISK_MINORS (1 << PARTN_BITS)
#else
#define IDE_DISK_MINORS 1
#define IDE_DISK_MINORS 0
#endif

struct ide_disk_obj {
Expand Down
74 changes: 54 additions & 20 deletions trunk/drivers/scsi/sd.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC);
#if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT)
#define SD_MINORS 16
#else
#define SD_MINORS 1
#define SD_MINORS 0
#endif

static int sd_revalidate_disk(struct gendisk *);
Expand Down Expand Up @@ -1769,6 +1769,52 @@ static int sd_revalidate_disk(struct gendisk *disk)
return 0;
}

/**
* sd_format_disk_name - format disk name
* @prefix: name prefix - ie. "sd" for SCSI disks
* @index: index of the disk to format name for
* @buf: output buffer
* @buflen: length of the output buffer
*
* SCSI disk names starts at sda. The 26th device is sdz and the
* 27th is sdaa. The last one for two lettered suffix is sdzz
* which is followed by sdaaa.
*
* This is basically 26 base counting with one extra 'nil' entry
* at the beggining from the second digit on and can be
* determined using similar method as 26 base conversion with the
* index shifted -1 after each digit is computed.
*
* CONTEXT:
* Don't care.
*
* RETURNS:
* 0 on success, -errno on failure.
*/
static int sd_format_disk_name(char *prefix, int index, char *buf, int buflen)
{
const int base = 'z' - 'a' + 1;
char *begin = buf + strlen(prefix);
char *end = buf + buflen;
char *p;
int unit;

p = end - 1;
*p = '\0';
unit = base;
do {
if (p == begin)
return -EINVAL;
*--p = 'a' + (index % unit);
index = (index / unit) - 1;
} while (index >= 0);

memmove(begin, p, end - p);
memcpy(buf, prefix, strlen(prefix));

return 0;
}

/**
* sd_probe - called during driver initialization and whenever a
* new scsi device is attached to the system. It is called once
Expand Down Expand Up @@ -1821,8 +1867,8 @@ static int sd_probe(struct device *dev)
if (error)
goto out_put;

error = -EBUSY;
if (index >= SD_MAX_DISKS)
error = sd_format_disk_name("sd", index, gd->disk_name, DISK_NAME_LEN);
if (error)
goto out_free_index;

sdkp->device = sdp;
Expand All @@ -1849,24 +1895,12 @@ static int sd_probe(struct device *dev)

get_device(&sdp->sdev_gendev);

gd->major = sd_major((index & 0xf0) >> 4);
gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00);
gd->minors = SD_MINORS;
gd->fops = &sd_fops;

if (index < 26) {
sprintf(gd->disk_name, "sd%c", 'a' + index % 26);
} else if (index < (26 + 1) * 26) {
sprintf(gd->disk_name, "sd%c%c",
'a' + index / 26 - 1,'a' + index % 26);
} else {
const unsigned int m1 = (index / 26 - 1) / 26 - 1;
const unsigned int m2 = (index / 26 - 1) % 26;
const unsigned int m3 = index % 26;
sprintf(gd->disk_name, "sd%c%c%c",
'a' + m1, 'a' + m2, 'a' + m3);
if (index < SD_MAX_DISKS) {
gd->major = sd_major((index & 0xf0) >> 4);
gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00);
gd->minors = SD_MINORS;
}

gd->fops = &sd_fops;
gd->private_data = &sdkp->driver;
gd->queue = sdkp->device->request_queue;

Expand Down
1 change: 1 addition & 0 deletions trunk/fs/partitions/check.c
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,7 @@ void del_gendisk(struct gendisk *disk)
disk_part_iter_exit(&piter);

invalidate_partition(disk, 0);
blk_free_devt(disk_to_dev(disk)->devt);
set_capacity(disk, 0);
disk->flags &= ~GENHD_FL_UP;
unlink_gendisk(disk);
Expand Down
3 changes: 2 additions & 1 deletion trunk/include/linux/genhd.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ enum {
};

#define DISK_MAX_PARTS 256
#define DISK_NAME_LEN 32

#include <linux/major.h>
#include <linux/device.h>
Expand Down Expand Up @@ -140,7 +141,7 @@ struct gendisk {
int minors; /* maximum number of minors, =1 for
* disks that can't be partitioned. */

char disk_name[32]; /* name of major driver */
char disk_name[DISK_NAME_LEN]; /* name of major driver */

/* Array of pointers to partitions indexed by partno.
* Protected with matching bdev lock but stat and other
Expand Down

0 comments on commit 6499c75

Please sign in to comment.