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
a9a5b952
Commit
a9a5b952
authored
May 13, 2003
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge home:v2.5/linux
into penguin.transmeta.com:/home/torvalds/v2.5/linux
parents
84725bf0
55262c2d
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
210 additions
and
37 deletions
+210
-37
drivers/block/ll_rw_blk.c
drivers/block/ll_rw_blk.c
+121
-10
drivers/block/scsi_ioctl.c
drivers/block/scsi_ioctl.c
+2
-6
drivers/ide/ide-cd.c
drivers/ide/ide-cd.c
+1
-0
drivers/ide/ide-disk.c
drivers/ide/ide-disk.c
+13
-1
drivers/ide/ide-probe.c
drivers/ide/ide-probe.c
+5
-2
include/linux/bio.h
include/linux/bio.h
+19
-7
include/linux/blkdev.h
include/linux/blkdev.h
+49
-11
No files found.
drivers/block/ll_rw_blk.c
View file @
a9a5b952
...
...
@@ -1616,7 +1616,8 @@ static int __make_request(request_queue_t *q, struct bio *bio)
sector
=
bio
->
bi_sector
;
nr_sectors
=
bio_sectors
(
bio
);
cur_nr_sectors
=
bio_iovec
(
bio
)
->
bv_len
>>
9
;
cur_nr_sectors
=
bio_cur_sectors
(
bio
);
rw
=
bio_data_dir
(
bio
);
/*
...
...
@@ -1672,7 +1673,10 @@ static int __make_request(request_queue_t *q, struct bio *bio)
}
bio
->
bi_next
=
req
->
bio
;
req
->
bio
=
bio
;
req
->
cbio
=
req
->
bio
=
bio
;
req
->
nr_cbio_segments
=
bio_segments
(
bio
);
req
->
nr_cbio_sectors
=
bio_sectors
(
bio
);
/*
* may not be valid. if the low level driver said
* it didn't need a bounce buffer then it better
...
...
@@ -1740,9 +1744,11 @@ static int __make_request(request_queue_t *q, struct bio *bio)
req
->
current_nr_sectors
=
req
->
hard_cur_sectors
=
cur_nr_sectors
;
req
->
nr_phys_segments
=
bio_phys_segments
(
q
,
bio
);
req
->
nr_hw_segments
=
bio_hw_segments
(
q
,
bio
);
req
->
nr_cbio_segments
=
bio_segments
(
bio
);
req
->
nr_cbio_sectors
=
bio_sectors
(
bio
);
req
->
buffer
=
bio_data
(
bio
);
/* see ->buffer comment above */
req
->
waiting
=
NULL
;
req
->
bio
=
req
->
biotail
=
bio
;
req
->
cbio
=
req
->
bio
=
req
->
biotail
=
bio
;
req
->
rq_disk
=
bio
->
bi_bdev
->
bd_disk
;
req
->
start_time
=
jiffies
;
...
...
@@ -1914,6 +1920,81 @@ int submit_bio(int rw, struct bio *bio)
return
1
;
}
/**
* blk_rq_next_segment
* @rq: the request being processed
*
* Description:
* Points to the next segment in the request if the current segment
* is complete. Leaves things unchanged if this segment is not over
* or if no more segments are left in this request.
*
* Meant to be used for bio traversal during I/O submission
* Does not affect any I/O completions or update completion state
* in the request, and does not modify any bio fields.
*
* Decrementing rq->nr_sectors, rq->current_nr_sectors and
* rq->nr_cbio_sectors as data is transferred is the caller's
* responsibility and should be done before calling this routine.
**/
void
blk_rq_next_segment
(
struct
request
*
rq
)
{
if
(
rq
->
current_nr_sectors
>
0
)
return
;
if
(
rq
->
nr_cbio_sectors
>
0
)
{
--
rq
->
nr_cbio_segments
;
rq
->
current_nr_sectors
=
blk_rq_vec
(
rq
)
->
bv_len
>>
9
;
}
else
{
if
((
rq
->
cbio
=
rq
->
cbio
->
bi_next
))
{
rq
->
nr_cbio_segments
=
bio_segments
(
rq
->
cbio
);
rq
->
nr_cbio_sectors
=
bio_sectors
(
rq
->
cbio
);
rq
->
current_nr_sectors
=
bio_cur_sectors
(
rq
->
cbio
);
}
}
/* remember the size of this segment before we start I/O */
rq
->
hard_cur_sectors
=
rq
->
current_nr_sectors
;
}
/**
* process_that_request_first - process partial request submission
* @req: the request being processed
* @nr_sectors: number of sectors I/O has been submitted on
*
* Description:
* May be used for processing bio's while submitting I/O without
* signalling completion. Fails if more data is requested than is
* available in the request in which case it doesn't advance any
* pointers.
*
* Assumes a request is correctly set up. No sanity checks.
*
* Return:
* 0 - no more data left to submit (not processed)
* 1 - data available to submit for this request (processed)
**/
int
process_that_request_first
(
struct
request
*
req
,
unsigned
int
nr_sectors
)
{
unsigned
int
nsect
;
if
(
req
->
nr_sectors
<
nr_sectors
)
return
0
;
req
->
nr_sectors
-=
nr_sectors
;
req
->
sector
+=
nr_sectors
;
while
(
nr_sectors
)
{
nsect
=
min_t
(
unsigned
,
req
->
current_nr_sectors
,
nr_sectors
);
req
->
current_nr_sectors
-=
nsect
;
nr_sectors
-=
nsect
;
if
(
req
->
cbio
)
{
req
->
nr_cbio_sectors
-=
nsect
;
blk_rq_next_segment
(
req
);
}
}
return
1
;
}
void
blk_recalc_rq_segments
(
struct
request
*
rq
)
{
struct
bio
*
bio
;
...
...
@@ -1922,8 +2003,6 @@ void blk_recalc_rq_segments(struct request *rq)
if
(
!
rq
->
bio
)
return
;
rq
->
buffer
=
bio_data
(
rq
->
bio
);
nr_phys_segs
=
nr_hw_segs
=
0
;
rq_for_each_bio
(
bio
,
rq
)
{
/* Force bio hw/phys segs to be recalculated. */
...
...
@@ -1941,11 +2020,24 @@ void blk_recalc_rq_sectors(struct request *rq, int nsect)
{
if
(
blk_fs_request
(
rq
))
{
rq
->
hard_sector
+=
nsect
;
rq
->
nr_sectors
=
rq
->
hard_nr_sectors
-=
nsect
;
rq
->
sector
=
rq
->
hard_sector
;
rq
->
hard_nr_sectors
-=
nsect
;
rq
->
current_nr_sectors
=
bio_iovec
(
rq
->
bio
)
->
bv_len
>>
9
;
rq
->
hard_cur_sectors
=
rq
->
current_nr_sectors
;
/*
* Move the I/O submission pointers ahead if required,
* i.e. for drivers not aware of rq->cbio.
*/
if
((
rq
->
nr_sectors
>=
rq
->
hard_nr_sectors
)
&&
(
rq
->
sector
<=
rq
->
hard_sector
))
{
rq
->
sector
=
rq
->
hard_sector
;
rq
->
nr_sectors
=
rq
->
hard_nr_sectors
;
rq
->
hard_cur_sectors
=
bio_cur_sectors
(
rq
->
bio
);
rq
->
current_nr_sectors
=
rq
->
hard_cur_sectors
;
rq
->
nr_cbio_segments
=
bio_segments
(
rq
->
bio
);
rq
->
nr_cbio_sectors
=
bio_sectors
(
rq
->
bio
);
rq
->
buffer
=
bio_data
(
rq
->
bio
);
rq
->
cbio
=
rq
->
bio
;
}
/*
* if total number of sectors is less than the first segment
...
...
@@ -2139,9 +2231,27 @@ void blk_rq_bio_prep(request_queue_t *q, struct request *rq, struct bio *bio)
rq
->
current_nr_sectors
=
bio_cur_sectors
(
bio
);
rq
->
hard_cur_sectors
=
rq
->
current_nr_sectors
;
rq
->
hard_nr_sectors
=
rq
->
nr_sectors
=
bio_sectors
(
bio
);
rq
->
nr_cbio_segments
=
bio_segments
(
bio
);
rq
->
nr_cbio_sectors
=
bio_sectors
(
bio
);
rq
->
buffer
=
bio_data
(
bio
);
rq
->
bio
=
rq
->
biotail
=
bio
;
rq
->
cbio
=
rq
->
bio
=
rq
->
biotail
=
bio
;
}
void
blk_rq_prep_restart
(
struct
request
*
rq
)
{
struct
bio
*
bio
;
bio
=
rq
->
cbio
=
rq
->
bio
;
if
(
bio
)
{
rq
->
nr_cbio_segments
=
bio_segments
(
bio
);
rq
->
nr_cbio_sectors
=
bio_sectors
(
bio
);
rq
->
hard_cur_sectors
=
bio_cur_sectors
(
bio
);
rq
->
buffer
=
bio_data
(
bio
);
}
rq
->
sector
=
rq
->
hard_sector
;
rq
->
nr_sectors
=
rq
->
hard_nr_sectors
;
rq
->
current_nr_sectors
=
rq
->
hard_cur_sectors
;
}
int
__init
blk_dev_init
(
void
)
...
...
@@ -2169,6 +2279,7 @@ int __init blk_dev_init(void)
return
0
;
};
EXPORT_SYMBOL
(
process_that_request_first
);
EXPORT_SYMBOL
(
end_that_request_first
);
EXPORT_SYMBOL
(
end_that_request_chunk
);
EXPORT_SYMBOL
(
end_that_request_last
);
...
...
drivers/block/scsi_ioctl.c
View file @
a9a5b952
...
...
@@ -212,7 +212,7 @@ static int sg_io(request_queue_t *q, struct block_device *bdev,
}
}
rq
=
blk_get_request
(
q
,
WRITE
,
__GFP_WAIT
);
rq
=
blk_get_request
(
q
,
writing
?
WRITE
:
READ
,
__GFP_WAIT
);
/*
* fill in request structure
...
...
@@ -227,8 +227,6 @@ static int sg_io(request_queue_t *q, struct block_device *bdev,
rq
->
sense_len
=
0
;
rq
->
flags
|=
REQ_BLOCK_PC
;
if
(
writing
)
rq
->
flags
|=
REQ_RW
;
rq
->
hard_nr_sectors
=
rq
->
nr_sectors
=
nr_sectors
;
rq
->
hard_cur_sectors
=
rq
->
current_nr_sectors
=
nr_sectors
;
...
...
@@ -329,7 +327,7 @@ static int sg_scsi_ioctl(request_queue_t *q, struct block_device *bdev,
memset
(
buffer
,
0
,
bytes
);
}
rq
=
blk_get_request
(
q
,
WRITE
,
__GFP_WAIT
);
rq
=
blk_get_request
(
q
,
in_len
?
WRITE
:
READ
,
__GFP_WAIT
);
cmdlen
=
COMMAND_SIZE
(
opcode
);
...
...
@@ -373,8 +371,6 @@ static int sg_scsi_ioctl(request_queue_t *q, struct block_device *bdev,
rq
->
data
=
buffer
;
rq
->
data_len
=
bytes
;
rq
->
flags
|=
REQ_BLOCK_PC
;
if
(
in_len
)
rq
->
flags
|=
REQ_RW
;
blk_do_rq
(
q
,
bdev
,
rq
);
err
=
rq
->
errors
&
0xff
;
/* only 8 bit SCSI status */
...
...
drivers/ide/ide-cd.c
View file @
a9a5b952
...
...
@@ -2070,6 +2070,7 @@ static int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense)
req
.
sense
=
sense
;
req
.
cmd
[
0
]
=
GPCMD_TEST_UNIT_READY
;
req
.
flags
|=
REQ_QUIET
;
#if ! STANDARD_ATAPI
/* the Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to
...
...
drivers/ide/ide-disk.c
View file @
a9a5b952
...
...
@@ -1479,7 +1479,7 @@ static int probe_lba_addressing (ide_drive_t *drive, int arg)
static
int
set_lba_addressing
(
ide_drive_t
*
drive
,
int
arg
)
{
return
(
probe_lba_addressing
(
drive
,
arg
)
);
return
probe_lba_addressing
(
drive
,
arg
);
}
static
void
idedisk_add_settings
(
ide_drive_t
*
drive
)
...
...
@@ -1566,6 +1566,18 @@ static void idedisk_setup (ide_drive_t *drive)
(
void
)
probe_lba_addressing
(
drive
,
1
);
if
(
drive
->
addressing
==
1
)
{
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
int
max_s
=
2048
;
if
(
max_s
>
hwif
->
rqsize
)
max_s
=
hwif
->
rqsize
;
blk_queue_max_sectors
(
&
drive
->
queue
,
max_s
);
}
printk
(
"%s: max request size: %dKiB
\n
"
,
drive
->
name
,
drive
->
queue
.
max_sectors
/
2
);
/* Extract geometry if we did not already have one for the drive */
if
(
!
drive
->
cyl
||
!
drive
->
head
||
!
drive
->
sect
)
{
drive
->
cyl
=
drive
->
bios_cyl
=
id
->
cyls
;
...
...
drivers/ide/ide-probe.c
View file @
a9a5b952
...
...
@@ -998,6 +998,7 @@ EXPORT_SYMBOL(save_match);
static
void
ide_init_queue
(
ide_drive_t
*
drive
)
{
request_queue_t
*
q
=
&
drive
->
queue
;
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
int
max_sectors
=
256
;
/*
...
...
@@ -1013,8 +1014,10 @@ static void ide_init_queue(ide_drive_t *drive)
drive
->
queue_setup
=
1
;
blk_queue_segment_boundary
(
q
,
0xffff
);
if
(
HWIF
(
drive
)
->
rqsize
)
max_sectors
=
HWIF
(
drive
)
->
rqsize
;
if
(
!
hwif
->
rqsize
)
hwif
->
rqsize
=
hwif
->
addressing
?
256
:
65536
;
if
(
hwif
->
rqsize
<
max_sectors
)
max_sectors
=
hwif
->
rqsize
;
blk_queue_max_sectors
(
q
,
max_sectors
);
/* IDE DMA can do PRD_ENTRIES number of segments. */
...
...
include/linux/bio.h
View file @
a9a5b952
...
...
@@ -131,6 +131,7 @@ struct bio {
#define bio_iovec(bio) bio_iovec_idx((bio), (bio)->bi_idx)
#define bio_page(bio) bio_iovec((bio))->bv_page
#define bio_offset(bio) bio_iovec((bio))->bv_offset
#define bio_segments(bio) ((bio)->bi_vcnt - (bio)->bi_idx)
#define bio_sectors(bio) ((bio)->bi_size >> 9)
#define bio_cur_sectors(bio) (bio_iovec(bio)->bv_len >> 9)
#define bio_data(bio) (page_address(bio_page((bio))) + bio_offset((bio)))
...
...
@@ -226,12 +227,12 @@ extern void bio_check_pages_dirty(struct bio *bio);
#ifdef CONFIG_HIGHMEM
/*
* remember to add offset! and never ever reenable interrupts between a
* b
io_kmap_irq and bio
_kunmap_irq!!
* b
vec_kmap_irq and bvec
_kunmap_irq!!
*
* This function MUST be inlined - it plays with the CPU interrupt flags.
* Hence the `extern inline'.
*/
extern
inline
char
*
b
io_kmap_irq
(
struct
bio
*
bio
,
unsigned
long
*
flags
)
extern
inline
char
*
b
vec_kmap_irq
(
struct
bio_vec
*
bvec
,
unsigned
long
*
flags
)
{
unsigned
long
addr
;
...
...
@@ -240,15 +241,15 @@ extern inline char *bio_kmap_irq(struct bio *bio, unsigned long *flags)
* balancing is a lot nicer this way
*/
local_irq_save
(
*
flags
);
addr
=
(
unsigned
long
)
kmap_atomic
(
b
io_page
(
bio
)
,
KM_BIO_SRC_IRQ
);
addr
=
(
unsigned
long
)
kmap_atomic
(
b
vec
->
bv_page
,
KM_BIO_SRC_IRQ
);
if
(
addr
&
~
PAGE_MASK
)
BUG
();
return
(
char
*
)
addr
+
b
io_offset
(
bio
)
;
return
(
char
*
)
addr
+
b
vec
->
bv_offset
;
}
extern
inline
void
b
io
_kunmap_irq
(
char
*
buffer
,
unsigned
long
*
flags
)
extern
inline
void
b
vec
_kunmap_irq
(
char
*
buffer
,
unsigned
long
*
flags
)
{
unsigned
long
ptr
=
(
unsigned
long
)
buffer
&
PAGE_MASK
;
...
...
@@ -257,8 +258,19 @@ extern inline void bio_kunmap_irq(char *buffer, unsigned long *flags)
}
#else
#define b
io_kmap_irq(bio, flags) (bio_data(bio)
)
#define b
io
_kunmap_irq(buf, flags) do { *(flags) = 0; } while (0)
#define b
vec_kmap_irq(bvec, flags) (page_address((bvec)->bv_page) + (bvec)->bv_offset
)
#define b
vec
_kunmap_irq(buf, flags) do { *(flags) = 0; } while (0)
#endif
extern
inline
char
*
__bio_kmap_irq
(
struct
bio
*
bio
,
unsigned
short
idx
,
unsigned
long
*
flags
)
{
return
bvec_kmap_irq
(
bio_iovec_idx
(
bio
,
idx
),
flags
);
}
#define __bio_kunmap_irq(buf, flags) bvec_kunmap_irq(buf, flags)
#define bio_kmap_irq(bio, flags) \
__bio_kmap_irq((bio), (bio)->bi_idx, (flags))
#define bio_kunmap_irq(buf,flags) __bio_kunmap_irq(buf, flags)
#endif
/* __LINUX_BIO_H */
include/linux/blkdev.h
View file @
a9a5b952
...
...
@@ -11,6 +11,7 @@
#include <linux/backing-dev.h>
#include <linux/wait.h>
#include <linux/mempool.h>
#include <linux/bio.h>
#include <asm/scatterlist.h>
...
...
@@ -36,25 +37,35 @@ struct request {
* blkdev_dequeue_request! */
unsigned
long
flags
;
/* see REQ_ bits below */
sector_t
sector
;
unsigned
long
nr_sectors
;
/* Maintain bio traversal state for part by part I/O submission.
* hard_* are block layer internals, no driver should touch them!
*/
sector_t
sector
;
/* next sector to submit */
unsigned
long
nr_sectors
;
/* no. of sectors left to submit */
/* no. of sectors left to submit in the current segment */
unsigned
int
current_nr_sectors
;
sector_t
hard_sector
;
/* next sector to complete */
unsigned
long
hard_nr_sectors
;
/* no. of sectors left to complete */
/* no. of sectors left to complete in the current segment */
unsigned
int
hard_cur_sectors
;
/* no. of segments left to submit in the current bio */
unsigned
short
nr_cbio_segments
;
/* no. of sectors left to submit in the current bio */
unsigned
long
nr_cbio_sectors
;
struct
bio
*
cbio
;
/* next bio to submit */
struct
bio
*
bio
;
/* next unfinished bio to complete */
struct
bio
*
biotail
;
void
*
elevator_private
;
int
rq_status
;
/* should split this into a few status bits */
struct
gendisk
*
rq_disk
;
int
errors
;
unsigned
long
start_time
;
sector_t
hard_sector
;
/* the hard_* are block layer
* internals, no driver should
* touch them
*/
unsigned
long
hard_nr_sectors
;
unsigned
int
hard_cur_sectors
;
struct
bio
*
bio
;
struct
bio
*
biotail
;
/* Number of scatter-gather DMA addr+len pairs after
* physical address coalescing is performed.
...
...
@@ -284,6 +295,32 @@ struct request_queue
*/
#define blk_queue_headactive(q, head_active)
/* current index into bio being processed for submission */
#define blk_rq_idx(rq) ((rq)->cbio->bi_vcnt - (rq)->nr_cbio_segments)
/* current bio vector being processed */
#define blk_rq_vec(rq) (bio_iovec_idx((rq)->cbio, blk_rq_idx(rq)))
/* current offset with respect to start of the segment being submitted */
#define blk_rq_offset(rq) \
(((rq)->hard_cur_sectors - (rq)->current_nr_sectors) << 9)
/*
* temporarily mapping a (possible) highmem bio (typically for PIO transfer)
*/
/* Assumes rq->cbio != NULL */
static
inline
char
*
rq_map_buffer
(
struct
request
*
rq
,
unsigned
long
*
flags
)
{
return
(
__bio_kmap_irq
(
rq
->
cbio
,
blk_rq_idx
(
rq
),
flags
)
+
blk_rq_offset
(
rq
));
}
static
inline
void
rq_unmap_buffer
(
char
*
buffer
,
unsigned
long
*
flags
)
{
__bio_kunmap_irq
(
buffer
,
flags
);
}
/*
* q->prep_rq_fn return values
*/
...
...
@@ -362,6 +399,7 @@ static inline request_queue_t *bdev_get_queue(struct block_device *bdev)
extern
int
end_that_request_first
(
struct
request
*
,
int
,
int
);
extern
int
end_that_request_chunk
(
struct
request
*
,
int
,
int
);
extern
void
end_that_request_last
(
struct
request
*
);
extern
int
process_that_request_first
(
struct
request
*
,
unsigned
int
);
extern
void
end_request
(
struct
request
*
req
,
int
uptodate
);
static
inline
void
blkdev_dequeue_request
(
struct
request
*
req
)
...
...
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