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
7d9eb12c
Commit
7d9eb12c
authored
Jul 08, 2008
by
Chris Mason
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Btrfs: Add locking around volume management (device add/remove/balance)
Signed-off-by:
Chris Mason
<
chris.mason@oracle.com
>
parent
a7a16fd7
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
103 additions
and
40 deletions
+103
-40
fs/btrfs/ctree.c
fs/btrfs/ctree.c
+0
-4
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+1
-0
fs/btrfs/disk-io.c
fs/btrfs/disk-io.c
+1
-0
fs/btrfs/extent-tree.c
fs/btrfs/extent-tree.c
+55
-18
fs/btrfs/ioctl.c
fs/btrfs/ioctl.c
+2
-4
fs/btrfs/volumes.c
fs/btrfs/volumes.c
+44
-14
No files found.
fs/btrfs/ctree.c
View file @
7d9eb12c
...
@@ -1251,10 +1251,6 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -1251,10 +1251,6 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
WARN_ON
(
p
->
nodes
[
0
]
!=
NULL
);
WARN_ON
(
p
->
nodes
[
0
]
!=
NULL
);
WARN_ON
(
cow
&&
root
==
root
->
fs_info
->
extent_root
&&
WARN_ON
(
cow
&&
root
==
root
->
fs_info
->
extent_root
&&
!
mutex_is_locked
(
&
root
->
fs_info
->
alloc_mutex
));
!
mutex_is_locked
(
&
root
->
fs_info
->
alloc_mutex
));
WARN_ON
(
root
==
root
->
fs_info
->
chunk_root
&&
!
mutex_is_locked
(
&
root
->
fs_info
->
chunk_mutex
));
WARN_ON
(
root
==
root
->
fs_info
->
dev_root
&&
!
mutex_is_locked
(
&
root
->
fs_info
->
chunk_mutex
));
if
(
ins_len
<
0
)
if
(
ins_len
<
0
)
lowest_unlock
=
2
;
lowest_unlock
=
2
;
again:
again:
...
...
fs/btrfs/ctree.h
View file @
7d9eb12c
...
@@ -523,6 +523,7 @@ struct btrfs_fs_info {
...
@@ -523,6 +523,7 @@ struct btrfs_fs_info {
struct
mutex
alloc_mutex
;
struct
mutex
alloc_mutex
;
struct
mutex
chunk_mutex
;
struct
mutex
chunk_mutex
;
struct
mutex
drop_mutex
;
struct
mutex
drop_mutex
;
struct
mutex
volume_mutex
;
struct
list_head
trans_list
;
struct
list_head
trans_list
;
struct
list_head
hashers
;
struct
list_head
hashers
;
struct
list_head
dead_roots
;
struct
list_head
dead_roots
;
...
...
fs/btrfs/disk-io.c
View file @
7d9eb12c
...
@@ -1287,6 +1287,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
...
@@ -1287,6 +1287,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
mutex_init
(
&
fs_info
->
chunk_mutex
);
mutex_init
(
&
fs_info
->
chunk_mutex
);
mutex_init
(
&
fs_info
->
transaction_kthread_mutex
);
mutex_init
(
&
fs_info
->
transaction_kthread_mutex
);
mutex_init
(
&
fs_info
->
cleaner_mutex
);
mutex_init
(
&
fs_info
->
cleaner_mutex
);
mutex_init
(
&
fs_info
->
volume_mutex
);
#if 0
#if 0
ret = add_hasher(fs_info, "crc32c");
ret = add_hasher(fs_info, "crc32c");
...
...
fs/btrfs/extent-tree.c
View file @
7d9eb12c
...
@@ -245,6 +245,7 @@ static int noinline find_search_start(struct btrfs_root *root,
...
@@ -245,6 +245,7 @@ static int noinline find_search_start(struct btrfs_root *root,
u64
search_start
=
*
start_ret
;
u64
search_start
=
*
start_ret
;
int
wrapped
=
0
;
int
wrapped
=
0
;
WARN_ON
(
!
mutex_is_locked
(
&
root
->
fs_info
->
alloc_mutex
));
total_fs_bytes
=
btrfs_super_total_bytes
(
&
root
->
fs_info
->
super_copy
);
total_fs_bytes
=
btrfs_super_total_bytes
(
&
root
->
fs_info
->
super_copy
);
free_space_cache
=
&
root
->
fs_info
->
free_space_cache
;
free_space_cache
=
&
root
->
fs_info
->
free_space_cache
;
...
@@ -1242,6 +1243,7 @@ static int update_block_group(struct btrfs_trans_handle *trans,
...
@@ -1242,6 +1243,7 @@ static int update_block_group(struct btrfs_trans_handle *trans,
u64
start
;
u64
start
;
u64
end
;
u64
end
;
WARN_ON
(
!
mutex_is_locked
(
&
root
->
fs_info
->
alloc_mutex
));
while
(
total
)
{
while
(
total
)
{
cache
=
btrfs_lookup_block_group
(
info
,
bytenr
);
cache
=
btrfs_lookup_block_group
(
info
,
bytenr
);
if
(
!
cache
)
{
if
(
!
cache
)
{
...
@@ -1297,6 +1299,7 @@ static int update_pinned_extents(struct btrfs_root *root,
...
@@ -1297,6 +1299,7 @@ static int update_pinned_extents(struct btrfs_root *root,
struct
btrfs_block_group_cache
*
cache
;
struct
btrfs_block_group_cache
*
cache
;
struct
btrfs_fs_info
*
fs_info
=
root
->
fs_info
;
struct
btrfs_fs_info
*
fs_info
=
root
->
fs_info
;
WARN_ON
(
!
mutex_is_locked
(
&
root
->
fs_info
->
alloc_mutex
));
if
(
pin
)
{
if
(
pin
)
{
set_extent_dirty
(
&
fs_info
->
pinned_extents
,
set_extent_dirty
(
&
fs_info
->
pinned_extents
,
bytenr
,
bytenr
+
num
-
1
,
GFP_NOFS
);
bytenr
,
bytenr
+
num
-
1
,
GFP_NOFS
);
...
@@ -1391,6 +1394,7 @@ static int finish_current_insert(struct btrfs_trans_handle *trans,
...
@@ -1391,6 +1394,7 @@ static int finish_current_insert(struct btrfs_trans_handle *trans,
int
level
;
int
level
;
int
err
=
0
;
int
err
=
0
;
WARN_ON
(
!
mutex_is_locked
(
&
extent_root
->
fs_info
->
alloc_mutex
));
btrfs_set_stack_extent_refs
(
&
extent_item
,
1
);
btrfs_set_stack_extent_refs
(
&
extent_item
,
1
);
btrfs_set_key_type
(
&
ins
,
BTRFS_EXTENT_ITEM_KEY
);
btrfs_set_key_type
(
&
ins
,
BTRFS_EXTENT_ITEM_KEY
);
path
=
btrfs_alloc_path
();
path
=
btrfs_alloc_path
();
...
@@ -1437,6 +1441,7 @@ static int pin_down_bytes(struct btrfs_root *root, u64 bytenr, u32 num_bytes,
...
@@ -1437,6 +1441,7 @@ static int pin_down_bytes(struct btrfs_root *root, u64 bytenr, u32 num_bytes,
{
{
int
err
=
0
;
int
err
=
0
;
WARN_ON
(
!
mutex_is_locked
(
&
root
->
fs_info
->
alloc_mutex
));
if
(
!
pending
)
{
if
(
!
pending
)
{
struct
extent_buffer
*
buf
;
struct
extent_buffer
*
buf
;
buf
=
btrfs_find_tree_block
(
root
,
bytenr
,
num_bytes
);
buf
=
btrfs_find_tree_block
(
root
,
bytenr
,
num_bytes
);
...
@@ -1490,6 +1495,7 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -1490,6 +1495,7 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
struct
btrfs_extent_item
*
ei
;
struct
btrfs_extent_item
*
ei
;
u32
refs
;
u32
refs
;
WARN_ON
(
!
mutex_is_locked
(
&
root
->
fs_info
->
alloc_mutex
));
key
.
objectid
=
bytenr
;
key
.
objectid
=
bytenr
;
btrfs_set_key_type
(
&
key
,
BTRFS_EXTENT_ITEM_KEY
);
btrfs_set_key_type
(
&
key
,
BTRFS_EXTENT_ITEM_KEY
);
key
.
offset
=
num_bytes
;
key
.
offset
=
num_bytes
;
...
@@ -1619,6 +1625,7 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct
...
@@ -1619,6 +1625,7 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct
struct
extent_io_tree
*
pending_del
;
struct
extent_io_tree
*
pending_del
;
struct
extent_io_tree
*
pinned_extents
;
struct
extent_io_tree
*
pinned_extents
;
WARN_ON
(
!
mutex_is_locked
(
&
extent_root
->
fs_info
->
alloc_mutex
));
pending_del
=
&
extent_root
->
fs_info
->
pending_del
;
pending_del
=
&
extent_root
->
fs_info
->
pending_del
;
pinned_extents
=
&
extent_root
->
fs_info
->
pinned_extents
;
pinned_extents
=
&
extent_root
->
fs_info
->
pinned_extents
;
...
@@ -2428,6 +2435,10 @@ int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -2428,6 +2435,10 @@ int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_node_key
(
node
,
&
found_key
,
path
->
slots
[
level
]);
btrfs_node_key
(
node
,
&
found_key
,
path
->
slots
[
level
]);
WARN_ON
(
memcmp
(
&
found_key
,
&
root_item
->
drop_progress
,
WARN_ON
(
memcmp
(
&
found_key
,
&
root_item
->
drop_progress
,
sizeof
(
found_key
)));
sizeof
(
found_key
)));
/*
* unlock our path, this is safe because only this
* function is allowed to delete this snapshot
*/
for
(
i
=
0
;
i
<
BTRFS_MAX_LEVEL
;
i
++
)
{
for
(
i
=
0
;
i
<
BTRFS_MAX_LEVEL
;
i
++
)
{
if
(
path
->
nodes
[
i
]
&&
path
->
locks
[
i
])
{
if
(
path
->
nodes
[
i
]
&&
path
->
locks
[
i
])
{
path
->
locks
[
i
]
=
0
;
path
->
locks
[
i
]
=
0
;
...
@@ -2611,7 +2622,6 @@ static int find_root_for_ref(struct btrfs_root *root,
...
@@ -2611,7 +2622,6 @@ static int find_root_for_ref(struct btrfs_root *root,
u64
root_search_start
=
BTRFS_FS_TREE_OBJECTID
;
u64
root_search_start
=
BTRFS_FS_TREE_OBJECTID
;
u64
found_bytenr
;
u64
found_bytenr
;
int
ret
;
int
ret
;
int
i
;
root_location
.
offset
=
(
u64
)
-
1
;
root_location
.
offset
=
(
u64
)
-
1
;
root_location
.
type
=
BTRFS_ROOT_ITEM_KEY
;
root_location
.
type
=
BTRFS_ROOT_ITEM_KEY
;
...
@@ -2635,12 +2645,6 @@ static int find_root_for_ref(struct btrfs_root *root,
...
@@ -2635,12 +2645,6 @@ static int find_root_for_ref(struct btrfs_root *root,
found_bytenr
=
path
->
nodes
[
level
]
->
start
;
found_bytenr
=
path
->
nodes
[
level
]
->
start
;
}
}
for
(
i
=
level
;
i
<
BTRFS_MAX_LEVEL
;
i
++
)
{
if
(
!
path
->
nodes
[
i
])
break
;
free_extent_buffer
(
path
->
nodes
[
i
]);
path
->
nodes
[
i
]
=
NULL
;
}
btrfs_release_path
(
cur_root
,
path
);
btrfs_release_path
(
cur_root
,
path
);
if
(
found_bytenr
==
bytenr
)
{
if
(
found_bytenr
==
bytenr
)
{
...
@@ -2689,6 +2693,8 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root,
...
@@ -2689,6 +2693,8 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root,
int
ret
;
int
ret
;
int
level
;
int
level
;
WARN_ON
(
!
mutex_is_locked
(
&
extent_root
->
fs_info
->
alloc_mutex
));
ref
=
btrfs_item_ptr
(
path
->
nodes
[
0
],
path
->
slots
[
0
],
ref
=
btrfs_item_ptr
(
path
->
nodes
[
0
],
path
->
slots
[
0
],
struct
btrfs_extent_ref
);
struct
btrfs_extent_ref
);
ref_root
=
btrfs_ref_root
(
path
->
nodes
[
0
],
ref
);
ref_root
=
btrfs_ref_root
(
path
->
nodes
[
0
],
ref
);
...
@@ -2707,6 +2713,7 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root,
...
@@ -2707,6 +2713,7 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root,
found_root
=
btrfs_read_fs_root_no_name
(
extent_root
->
fs_info
,
found_root
=
btrfs_read_fs_root_no_name
(
extent_root
->
fs_info
,
&
root_location
);
&
root_location
);
BUG_ON
(
!
found_root
);
BUG_ON
(
!
found_root
);
mutex_unlock
(
&
extent_root
->
fs_info
->
alloc_mutex
);
if
(
ref_objectid
>=
BTRFS_FIRST_FREE_OBJECTID
)
{
if
(
ref_objectid
>=
BTRFS_FIRST_FREE_OBJECTID
)
{
found_key
.
objectid
=
ref_objectid
;
found_key
.
objectid
=
ref_objectid
;
...
@@ -2748,9 +2755,9 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root,
...
@@ -2748,9 +2755,9 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root,
/* this can happen if the reference is not against
/* this can happen if the reference is not against
* the latest version of the tree root
* the latest version of the tree root
*/
*/
if
(
is_bad_inode
(
inode
))
{
if
(
is_bad_inode
(
inode
))
goto
out
;
goto
out
;
}
*
last_file_objectid
=
inode
->
i_ino
;
*
last_file_objectid
=
inode
->
i_ino
;
*
last_file_root
=
found_root
->
root_key
.
objectid
;
*
last_file_root
=
found_root
->
root_key
.
objectid
;
*
last_file_offset
=
ref_offset
;
*
last_file_offset
=
ref_offset
;
...
@@ -2760,7 +2767,7 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root,
...
@@ -2760,7 +2767,7 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root,
}
else
{
}
else
{
struct
btrfs_trans_handle
*
trans
;
struct
btrfs_trans_handle
*
trans
;
struct
extent_buffer
*
eb
;
struct
extent_buffer
*
eb
;
int
i
;
int
needs_lock
=
0
;
eb
=
read_tree_block
(
found_root
,
extent_key
->
objectid
,
eb
=
read_tree_block
(
found_root
,
extent_key
->
objectid
,
extent_key
->
offset
,
0
);
extent_key
->
offset
,
0
);
...
@@ -2782,26 +2789,40 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root,
...
@@ -2782,26 +2789,40 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root,
if
(
ret
)
if
(
ret
)
goto
out
;
goto
out
;
/*
* right here almost anything could happen to our key,
* but that's ok. The cow below will either relocate it
* or someone else will have relocated it. Either way,
* it is in a different spot than it was before and
* we're happy.
*/
trans
=
btrfs_start_transaction
(
found_root
,
1
);
trans
=
btrfs_start_transaction
(
found_root
,
1
);
if
(
found_root
==
extent_root
->
fs_info
->
extent_root
||
found_root
==
extent_root
->
fs_info
->
chunk_root
||
found_root
==
extent_root
->
fs_info
->
dev_root
)
{
needs_lock
=
1
;
mutex_lock
(
&
extent_root
->
fs_info
->
alloc_mutex
);
}
path
->
lowest_level
=
level
;
path
->
lowest_level
=
level
;
path
->
reada
=
2
;
path
->
reada
=
2
;
ret
=
btrfs_search_slot
(
trans
,
found_root
,
&
found_key
,
path
,
ret
=
btrfs_search_slot
(
trans
,
found_root
,
&
found_key
,
path
,
0
,
1
);
0
,
1
);
path
->
lowest_level
=
0
;
path
->
lowest_level
=
0
;
for
(
i
=
level
;
i
<
BTRFS_MAX_LEVEL
;
i
++
)
{
if
(
!
path
->
nodes
[
i
])
break
;
free_extent_buffer
(
path
->
nodes
[
i
]);
path
->
nodes
[
i
]
=
NULL
;
}
btrfs_release_path
(
found_root
,
path
);
btrfs_release_path
(
found_root
,
path
);
if
(
found_root
==
found_root
->
fs_info
->
extent_root
)
if
(
found_root
==
found_root
->
fs_info
->
extent_root
)
btrfs_extent_post_op
(
trans
,
found_root
);
btrfs_extent_post_op
(
trans
,
found_root
);
if
(
needs_lock
)
mutex_unlock
(
&
extent_root
->
fs_info
->
alloc_mutex
);
btrfs_end_transaction
(
trans
,
found_root
);
btrfs_end_transaction
(
trans
,
found_root
);
}
}
out:
out:
mutex_lock
(
&
extent_root
->
fs_info
->
alloc_mutex
);
return
0
;
return
0
;
}
}
...
@@ -2943,7 +2964,10 @@ int __alloc_chunk_for_shrink(struct btrfs_root *root,
...
@@ -2943,7 +2964,10 @@ int __alloc_chunk_for_shrink(struct btrfs_root *root,
if
(
btrfs_block_group_used
(
&
shrink_block_group
->
item
)
>
0
)
{
if
(
btrfs_block_group_used
(
&
shrink_block_group
->
item
)
>
0
)
{
mutex_unlock
(
&
root
->
fs_info
->
alloc_mutex
);
trans
=
btrfs_start_transaction
(
root
,
1
);
trans
=
btrfs_start_transaction
(
root
,
1
);
mutex_lock
(
&
root
->
fs_info
->
alloc_mutex
);
new_alloc_flags
=
update_block_group_flags
(
root
,
new_alloc_flags
=
update_block_group_flags
(
root
,
shrink_block_group
->
flags
);
shrink_block_group
->
flags
);
if
(
new_alloc_flags
!=
shrink_block_group
->
flags
)
{
if
(
new_alloc_flags
!=
shrink_block_group
->
flags
)
{
...
@@ -2954,7 +2978,10 @@ int __alloc_chunk_for_shrink(struct btrfs_root *root,
...
@@ -2954,7 +2978,10 @@ int __alloc_chunk_for_shrink(struct btrfs_root *root,
}
}
do_chunk_alloc
(
trans
,
root
->
fs_info
->
extent_root
,
do_chunk_alloc
(
trans
,
root
->
fs_info
->
extent_root
,
calc
+
2
*
1024
*
1024
,
new_alloc_flags
,
force
);
calc
+
2
*
1024
*
1024
,
new_alloc_flags
,
force
);
mutex_unlock
(
&
root
->
fs_info
->
alloc_mutex
);
btrfs_end_transaction
(
trans
,
root
);
btrfs_end_transaction
(
trans
,
root
);
mutex_lock
(
&
root
->
fs_info
->
alloc_mutex
);
}
}
return
0
;
return
0
;
}
}
...
@@ -3031,9 +3058,9 @@ int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 shrink_start)
...
@@ -3031,9 +3058,9 @@ int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 shrink_start)
if
(
ret
<
0
)
if
(
ret
<
0
)
goto
out
;
goto
out
;
next:
leaf
=
path
->
nodes
[
0
];
leaf
=
path
->
nodes
[
0
];
nritems
=
btrfs_header_nritems
(
leaf
);
nritems
=
btrfs_header_nritems
(
leaf
);
next:
if
(
path
->
slots
[
0
]
>=
nritems
)
{
if
(
path
->
slots
[
0
]
>=
nritems
)
{
ret
=
btrfs_next_leaf
(
root
,
path
);
ret
=
btrfs_next_leaf
(
root
,
path
);
if
(
ret
<
0
)
if
(
ret
<
0
)
...
@@ -3083,6 +3110,7 @@ int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 shrink_start)
...
@@ -3083,6 +3110,7 @@ int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 shrink_start)
printk
(
"btrfs relocate found %llu last extent was %llu
\n
"
,
printk
(
"btrfs relocate found %llu last extent was %llu
\n
"
,
(
unsigned
long
long
)
total_found
,
(
unsigned
long
long
)
total_found
,
(
unsigned
long
long
)
found_key
.
objectid
);
(
unsigned
long
long
)
found_key
.
objectid
);
mutex_unlock
(
&
root
->
fs_info
->
alloc_mutex
);
trans
=
btrfs_start_transaction
(
tree_root
,
1
);
trans
=
btrfs_start_transaction
(
tree_root
,
1
);
btrfs_commit_transaction
(
trans
,
tree_root
);
btrfs_commit_transaction
(
trans
,
tree_root
);
...
@@ -3090,6 +3118,7 @@ int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 shrink_start)
...
@@ -3090,6 +3118,7 @@ int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 shrink_start)
trans
=
btrfs_start_transaction
(
tree_root
,
1
);
trans
=
btrfs_start_transaction
(
tree_root
,
1
);
btrfs_commit_transaction
(
trans
,
tree_root
);
btrfs_commit_transaction
(
trans
,
tree_root
);
mutex_lock
(
&
root
->
fs_info
->
alloc_mutex
);
goto
again
;
goto
again
;
}
}
...
@@ -3097,7 +3126,10 @@ int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 shrink_start)
...
@@ -3097,7 +3126,10 @@ int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 shrink_start)
* we've freed all the extents, now remove the block
* we've freed all the extents, now remove the block
* group item from the tree
* group item from the tree
*/
*/
mutex_unlock
(
&
root
->
fs_info
->
alloc_mutex
);
trans
=
btrfs_start_transaction
(
root
,
1
);
trans
=
btrfs_start_transaction
(
root
,
1
);
mutex_lock
(
&
root
->
fs_info
->
alloc_mutex
);
memcpy
(
&
key
,
&
shrink_block_group
->
key
,
sizeof
(
key
));
memcpy
(
&
key
,
&
shrink_block_group
->
key
,
sizeof
(
key
));
ret
=
btrfs_search_slot
(
trans
,
root
,
&
key
,
path
,
-
1
,
1
);
ret
=
btrfs_search_slot
(
trans
,
root
,
&
key
,
path
,
-
1
,
1
);
...
@@ -3119,8 +3151,12 @@ int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 shrink_start)
...
@@ -3119,8 +3151,12 @@ int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 shrink_start)
kfree
(
shrink_block_group
);
kfree
(
shrink_block_group
);
btrfs_del_item
(
trans
,
root
,
path
);
btrfs_del_item
(
trans
,
root
,
path
);
btrfs_release_path
(
root
,
path
);
mutex_unlock
(
&
root
->
fs_info
->
alloc_mutex
);
btrfs_commit_transaction
(
trans
,
root
);
btrfs_commit_transaction
(
trans
,
root
);
mutex_lock
(
&
root
->
fs_info
->
alloc_mutex
);
/* the code to unpin extents might set a few bits in the free
/* the code to unpin extents might set a few bits in the free
* space cache for this range again
* space cache for this range again
*/
*/
...
@@ -3263,6 +3299,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
...
@@ -3263,6 +3299,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
struct
btrfs_block_group_cache
*
cache
;
struct
btrfs_block_group_cache
*
cache
;
struct
extent_io_tree
*
block_group_cache
;
struct
extent_io_tree
*
block_group_cache
;
WARN_ON
(
!
mutex_is_locked
(
&
root
->
fs_info
->
alloc_mutex
));
extent_root
=
root
->
fs_info
->
extent_root
;
extent_root
=
root
->
fs_info
->
extent_root
;
block_group_cache
=
&
root
->
fs_info
->
block_group_cache
;
block_group_cache
=
&
root
->
fs_info
->
block_group_cache
;
...
...
fs/btrfs/ioctl.c
View file @
7d9eb12c
...
@@ -307,8 +307,7 @@ static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg)
...
@@ -307,8 +307,7 @@ static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg)
goto
out
;
goto
out
;
}
}
mutex_lock
(
&
root
->
fs_info
->
alloc_mutex
);
mutex_lock
(
&
root
->
fs_info
->
volume_mutex
);
mutex_lock
(
&
root
->
fs_info
->
chunk_mutex
);
sizestr
=
vol_args
->
name
;
sizestr
=
vol_args
->
name
;
devstr
=
strchr
(
sizestr
,
':'
);
devstr
=
strchr
(
sizestr
,
':'
);
if
(
devstr
)
{
if
(
devstr
)
{
...
@@ -378,8 +377,7 @@ static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg)
...
@@ -378,8 +377,7 @@ static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg)
}
}
out_unlock:
out_unlock:
mutex_lock
(
&
root
->
fs_info
->
alloc_mutex
);
mutex_unlock
(
&
root
->
fs_info
->
volume_mutex
);
mutex_lock
(
&
root
->
fs_info
->
chunk_mutex
);
out:
out:
kfree
(
vol_args
);
kfree
(
vol_args
);
return
ret
;
return
ret
;
...
...
fs/btrfs/volumes.c
View file @
7d9eb12c
...
@@ -56,6 +56,18 @@ void btrfs_unlock_volumes(void)
...
@@ -56,6 +56,18 @@ void btrfs_unlock_volumes(void)
mutex_unlock
(
&
uuid_mutex
);
mutex_unlock
(
&
uuid_mutex
);
}
}
static
void
lock_chunks
(
struct
btrfs_root
*
root
)
{
mutex_lock
(
&
root
->
fs_info
->
alloc_mutex
);
mutex_lock
(
&
root
->
fs_info
->
chunk_mutex
);
}
static
void
unlock_chunks
(
struct
btrfs_root
*
root
)
{
mutex_unlock
(
&
root
->
fs_info
->
alloc_mutex
);
mutex_unlock
(
&
root
->
fs_info
->
chunk_mutex
);
}
int
btrfs_cleanup_fs_uuids
(
void
)
int
btrfs_cleanup_fs_uuids
(
void
)
{
{
struct
btrfs_fs_devices
*
fs_devices
;
struct
btrfs_fs_devices
*
fs_devices
;
...
@@ -822,6 +834,7 @@ static int btrfs_rm_dev_item(struct btrfs_root *root,
...
@@ -822,6 +834,7 @@ static int btrfs_rm_dev_item(struct btrfs_root *root,
key
.
objectid
=
BTRFS_DEV_ITEMS_OBJECTID
;
key
.
objectid
=
BTRFS_DEV_ITEMS_OBJECTID
;
key
.
type
=
BTRFS_DEV_ITEM_KEY
;
key
.
type
=
BTRFS_DEV_ITEM_KEY
;
key
.
offset
=
device
->
devid
;
key
.
offset
=
device
->
devid
;
lock_chunks
(
root
);
ret
=
btrfs_search_slot
(
trans
,
root
,
&
key
,
path
,
-
1
,
1
);
ret
=
btrfs_search_slot
(
trans
,
root
,
&
key
,
path
,
-
1
,
1
);
if
(
ret
<
0
)
if
(
ret
<
0
)
...
@@ -856,6 +869,7 @@ static int btrfs_rm_dev_item(struct btrfs_root *root,
...
@@ -856,6 +869,7 @@ static int btrfs_rm_dev_item(struct btrfs_root *root,
total_bytes
-
1
);
total_bytes
-
1
);
out:
out:
btrfs_free_path
(
path
);
btrfs_free_path
(
path
);
unlock_chunks
(
root
);
btrfs_commit_transaction
(
trans
,
root
);
btrfs_commit_transaction
(
trans
,
root
);
return
ret
;
return
ret
;
}
}
...
@@ -870,9 +884,8 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
...
@@ -870,9 +884,8 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
u64
devid
;
u64
devid
;
int
ret
=
0
;
int
ret
=
0
;
mutex_lock
(
&
root
->
fs_info
->
alloc_mutex
);
mutex_lock
(
&
root
->
fs_info
->
chunk_mutex
);
mutex_lock
(
&
uuid_mutex
);
mutex_lock
(
&
uuid_mutex
);
mutex_lock
(
&
root
->
fs_info
->
volume_mutex
);
all_avail
=
root
->
fs_info
->
avail_data_alloc_bits
|
all_avail
=
root
->
fs_info
->
avail_data_alloc_bits
|
root
->
fs_info
->
avail_system_alloc_bits
|
root
->
fs_info
->
avail_system_alloc_bits
|
...
@@ -988,9 +1001,8 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
...
@@ -988,9 +1001,8 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
if
(
bdev
)
if
(
bdev
)
close_bdev_excl
(
bdev
);
close_bdev_excl
(
bdev
);
out:
out:
mutex_unlock
(
&
root
->
fs_info
->
volume_mutex
);
mutex_unlock
(
&
uuid_mutex
);
mutex_unlock
(
&
uuid_mutex
);
mutex_unlock
(
&
root
->
fs_info
->
chunk_mutex
);
mutex_unlock
(
&
root
->
fs_info
->
alloc_mutex
);
return
ret
;
return
ret
;
}
}
...
@@ -1010,10 +1022,10 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
...
@@ -1010,10 +1022,10 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
return
-
EIO
;
return
-
EIO
;
}
}
mutex_lock
(
&
root
->
fs_info
->
alloc_mutex
);
mutex_lock
(
&
root
->
fs_info
->
volume_mutex
);
mutex_lock
(
&
root
->
fs_info
->
chunk_mutex
);
trans
=
btrfs_start_transaction
(
root
,
1
);
trans
=
btrfs_start_transaction
(
root
,
1
);
lock_chunks
(
root
);
devices
=
&
root
->
fs_info
->
fs_devices
->
devices
;
devices
=
&
root
->
fs_info
->
fs_devices
->
devices
;
list_for_each
(
cur
,
devices
)
{
list_for_each
(
cur
,
devices
)
{
device
=
list_entry
(
cur
,
struct
btrfs_device
,
dev_list
);
device
=
list_entry
(
cur
,
struct
btrfs_device
,
dev_list
);
...
@@ -1065,9 +1077,9 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
...
@@ -1065,9 +1077,9 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
root
->
fs_info
->
fs_devices
->
num_devices
++
;
root
->
fs_info
->
fs_devices
->
num_devices
++
;
root
->
fs_info
->
fs_devices
->
open_devices
++
;
root
->
fs_info
->
fs_devices
->
open_devices
++
;
out:
out:
unlock_chunks
(
root
);
btrfs_end_transaction
(
trans
,
root
);
btrfs_end_transaction
(
trans
,
root
);
mutex_unlock
(
&
root
->
fs_info
->
chunk_mutex
);
mutex_unlock
(
&
root
->
fs_info
->
volume_mutex
);
mutex_unlock
(
&
root
->
fs_info
->
alloc_mutex
);
return
ret
;
return
ret
;
...
@@ -1122,7 +1134,7 @@ int btrfs_update_device(struct btrfs_trans_handle *trans,
...
@@ -1122,7 +1134,7 @@ int btrfs_update_device(struct btrfs_trans_handle *trans,
return
ret
;
return
ret
;
}
}
int
btrfs_grow_device
(
struct
btrfs_trans_handle
*
trans
,
static
int
__
btrfs_grow_device
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_device
*
device
,
u64
new_size
)
struct
btrfs_device
*
device
,
u64
new_size
)
{
{
struct
btrfs_super_block
*
super_copy
=
struct
btrfs_super_block
*
super_copy
=
...
@@ -1134,6 +1146,16 @@ int btrfs_grow_device(struct btrfs_trans_handle *trans,
...
@@ -1134,6 +1146,16 @@ int btrfs_grow_device(struct btrfs_trans_handle *trans,
return
btrfs_update_device
(
trans
,
device
);
return
btrfs_update_device
(
trans
,
device
);
}
}
int
btrfs_grow_device
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_device
*
device
,
u64
new_size
)
{
int
ret
;
lock_chunks
(
device
->
dev_root
);
ret
=
__btrfs_grow_device
(
trans
,
device
,
new_size
);
unlock_chunks
(
device
->
dev_root
);
return
ret
;
}
static
int
btrfs_free_chunk
(
struct
btrfs_trans_handle
*
trans
,
static
int
btrfs_free_chunk
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_root
*
root
,
u64
chunk_tree
,
u64
chunk_objectid
,
u64
chunk_tree
,
u64
chunk_objectid
,
...
@@ -1234,6 +1256,8 @@ int btrfs_relocate_chunk(struct btrfs_root *root,
...
@@ -1234,6 +1256,8 @@ int btrfs_relocate_chunk(struct btrfs_root *root,
trans
=
btrfs_start_transaction
(
root
,
1
);
trans
=
btrfs_start_transaction
(
root
,
1
);
BUG_ON
(
!
trans
);
BUG_ON
(
!
trans
);
lock_chunks
(
root
);
/*
/*
* step two, delete the device extents and the
* step two, delete the device extents and the
* chunk tree entries
* chunk tree entries
...
@@ -1278,6 +1302,7 @@ int btrfs_relocate_chunk(struct btrfs_root *root,
...
@@ -1278,6 +1302,7 @@ int btrfs_relocate_chunk(struct btrfs_root *root,
/* once for us */
/* once for us */
free_extent_map
(
em
);
free_extent_map
(
em
);
unlock_chunks
(
root
);
btrfs_end_transaction
(
trans
,
root
);
btrfs_end_transaction
(
trans
,
root
);
return
0
;
return
0
;
}
}
...
@@ -1308,8 +1333,7 @@ int btrfs_balance(struct btrfs_root *dev_root)
...
@@ -1308,8 +1333,7 @@ int btrfs_balance(struct btrfs_root *dev_root)
struct
btrfs_key
found_key
;
struct
btrfs_key
found_key
;
BUG
();
/* FIXME, needs locking */
mutex_lock
(
&
dev_root
->
fs_info
->
volume_mutex
);
dev_root
=
dev_root
->
fs_info
->
dev_root
;
dev_root
=
dev_root
->
fs_info
->
dev_root
;
/* step one make some room on all the devices */
/* step one make some room on all the devices */
...
@@ -1355,13 +1379,14 @@ int btrfs_balance(struct btrfs_root *dev_root)
...
@@ -1355,13 +1379,14 @@ int btrfs_balance(struct btrfs_root *dev_root)
ret
=
btrfs_previous_item
(
chunk_root
,
path
,
0
,
ret
=
btrfs_previous_item
(
chunk_root
,
path
,
0
,
BTRFS_CHUNK_ITEM_KEY
);
BTRFS_CHUNK_ITEM_KEY
);
if
(
ret
)
{
if
(
ret
)
break
;
break
;
}
btrfs_item_key_to_cpu
(
path
->
nodes
[
0
],
&
found_key
,
btrfs_item_key_to_cpu
(
path
->
nodes
[
0
],
&
found_key
,
path
->
slots
[
0
]);
path
->
slots
[
0
]);
if
(
found_key
.
objectid
!=
key
.
objectid
)
if
(
found_key
.
objectid
!=
key
.
objectid
)
break
;
break
;
chunk
=
btrfs_item_ptr
(
path
->
nodes
[
0
],
chunk
=
btrfs_item_ptr
(
path
->
nodes
[
0
],
path
->
slots
[
0
],
path
->
slots
[
0
],
struct
btrfs_chunk
);
struct
btrfs_chunk
);
...
@@ -1370,16 +1395,17 @@ int btrfs_balance(struct btrfs_root *dev_root)
...
@@ -1370,16 +1395,17 @@ int btrfs_balance(struct btrfs_root *dev_root)
if
(
key
.
offset
==
0
)
if
(
key
.
offset
==
0
)
break
;
break
;
btrfs_release_path
(
chunk_root
,
path
);
ret
=
btrfs_relocate_chunk
(
chunk_root
,
ret
=
btrfs_relocate_chunk
(
chunk_root
,
chunk_root
->
root_key
.
objectid
,
chunk_root
->
root_key
.
objectid
,
found_key
.
objectid
,
found_key
.
objectid
,
found_key
.
offset
);
found_key
.
offset
);
BUG_ON
(
ret
);
BUG_ON
(
ret
);
btrfs_release_path
(
chunk_root
,
path
);
}
}
ret
=
0
;
ret
=
0
;
error:
error:
btrfs_free_path
(
path
);
btrfs_free_path
(
path
);
mutex_unlock
(
&
dev_root
->
fs_info
->
volume_mutex
);
return
ret
;
return
ret
;
}
}
...
@@ -1419,14 +1445,18 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size)
...
@@ -1419,14 +1445,18 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size)
path
->
reada
=
2
;
path
->
reada
=
2
;
lock_chunks
(
root
);
device
->
total_bytes
=
new_size
;
device
->
total_bytes
=
new_size
;
ret
=
btrfs_update_device
(
trans
,
device
);
ret
=
btrfs_update_device
(
trans
,
device
);
if
(
ret
)
{
if
(
ret
)
{
unlock_chunks
(
root
);
btrfs_end_transaction
(
trans
,
root
);
btrfs_end_transaction
(
trans
,
root
);
goto
done
;
goto
done
;
}
}
WARN_ON
(
diff
>
old_total
);
WARN_ON
(
diff
>
old_total
);
btrfs_set_super_total_bytes
(
super_copy
,
old_total
-
diff
);
btrfs_set_super_total_bytes
(
super_copy
,
old_total
-
diff
);
unlock_chunks
(
root
);
btrfs_end_transaction
(
trans
,
root
);
btrfs_end_transaction
(
trans
,
root
);
key
.
objectid
=
device
->
devid
;
key
.
objectid
=
device
->
devid
;
...
...
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