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
8790d502
Commit
8790d502
authored
Apr 03, 2008
by
Chris Mason
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Btrfs: Add support for mirroring across drives
Signed-off-by:
Chris Mason
<
chris.mason@oracle.com
>
parent
0ef8b242
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
198 additions
and
93 deletions
+198
-93
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+7
-2
fs/btrfs/disk-io.c
fs/btrfs/disk-io.c
+7
-13
fs/btrfs/extent-tree.c
fs/btrfs/extent-tree.c
+49
-44
fs/btrfs/inode.c
fs/btrfs/inode.c
+3
-1
fs/btrfs/volumes.c
fs/btrfs/volumes.c
+126
-28
fs/btrfs/volumes.h
fs/btrfs/volumes.h
+6
-5
No files found.
fs/btrfs/ctree.h
View file @
8790d502
...
...
@@ -418,6 +418,7 @@ struct btrfs_csum_item {
#define BTRFS_BLOCK_GROUP_SYSTEM (1 << 1)
#define BTRFS_BLOCK_GROUP_METADATA (1 << 2)
#define BTRFS_BLOCK_GROUP_RAID0 (1 << 3)
#define BTRFS_BLOCK_GROUP_RAID1 (1 << 4)
struct
btrfs_block_group_item
{
...
...
@@ -504,8 +505,12 @@ struct btrfs_fs_info {
u64
delalloc_bytes
;
u64
last_alloc
;
u64
last_data_alloc
;
int
extra_data_alloc_bits
;
int
extra_alloc_bits
;
int
avail_data_alloc_bits
;
int
avail_metadata_alloc_bits
;
int
avail_system_alloc_bits
;
int
data_alloc_profile
;
int
metadata_alloc_profile
;
int
system_alloc_profile
;
};
/*
...
...
fs/btrfs/disk-io.c
View file @
8790d502
...
...
@@ -735,7 +735,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
GFP_NOFS
);
struct
btrfs_root
*
tree_root
=
kmalloc
(
sizeof
(
struct
btrfs_root
),
GFP_NOFS
);
struct
btrfs_fs_info
*
fs_info
=
k
m
alloc
(
sizeof
(
*
fs_info
),
struct
btrfs_fs_info
*
fs_info
=
k
z
alloc
(
sizeof
(
*
fs_info
),
GFP_NOFS
);
struct
btrfs_root
*
chunk_root
=
kmalloc
(
sizeof
(
struct
btrfs_root
),
GFP_NOFS
);
...
...
@@ -744,6 +744,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
int
ret
;
int
err
=
-
EINVAL
;
struct
btrfs_super_block
*
disk_super
;
if
(
!
extent_root
||
!
tree_root
||
!
fs_info
)
{
err
=
-
ENOMEM
;
goto
fail
;
...
...
@@ -756,11 +757,8 @@ struct btrfs_root *open_ctree(struct super_block *sb,
spin_lock_init
(
&
fs_info
->
delalloc_lock
);
spin_lock_init
(
&
fs_info
->
new_trans_lock
);
memset
(
&
fs_info
->
super_kobj
,
0
,
sizeof
(
fs_info
->
super_kobj
));
init_completion
(
&
fs_info
->
kobj_unregister
);
sb_set_blocksize
(
sb
,
4096
);
fs_info
->
running_transaction
=
NULL
;
fs_info
->
last_trans_committed
=
0
;
fs_info
->
tree_root
=
tree_root
;
fs_info
->
extent_root
=
extent_root
;
fs_info
->
chunk_root
=
chunk_root
;
...
...
@@ -770,11 +768,8 @@ struct btrfs_root *open_ctree(struct super_block *sb,
INIT_LIST_HEAD
(
&
fs_info
->
space_info
);
btrfs_mapping_init
(
&
fs_info
->
mapping_tree
);
fs_info
->
sb
=
sb
;
fs_info
->
throttles
=
0
;
fs_info
->
mount_opt
=
0
;
fs_info
->
max_extent
=
(
u64
)
-
1
;
fs_info
->
max_inline
=
8192
*
1024
;
fs_info
->
delalloc_bytes
=
0
;
setup_bdi
(
fs_info
,
&
fs_info
->
bdi
);
fs_info
->
btree_inode
=
new_inode
(
sb
);
fs_info
->
btree_inode
->
i_ino
=
1
;
...
...
@@ -802,12 +797,6 @@ struct btrfs_root *open_ctree(struct super_block *sb,
extent_io_tree_init
(
&
fs_info
->
extent_ins
,
fs_info
->
btree_inode
->
i_mapping
,
GFP_NOFS
);
fs_info
->
do_barriers
=
1
;
fs_info
->
closing
=
0
;
fs_info
->
total_pinned
=
0
;
fs_info
->
last_alloc
=
0
;
fs_info
->
last_data_alloc
=
0
;
fs_info
->
extra_alloc_bits
=
0
;
fs_info
->
extra_data_alloc_bits
=
0
;
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18)
INIT_WORK
(
&
fs_info
->
trans_work
,
btrfs_transaction_cleaner
,
fs_info
);
...
...
@@ -923,6 +912,11 @@ struct btrfs_root *open_ctree(struct super_block *sb,
btrfs_read_block_groups
(
extent_root
);
fs_info
->
generation
=
btrfs_super_generation
(
disk_super
)
+
1
;
if
(
btrfs_super_num_devices
(
disk_super
)
>
0
)
{
fs_info
->
data_alloc_profile
=
BTRFS_BLOCK_GROUP_RAID0
;
fs_info
->
metadata_alloc_profile
=
BTRFS_BLOCK_GROUP_RAID1
;
fs_info
->
system_alloc_profile
=
BTRFS_BLOCK_GROUP_RAID0
;
}
mutex_unlock
(
&
fs_info
->
fs_mutex
);
return
tree_root
;
...
...
fs/btrfs/extent-tree.c
View file @
8790d502
...
...
@@ -230,9 +230,13 @@ static int noinline find_search_start(struct btrfs_root *root,
goto
new_group
;
if
(
start
+
num
>
total_fs_bytes
)
goto
new_group
;
if
(
!
block_group_bits
(
cache
,
data
))
{
printk
(
"block group bits don't match %Lu %Lu
\n
"
,
cache
->
flags
,
data
);
}
*
start_ret
=
start
;
return
0
;
}
out
:
}
out:
cache
=
btrfs_lookup_block_group
(
root
->
fs_info
,
search_start
);
if
(
!
cache
)
{
printk
(
"Unable to find block group for %Lu
\n
"
,
search_start
);
...
...
@@ -365,14 +369,17 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
if
(
cache
->
key
.
objectid
>
total_fs_bytes
)
break
;
if
(
full_search
)
free_check
=
cache
->
key
.
offset
;
else
free_check
=
div_factor
(
cache
->
key
.
offset
,
factor
);
if
(
block_group_bits
(
cache
,
data
))
{
if
(
full_search
)
free_check
=
cache
->
key
.
offset
;
else
free_check
=
div_factor
(
cache
->
key
.
offset
,
factor
);
if
(
used
+
cache
->
pinned
<
free_check
)
{
found_group
=
cache
;
goto
found
;
if
(
used
+
cache
->
pinned
<
free_check
)
{
found_group
=
cache
;
goto
found
;
}
}
cond_resched
();
}
...
...
@@ -1038,6 +1045,19 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags,
return
0
;
}
static
void
set_avail_alloc_bits
(
struct
btrfs_fs_info
*
fs_info
,
u64
flags
)
{
u64
extra_flags
=
flags
&
(
BTRFS_BLOCK_GROUP_RAID0
|
BTRFS_BLOCK_GROUP_RAID1
);
if
(
extra_flags
)
{
if
(
flags
&
BTRFS_BLOCK_GROUP_DATA
)
fs_info
->
avail_data_alloc_bits
|=
extra_flags
;
if
(
flags
&
BTRFS_BLOCK_GROUP_METADATA
)
fs_info
->
avail_metadata_alloc_bits
|=
extra_flags
;
if
(
flags
&
BTRFS_BLOCK_GROUP_SYSTEM
)
fs_info
->
avail_system_alloc_bits
|=
extra_flags
;
}
}
static
int
do_chunk_alloc
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
extent_root
,
u64
alloc_bytes
,
...
...
@@ -1060,7 +1080,7 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans,
if
(
space_info
->
full
)
return
0
;
thresh
=
div_factor
(
space_info
->
total_bytes
,
7
);
thresh
=
div_factor
(
space_info
->
total_bytes
,
6
);
if
((
space_info
->
bytes_used
+
space_info
->
bytes_pinned
+
alloc_bytes
)
<
thresh
)
return
0
;
...
...
@@ -1079,16 +1099,7 @@ printk("space info full %Lu\n", flags);
start
,
num_bytes
);
BUG_ON
(
ret
);
if
(
flags
&
BTRFS_BLOCK_GROUP_RAID0
)
{
if
(
flags
&
BTRFS_BLOCK_GROUP_DATA
)
{
extent_root
->
fs_info
->
extra_data_alloc_bits
=
BTRFS_BLOCK_GROUP_RAID0
;
}
if
(
flags
&
BTRFS_BLOCK_GROUP_METADATA
)
{
extent_root
->
fs_info
->
extra_alloc_bits
=
BTRFS_BLOCK_GROUP_RAID0
;
}
}
set_avail_alloc_bits
(
extent_root
->
fs_info
,
flags
);
return
0
;
}
...
...
@@ -1529,6 +1540,7 @@ static int noinline find_free_extent(struct btrfs_trans_handle *trans,
if
(
data
&
BTRFS_BLOCK_GROUP_METADATA
)
{
last_ptr
=
&
root
->
fs_info
->
last_alloc
;
empty_cluster
=
256
*
1024
;
}
if
((
data
&
BTRFS_BLOCK_GROUP_DATA
)
&&
btrfs_test_opt
(
root
,
SSD
))
{
...
...
@@ -1693,6 +1705,7 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
u64
root_used
;
u64
search_start
=
0
;
u64
new_hint
;
u64
alloc_profile
;
u32
sizes
[
2
];
struct
btrfs_fs_info
*
info
=
root
->
fs_info
;
struct
btrfs_root
*
extent_root
=
info
->
extent_root
;
...
...
@@ -1700,31 +1713,32 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
struct
btrfs_extent_ref
*
ref
;
struct
btrfs_path
*
path
;
struct
btrfs_key
keys
[
2
];
int
extra_chunk_alloc_bits
=
0
;
if
(
data
)
{
data
=
BTRFS_BLOCK_GROUP_DATA
|
info
->
extra_data_alloc_bits
;
alloc_profile
=
info
->
avail_data_alloc_bits
&
info
->
data_alloc_profile
;
data
=
BTRFS_BLOCK_GROUP_DATA
|
alloc_profile
;
}
else
if
(
root
==
root
->
fs_info
->
chunk_root
)
{
data
=
BTRFS_BLOCK_GROUP_SYSTEM
;
alloc_profile
=
info
->
avail_system_alloc_bits
&
info
->
system_alloc_profile
;
data
=
BTRFS_BLOCK_GROUP_SYSTEM
|
alloc_profile
;
}
else
{
data
=
BTRFS_BLOCK_GROUP_METADATA
|
info
->
extra_alloc_bits
;
alloc_profile
=
info
->
avail_metadata_alloc_bits
&
info
->
metadata_alloc_profile
;
data
=
BTRFS_BLOCK_GROUP_METADATA
|
alloc_profile
;
}
if
(
btrfs_super_num_devices
(
&
info
->
super_copy
)
>
1
&&
!
(
data
&
BTRFS_BLOCK_GROUP_SYSTEM
))
extra_chunk_alloc_bits
=
BTRFS_BLOCK_GROUP_RAID0
;
if
(
root
->
ref_cows
)
{
if
(
!
(
data
&
BTRFS_BLOCK_GROUP_METADATA
))
{
ret
=
do_chunk_alloc
(
trans
,
root
->
fs_info
->
extent_root
,
2
*
1024
*
1024
,
BTRFS_BLOCK_GROUP_METADATA
|
info
->
extra_alloc_bits
|
extra_chunk_alloc_bits
);
(
info
->
metadata_alloc_profile
&
info
->
avail_metadata_alloc_bits
)
);
BUG_ON
(
ret
);
}
ret
=
do_chunk_alloc
(
trans
,
root
->
fs_info
->
extent_root
,
num_bytes
+
2
*
1024
*
1024
,
data
|
extra_chunk_alloc_bits
);
num_bytes
+
2
*
1024
*
1024
,
data
);
BUG_ON
(
ret
);
}
...
...
@@ -2046,12 +2060,12 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
if
(
!
next
||
!
btrfs_buffer_uptodate
(
next
))
{
free_extent_buffer
(
next
);
reada_walk_down
(
root
,
cur
,
path
->
slots
[
*
level
]);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
next
=
read_tree_block
(
root
,
bytenr
,
blocksize
);
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
/* we used to drop the lock above, keep the
* code to double check so that we won't forget
* when we drop the lock again in the future
*/
/* we've dropped the lock, double check */
ret
=
lookup_extent_ref
(
trans
,
root
,
bytenr
,
blocksize
,
&
refs
);
BUG_ON
(
ret
);
...
...
@@ -2739,16 +2753,7 @@ int btrfs_read_block_groups(struct btrfs_root *root)
}
else
if
(
cache
->
flags
&
BTRFS_BLOCK_GROUP_METADATA
)
{
bit
=
BLOCK_GROUP_METADATA
;
}
if
(
cache
->
flags
&
BTRFS_BLOCK_GROUP_RAID0
)
{
if
(
cache
->
flags
&
BTRFS_BLOCK_GROUP_DATA
)
{
info
->
extra_data_alloc_bits
=
BTRFS_BLOCK_GROUP_RAID0
;
}
if
(
cache
->
flags
&
BTRFS_BLOCK_GROUP_METADATA
)
{
info
->
extra_alloc_bits
=
BTRFS_BLOCK_GROUP_RAID0
;
}
}
set_avail_alloc_bits
(
info
,
cache
->
flags
);
ret
=
update_space_info
(
info
,
cache
->
flags
,
found_key
.
offset
,
btrfs_block_group_used
(
&
cache
->
item
),
...
...
fs/btrfs/inode.c
View file @
8790d502
...
...
@@ -306,6 +306,7 @@ int btrfs_merge_bio_hook(struct page *page, unsigned long offset,
u64
physical
;
u64
length
=
0
;
u64
map_length
;
int
total_devs
;
struct
bio_vec
*
bvec
;
int
i
;
int
ret
;
...
...
@@ -315,7 +316,8 @@ int btrfs_merge_bio_hook(struct page *page, unsigned long offset,
}
map_tree
=
&
root
->
fs_info
->
mapping_tree
;
map_length
=
length
;
ret
=
btrfs_map_block
(
map_tree
,
logical
,
&
physical
,
&
map_length
,
&
dev
);
ret
=
btrfs_map_block
(
map_tree
,
READ
,
0
,
logical
,
&
physical
,
&
map_length
,
&
dev
,
&
total_devs
);
if
(
map_length
<
length
+
size
)
{
return
1
;
}
...
...
fs/btrfs/volumes.c
View file @
8790d502
...
...
@@ -31,6 +31,13 @@ struct stripe {
u64
physical
;
};
struct
multi_bio
{
atomic_t
stripes
;
bio_end_io_t
*
end_io
;
void
*
private
;
int
error
;
};
struct
map_lookup
{
u64
type
;
int
io_align
;
...
...
@@ -632,12 +639,12 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
if
(
list_empty
(
dev_list
))
return
-
ENOSPC
;
if
(
type
&
BTRFS_BLOCK_GROUP_RAID0
)
if
(
type
&
(
BTRFS_BLOCK_GROUP_RAID0
)
)
num_stripes
=
btrfs_super_num_devices
(
&
info
->
super_copy
);
if
(
type
&
BTRFS_BLOCK_GROUP_DATA
)
stripe_len
=
64
*
1024
;
if
(
type
&
(
BTRFS_BLOCK_GROUP_METADATA
|
BTRFS_BLOCK_GROUP_SYSTEM
))
stripe_len
=
32
*
1024
;
if
(
type
&
(
BTRFS_BLOCK_GROUP_RAID1
))
{
num_stripes
=
min_t
(
u64
,
2
,
btrfs_super_num_devices
(
&
info
->
super_copy
));
}
again:
INIT_LIST_HEAD
(
&
private_devs
);
cur
=
dev_list
->
next
;
...
...
@@ -682,7 +689,11 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
stripes
=
&
chunk
->
stripe
;
*
num_bytes
=
calc_size
*
num_stripes
;
if
(
type
&
BTRFS_BLOCK_GROUP_RAID1
)
*
num_bytes
=
calc_size
;
else
*
num_bytes
=
calc_size
*
num_stripes
;
index
=
0
;
while
(
index
<
num_stripes
)
{
BUG_ON
(
list_empty
(
&
private_devs
));
...
...
@@ -694,7 +705,7 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
key
.
objectid
,
calc_size
,
&
dev_offset
);
BUG_ON
(
ret
);
printk
(
"alloc chunk s
ize %Lu from dev %Lu
\n
"
,
calc_size
,
device
->
devid
);
printk
(
"alloc chunk s
tart %Lu size %Lu from dev %Lu type %Lu
\n
"
,
key
.
objectid
,
calc_size
,
device
->
devid
,
type
);
device
->
bytes_used
+=
calc_size
;
ret
=
btrfs_update_device
(
trans
,
device
);
BUG_ON
(
ret
);
...
...
@@ -774,9 +785,9 @@ void btrfs_mapping_tree_free(struct btrfs_mapping_tree *tree)
}
}
int
btrfs_map_block
(
struct
btrfs_mapping_tree
*
map_tree
,
u64
logical
,
u64
*
phys
,
u64
*
length
,
struct
btrfs_device
**
dev
)
int
btrfs_map_block
(
struct
btrfs_mapping_tree
*
map_tree
,
int
rw
,
int
dev_nr
,
u64
logical
,
u64
*
phys
,
u64
*
length
,
struct
btrfs_device
**
dev
,
int
*
total_devs
)
{
struct
extent_map
*
em
;
struct
map_lookup
*
map
;
...
...
@@ -808,19 +819,39 @@ int btrfs_map_block(struct btrfs_mapping_tree *map_tree,
/* stripe_offset is the offset of this block in its stripe*/
stripe_offset
=
offset
-
stripe_offset
;
/*
* after this do_div call, stripe_nr is the number of stripes
* on this device we have to walk to find the data, and
* stripe_index is the number of our device in the stripe array
*/
stripe_index
=
do_div
(
stripe_nr
,
map
->
num_stripes
);
if
(
map
->
type
&
BTRFS_BLOCK_GROUP_RAID1
)
{
stripe_index
=
dev_nr
;
if
(
rw
&
(
1
<<
BIO_RW
))
*
total_devs
=
map
->
num_stripes
;
else
{
int
i
;
u64
least
=
(
u64
)
-
1
;
struct
btrfs_device
*
cur
;
for
(
i
=
0
;
i
<
map
->
num_stripes
;
i
++
)
{
cur
=
map
->
stripes
[
i
].
dev
;
spin_lock
(
&
cur
->
io_lock
);
if
(
cur
->
total_ios
<
least
)
{
least
=
cur
->
total_ios
;
stripe_index
=
i
;
}
spin_unlock
(
&
cur
->
io_lock
);
}
*
total_devs
=
1
;
}
}
else
{
/*
* after this do_div call, stripe_nr is the number of stripes
* on this device we have to walk to find the data, and
* stripe_index is the number of our device in the stripe array
*/
stripe_index
=
do_div
(
stripe_nr
,
map
->
num_stripes
);
}
BUG_ON
(
stripe_index
>=
map
->
num_stripes
);
*
phys
=
map
->
stripes
[
stripe_index
].
physical
+
stripe_offset
+
stripe_nr
*
map
->
stripe_len
;
if
(
map
->
type
&
BTRFS_BLOCK_GROUP_RAID0
)
{
if
(
map
->
type
&
(
BTRFS_BLOCK_GROUP_RAID0
|
BTRFS_BLOCK_GROUP_RAID1
)
)
{
/* we limit the length of each bio to what fits in a stripe */
*
length
=
min_t
(
u64
,
em
->
len
-
offset
,
map
->
stripe_len
-
stripe_offset
);
...
...
@@ -833,33 +864,98 @@ int btrfs_map_block(struct btrfs_mapping_tree *map_tree,
return
0
;
}
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)
static
void
end_bio_multi_stripe
(
struct
bio
*
bio
,
int
err
)
#else
static
int
end_bio_multi_stripe
(
struct
bio
*
bio
,
unsigned
int
bytes_done
,
int
err
)
#endif
{
struct
multi_bio
*
multi
=
bio
->
bi_private
;
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23)
if
(
bio
->
bi_size
)
return
1
;
#endif
if
(
err
)
multi
->
error
=
err
;
if
(
atomic_dec_and_test
(
&
multi
->
stripes
))
{
bio
->
bi_private
=
multi
->
private
;
bio
->
bi_end_io
=
multi
->
end_io
;
if
(
!
err
&&
multi
->
error
)
err
=
multi
->
error
;
kfree
(
multi
);
bio_endio
(
bio
,
err
);
}
else
{
bio_put
(
bio
);
}
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23)
return
0
;
#endif
}
int
btrfs_map_bio
(
struct
btrfs_root
*
root
,
int
rw
,
struct
bio
*
bio
)
{
struct
btrfs_mapping_tree
*
map_tree
;
struct
btrfs_device
*
dev
;
struct
bio
*
first_bio
=
bio
;
u64
logical
=
bio
->
bi_sector
<<
9
;
u64
physical
;
u64
length
=
0
;
u64
map_length
;
struct
bio_vec
*
bvec
;
struct
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
;
}
map_tree
=
&
root
->
fs_info
->
mapping_tree
;
map_length
=
length
;
ret
=
btrfs_map_block
(
map_tree
,
logical
,
&
physical
,
&
map_length
,
&
dev
);
if
(
map_length
<
length
)
{
printk
(
"mapping failed logical %Lu bio len %Lu physical %Lu "
"len %Lu
\n
"
,
logical
,
length
,
physical
,
map_length
);
BUG
();
while
(
dev_nr
<
total_devs
)
{
ret
=
btrfs_map_block
(
map_tree
,
rw
,
dev_nr
,
logical
,
&
physical
,
&
map_length
,
&
dev
,
&
total_devs
);
if
(
map_length
<
length
)
{
printk
(
"mapping failed logical %Lu bio len %Lu physical %Lu "
"len %Lu
\n
"
,
logical
,
length
,
physical
,
map_length
);
BUG
();
}
BUG_ON
(
map_length
<
length
);
if
(
total_devs
>
1
)
{
if
(
!
multi
)
{
multi
=
kmalloc
(
sizeof
(
*
multi
),
GFP_NOFS
);
atomic_set
(
&
multi
->
stripes
,
1
);
multi
->
end_io
=
bio
->
bi_end_io
;
multi
->
private
=
first_bio
->
bi_private
;
multi
->
error
=
0
;
}
else
{
atomic_inc
(
&
multi
->
stripes
);
}
if
(
dev_nr
<
total_devs
-
1
)
{
bio
=
bio_clone
(
first_bio
,
GFP_NOFS
);
BUG_ON
(
!
bio
);
}
else
{
bio
=
first_bio
;
}
bio
->
bi_private
=
multi
;
bio
->
bi_end_io
=
end_bio_multi_stripe
;
}
bio
->
bi_sector
=
physical
>>
9
;
bio
->
bi_bdev
=
dev
->
bdev
;
spin_lock
(
&
dev
->
io_lock
);
dev
->
total_ios
++
;
spin_unlock
(
&
dev
->
io_lock
);
submit_bio
(
rw
,
bio
);
dev_nr
++
;
}
BUG_ON
(
map_length
<
length
);
bio
->
bi_sector
=
physical
>>
9
;
bio
->
bi_bdev
=
dev
->
bdev
;
submit_bio
(
rw
,
bio
);
return
0
;
}
...
...
@@ -982,6 +1078,8 @@ static int read_one_dev(struct btrfs_root *root,
return
-
ENOMEM
;
list_add
(
&
device
->
dev_list
,
&
root
->
fs_info
->
fs_devices
->
devices
);
device
->
total_ios
=
0
;
spin_lock_init
(
&
device
->
io_lock
);
}
fill_device_from_item
(
leaf
,
dev_item
,
device
);
...
...
fs/btrfs/volumes.h
View file @
8790d502
...
...
@@ -18,12 +18,16 @@
#ifndef __BTRFS_VOLUMES_
#define __BTRFS_VOLUMES_
struct
btrfs_device
{
struct
list_head
dev_list
;
struct
btrfs_root
*
dev_root
;
spinlock_t
io_lock
;
struct
block_device
*
bdev
;
u64
total_ios
;
char
*
name
;
/* the internal btrfs device id */
...
...
@@ -68,9 +72,9 @@ struct btrfs_fs_devices {
int
btrfs_alloc_dev_extent
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_device
*
device
,
u64
owner
,
u64
num_bytes
,
u64
*
start
);
int
btrfs_map_block
(
struct
btrfs_mapping_tree
*
map_tree
,
int
btrfs_map_block
(
struct
btrfs_mapping_tree
*
map_tree
,
int
rw
,
int
stripe_nr
,
u64
logical
,
u64
*
phys
,
u64
*
length
,
struct
btrfs_device
**
dev
);
struct
btrfs_device
**
dev
,
int
*
total_stripes
);
int
btrfs_read_sys_array
(
struct
btrfs_root
*
root
);
int
btrfs_read_chunk_tree
(
struct
btrfs_root
*
root
);
int
btrfs_alloc_chunk
(
struct
btrfs_trans_handle
*
trans
,
...
...
@@ -80,9 +84,6 @@ void btrfs_mapping_init(struct btrfs_mapping_tree *tree);
void
btrfs_mapping_tree_free
(
struct
btrfs_mapping_tree
*
tree
);
int
btrfs_map_bio
(
struct
btrfs_root
*
root
,
int
rw
,
struct
bio
*
bio
);
int
btrfs_read_super_device
(
struct
btrfs_root
*
root
,
struct
extent_buffer
*
buf
);
int
btrfs_map_block
(
struct
btrfs_mapping_tree
*
map_tree
,
u64
logical
,
u64
*
phys
,
u64
*
length
,
struct
btrfs_device
**
dev
);
int
btrfs_open_devices
(
struct
btrfs_fs_devices
*
fs_devices
,
int
flags
,
void
*
holder
);
int
btrfs_scan_one_device
(
const
char
*
path
,
int
flags
,
void
*
holder
,
...
...
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