Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
d572f1a5
Commit
d572f1a5
authored
Aug 13, 2002
by
Alexander Viro
Committed by
Andy Grover
Aug 13, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] per-disk gendisks in ataraid
parent
59a00f8c
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
77 additions
and
251 deletions
+77
-251
drivers/ide/ataraid.c
drivers/ide/ataraid.c
+36
-31
drivers/ide/ataraid.h
drivers/ide/ataraid.h
+1
-8
drivers/ide/hptraid.c
drivers/ide/hptraid.c
+18
-74
drivers/ide/pdcraid.c
drivers/ide/pdcraid.c
+22
-134
fs/partitions/check.c
fs/partitions/check.c
+0
-4
No files found.
drivers/ide/ataraid.c
View file @
d572f1a5
...
...
@@ -28,6 +28,7 @@
#include <linux/ioctl.h>
#include <linux/kdev_t.h>
#include <linux/swap.h>
#include <linux/buffer_head.h>
#include <linux/ide.h>
#include <asm/uaccess.h>
...
...
@@ -44,7 +45,9 @@ static void ataraid_split_request(request_queue_t * q, int rw,
struct
buffer_head
*
bh
);
struct
gendisk
ataraid_gendisk
;
static
struct
gendisk
ataraid_gendisk
[
16
];
static
struct
hd_struct
*
ataraid_part
;
static
char
*
ataraid_names
;
static
int
ataraid_readahead
[
256
];
static
struct
block_device_operations
ataraid_fops
=
{
...
...
@@ -229,9 +232,28 @@ void ataraid_release_device(int device)
void
ataraid_register_disk
(
int
device
,
long
size
)
{
register_disk
(
&
ataraid_gendisk
,
mk_kdev
(
ATAMAJOR
,
16
*
device
),
16
,
&
ataraid_fops
,
size
);
struct
gendisk
*
disk
=
ataraid_gendisk
+
device
;
char
*
name
=
ataraid_names
+
12
*
device
;
sprintf
(
name
,
"ataraid/d%d"
,
device
);
disk
->
part
=
ataraid_part
+
16
*
device
;
disk
->
major
=
ATAMAJOR
;
disk
->
first_minor
=
16
*
device
;
disk
->
major_name
=
name
;
disk
->
minor_shift
=
4
;
disk
->
nr_real
=
1
;
disk
->
fops
=
&
ataraid_fops
;
add_gendisk
(
disk
);
register_disk
(
disk
,
mk_kdev
(
disk
->
major
,
disk
->
first_minor
),
1
<<
disk
->
minor_shift
,
disk
->
fops
,
size
);
}
void
ataraid_unregister_disk
(
int
device
)
{
del_gendisk
(
&
ataraid_gendisk
[
device
]);
}
static
__init
int
ataraid_init
(
void
)
...
...
@@ -241,61 +263,44 @@ static __init int ataraid_init(void)
ataraid_readahead
[
i
]
=
1023
;
/* setup the gendisk structure */
ataraid_gendisk
.
part
=
kmalloc
(
256
*
sizeof
(
struct
hd_struct
),
GFP_KERNEL
);
if
(
ataraid_gendisk
.
part
==
NULL
)
{
ataraid_part
=
kmalloc
(
256
*
sizeof
(
struct
hd_struct
),
GFP_KERNEL
);
ataraid_names
=
kmalloc
(
16
*
12
,
GFP_KERNEL
);
if
(
!
ataraid_part
||
!
ataraid_names
)
{
kfree
(
ataraid_part
);
kfree
(
ataraid_names
);
printk
(
KERN_ERR
"ataraid: Couldn't allocate memory, aborting
\n
"
);
return
-
1
;
}
memset
(
&
ataraid_gendisk
.
part
[
0
],
0
,
256
*
sizeof
(
struct
hd_struct
));
ataraid_gendisk
.
major
=
ATAMAJOR
;
ataraid_gendisk
.
major_name
=
"ataraid"
;
ataraid_gendisk
.
minor_shift
=
4
;
ataraid_gendisk
.
nr_real
=
16
;
ataraid_gendisk
.
fops
=
&
ataraid_fops
;
add_gendisk
(
&
ataraid_gendisk
);
memset
(
ataraid_part
,
0
,
256
*
sizeof
(
struct
hd_struct
));
if
(
register_blkdev
(
ATAMAJOR
,
"ataraid"
,
&
ataraid_fops
))
{
kfree
(
ataraid_part
);
kfree
(
ataraid_names
);
printk
(
KERN_ERR
"ataraid: Could not get major %d
\n
"
,
ATAMAJOR
);
return
-
1
;
}
blk_queue_make_request
(
BLK_DEFAULT_QUEUE
(
ATAMAJOR
),
ataraid_make_request
);
return
0
;
}
static
void
__exit
ataraid_exit
(
void
)
{
unregister_blkdev
(
ATAMAJOR
,
"ataraid"
);
del_gendisk
(
&
ataraid_gendisk
);
if
(
ataraid_gendisk
.
part
)
{
kfree
(
ataraid_gendisk
.
part
);
ataraid_gendisk
.
part
=
NULL
;
}
kfree
(
ataraid_part
);
kfree
(
ataraid_names
);
}
module_init
(
ataraid_init
);
module_exit
(
ataraid_exit
);
EXPORT_SYMBOL
(
ataraid_get_device
);
EXPORT_SYMBOL
(
ataraid_release_device
);
EXPORT_SYMBOL
(
ataraid_gendisk
);
EXPORT_SYMBOL
(
ataraid_register_disk
);
EXPORT_SYMBOL
(
ataraid_unregister_disk
);
MODULE_LICENSE
(
"GPL"
);
drivers/ide/ataraid.h
View file @
d572f1a5
...
...
@@ -56,17 +56,10 @@ struct ataraid_bh_private {
atomic_t
count
;
};
extern
struct
gendisk
ataraid_gendisk
;
extern
int
ataraid_get_device
(
struct
raid_device_operations
*
fops
);
extern
void
ataraid_release_device
(
int
device
);
extern
int
get_blocksize
(
kdev_t
dev
);
extern
void
ataraid_register_disk
(
int
device
,
long
size
);
extern
void
ataraid_unregister_disk
(
int
device
);
extern
struct
buffer_head
*
ataraid_get_bhead
(
void
);
extern
struct
ataraid_bh_private
*
ataraid_get_private
(
void
);
extern
void
ataraid_end_request
(
struct
buffer_head
*
bh
,
int
uptodate
);
drivers/ide/hptraid.c
View file @
d572f1a5
...
...
@@ -74,62 +74,20 @@ static struct hptraid raid[16];
static
int
hptraid_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
unsigned
int
minor
;
unsigned
char
val
;
unsigned
long
sectors
;
if
(
!
inode
||
kdev_none
(
inode
->
i_rdev
))
return
-
EINVAL
;
minor
=
minor
(
inode
->
i_rdev
)
>>
SHIFT
;
switch
(
cmd
)
{
case
BLKGETSIZE
:
/* Return device size */
if
(
!
arg
)
return
-
EINVAL
;
sectors
=
ataraid_gendisk
.
part
[
minor
(
inode
->
i_rdev
)].
nr_sects
;
if
(
minor
(
inode
->
i_rdev
)
&
15
)
return
put_user
(
sectors
,
(
unsigned
long
*
)
arg
);
return
put_user
(
raid
[
minor
].
sectors
,
(
unsigned
long
*
)
arg
);
break
;
case
HDIO_GETGEO
:
{
struct
hd_geometry
*
loc
=
(
struct
hd_geometry
*
)
arg
;
unsigned
short
bios_cyl
;
if
(
!
loc
)
return
-
EINVAL
;
val
=
255
;
if
(
put_user
(
val
,
(
u8
*
)
&
loc
->
heads
))
return
-
EFAULT
;
val
=
63
;
if
(
put_user
(
val
,
(
u8
*
)
&
loc
->
sectors
))
return
-
EFAULT
;
bios_cyl
=
raid
[
minor
].
sectors
/
63
/
255
;
if
(
put_user
(
bios_cyl
,
(
unsigned
short
*
)
&
loc
->
cylinders
))
return
-
EFAULT
;
if
(
put_user
((
unsigned
)
ataraid_gendisk
.
part
[
minor
(
inode
->
i_rdev
)].
start_sect
,
(
unsigned
long
*
)
&
loc
->
start
))
return
-
EFAULT
;
return
0
;
}
unsigned
int
minor
=
minor
(
inode
->
i_rdev
)
>>
SHIFT
;
struct
hd_geometry
*
geometry
=
(
struct
hd_geometry
*
)
arg
;
struct
hd_geometry
g
;
default:
if
(
cmd
!=
HDIO_GETGEO
)
return
-
EINVAL
;
};
return
0
;
g
.
heads
=
255
;
g
.
sectors
=
63
;
g
.
cylinders
=
raid
[
minor
].
sectors
/
63
/
255
;
g
.
start
=
get_start_sect
(
inode
->
i_bdev
);
return
copy_to_user
(
geometry
,
&
g
,
sizeof
g
)
?
-
EFAULT
:
0
;
}
static
int
hptraid_make_request
(
request_queue_t
*
q
,
int
rw
,
struct
buffer_head
*
bh
)
{
...
...
@@ -160,10 +118,6 @@ static int hptraid_make_request(request_queue_t * q, int rw,
if
(
thisraid
->
stride
==
0
)
thisraid
->
stride
=
1
;
/* Partitions need adding of the start sector of the partition to the requested sector */
rsect
+=
ataraid_gendisk
.
part
[
minor
(
bh
->
b_rdev
)].
start_sect
;
/* Woops we need to split the request to avoid crossing a stride barrier */
if
((
rsect
/
thisraid
->
stride
)
!=
((
rsect
+
(
bh
->
b_size
/
512
)
-
1
)
/
thisraid
->
stride
))
{
...
...
@@ -273,7 +227,6 @@ static void __init probedisk(int major, int minor, int device)
{
int
i
;
struct
block_device
*
bdev
=
bdget
(
mk_kdev
(
major
,
minor
));
struct
gendisk
*
gd
;
if
(
!
bdev
)
return
;
...
...
@@ -301,19 +254,9 @@ static void __init probedisk(int major, int minor, int device)
if
(
i
>
8
)
goto
out
;
if
(
bd_claim
(
bdev
,
&
raid
[
device
].
disk
[
i
])
<
0
)
goto
out
;
raid
[
device
].
disk
[
i
].
bdev
=
bdev
;
/* This is supposed to prevent others from stealing our underlying disks */
/* now blank the /proc/partitions table for the wrong partition table,
so that scripts don't accidentally mount it and crash the kernel */
/* XXX: the 0 is an utter hack --hch */
gd
=
get_gendisk
(
mk_kdev
(
major
,
0
));
if
(
gd
!=
NULL
)
{
int
j
;
for
(
j
=
1
+
(
minor
<<
gd
->
minor_shift
);
j
<
((
minor
+
1
)
<<
gd
->
minor_shift
);
j
++
)
gd
->
part
[
j
].
nr_sects
=
0
;
}
raid
[
device
].
disk
[
i
].
device
=
mk_kdev
(
major
,
minor
);
raid
[
device
].
disk
[
i
].
sectors
=
maxsectors
(
major
,
minor
);
raid
[
device
].
stride
=
(
1
<<
prom
.
raid0_shift
);
...
...
@@ -367,10 +310,6 @@ static __init int hptraid_init_one(int device)
fill_cutoff
(
device
);
/* Initialize the gendisk structure */
ataraid_register_disk
(
device
,
raid
[
device
].
sectors
);
count
=
0
;
printk
(
KERN_INFO
"Highpoint HPT370 Softwareraid driver for linux version 0.01
\n
"
);
...
...
@@ -383,6 +322,7 @@ static __init int hptraid_init_one(int device)
}
}
if
(
count
)
{
ataraid_register_disk
(
device
,
raid
[
device
].
sectors
);
printk
(
KERN_INFO
"Raid array consists of %i drives.
\n
"
,
count
);
return
0
;
...
...
@@ -414,11 +354,15 @@ static void __exit hptraid_exit(void)
struct
block_device
*
bdev
=
raid
[
device
].
disk
[
i
].
bdev
;
raid
[
device
].
disk
[
i
].
bdev
=
NULL
;
if
(
bdev
)
if
(
bdev
)
{
bd_release
(
bdev
);
blkdev_put
(
bdev
,
BDEV_RAW
);
}
}
if
(
raid
[
device
].
sectors
)
if
(
raid
[
device
].
sectors
)
{
ataraid_unregister_disk
(
device
);
ataraid_release_device
(
device
);
}
}
}
...
...
drivers/ide/pdcraid.c
View file @
d572f1a5
...
...
@@ -103,118 +103,18 @@ static struct pdcraid raid[16];
static
int
pdcraid_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
unsigned
int
minor
;
unsigned
long
sectors
;
if
(
!
inode
||
kdev_none
(
inode
->
i_rdev
)
)
unsigned
int
minor
=
minor
(
inode
->
i_rdev
)
>>
SHIFT
;
struct
hd_geometry
*
geometry
=
(
struct
hd_geometry
*
)
arg
;
struct
hd_geometry
g
;
if
(
cmd
!=
HDIO_GETGEO
)
return
-
EINVAL
;
minor
=
minor
(
inode
->
i_rdev
)
>>
SHIFT
;
switch
(
cmd
)
{
case
BLKGETSIZE
:
/* Return device size */
if
(
!
arg
)
return
-
EINVAL
;
sectors
=
ataraid_gendisk
.
part
[
minor
(
inode
->
i_rdev
)].
nr_sects
;
if
(
minor
(
inode
->
i_rdev
)
&
15
)
return
put_user
(
sectors
,
(
unsigned
long
*
)
arg
);
return
put_user
(
raid
[
minor
].
sectors
,
(
unsigned
long
*
)
arg
);
break
;
case
HDIO_GETGEO
:
{
struct
hd_geometry
*
loc
=
(
struct
hd_geometry
*
)
arg
;
unsigned
short
bios_cyl
=
raid
[
minor
].
geom
.
cylinders
;
/* truncate */
if
(
!
loc
)
return
-
EINVAL
;
if
(
put_user
(
raid
[
minor
].
geom
.
heads
,
(
u8
*
)
&
loc
->
heads
))
return
-
EFAULT
;
if
(
put_user
(
raid
[
minor
].
geom
.
sectors
,
(
u8
*
)
&
loc
->
sectors
))
return
-
EFAULT
;
if
(
put_user
(
bios_cyl
,
(
unsigned
short
*
)
&
loc
->
cylinders
))
return
-
EFAULT
;
if
(
put_user
((
unsigned
)
ataraid_gendisk
.
part
[
minor
(
inode
->
i_rdev
)].
start_sect
,
(
unsigned
long
*
)
&
loc
->
start
))
return
-
EFAULT
;
return
0
;
}
default:
printk
(
"Invalid ioctl
\n
"
);
return
-
EINVAL
;
};
return
0
;
}
unsigned
long
partition_map_normal
(
unsigned
long
block
,
unsigned
long
partition_off
,
unsigned
long
partition_size
,
int
stride
)
{
return
block
+
partition_off
;
}
unsigned
long
partition_map_linux
(
unsigned
long
block
,
unsigned
long
partition_off
,
unsigned
long
partition_size
,
int
stride
)
{
unsigned
long
newblock
;
newblock
=
stride
-
(
partition_off
%
stride
);
if
(
newblock
==
stride
)
newblock
=
0
;
newblock
+=
block
;
newblock
=
newblock
%
partition_size
;
newblock
+=
partition_off
;
return
newblock
;
}
static
int
funky_remap
[
8
]
=
{
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
};
unsigned
long
partition_map_linux_raid0_4disk
(
unsigned
long
block
,
unsigned
long
partition_off
,
unsigned
long
partition_size
,
int
stride
)
{
unsigned
long
newblock
,
temp
,
temp2
;
newblock
=
stride
-
(
partition_off
%
stride
);
if
(
newblock
==
stride
)
newblock
=
0
;
if
(
block
<
(
partition_size
/
(
8
*
stride
))
*
8
*
stride
)
{
temp
=
block
%
stride
;
temp2
=
block
/
stride
;
temp2
=
((
temp2
>>
3
)
<<
3
)
|
(
funky_remap
[
temp2
&
7
]);
block
=
temp2
*
stride
+
temp
;
}
newblock
+=
block
;
newblock
=
newblock
%
partition_size
;
newblock
+=
partition_off
;
return
newblock
;
g
.
heads
=
raid
[
minor
].
geom
.
heads
;
g
.
sectors
=
raid
[
minor
].
geom
.
sectors
;
g
.
cylinders
=
raid
[
minor
].
geom
.
cylinders
;
g
.
start
=
get_start_sect
(
inode
->
i_bdev
);
return
copy_to_user
(
geometry
,
&
g
,
sizeof
g
)
?
-
EFAULT
:
0
;
}
static
int
pdcraid0_make_request
(
request_queue_t
*
q
,
int
rw
,
struct
buffer_head
*
bh
)
{
...
...
@@ -240,20 +140,11 @@ static int pdcraid0_make_request(request_queue_t * q, int rw,
* point, we have to divide by one less.
*/
device
=
(
bh
->
b_rdev
>>
SHIFT
)
&
MAJOR_MASK
;
device
=
minor
(
bh
->
b_rdev
)
>>
SHIFT
;
thisraid
=
&
raid
[
device
];
if
(
thisraid
->
stride
==
0
)
thisraid
->
stride
=
1
;
/* Partitions need adding of the start sector of the partition to the requested sector */
rsect
=
partition_map_normal
(
rsect
,
ataraid_gendisk
.
part
[
MINOR
(
bh
->
b_rdev
)].
start_sect
,
ataraid_gendisk
.
part
[
MINOR
(
bh
->
b_rdev
)].
nr_sects
,
thisraid
->
stride
);
/* Woops we need to split the request to avoid crossing a stride barrier */
if
((
rsect
/
thisraid
->
stride
)
!=
((
rsect
+
(
bh
->
b_size
/
512
)
-
1
)
/
thisraid
->
stride
))
{
...
...
@@ -320,7 +211,7 @@ static int pdcraid1_write_request(request_queue_t * q, int rw,
int
device
;
int
i
;
device
=
(
bh
->
b_rdev
>>
SHIFT
)
&
MAJOR_MASK
;
device
=
minor
(
bh
->
b_rdev
)
>>
SHIFT
;
private
=
ataraid_get_private
();
if
(
private
==
NULL
)
BUG
();
...
...
@@ -341,7 +232,6 @@ static int pdcraid1_write_request(request_queue_t * q, int rw,
bh1
->
b_end_io
=
ataraid_end_request
;
bh1
->
b_private
=
private
;
bh1
->
b_rsector
+=
ataraid_gendisk
.
part
[
MINOR
(
bh
->
b_rdev
)].
start_sect
;
/* partition offset */
bh1
->
b_rdev
=
raid
[
device
].
disk
[
i
].
device
;
/* update the last known head position for the drive */
...
...
@@ -361,15 +251,13 @@ static int pdcraid1_read_request(request_queue_t * q, int rw,
int
bestsofar
,
bestdist
,
i
;
static
int
previous
;
device
=
minor
(
bh
->
b_rdev
)
>>
SHIFT
;
/* Reads are simple in principle. Pick a disk and go.
Initially I cheat by just picking the one which the last known
head position is closest by.
Later on, online/offline checking and performance needs adding */
device
=
(
bh
->
b_rdev
>>
SHIFT
)
&
MAJOR_MASK
;
bh
->
b_rsector
+=
ataraid_gendisk
.
part
[
MINOR
(
bh
->
b_rdev
)].
start_sect
;
bestsofar
=
0
;
bestdist
=
raid
[
device
].
disk
[
0
].
last_pos
-
bh
->
b_rsector
;
if
(
bestdist
<
0
)
...
...
@@ -575,6 +463,7 @@ static void __init fill_cutoff(int device)
static
__init
int
pdcraid_init_one
(
int
device
,
int
raidlevel
)
{
int
i
,
count
;
struct
pdcraid
*
p
=
raid
+
device
;
for
(
i
=
0
;
i
<
14
;
i
++
)
probedisk
(
i
,
device
,
raidlevel
);
...
...
@@ -582,22 +471,19 @@ static __init int pdcraid_init_one(int device, int raidlevel)
if
(
raidlevel
==
0
)
fill_cutoff
(
device
);
/* Initialize the gendisk structure */
ataraid_register_disk
(
device
,
raid
[
device
].
sectors
);
count
=
0
;
for
(
i
=
0
;
i
<
8
;
i
++
)
{
if
(
raid
[
device
].
disk
[
i
].
device
!=
0
)
{
if
(
p
->
disk
[
i
].
device
!=
0
)
{
printk
(
KERN_INFO
"Drive %i is %li Mb (%i / %i)
\n
"
,
i
,
raid
[
device
].
disk
[
i
].
sectors
/
2048
,
major
(
raid
[
device
].
disk
[
i
].
device
),
minor
(
raid
[
device
].
disk
[
i
].
device
));
i
,
p
->
disk
[
i
].
sectors
/
2048
,
major
(
p
->
disk
[
i
].
device
),
minor
(
p
->
disk
[
i
].
device
));
count
++
;
}
}
if
(
count
)
{
ataraid_register_disk
(
device
,
p
->
sectors
);
printk
(
KERN_INFO
"Raid%i array consists of %i drives.
\n
"
,
raidlevel
,
count
);
return
0
;
...
...
@@ -660,8 +546,10 @@ static void __exit pdcraid_exit(void)
if
(
bdev
)
blkdev_put
(
bdev
,
BDEV_RAW
);
}
if
(
raid
[
device
].
sectors
)
if
(
raid
[
device
].
sectors
)
{
ataraid_unregister_disk
(
device
);
ataraid_release_device
(
device
);
}
}
}
...
...
fs/partitions/check.c
View file @
d572f1a5
...
...
@@ -137,10 +137,6 @@ char *disk_name (struct gendisk *hd, int minor, char *buf)
sprintf
(
s
,
"%s%d"
,
"md"
,
unit
);
maj
=
s
;
break
;
case
ATARAID_MAJOR
:
sprintf
(
s
,
"ataraid/d%d"
,
unit
);
maj
=
s
;
break
;
case
ACSI_MAJOR
:
case
I2O_MAJOR
:
case
DASD_MAJOR
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment