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
Kirill Smelkov
linux
Commits
c21c3ad0
Commit
c21c3ad0
authored
Oct 02, 2002
by
Andrew Morton
Committed by
Linus Torvalds
Oct 02, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] convert direct-io to use bio_add_page()
From Badari Pavlati. Use bio_add_page() in direct-io.c.
parent
7b88e5e0
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
43 additions
and
40 deletions
+43
-40
fs/direct-io.c
fs/direct-io.c
+43
-40
No files found.
fs/direct-io.c
View file @
c21c3ad0
...
@@ -23,12 +23,6 @@
...
@@ -23,12 +23,6 @@
#include <linux/rwsem.h>
#include <linux/rwsem.h>
#include <asm/atomic.h>
#include <asm/atomic.h>
/*
* The largest-sized BIO which this code will assemble, in bytes. Set this
* to PAGE_SIZE if your drivers are broken.
*/
#define DIO_BIO_MAX_SIZE (16*1024)
/*
/*
* How many user pages to map in one call to get_user_pages(). This determines
* How many user pages to map in one call to get_user_pages(). This determines
* the size of a structure on the stack.
* the size of a structure on the stack.
...
@@ -38,7 +32,6 @@
...
@@ -38,7 +32,6 @@
struct
dio
{
struct
dio
{
/* BIO submission state */
/* BIO submission state */
struct
bio
*
bio
;
/* bio under assembly */
struct
bio
*
bio
;
/* bio under assembly */
struct
bio_vec
*
bvec
;
/* current bvec in that bio */
struct
inode
*
inode
;
struct
inode
*
inode
;
int
rw
;
int
rw
;
unsigned
blkbits
;
/* doesn't change */
unsigned
blkbits
;
/* doesn't change */
...
@@ -180,15 +173,10 @@ dio_bio_alloc(struct dio *dio, struct block_device *bdev,
...
@@ -180,15 +173,10 @@ dio_bio_alloc(struct dio *dio, struct block_device *bdev,
return
-
ENOMEM
;
return
-
ENOMEM
;
bio
->
bi_bdev
=
bdev
;
bio
->
bi_bdev
=
bdev
;
bio
->
bi_vcnt
=
nr_vecs
;
bio
->
bi_idx
=
0
;
bio
->
bi_size
=
0
;
bio
->
bi_sector
=
first_sector
;
bio
->
bi_sector
=
first_sector
;
bio
->
bi_io_vec
[
0
].
bv_page
=
NULL
;
bio
->
bi_end_io
=
dio_bio_end_io
;
bio
->
bi_end_io
=
dio_bio_end_io
;
dio
->
bio
=
bio
;
dio
->
bio
=
bio
;
dio
->
bvec
=
NULL
;
/* debug */
return
0
;
return
0
;
}
}
...
@@ -196,14 +184,11 @@ static void dio_bio_submit(struct dio *dio)
...
@@ -196,14 +184,11 @@ static void dio_bio_submit(struct dio *dio)
{
{
struct
bio
*
bio
=
dio
->
bio
;
struct
bio
*
bio
=
dio
->
bio
;
bio
->
bi_vcnt
=
bio
->
bi_idx
;
bio
->
bi_idx
=
0
;
bio
->
bi_private
=
dio
;
bio
->
bi_private
=
dio
;
atomic_inc
(
&
dio
->
bio_count
);
atomic_inc
(
&
dio
->
bio_count
);
submit_bio
(
dio
->
rw
,
bio
);
submit_bio
(
dio
->
rw
,
bio
);
dio
->
bio
=
NULL
;
dio
->
bio
=
NULL
;
dio
->
bvec
=
NULL
;
dio
->
boundary
=
0
;
dio
->
boundary
=
0
;
}
}
...
@@ -394,8 +379,7 @@ static void dio_prep_bio(struct dio *dio)
...
@@ -394,8 +379,7 @@ static void dio_prep_bio(struct dio *dio)
if
(
dio
->
bio
==
NULL
)
if
(
dio
->
bio
==
NULL
)
return
;
return
;
if
(
dio
->
bio
->
bi_idx
==
dio
->
bio
->
bi_vcnt
||
if
(
dio
->
boundary
||
dio
->
boundary
||
dio
->
last_block_in_bio
!=
dio
->
next_block_in_bio
-
1
)
dio
->
last_block_in_bio
!=
dio
->
next_block_in_bio
-
1
)
dio_bio_submit
(
dio
);
dio_bio_submit
(
dio
);
}
}
...
@@ -406,19 +390,44 @@ static void dio_prep_bio(struct dio *dio)
...
@@ -406,19 +390,44 @@ static void dio_prep_bio(struct dio *dio)
static
int
dio_new_bio
(
struct
dio
*
dio
)
static
int
dio_new_bio
(
struct
dio
*
dio
)
{
{
sector_t
sector
;
sector_t
sector
;
int
ret
;
int
ret
,
nr_pages
;
ret
=
dio_bio_reap
(
dio
);
ret
=
dio_bio_reap
(
dio
);
if
(
ret
)
if
(
ret
)
goto
out
;
goto
out
;
sector
=
dio
->
next_block_in_bio
<<
(
dio
->
blkbits
-
9
);
sector
=
dio
->
next_block_in_bio
<<
(
dio
->
blkbits
-
9
);
ret
=
dio_bio_alloc
(
dio
,
dio
->
map_bh
.
b_bdev
,
sector
,
nr_pages
=
min
(
dio
->
total_pages
,
BIO_MAX_PAGES
);
DIO_BIO_MAX_SIZE
/
PAGE_SIZE
);
ret
=
dio_bio_alloc
(
dio
,
dio
->
map_bh
.
b_bdev
,
sector
,
nr_pages
);
dio
->
boundary
=
0
;
dio
->
boundary
=
0
;
out:
out:
return
ret
;
return
ret
;
}
}
static
int
dio_bio_add_page
(
struct
dio
*
dio
,
struct
page
*
page
,
unsigned
int
bv_len
,
unsigned
int
bv_offset
)
{
int
ret
=
0
;
if
(
bv_len
==
0
)
goto
out
;
page_cache_get
(
page
);
if
(
bio_add_page
(
dio
->
bio
,
page
,
bv_len
,
bv_offset
))
{
dio_bio_submit
(
dio
);
ret
=
dio_new_bio
(
dio
);
if
(
ret
==
0
)
{
ret
=
bio_add_page
(
dio
->
bio
,
page
,
bv_len
,
bv_offset
);
BUG_ON
(
ret
!=
0
);
}
}
page_cache_release
(
page
);
out:
return
ret
;
}
/*
/*
* Walk the user pages, and the file, mapping blocks to disk and emitting BIOs.
* Walk the user pages, and the file, mapping blocks to disk and emitting BIOs.
*
*
...
@@ -439,13 +448,15 @@ int do_direct_IO(struct dio *dio)
...
@@ -439,13 +448,15 @@ int do_direct_IO(struct dio *dio)
const
unsigned
blocks_per_page
=
PAGE_SIZE
>>
blkbits
;
const
unsigned
blocks_per_page
=
PAGE_SIZE
>>
blkbits
;
struct
page
*
page
;
struct
page
*
page
;
unsigned
block_in_page
;
unsigned
block_in_page
;
int
ret
;
int
ret
=
0
;
/* The I/O can start at any block offset within the first page */
/* The I/O can start at any block offset within the first page */
block_in_page
=
dio
->
first_block_in_page
;
block_in_page
=
dio
->
first_block_in_page
;
while
(
dio
->
block_in_file
<
dio
->
final_block_in_request
)
{
while
(
dio
->
block_in_file
<
dio
->
final_block_in_request
)
{
int
new_page
;
/* Need to insert this page into the BIO? */
int
new_page
;
/* Need to insert this page into the BIO? */
unsigned
int
bv_offset
;
unsigned
int
bv_len
;
page
=
dio_get_page
(
dio
);
page
=
dio_get_page
(
dio
);
if
(
IS_ERR
(
page
))
{
if
(
IS_ERR
(
page
))
{
...
@@ -454,15 +465,16 @@ int do_direct_IO(struct dio *dio)
...
@@ -454,15 +465,16 @@ int do_direct_IO(struct dio *dio)
}
}
new_page
=
1
;
new_page
=
1
;
bv_offset
=
0
;
bv_len
=
0
;
while
(
block_in_page
<
blocks_per_page
)
{
while
(
block_in_page
<
blocks_per_page
)
{
struct
bio
*
bio
;
unsigned
this_chunk_bytes
;
/* # of bytes mapped */
unsigned
this_chunk_bytes
;
/* # of bytes mapped */
unsigned
this_chunk_blocks
;
/* # of blocks */
unsigned
this_chunk_blocks
;
/* # of blocks */
unsigned
u
;
unsigned
u
;
ret
=
get_more_blocks
(
dio
);
ret
=
get_more_blocks
(
dio
);
if
(
ret
)
if
(
ret
)
goto
fail_release
;
goto
out
;
/* Handle holes */
/* Handle holes */
if
(
!
buffer_mapped
(
&
dio
->
map_bh
))
{
if
(
!
buffer_mapped
(
&
dio
->
map_bh
))
{
...
@@ -481,24 +493,19 @@ int do_direct_IO(struct dio *dio)
...
@@ -481,24 +493,19 @@ int do_direct_IO(struct dio *dio)
if
(
dio
->
bio
==
NULL
)
{
if
(
dio
->
bio
==
NULL
)
{
ret
=
dio_new_bio
(
dio
);
ret
=
dio_new_bio
(
dio
);
if
(
ret
)
if
(
ret
)
goto
fail_release
;
goto
out
;
new_page
=
1
;
new_page
=
1
;
}
}
bio
=
dio
->
bio
;
if
(
new_page
)
{
if
(
new_page
)
{
dio
->
bvec
=
&
bio
->
bi_io_vec
[
bio
->
bi_idx
];
bv_len
=
0
;
page_cache_get
(
page
);
bv_offset
=
block_in_page
<<
blkbits
;
dio
->
bvec
->
bv_page
=
page
;
dio
->
bvec
->
bv_len
=
0
;
dio
->
bvec
->
bv_offset
=
block_in_page
<<
blkbits
;
bio
->
bi_idx
++
;
new_page
=
0
;
new_page
=
0
;
}
}
/* Work out how much disk we can add to this page */
/* Work out how much disk we can add to this page */
this_chunk_blocks
=
dio
->
blocks_available
;
this_chunk_blocks
=
dio
->
blocks_available
;
u
=
(
PAGE_SIZE
-
(
dio
->
bvec
->
bv_offset
+
dio
->
bvec
->
bv_len
))
>>
blkbits
;
u
=
(
PAGE_SIZE
-
(
bv_len
+
bv_offset
))
>>
blkbits
;
if
(
this_chunk_blocks
>
u
)
if
(
this_chunk_blocks
>
u
)
this_chunk_blocks
=
u
;
this_chunk_blocks
=
u
;
u
=
dio
->
final_block_in_request
-
dio
->
block_in_file
;
u
=
dio
->
final_block_in_request
-
dio
->
block_in_file
;
...
@@ -507,8 +514,7 @@ int do_direct_IO(struct dio *dio)
...
@@ -507,8 +514,7 @@ int do_direct_IO(struct dio *dio)
this_chunk_bytes
=
this_chunk_blocks
<<
blkbits
;
this_chunk_bytes
=
this_chunk_blocks
<<
blkbits
;
BUG_ON
(
this_chunk_bytes
==
0
);
BUG_ON
(
this_chunk_bytes
==
0
);
dio
->
bvec
->
bv_len
+=
this_chunk_bytes
;
bv_len
+=
this_chunk_bytes
;
bio
->
bi_size
+=
this_chunk_bytes
;
dio
->
next_block_in_bio
+=
this_chunk_blocks
;
dio
->
next_block_in_bio
+=
this_chunk_blocks
;
dio
->
last_block_in_bio
=
dio
->
next_block_in_bio
-
1
;
dio
->
last_block_in_bio
=
dio
->
next_block_in_bio
-
1
;
dio
->
boundary
=
buffer_boundary
(
&
dio
->
map_bh
);
dio
->
boundary
=
buffer_boundary
(
&
dio
->
map_bh
);
...
@@ -521,13 +527,11 @@ int do_direct_IO(struct dio *dio)
...
@@ -521,13 +527,11 @@ int do_direct_IO(struct dio *dio)
if
(
dio
->
block_in_file
==
dio
->
final_block_in_request
)
if
(
dio
->
block_in_file
==
dio
->
final_block_in_request
)
break
;
break
;
}
}
ret
=
dio_bio_add_page
(
dio
,
page
,
bv_len
,
bv_offset
);
if
(
ret
)
goto
out
;
block_in_page
=
0
;
block_in_page
=
0
;
page_cache_release
(
page
);
}
}
ret
=
0
;
goto
out
;
fail_release:
page_cache_release
(
page
);
out:
out:
return
ret
;
return
ret
;
}
}
...
@@ -543,7 +547,6 @@ direct_io_worker(int rw, struct inode *inode, const struct iovec *iov,
...
@@ -543,7 +547,6 @@ direct_io_worker(int rw, struct inode *inode, const struct iovec *iov,
size_t
bytes
,
tot_bytes
=
0
;
size_t
bytes
,
tot_bytes
=
0
;
dio
.
bio
=
NULL
;
dio
.
bio
=
NULL
;
dio
.
bvec
=
NULL
;
dio
.
inode
=
inode
;
dio
.
inode
=
inode
;
dio
.
rw
=
rw
;
dio
.
rw
=
rw
;
dio
.
blkbits
=
blkbits
;
dio
.
blkbits
=
blkbits
;
...
...
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