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
cea9e445
Commit
cea9e445
authored
Apr 09, 2008
by
Chris Mason
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Change btrfs_map_block to return a structure with mappings for all stripes
Signed-off-by:
Chris Mason
<
chris.mason@oracle.com
>
parent
d18a2c44
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
103 additions
and
69 deletions
+103
-69
fs/btrfs/ctree.c
fs/btrfs/ctree.c
+3
-1
fs/btrfs/inode.c
fs/btrfs/inode.c
+3
-5
fs/btrfs/volumes.c
fs/btrfs/volumes.c
+75
-60
fs/btrfs/volumes.h
fs/btrfs/volumes.h
+22
-3
No files found.
fs/btrfs/ctree.c
View file @
cea9e445
...
...
@@ -2025,8 +2025,10 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
root
->
root_key
.
objectid
,
root_gen
,
disk_key
.
objectid
,
0
,
l
->
start
,
0
);
if
(
IS_ERR
(
right
))
if
(
IS_ERR
(
right
))
{
BUG_ON
(
1
);
return
PTR_ERR
(
right
);
}
memset_extent_buffer
(
right
,
0
,
0
,
sizeof
(
struct
btrfs_header
));
btrfs_set_header_bytenr
(
right
,
right
->
start
);
...
...
fs/btrfs/inode.c
View file @
cea9e445
...
...
@@ -301,12 +301,9 @@ int btrfs_merge_bio_hook(struct page *page, unsigned long offset,
{
struct
btrfs_root
*
root
=
BTRFS_I
(
page
->
mapping
->
host
)
->
root
;
struct
btrfs_mapping_tree
*
map_tree
;
struct
btrfs_device
*
dev
;
u64
logical
=
bio
->
bi_sector
<<
9
;
u64
physical
;
u64
length
=
0
;
u64
map_length
;
int
total_devs
;
struct
bio_vec
*
bvec
;
int
i
;
int
ret
;
...
...
@@ -316,8 +313,9 @@ 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
,
READ
,
0
,
logical
,
&
physical
,
&
map_length
,
&
dev
,
&
total_devs
);
ret
=
btrfs_map_block
(
map_tree
,
READ
,
logical
,
&
map_length
,
NULL
);
if
(
map_length
<
length
+
size
)
{
return
1
;
}
...
...
fs/btrfs/volumes.c
View file @
cea9e445
...
...
@@ -26,18 +26,6 @@
#include "print-tree.h"
#include "volumes.h"
struct
stripe
{
struct
btrfs_device
*
dev
;
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
;
...
...
@@ -45,11 +33,11 @@ struct map_lookup {
int
stripe_len
;
int
sector_size
;
int
num_stripes
;
struct
stripe
stripes
[];
struct
btrfs_bio_
stripe
stripes
[];
};
#define map_lookup_size(n) (sizeof(struct map_lookup) + \
(sizeof(struct stripe) * (n)))
(sizeof(struct
btrfs_bio_
stripe) * (n)))
static
DEFINE_MUTEX
(
uuid_mutex
);
static
LIST_HEAD
(
fs_uuids
);
...
...
@@ -801,8 +789,8 @@ void btrfs_mapping_tree_free(struct btrfs_mapping_tree *tree)
}
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
)
u64
logical
,
u64
*
length
,
struct
btrfs_
multi_bio
**
multi_ret
)
{
struct
extent_map
*
em
;
struct
map_lookup
*
map
;
...
...
@@ -810,8 +798,21 @@ int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
u64
offset
;
u64
stripe_offset
;
u64
stripe_nr
;
int
stripes_allocated
=
8
;
int
stripe_index
;
int
i
;
struct
btrfs_multi_bio
*
multi
=
NULL
;
if
(
multi_ret
&&
!
(
rw
&
(
1
<<
BIO_RW
)))
{
stripes_allocated
=
1
;
}
again:
if
(
multi_ret
)
{
multi
=
kzalloc
(
btrfs_multi_bio_size
(
stripes_allocated
),
GFP_NOFS
);
if
(
!
multi
)
return
-
ENOMEM
;
}
spin_lock
(
&
em_tree
->
lock
);
em
=
lookup_extent_mapping
(
em_tree
,
logical
,
*
length
);
...
...
@@ -821,6 +822,17 @@ int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
map
=
(
struct
map_lookup
*
)
em
->
bdev
;
offset
=
logical
-
em
->
start
;
/* if our multi bio struct is too small, back off and try again */
if
(
multi_ret
&&
(
rw
&
(
1
<<
BIO_RW
))
&&
stripes_allocated
<
map
->
num_stripes
&&
((
map
->
type
&
BTRFS_BLOCK_GROUP_RAID1
)
||
(
map
->
type
&
BTRFS_BLOCK_GROUP_DUP
)))
{
stripes_allocated
=
map
->
num_stripes
;
spin_unlock
(
&
em_tree
->
lock
);
free_extent_map
(
em
);
kfree
(
multi
);
goto
again
;
}
stripe_nr
=
offset
;
/*
* stripe_nr counts the total number of stripes we have to stride
...
...
@@ -834,10 +846,22 @@ int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
/* stripe_offset is the offset of this block in its stripe*/
stripe_offset
=
offset
-
stripe_offset
;
if
(
map
->
type
&
(
BTRFS_BLOCK_GROUP_RAID0
|
BTRFS_BLOCK_GROUP_RAID1
|
BTRFS_BLOCK_GROUP_DUP
))
{
/* 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
);
}
else
{
*
length
=
em
->
len
-
offset
;
}
if
(
!
multi_ret
)
goto
out
;
multi
->
num_stripes
=
1
;
stripe_index
=
0
;
if
(
map
->
type
&
BTRFS_BLOCK_GROUP_RAID1
)
{
stripe_index
=
dev_nr
;
if
(
rw
&
(
1
<<
BIO_RW
))
*
total_dev
s
=
map
->
num_stripes
;
multi
->
num_stripe
s
=
map
->
num_stripes
;
else
{
int
i
;
u64
least
=
(
u64
)
-
1
;
...
...
@@ -852,16 +876,10 @@ int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
}
spin_unlock
(
&
cur
->
io_lock
);
}
*
total_devs
=
1
;
}
}
else
if
(
map
->
type
&
BTRFS_BLOCK_GROUP_DUP
)
{
if
(
rw
==
WRITE
)
{
*
total_devs
=
map
->
num_stripes
;
stripe_index
=
dev_nr
;
}
else
{
stripe_index
=
0
;
*
total_devs
=
1
;
}
if
(
rw
&
(
1
<<
BIO_RW
))
multi
->
num_stripes
=
map
->
num_stripes
;
}
else
{
/*
* after this do_div call, stripe_nr is the number of stripes
...
...
@@ -871,18 +889,17 @@ int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
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
|
BTRFS_BLOCK_GROUP_RAID1
|
BTRFS_BLOCK_GROUP_DUP
))
{
/* 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
);
}
else
{
*
length
=
em
->
len
-
offset
;
BUG_ON
(
stripe_index
!=
0
&&
multi
->
num_stripes
>
1
);
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
;
stripe_index
++
;
}
*
dev
=
map
->
stripes
[
stripe_index
].
dev
;
*
multi_ret
=
multi
;
out:
free_extent_map
(
em
);
spin_unlock
(
&
em_tree
->
lock
);
return
0
;
...
...
@@ -895,7 +912,7 @@ static int end_bio_multi_stripe(struct bio *bio,
unsigned
int
bytes_done
,
int
err
)
#endif
{
struct
multi_bio
*
multi
=
bio
->
bi_private
;
struct
btrfs_
multi_bio
*
multi
=
bio
->
bi_private
;
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23)
if
(
bio
->
bi_size
)
...
...
@@ -904,7 +921,7 @@ static int end_bio_multi_stripe(struct bio *bio,
if
(
err
)
multi
->
error
=
err
;
if
(
atomic_dec_and_test
(
&
multi
->
stripes
))
{
if
(
atomic_dec_and_test
(
&
multi
->
stripes
_pending
))
{
bio
->
bi_private
=
multi
->
private
;
bio
->
bi_end_io
=
multi
->
end_io
;
...
...
@@ -927,11 +944,10 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio)
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
;
struct
btrfs_
multi_bio
*
multi
=
NULL
;
int
i
;
int
ret
;
int
dev_nr
=
0
;
...
...
@@ -943,26 +959,22 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio)
map_tree
=
&
root
->
fs_info
->
mapping_tree
;
map_length
=
length
;
ret
=
btrfs_map_block
(
map_tree
,
rw
,
logical
,
&
map_length
,
&
multi
);
BUG_ON
(
ret
);
total_devs
=
multi
->
num_stripes
;
if
(
map_length
<
length
)
{
printk
(
"mapping failed logical %Lu bio len %Lu "
"len %Lu
\n
"
,
logical
,
length
,
map_length
);
BUG
();
}
multi
->
end_io
=
first_bio
->
bi_end_io
;
multi
->
private
=
first_bio
->
bi_private
;
atomic_set
(
&
multi
->
stripes_pending
,
multi
->
num_stripes
);
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
);
...
...
@@ -972,7 +984,8 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio)
bio
->
bi_private
=
multi
;
bio
->
bi_end_io
=
end_bio_multi_stripe
;
}
bio
->
bi_sector
=
physical
>>
9
;
bio
->
bi_sector
=
multi
->
stripes
[
dev_nr
].
physical
>>
9
;
dev
=
multi
->
stripes
[
dev_nr
].
dev
;
bio
->
bi_bdev
=
dev
->
bdev
;
spin_lock
(
&
dev
->
io_lock
);
dev
->
total_ios
++
;
...
...
@@ -980,6 +993,8 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio)
submit_bio
(
rw
,
bio
);
dev_nr
++
;
}
if
(
total_devs
==
1
)
kfree
(
multi
);
return
0
;
}
...
...
fs/btrfs/volumes.h
View file @
cea9e445
...
...
@@ -19,6 +19,8 @@
#ifndef __BTRFS_VOLUMES_
#define __BTRFS_VOLUMES_
#include <linux/bio.h>
struct
btrfs_device
{
struct
list_head
dev_list
;
struct
btrfs_root
*
dev_root
;
...
...
@@ -69,12 +71,29 @@ struct btrfs_fs_devices {
struct
list_head
list
;
};
struct
btrfs_bio_stripe
{
struct
btrfs_device
*
dev
;
u64
physical
;
};
struct
btrfs_multi_bio
{
atomic_t
stripes_pending
;
bio_end_io_t
*
end_io
;
void
*
private
;
int
error
;
int
num_stripes
;
struct
btrfs_bio_stripe
stripes
[];
};
#define btrfs_multi_bio_size(n) (sizeof(struct btrfs_multi_bio) + \
(sizeof(struct btrfs_bio_stripe) * (n)))
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
rw
,
int
stripe_nr
,
u64
logical
,
u64
*
phys
,
u64
*
length
,
struct
btrfs_
device
**
dev
,
int
*
total_stripes
);
int
btrfs_map_block
(
struct
btrfs_mapping_tree
*
map_tree
,
int
rw
,
u64
logical
,
u64
*
length
,
struct
btrfs_
multi_bio
**
multi_ret
);
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
,
...
...
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