Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
9b3f68b9
Commit
9b3f68b9
authored
Apr 18, 2008
by
Chris Mason
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Btrfs: Calculate appropriate chunk sizes for both small and large filesystems
Signed-off-by:
Chris Mason
<
chris.mason@oracle.com
>
parent
7b13b7b1
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
61 additions
and
7 deletions
+61
-7
fs/btrfs/volumes.c
fs/btrfs/volumes.c
+61
-7
No files found.
fs/btrfs/volumes.c
View file @
9b3f68b9
...
...
@@ -627,6 +627,27 @@ int btrfs_add_system_chunk(struct btrfs_trans_handle *trans,
return
0
;
}
static
u64
div_factor
(
u64
num
,
int
factor
)
{
if
(
factor
==
10
)
return
num
;
num
*=
factor
;
do_div
(
num
,
10
);
return
num
;
}
static
u64
chunk_bytes_by_type
(
u64
type
,
u64
calc_size
,
int
num_stripes
,
int
sub_stripes
)
{
if
(
type
&
(
BTRFS_BLOCK_GROUP_RAID1
|
BTRFS_BLOCK_GROUP_DUP
))
return
calc_size
;
else
if
(
type
&
BTRFS_BLOCK_GROUP_RAID10
)
return
calc_size
*
(
num_stripes
/
sub_stripes
);
else
return
calc_size
*
num_stripes
;
}
int
btrfs_alloc_chunk
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
extent_root
,
u64
*
start
,
u64
*
num_bytes
,
u64
type
)
...
...
@@ -643,11 +664,14 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
struct
extent_map_tree
*
em_tree
;
struct
map_lookup
*
map
;
struct
extent_map
*
em
;
int
min_chunk_size
=
8
*
1024
*
1024
;
u64
physical
;
u64
calc_size
=
1024
*
1024
*
1024
;
u64
min_free
=
calc_size
;
u64
max_chunk_size
=
calc_size
;
u64
min_free
;
u64
avail
;
u64
max_avail
=
0
;
u64
percent_max
;
int
num_stripes
=
1
;
int
sub_stripes
=
0
;
int
looped
=
0
;
...
...
@@ -666,6 +690,8 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
if
(
type
&
(
BTRFS_BLOCK_GROUP_RAID1
))
{
num_stripes
=
min_t
(
u64
,
2
,
btrfs_super_num_devices
(
&
info
->
super_copy
));
if
(
num_stripes
<
2
)
return
-
ENOSPC
;
}
if
(
type
&
(
BTRFS_BLOCK_GROUP_RAID10
))
{
num_stripes
=
btrfs_super_num_devices
(
&
info
->
super_copy
);
...
...
@@ -674,13 +700,45 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
num_stripes
&=
~
(
u32
)
1
;
sub_stripes
=
2
;
}
if
(
type
&
BTRFS_BLOCK_GROUP_DATA
)
{
max_chunk_size
=
10
*
calc_size
;
min_chunk_size
=
256
*
1024
*
1024
;
}
else
if
(
type
&
BTRFS_BLOCK_GROUP_METADATA
)
{
max_chunk_size
=
4
*
calc_size
;
min_chunk_size
=
64
*
1024
*
1024
;
}
else
{
min_chunk_size
=
32
*
1024
*
1024
;
}
/* we don't want a chunk larger than 10% of the FS */
percent_max
=
div_factor
(
btrfs_super_total_bytes
(
&
info
->
super_copy
),
1
);
max_chunk_size
=
min
(
percent_max
,
max_chunk_size
);
if
(
calc_size
*
num_stripes
>
max_chunk_size
)
{
calc_size
=
max_chunk_size
;
do_div
(
calc_size
,
num_stripes
);
do_div
(
calc_size
,
stripe_len
);
calc_size
*=
stripe_len
;
}
/* we don't want tiny stripes */
*
num_bytes
=
chunk_bytes_by_type
(
type
,
calc_size
,
num_stripes
,
sub_stripes
);
calc_size
=
max_t
(
u64
,
chunk_bytes_by_type
(
type
,
min_chunk_size
,
num_stripes
,
sub_stripes
),
calc_size
);
again:
do_div
(
calc_size
,
stripe_len
);
calc_size
*=
stripe_len
;
INIT_LIST_HEAD
(
&
private_devs
);
cur
=
dev_list
->
next
;
index
=
0
;
if
(
type
&
BTRFS_BLOCK_GROUP_DUP
)
min_free
=
calc_size
*
2
;
else
min_free
=
calc_size
;
/* build a private list of devices we will allocate from */
while
(
index
<
num_stripes
)
{
...
...
@@ -727,13 +785,9 @@ again:
}
stripes
=
&
chunk
->
stripe
;
*
num_bytes
=
chunk_bytes_by_type
(
type
,
calc_size
,
num_stripes
,
sub_stripes
);
if
(
type
&
(
BTRFS_BLOCK_GROUP_RAID1
|
BTRFS_BLOCK_GROUP_DUP
))
*
num_bytes
=
calc_size
;
else
if
(
type
&
BTRFS_BLOCK_GROUP_RAID10
)
*
num_bytes
=
calc_size
*
(
num_stripes
/
sub_stripes
);
else
*
num_bytes
=
calc_size
*
num_stripes
;
index
=
0
;
printk
(
"new chunk type %Lu start %Lu size %Lu
\n
"
,
type
,
key
.
offset
,
*
num_bytes
);
...
...
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