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
f2d8d74d
Commit
f2d8d74d
authored
Apr 21, 2008
by
Chris Mason
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Btrfs: Make an unplug function that doesn't unplug every spindle
Signed-off-by:
Chris Mason
<
chris.mason@oracle.com
>
parent
4ef64eae
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
75 additions
and
38 deletions
+75
-38
fs/btrfs/disk-io.c
fs/btrfs/disk-io.c
+15
-11
fs/btrfs/inode.c
fs/btrfs/inode.c
+1
-5
fs/btrfs/volumes.c
fs/btrfs/volumes.c
+57
-22
fs/btrfs/volumes.h
fs/btrfs/volumes.h
+2
-0
No files found.
fs/btrfs/disk-io.c
View file @
f2d8d74d
...
...
@@ -913,18 +913,22 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits)
void
btrfs_unplug_io_fn
(
struct
backing_dev_info
*
bdi
,
struct
page
*
page
)
{
struct
list_head
*
cur
;
struct
btrfs_device
*
device
;
struct
btrfs_fs_info
*
info
;
struct
inode
*
inode
=
page
->
mapping
->
host
;
struct
extent_map_tree
*
em_tree
;
struct
extent_map
*
em
;
u64
offset
=
page_offset
(
page
);
info
=
(
struct
btrfs_fs_info
*
)
bdi
->
unplug_io_data
;
list_for_each
(
cur
,
&
info
->
fs_devices
->
devices
)
{
device
=
list_entry
(
cur
,
struct
btrfs_device
,
dev_list
);
bdi
=
blk_get_backing_dev_info
(
device
->
bdev
);
if
(
bdi
->
unplug_io_fn
)
{
bdi
->
unplug_io_fn
(
bdi
,
page
);
}
}
em_tree
=
&
BTRFS_I
(
inode
)
->
extent_tree
;
spin_lock
(
&
em_tree
->
lock
);
em
=
lookup_extent_mapping
(
em_tree
,
offset
,
PAGE_CACHE_SIZE
);
spin_unlock
(
&
em_tree
->
lock
);
if
(
!
em
)
return
;
offset
=
offset
-
em
->
start
;
btrfs_unplug_page
(
&
BTRFS_I
(
inode
)
->
root
->
fs_info
->
mapping_tree
,
em
->
block_start
+
offset
,
page
);
free_extent_map
(
em
);
}
static
int
setup_bdi
(
struct
btrfs_fs_info
*
info
,
struct
backing_dev_info
*
bdi
)
...
...
fs/btrfs/inode.c
View file @
f2d8d74d
...
...
@@ -313,13 +313,9 @@ int btrfs_merge_bio_hook(struct page *page, unsigned long offset,
u64
logical
=
bio
->
bi_sector
<<
9
;
u64
length
=
0
;
u64
map_length
;
struct
bio_vec
*
bvec
;
int
i
;
int
ret
;
bio_for_each_segment
(
bvec
,
bio
,
i
)
{
length
+=
bvec
->
bv_len
;
}
length
=
bio
->
bi_size
;
map_tree
=
&
root
->
fs_info
->
mapping_tree
;
map_length
=
length
;
ret
=
btrfs_map_block
(
map_tree
,
READ
,
logical
,
...
...
fs/btrfs/volumes.c
View file @
f2d8d74d
...
...
@@ -18,6 +18,7 @@
#include <linux/sched.h>
#include <linux/bio.h>
#include <linux/buffer_head.h>
#include <linux/blkdev.h>
#include <asm/div64.h>
#include "ctree.h"
#include "extent_map.h"
...
...
@@ -930,9 +931,10 @@ int btrfs_num_copies(struct btrfs_mapping_tree *map_tree, u64 logical, u64 len)
return
ret
;
}
int
btrfs_map_block
(
struct
btrfs_mapping_tree
*
map_tree
,
int
rw
,
u64
logical
,
u64
*
length
,
struct
btrfs_multi_bio
**
multi_ret
,
int
mirror_num
)
static
int
__btrfs_map_block
(
struct
btrfs_mapping_tree
*
map_tree
,
int
rw
,
u64
logical
,
u64
*
length
,
struct
btrfs_multi_bio
**
multi_ret
,
int
mirror_num
,
struct
page
*
unplug_page
)
{
struct
extent_map
*
em
;
struct
map_lookup
*
map
;
...
...
@@ -944,6 +946,7 @@ int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
int
stripes_required
=
1
;
int
stripe_index
;
int
i
;
int
num_stripes
;
struct
btrfs_multi_bio
*
multi
=
NULL
;
if
(
multi_ret
&&
!
(
rw
&
(
1
<<
BIO_RW
)))
{
...
...
@@ -960,10 +963,14 @@ int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
spin_lock
(
&
em_tree
->
lock
);
em
=
lookup_extent_mapping
(
em_tree
,
logical
,
*
length
);
spin_unlock
(
&
em_tree
->
lock
);
if
(
!
em
&&
unplug_page
)
return
0
;
if
(
!
em
)
{
printk
(
"unable to find logical %Lu
\n
"
,
logical
);
BUG
();
}
BUG_ON
(
!
em
);
BUG_ON
(
em
->
start
>
logical
||
em
->
start
+
em
->
len
<
logical
);
map
=
(
struct
map_lookup
*
)
em
->
bdev
;
...
...
@@ -1010,14 +1017,15 @@ int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
}
else
{
*
length
=
em
->
len
-
offset
;
}
if
(
!
multi_ret
)
if
(
!
multi_ret
&&
!
unplug_page
)
goto
out
;
multi
->
num_stripes
=
1
;
num_stripes
=
1
;
stripe_index
=
0
;
if
(
map
->
type
&
BTRFS_BLOCK_GROUP_RAID1
)
{
if
(
rw
&
(
1
<<
BIO_RW
))
multi
->
num_stripes
=
map
->
num_stripes
;
if
(
unplug_page
||
(
rw
&
(
1
<<
BIO_RW
)
))
num_stripes
=
map
->
num_stripes
;
else
if
(
mirror_num
)
{
stripe_index
=
mirror_num
-
1
;
}
else
{
...
...
@@ -1037,7 +1045,7 @@ int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
}
}
else
if
(
map
->
type
&
BTRFS_BLOCK_GROUP_DUP
)
{
if
(
rw
&
(
1
<<
BIO_RW
))
multi
->
num_stripes
=
map
->
num_stripes
;
num_stripes
=
map
->
num_stripes
;
else
if
(
mirror_num
)
stripe_index
=
mirror_num
-
1
;
}
else
if
(
map
->
type
&
BTRFS_BLOCK_GROUP_RAID10
)
{
...
...
@@ -1047,8 +1055,8 @@ int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
stripe_index
=
do_div
(
stripe_nr
,
factor
);
stripe_index
*=
map
->
sub_stripes
;
if
(
rw
&
(
1
<<
BIO_RW
))
multi
->
num_stripes
=
map
->
sub_stripes
;
if
(
unplug_page
||
(
rw
&
(
1
<<
BIO_RW
)
))
num_stripes
=
map
->
sub_stripes
;
else
if
(
mirror_num
)
stripe_index
+=
mirror_num
-
1
;
else
...
...
@@ -1063,19 +1071,50 @@ int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
}
BUG_ON
(
stripe_index
>=
map
->
num_stripes
);
for
(
i
=
0
;
i
<
multi
->
num_stripes
;
i
++
)
{
multi
->
stripes
[
i
].
physical
=
map
->
stripes
[
stripe_index
].
physical
+
stripe_offset
+
stripe_nr
*
map
->
stripe_len
;
multi
->
stripes
[
i
].
dev
=
map
->
stripes
[
stripe_index
].
dev
;
for
(
i
=
0
;
i
<
num_stripes
;
i
++
)
{
if
(
unplug_page
)
{
struct
btrfs_device
*
device
;
struct
backing_dev_info
*
bdi
;
device
=
map
->
stripes
[
stripe_index
].
dev
;
bdi
=
blk_get_backing_dev_info
(
device
->
bdev
);
if
(
bdi
->
unplug_io_fn
)
{
bdi
->
unplug_io_fn
(
bdi
,
unplug_page
);
}
}
else
{
multi
->
stripes
[
i
].
physical
=
map
->
stripes
[
stripe_index
].
physical
+
stripe_offset
+
stripe_nr
*
map
->
stripe_len
;
multi
->
stripes
[
i
].
dev
=
map
->
stripes
[
stripe_index
].
dev
;
}
stripe_index
++
;
}
*
multi_ret
=
multi
;
if
(
multi_ret
)
{
*
multi_ret
=
multi
;
multi
->
num_stripes
=
num_stripes
;
}
out:
free_extent_map
(
em
);
return
0
;
}
int
btrfs_map_block
(
struct
btrfs_mapping_tree
*
map_tree
,
int
rw
,
u64
logical
,
u64
*
length
,
struct
btrfs_multi_bio
**
multi_ret
,
int
mirror_num
)
{
return
__btrfs_map_block
(
map_tree
,
rw
,
logical
,
length
,
multi_ret
,
mirror_num
,
NULL
);
}
int
btrfs_unplug_page
(
struct
btrfs_mapping_tree
*
map_tree
,
u64
logical
,
struct
page
*
page
)
{
u64
length
=
PAGE_CACHE_SIZE
;
return
__btrfs_map_block
(
map_tree
,
READ
,
logical
,
&
length
,
NULL
,
0
,
page
);
}
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)
static
void
end_bio_multi_stripe
(
struct
bio
*
bio
,
int
err
)
#else
...
...
@@ -1122,16 +1161,12 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
u64
logical
=
bio
->
bi_sector
<<
9
;
u64
length
=
0
;
u64
map_length
;
struct
bio_vec
*
bvec
;
struct
btrfs_multi_bio
*
multi
=
NULL
;
int
i
;
int
ret
;
int
dev_nr
=
0
;
int
total_devs
=
1
;
bio_for_each_segment
(
bvec
,
bio
,
i
)
{
length
+=
bvec
->
bv_len
;
}
length
=
bio
->
bi_size
;
map_tree
=
&
root
->
fs_info
->
mapping_tree
;
map_length
=
length
;
...
...
fs/btrfs/volumes.h
View file @
f2d8d74d
...
...
@@ -119,4 +119,6 @@ int btrfs_add_device(struct btrfs_trans_handle *trans,
struct
btrfs_device
*
device
);
int
btrfs_cleanup_fs_uuids
(
void
);
int
btrfs_num_copies
(
struct
btrfs_mapping_tree
*
map_tree
,
u64
logical
,
u64
len
);
int
btrfs_unplug_page
(
struct
btrfs_mapping_tree
*
map_tree
,
u64
logical
,
struct
page
*
page
);
#endif
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