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
d6025579
Commit
d6025579
authored
Mar 30, 2007
by
Chris Mason
Committed by
David Woodhouse
Mar 30, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Btrfs: corruption hunt continues
Signed-off-by:
Chris Mason
<
chris.mason@oracle.com
>
parent
22b0ebda
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
187 additions
and
105 deletions
+187
-105
fs/btrfs/bit-radix.c
fs/btrfs/bit-radix.c
+7
-2
fs/btrfs/ctree.c
fs/btrfs/ctree.c
+114
-87
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+32
-0
fs/btrfs/dir-item.c
fs/btrfs/dir-item.c
+2
-4
fs/btrfs/disk-io.c
fs/btrfs/disk-io.c
+19
-1
fs/btrfs/extent-tree.c
fs/btrfs/extent-tree.c
+4
-4
fs/btrfs/file-item.c
fs/btrfs/file-item.c
+2
-2
fs/btrfs/inode-map.c
fs/btrfs/inode-map.c
+1
-1
fs/btrfs/root-tree.c
fs/btrfs/root-tree.c
+4
-3
fs/btrfs/super.c
fs/btrfs/super.c
+1
-1
fs/btrfs/transaction.c
fs/btrfs/transaction.c
+1
-0
No files found.
fs/btrfs/bit-radix.c
View file @
d6025579
...
...
@@ -16,12 +16,14 @@ int set_radix_bit(struct radix_tree_root *radix, unsigned long bit)
bits
=
radix_tree_lookup
(
radix
,
slot
);
if
(
!
bits
)
{
bits
=
kmalloc
(
BIT_ARRAY_BYTES
,
GFP_NO
IO
);
bits
=
kmalloc
(
BIT_ARRAY_BYTES
,
GFP_NO
FS
);
if
(
!
bits
)
return
-
ENOMEM
;
memset
(
bits
+
1
,
0
,
BIT_ARRAY_BYTES
-
sizeof
(
unsigned
long
));
bits
[
0
]
=
slot
;
radix_tree_preload
(
GFP_NOFS
);
ret
=
radix_tree_insert
(
radix
,
slot
,
bits
);
radix_tree_preload_end
();
if
(
ret
)
return
ret
;
}
...
...
@@ -59,7 +61,7 @@ int clear_radix_bit(struct radix_tree_root *radix, unsigned long bit)
if
(
!
bits
)
return
0
;
clear_bit
(
bit_slot
,
bits
+
1
);
#if 0
for (i = 1; i < BIT_ARRAY_BYTES / sizeof(unsigned long); i++) {
if (bits[i]) {
empty = 0;
...
...
@@ -69,8 +71,11 @@ int clear_radix_bit(struct radix_tree_root *radix, unsigned long bit)
if (empty) {
bits = radix_tree_delete(radix, slot);
synchronize_rcu();
BUG_ON(!bits);
kfree(bits);
}
#endif
return
0
;
}
...
...
fs/btrfs/ctree.c
View file @
d6025579
...
...
@@ -51,7 +51,7 @@ static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_set_header_blocknr
(
&
cow_node
->
header
,
cow
->
b_blocknr
);
btrfs_set_header_generation
(
&
cow_node
->
header
,
trans
->
transid
);
*
cow_ret
=
cow
;
mark_buffer_dirty
(
cow
);
btrfs_
mark_buffer_dirty
(
cow
);
btrfs_inc_ref
(
trans
,
root
,
buf
);
if
(
buf
==
root
->
node
)
{
root
->
node
=
cow
;
...
...
@@ -62,7 +62,7 @@ static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
}
else
{
btrfs_set_node_blockptr
(
btrfs_buffer_node
(
parent
),
parent_slot
,
cow
->
b_blocknr
);
mark_buffer_dirty
(
parent
);
btrfs_
mark_buffer_dirty
(
parent
);
btrfs_free_extent
(
trans
,
root
,
buf
->
b_blocknr
,
1
,
1
);
}
btrfs_block_release
(
root
,
buf
);
...
...
@@ -312,11 +312,12 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
BUG_ON
(
!
child
);
root
->
node
=
child
;
path
->
nodes
[
level
]
=
NULL
;
clean_tree_block
(
trans
,
root
,
mid_buf
);
wait_on_buffer
(
mid_buf
);
/* once for the path */
btrfs_block_release
(
root
,
mid_buf
);
/* once for the root ptr */
btrfs_block_release
(
root
,
mid_buf
);
clean_tree_block
(
trans
,
root
,
mid_buf
);
return
btrfs_free_extent
(
trans
,
root
,
blocknr
,
1
,
1
);
}
parent
=
btrfs_buffer_node
(
parent_buf
);
...
...
@@ -351,8 +352,9 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
ret
=
wret
;
if
(
btrfs_header_nritems
(
&
right
->
header
)
==
0
)
{
u64
blocknr
=
right_buf
->
b_blocknr
;
btrfs_block_release
(
root
,
right_buf
);
clean_tree_block
(
trans
,
root
,
right_buf
);
wait_on_buffer
(
right_buf
);
btrfs_block_release
(
root
,
right_buf
);
right_buf
=
NULL
;
right
=
NULL
;
wret
=
del_ptr
(
trans
,
root
,
path
,
level
+
1
,
pslot
+
...
...
@@ -363,10 +365,11 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
if
(
wret
)
ret
=
wret
;
}
else
{
memcpy
(
&
parent
->
ptrs
[
pslot
+
1
].
key
,
&
right
->
ptrs
[
0
].
key
,
sizeof
(
struct
btrfs_disk_key
));
mark_buffer_dirty
(
parent_buf
);
btrfs_memcpy
(
root
,
parent
,
&
parent
->
ptrs
[
pslot
+
1
].
key
,
&
right
->
ptrs
[
0
].
key
,
sizeof
(
struct
btrfs_disk_key
));
btrfs_mark_buffer_dirty
(
parent_buf
);
}
}
if
(
btrfs_header_nritems
(
&
mid
->
header
)
==
1
)
{
...
...
@@ -388,8 +391,9 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
if
(
btrfs_header_nritems
(
&
mid
->
header
)
==
0
)
{
/* we've managed to empty the middle node, drop it */
u64
blocknr
=
mid_buf
->
b_blocknr
;
btrfs_block_release
(
root
,
mid_buf
);
clean_tree_block
(
trans
,
root
,
mid_buf
);
wait_on_buffer
(
mid_buf
);
btrfs_block_release
(
root
,
mid_buf
);
mid_buf
=
NULL
;
mid
=
NULL
;
wret
=
del_ptr
(
trans
,
root
,
path
,
level
+
1
,
pslot
);
...
...
@@ -400,9 +404,10 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
ret
=
wret
;
}
else
{
/* update the parent key to reflect our changes */
memcpy
(
&
parent
->
ptrs
[
pslot
].
key
,
&
mid
->
ptrs
[
0
].
key
,
sizeof
(
struct
btrfs_disk_key
));
mark_buffer_dirty
(
parent_buf
);
btrfs_memcpy
(
root
,
parent
,
&
parent
->
ptrs
[
pslot
].
key
,
&
mid
->
ptrs
[
0
].
key
,
sizeof
(
struct
btrfs_disk_key
));
btrfs_mark_buffer_dirty
(
parent_buf
);
}
/* update the path */
...
...
@@ -544,8 +549,8 @@ static int fixup_low_keys(struct btrfs_trans_handle *trans, struct btrfs_root
if
(
!
path
->
nodes
[
i
])
break
;
t
=
btrfs_buffer_node
(
path
->
nodes
[
i
]);
memcpy
(
&
t
->
ptrs
[
tslot
].
key
,
key
,
sizeof
(
*
key
));
mark_buffer_dirty
(
path
->
nodes
[
i
]);
btrfs_memcpy
(
root
,
t
,
&
t
->
ptrs
[
tslot
].
key
,
key
,
sizeof
(
*
key
));
btrfs_
mark_buffer_dirty
(
path
->
nodes
[
i
]);
if
(
tslot
!=
0
)
break
;
}
...
...
@@ -580,17 +585,17 @@ static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root
if
(
src_nritems
<
push_items
)
push_items
=
src_nritems
;
memcpy
(
dst
->
ptrs
+
dst_nritems
,
src
->
ptrs
,
push_items
*
sizeof
(
struct
btrfs_key_ptr
));
btrfs_memcpy
(
root
,
dst
,
dst
->
ptrs
+
dst_nritems
,
src
->
ptrs
,
push_items
*
sizeof
(
struct
btrfs_key_ptr
));
if
(
push_items
<
src_nritems
)
{
memmove
(
src
->
ptrs
,
src
->
ptrs
+
push_items
,
btrfs_memmove
(
root
,
src
,
src
->
ptrs
,
src
->
ptrs
+
push_items
,
(
src_nritems
-
push_items
)
*
sizeof
(
struct
btrfs_key_ptr
));
}
btrfs_set_header_nritems
(
&
src
->
header
,
src_nritems
-
push_items
);
btrfs_set_header_nritems
(
&
dst
->
header
,
dst_nritems
+
push_items
);
mark_buffer_dirty
(
src_buf
);
mark_buffer_dirty
(
dst_buf
);
btrfs_
mark_buffer_dirty
(
src_buf
);
btrfs_
mark_buffer_dirty
(
dst_buf
);
return
ret
;
}
...
...
@@ -629,16 +634,18 @@ static int balance_node_right(struct btrfs_trans_handle *trans, struct
if
(
max_push
<
push_items
)
push_items
=
max_push
;
memmove
(
dst
->
ptrs
+
push_items
,
dst
->
ptrs
,
dst_nritems
*
sizeof
(
struct
btrfs_key_ptr
));
memcpy
(
dst
->
ptrs
,
src
->
ptrs
+
src_nritems
-
push_items
,
push_items
*
sizeof
(
struct
btrfs_key_ptr
));
btrfs_memmove
(
root
,
dst
,
dst
->
ptrs
+
push_items
,
dst
->
ptrs
,
dst_nritems
*
sizeof
(
struct
btrfs_key_ptr
));
btrfs_memcpy
(
root
,
dst
,
dst
->
ptrs
,
src
->
ptrs
+
src_nritems
-
push_items
,
push_items
*
sizeof
(
struct
btrfs_key_ptr
));
btrfs_set_header_nritems
(
&
src
->
header
,
src_nritems
-
push_items
);
btrfs_set_header_nritems
(
&
dst
->
header
,
dst_nritems
+
push_items
);
mark_buffer_dirty
(
src_buf
);
mark_buffer_dirty
(
dst_buf
);
btrfs_
mark_buffer_dirty
(
src_buf
);
btrfs_
mark_buffer_dirty
(
dst_buf
);
return
ret
;
}
...
...
@@ -674,10 +681,11 @@ static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root
lower_key
=
&
((
struct
btrfs_leaf
*
)
lower
)
->
items
[
0
].
key
;
else
lower_key
=
&
lower
->
ptrs
[
0
].
key
;
memcpy
(
&
c
->
ptrs
[
0
].
key
,
lower_key
,
sizeof
(
struct
btrfs_disk_key
));
btrfs_memcpy
(
root
,
c
,
&
c
->
ptrs
[
0
].
key
,
lower_key
,
sizeof
(
struct
btrfs_disk_key
));
btrfs_set_node_blockptr
(
c
,
0
,
path
->
nodes
[
level
-
1
]
->
b_blocknr
);
mark_buffer_dirty
(
t
);
btrfs_
mark_buffer_dirty
(
t
);
/* the super has an extra ref to root->node */
btrfs_block_release
(
root
,
root
->
node
);
...
...
@@ -712,13 +720,15 @@ static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root
if
(
nritems
==
BTRFS_NODEPTRS_PER_BLOCK
(
root
))
BUG
();
if
(
slot
!=
nritems
)
{
memmove
(
lower
->
ptrs
+
slot
+
1
,
lower
->
ptrs
+
slot
,
(
nritems
-
slot
)
*
sizeof
(
struct
btrfs_key_ptr
));
btrfs_memmove
(
root
,
lower
,
lower
->
ptrs
+
slot
+
1
,
lower
->
ptrs
+
slot
,
(
nritems
-
slot
)
*
sizeof
(
struct
btrfs_key_ptr
));
}
memcpy
(
&
lower
->
ptrs
[
slot
].
key
,
key
,
sizeof
(
struct
btrfs_disk_key
));
btrfs_memcpy
(
root
,
lower
,
&
lower
->
ptrs
[
slot
].
key
,
key
,
sizeof
(
struct
btrfs_disk_key
));
btrfs_set_node_blockptr
(
lower
,
slot
,
blocknr
);
btrfs_set_header_nritems
(
&
lower
->
header
,
nritems
+
1
);
mark_buffer_dirty
(
path
->
nodes
[
level
]);
btrfs_
mark_buffer_dirty
(
path
->
nodes
[
level
]);
return
0
;
}
...
...
@@ -761,14 +771,14 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_set_header_parentid
(
&
split
->
header
,
btrfs_header_parentid
(
btrfs_buffer_header
(
root
->
node
)));
mid
=
(
c_nritems
+
1
)
/
2
;
memcpy
(
split
->
ptrs
,
c
->
ptrs
+
mid
,
(
c_nritems
-
mid
)
*
sizeof
(
struct
btrfs_key_ptr
));
btrfs_memcpy
(
root
,
split
,
split
->
ptrs
,
c
->
ptrs
+
mid
,
(
c_nritems
-
mid
)
*
sizeof
(
struct
btrfs_key_ptr
));
btrfs_set_header_nritems
(
&
split
->
header
,
c_nritems
-
mid
);
btrfs_set_header_nritems
(
&
c
->
header
,
mid
);
ret
=
0
;
mark_buffer_dirty
(
t
);
mark_buffer_dirty
(
split_buffer
);
btrfs_
mark_buffer_dirty
(
t
);
btrfs_
mark_buffer_dirty
(
split_buffer
);
wret
=
insert_ptr
(
trans
,
root
,
path
,
&
split
->
ptrs
[
0
].
key
,
split_buffer
->
b_blocknr
,
path
->
slots
[
level
+
1
]
+
1
,
level
+
1
);
...
...
@@ -875,17 +885,22 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
push_space
=
btrfs_item_end
(
left
->
items
+
left_nritems
-
push_items
);
push_space
-=
leaf_data_end
(
root
,
left
);
/* make room in the right data area */
memmove
(
btrfs_leaf_data
(
right
)
+
leaf_data_end
(
root
,
right
)
-
push_space
,
btrfs_leaf_data
(
right
)
+
leaf_data_end
(
root
,
right
),
BTRFS_LEAF_DATA_SIZE
(
root
)
-
leaf_data_end
(
root
,
right
));
btrfs_memmove
(
root
,
right
,
btrfs_leaf_data
(
right
)
+
leaf_data_end
(
root
,
right
)
-
push_space
,
btrfs_leaf_data
(
right
)
+
leaf_data_end
(
root
,
right
),
BTRFS_LEAF_DATA_SIZE
(
root
)
-
leaf_data_end
(
root
,
right
));
/* copy from the left data area */
memcpy
(
btrfs_leaf_data
(
right
)
+
BTRFS_LEAF_DATA_SIZE
(
root
)
-
push_space
,
btrfs_leaf_data
(
left
)
+
leaf_data_end
(
root
,
left
),
push_space
);
memmove
(
right
->
items
+
push_items
,
right
->
items
,
btrfs_memcpy
(
root
,
right
,
btrfs_leaf_data
(
right
)
+
BTRFS_LEAF_DATA_SIZE
(
root
)
-
push_space
,
btrfs_leaf_data
(
left
)
+
leaf_data_end
(
root
,
left
),
push_space
);
btrfs_memmove
(
root
,
right
,
right
->
items
+
push_items
,
right
->
items
,
right_nritems
*
sizeof
(
struct
btrfs_item
));
/* copy the items from left to right */
memcpy
(
right
->
items
,
left
->
items
+
left_nritems
-
push_items
,
push_items
*
sizeof
(
struct
btrfs_item
));
btrfs_memcpy
(
root
,
right
,
right
->
items
,
left
->
items
+
left_nritems
-
push_items
,
push_items
*
sizeof
(
struct
btrfs_item
));
/* update the item pointers */
right_nritems
+=
push_items
;
...
...
@@ -899,11 +914,11 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
left_nritems
-=
push_items
;
btrfs_set_header_nritems
(
&
left
->
header
,
left_nritems
);
mark_buffer_dirty
(
left_buf
);
mark_buffer_dirty
(
right_buf
);
memcpy
(
&
upper_node
->
ptrs
[
slot
+
1
].
key
,
btrfs_
mark_buffer_dirty
(
left_buf
);
btrfs_
mark_buffer_dirty
(
right_buf
);
btrfs_memcpy
(
root
,
upper_node
,
&
upper_node
->
ptrs
[
slot
+
1
].
key
,
&
right
->
items
[
0
].
key
,
sizeof
(
struct
btrfs_disk_key
));
mark_buffer_dirty
(
upper
);
btrfs_
mark_buffer_dirty
(
upper
);
/* then fixup the leaf pointer in the path */
if
(
path
->
slots
[
0
]
>=
left_nritems
)
{
...
...
@@ -977,14 +992,16 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
return
1
;
}
/* push data from right to left */
memcpy
(
left
->
items
+
btrfs_header_nritems
(
&
left
->
header
),
right
->
items
,
push_items
*
sizeof
(
struct
btrfs_item
));
btrfs_memcpy
(
root
,
left
,
left
->
items
+
btrfs_header_nritems
(
&
left
->
header
),
right
->
items
,
push_items
*
sizeof
(
struct
btrfs_item
));
push_space
=
BTRFS_LEAF_DATA_SIZE
(
root
)
-
btrfs_item_offset
(
right
->
items
+
push_items
-
1
);
memcpy
(
btrfs_leaf_data
(
left
)
+
leaf_data_end
(
root
,
left
)
-
push_space
,
btrfs_leaf_data
(
right
)
+
btrfs_item_offset
(
right
->
items
+
push_items
-
1
),
push_space
);
btrfs_memcpy
(
root
,
left
,
btrfs_leaf_data
(
left
)
+
leaf_data_end
(
root
,
left
)
-
push_space
,
btrfs_leaf_data
(
right
)
+
btrfs_item_offset
(
right
->
items
+
push_items
-
1
),
push_space
);
old_left_nritems
=
btrfs_header_nritems
(
&
left
->
header
);
BUG_ON
(
old_left_nritems
<
0
);
...
...
@@ -1000,10 +1017,11 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
/* fixup right node */
push_space
=
btrfs_item_offset
(
right
->
items
+
push_items
-
1
)
-
leaf_data_end
(
root
,
right
);
memmove
(
btrfs_leaf_data
(
right
)
+
BTRFS_LEAF_DATA_SIZE
(
root
)
-
push_space
,
btrfs_leaf_data
(
right
)
+
leaf_data_end
(
root
,
right
),
push_space
);
memmove
(
right
->
items
,
right
->
items
+
push_items
,
btrfs_memmove
(
root
,
right
,
btrfs_leaf_data
(
right
)
+
BTRFS_LEAF_DATA_SIZE
(
root
)
-
push_space
,
btrfs_leaf_data
(
right
)
+
leaf_data_end
(
root
,
right
),
push_space
);
btrfs_memmove
(
root
,
right
,
right
->
items
,
right
->
items
+
push_items
,
(
btrfs_header_nritems
(
&
right
->
header
)
-
push_items
)
*
sizeof
(
struct
btrfs_item
));
btrfs_set_header_nritems
(
&
right
->
header
,
...
...
@@ -1017,8 +1035,8 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
push_space
=
btrfs_item_offset
(
right
->
items
+
i
);
}
mark_buffer_dirty
(
t
);
mark_buffer_dirty
(
right_buf
);
btrfs_
mark_buffer_dirty
(
t
);
btrfs_
mark_buffer_dirty
(
right_buf
);
wret
=
fixup_low_keys
(
trans
,
root
,
path
,
&
right
->
items
[
0
].
key
,
1
);
if
(
wret
)
...
...
@@ -1110,11 +1128,12 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_header_parentid
(
btrfs_buffer_header
(
root
->
node
)));
data_copy_size
=
btrfs_item_end
(
l
->
items
+
mid
)
-
leaf_data_end
(
root
,
l
);
memcpy
(
right
->
items
,
l
->
items
+
mid
,
(
nritems
-
mid
)
*
sizeof
(
struct
btrfs_item
));
memcpy
(
btrfs_leaf_data
(
right
)
+
BTRFS_LEAF_DATA_SIZE
(
root
)
-
data_copy_size
,
btrfs_leaf_data
(
l
)
+
leaf_data_end
(
root
,
l
),
data_copy_size
);
btrfs_memcpy
(
root
,
right
,
right
->
items
,
l
->
items
+
mid
,
(
nritems
-
mid
)
*
sizeof
(
struct
btrfs_item
));
btrfs_memcpy
(
root
,
right
,
btrfs_leaf_data
(
right
)
+
BTRFS_LEAF_DATA_SIZE
(
root
)
-
data_copy_size
,
btrfs_leaf_data
(
l
)
+
leaf_data_end
(
root
,
l
),
data_copy_size
);
rt_data_off
=
BTRFS_LEAF_DATA_SIZE
(
root
)
-
btrfs_item_end
(
l
->
items
+
mid
);
...
...
@@ -1129,8 +1148,8 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
right_buffer
->
b_blocknr
,
path
->
slots
[
1
]
+
1
,
1
);
if
(
wret
)
ret
=
wret
;
mark_buffer_dirty
(
right_buffer
);
mark_buffer_dirty
(
l_buf
);
btrfs_
mark_buffer_dirty
(
right_buffer
);
btrfs_
mark_buffer_dirty
(
l_buf
);
BUG_ON
(
path
->
slots
[
0
]
!=
slot
);
if
(
mid
<=
slot
)
{
btrfs_block_release
(
root
,
path
->
nodes
[
0
]);
...
...
@@ -1200,22 +1219,23 @@ int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root
}
/* shift the items */
memmove
(
leaf
->
items
+
slot
+
1
,
leaf
->
items
+
slot
,
(
nritems
-
slot
)
*
sizeof
(
struct
btrfs_item
));
btrfs_memmove
(
root
,
leaf
,
leaf
->
items
+
slot
+
1
,
leaf
->
items
+
slot
,
(
nritems
-
slot
)
*
sizeof
(
struct
btrfs_item
));
/* shift the data */
memmove
(
btrfs_leaf_data
(
leaf
)
+
data_end
-
data_size
,
btrfs_leaf_data
(
leaf
)
+
data_end
,
old_data
-
data_end
);
btrfs_memmove
(
root
,
leaf
,
btrfs_leaf_data
(
leaf
)
+
data_end
-
data_size
,
btrfs_leaf_data
(
leaf
)
+
data_end
,
old_data
-
data_end
);
data_end
=
old_data
;
}
/* setup the item for the new data */
memcpy
(
&
leaf
->
items
[
slot
].
key
,
&
disk_key
,
sizeof
(
struct
btrfs_disk_key
));
btrfs_memcpy
(
root
,
leaf
,
&
leaf
->
items
[
slot
].
key
,
&
disk_key
,
sizeof
(
struct
btrfs_disk_key
));
btrfs_set_item_offset
(
leaf
->
items
+
slot
,
data_end
-
data_size
);
btrfs_set_item_size
(
leaf
->
items
+
slot
,
data_size
);
btrfs_set_header_nritems
(
&
leaf
->
header
,
nritems
+
1
);
mark_buffer_dirty
(
leaf_buf
);
btrfs_
mark_buffer_dirty
(
leaf_buf
);
ret
=
0
;
if
(
slot
==
0
)
...
...
@@ -1245,8 +1265,9 @@ int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root
if
(
!
ret
)
{
ptr
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
.
nodes
[
0
]),
path
.
slots
[
0
],
u8
);
memcpy
(
ptr
,
data
,
data_size
);
mark_buffer_dirty
(
path
.
nodes
[
0
]);
btrfs_memcpy
(
root
,
path
.
nodes
[
0
]
->
b_data
,
ptr
,
data
,
data_size
);
btrfs_mark_buffer_dirty
(
path
.
nodes
[
0
]);
}
btrfs_release_path
(
root
,
&
path
);
return
ret
;
...
...
@@ -1271,8 +1292,10 @@ static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
node
=
btrfs_buffer_node
(
parent
);
nritems
=
btrfs_header_nritems
(
&
node
->
header
);
if
(
slot
!=
nritems
-
1
)
{
memmove
(
node
->
ptrs
+
slot
,
node
->
ptrs
+
slot
+
1
,
sizeof
(
struct
btrfs_key_ptr
)
*
(
nritems
-
slot
-
1
));
btrfs_memmove
(
root
,
node
,
node
->
ptrs
+
slot
,
node
->
ptrs
+
slot
+
1
,
sizeof
(
struct
btrfs_key_ptr
)
*
(
nritems
-
slot
-
1
));
}
nritems
--
;
btrfs_set_header_nritems
(
&
node
->
header
,
nritems
);
...
...
@@ -1287,7 +1310,7 @@ static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
if
(
wret
)
ret
=
wret
;
}
mark_buffer_dirty
(
parent
);
btrfs_
mark_buffer_dirty
(
parent
);
return
ret
;
}
...
...
@@ -1317,16 +1340,18 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
if
(
slot
!=
nritems
-
1
)
{
int
i
;
int
data_end
=
leaf_data_end
(
root
,
leaf
);
memmove
(
btrfs_leaf_data
(
leaf
)
+
data_end
+
dsize
,
btrfs_leaf_data
(
leaf
)
+
data_end
,
doff
-
data_end
);
btrfs_memmove
(
root
,
leaf
,
btrfs_leaf_data
(
leaf
)
+
data_end
+
dsize
,
btrfs_leaf_data
(
leaf
)
+
data_end
,
doff
-
data_end
);
for
(
i
=
slot
+
1
;
i
<
nritems
;
i
++
)
{
u32
ioff
=
btrfs_item_offset
(
leaf
->
items
+
i
);
btrfs_set_item_offset
(
leaf
->
items
+
i
,
ioff
+
dsize
);
}
memmove
(
leaf
->
items
+
slot
,
leaf
->
items
+
slot
+
1
,
sizeof
(
struct
btrfs_item
)
*
(
nritems
-
slot
-
1
));
btrfs_memmove
(
root
,
leaf
,
leaf
->
items
+
slot
,
leaf
->
items
+
slot
+
1
,
sizeof
(
struct
btrfs_item
)
*
(
nritems
-
slot
-
1
));
}
btrfs_set_header_nritems
(
&
leaf
->
header
,
nritems
-
1
);
nritems
--
;
...
...
@@ -1336,6 +1361,7 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
btrfs_set_header_level
(
&
leaf
->
header
,
0
);
}
else
{
clean_tree_block
(
trans
,
root
,
leaf_buf
);
wait_on_buffer
(
leaf_buf
);
wret
=
del_ptr
(
trans
,
root
,
path
,
1
,
path
->
slots
[
1
]);
if
(
wret
)
ret
=
wret
;
...
...
@@ -1373,6 +1399,7 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
if
(
btrfs_header_nritems
(
&
leaf
->
header
)
==
0
)
{
u64
blocknr
=
leaf_buf
->
b_blocknr
;
clean_tree_block
(
trans
,
root
,
leaf_buf
);
wait_on_buffer
(
leaf_buf
);
wret
=
del_ptr
(
trans
,
root
,
path
,
1
,
slot
);
if
(
wret
)
ret
=
wret
;
...
...
@@ -1382,11 +1409,11 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
if
(
wret
)
ret
=
wret
;
}
else
{
mark_buffer_dirty
(
leaf_buf
);
btrfs_
mark_buffer_dirty
(
leaf_buf
);
btrfs_block_release
(
root
,
leaf_buf
);
}
}
else
{
mark_buffer_dirty
(
leaf_buf
);
btrfs_
mark_buffer_dirty
(
leaf_buf
);
}
}
return
ret
;
...
...
fs/btrfs/ctree.h
View file @
d6025579
...
...
@@ -2,6 +2,7 @@
#define __BTRFS__
#include <linux/fs.h>
#include <linux/buffer_head.h>
#include "bit-radix.h"
struct
btrfs_trans_handle
;
...
...
@@ -834,6 +835,37 @@ static inline struct btrfs_root *btrfs_sb(struct super_block *sb)
return
sb
->
s_fs_info
;
}
static
inline
void
btrfs_check_bounds
(
void
*
vptr
,
size_t
len
,
void
*
vcontainer
,
size_t
container_len
)
{
char
*
ptr
=
vptr
;
char
*
container
=
vcontainer
;
WARN_ON
(
ptr
<
container
);
WARN_ON
(
ptr
+
len
>
container
+
container_len
);
}
static
inline
void
btrfs_memcpy
(
struct
btrfs_root
*
root
,
void
*
dst_block
,
void
*
dst
,
const
void
*
src
,
size_t
nr
)
{
btrfs_check_bounds
(
dst
,
nr
,
dst_block
,
root
->
fs_info
->
sb
->
s_blocksize
);
memcpy
(
dst
,
src
,
nr
);
}
static
inline
void
btrfs_memmove
(
struct
btrfs_root
*
root
,
void
*
dst_block
,
void
*
dst
,
void
*
src
,
size_t
nr
)
{
btrfs_check_bounds
(
dst
,
nr
,
dst_block
,
root
->
fs_info
->
sb
->
s_blocksize
);
memmove
(
dst
,
src
,
nr
);
}
static
inline
void
btrfs_mark_buffer_dirty
(
struct
buffer_head
*
bh
)
{
WARN_ON
(
!
atomic_read
(
&
bh
->
b_count
));
mark_buffer_dirty
(
bh
);
}
/* helper function to cast into the data area of the leaf. */
#define btrfs_item_ptr(leaf, slot, type) \
((type *)(btrfs_leaf_data(leaf) + \
...
...
fs/btrfs/dir-item.c
View file @
d6025579
...
...
@@ -34,10 +34,8 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_set_dir_flags
(
dir_item
,
0
);
btrfs_set_dir_name_len
(
dir_item
,
name_len
);
name_ptr
=
(
char
*
)(
dir_item
+
1
);
memcpy
(
name_ptr
,
name
,
name_len
);
if
(
name_ptr
+
name_len
>
path
.
nodes
[
0
]
->
b_data
+
4096
)
WARN_ON
(
1
);
mark_buffer_dirty
(
path
.
nodes
[
0
]);
btrfs_memcpy
(
root
,
path
.
nodes
[
0
]
->
b_data
,
name_ptr
,
name
,
name_len
);
btrfs_mark_buffer_dirty
(
path
.
nodes
[
0
]);
out:
btrfs_release_path
(
root
,
&
path
);
return
ret
;
...
...
fs/btrfs/disk-io.c
View file @
d6025579
...
...
@@ -8,6 +8,17 @@
#include "disk-io.h"
#include "transaction.h"
#define PATTERN 0xDEADBEEFUL
static
inline
void
check_pattern
(
struct
buffer_head
*
buf
)
{
if
(
buf
->
b_private
!=
(
void
*
)
PATTERN
)
WARN_ON
(
1
);
}
static
inline
void
set_pattern
(
struct
buffer_head
*
buf
)
{
buf
->
b_private
=
(
void
*
)
PATTERN
;
}
static
int
check_tree_block
(
struct
btrfs_root
*
root
,
struct
buffer_head
*
buf
)
{
...
...
@@ -51,8 +62,10 @@ struct buffer_head *btrfs_find_tree_block(struct btrfs_root *root, u64 blocknr)
}
while
(
bh
!=
head
);
out_unlock:
unlock_page
(
page
);
if
(
ret
)
if
(
ret
)
{
touch_buffer
(
ret
);
check_pattern
(
ret
);
}
page_cache_release
(
page
);
return
ret
;
}
...
...
@@ -82,6 +95,7 @@ struct buffer_head *btrfs_find_create_tree_block(struct btrfs_root *root,
bh
->
b_bdev
=
root
->
fs_info
->
sb
->
s_bdev
;
bh
->
b_blocknr
=
first_block
;
set_buffer_mapped
(
bh
);
set_pattern
(
bh
);
}
if
(
bh
->
b_blocknr
==
blocknr
)
{
ret
=
bh
;
...
...
@@ -225,6 +239,7 @@ struct buffer_head *read_tree_block(struct btrfs_root *root, u64 blocknr)
if
(
!
buffer_uptodate
(
bh
))
goto
fail
;
csum_tree_block
(
root
,
bh
,
1
);
set_pattern
(
bh
);
}
else
{
unlock_buffer
(
bh
);
}
...
...
@@ -240,6 +255,7 @@ fail:
int
dirty_tree_block
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
buffer_head
*
buf
)
{
WARN_ON
(
atomic_read
(
&
buf
->
b_count
)
==
0
);
mark_buffer_dirty
(
buf
);
return
0
;
}
...
...
@@ -247,6 +263,7 @@ int dirty_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
int
clean_tree_block
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
buffer_head
*
buf
)
{
WARN_ON
(
atomic_read
(
&
buf
->
b_count
)
==
0
);
clear_buffer_dirty
(
buf
);
return
0
;
}
...
...
@@ -431,6 +448,7 @@ int close_ctree(struct btrfs_root *root)
void
btrfs_block_release
(
struct
btrfs_root
*
root
,
struct
buffer_head
*
buf
)
{
check_pattern
(
buf
);
brelse
(
buf
);
}
fs/btrfs/extent-tree.c
View file @
d6025579
...
...
@@ -39,7 +39,7 @@ static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
item
=
btrfs_item_ptr
(
l
,
path
.
slots
[
0
],
struct
btrfs_extent_item
);
refs
=
btrfs_extent_refs
(
item
);
btrfs_set_extent_refs
(
item
,
refs
+
1
);
mark_buffer_dirty
(
path
.
nodes
[
0
]);
btrfs_
mark_buffer_dirty
(
path
.
nodes
[
0
]);
btrfs_release_path
(
root
->
fs_info
->
extent_root
,
&
path
);
finish_current_insert
(
trans
,
root
->
fs_info
->
extent_root
);
...
...
@@ -177,10 +177,10 @@ static int pin_down_block(struct btrfs_root *root, u64 blocknr, int pending)
header
=
btrfs_buffer_header
(
bh
);
if
(
btrfs_header_generation
(
header
)
==
root
->
fs_info
->
running_transaction
->
transid
)
{
b
relse
(
bh
);
b
trfs_block_release
(
root
,
bh
);
return
0
;
}
b
relse
(
bh
);
b
trfs_block_release
(
root
,
bh
);
}
err
=
set_radix_bit
(
&
root
->
fs_info
->
pinned_radix
,
blocknr
);
}
else
{
...
...
@@ -224,7 +224,7 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
BUG_ON
(
ei
->
refs
==
0
);
refs
=
btrfs_extent_refs
(
ei
)
-
1
;
btrfs_set_extent_refs
(
ei
,
refs
);
mark_buffer_dirty
(
path
.
nodes
[
0
]);
btrfs_
mark_buffer_dirty
(
path
.
nodes
[
0
]);
if
(
refs
==
0
)
{
u64
super_blocks_used
;
...
...
fs/btrfs/file-item.c
View file @
d6025579
...
...
@@ -34,7 +34,7 @@ int btrfs_alloc_file_extent(struct btrfs_trans_handle *trans,
btrfs_set_file_extent_offset
(
item
,
0
);
btrfs_set_file_extent_num_blocks
(
item
,
ins
.
offset
);
btrfs_set_file_extent_generation
(
item
,
trans
->
transid
);
mark_buffer_dirty
(
path
.
nodes
[
0
]);
btrfs_
mark_buffer_dirty
(
path
.
nodes
[
0
]);
*
result
=
ins
.
objectid
;
btrfs_release_path
(
root
,
&
path
);
return
0
;
...
...
@@ -81,7 +81,7 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
struct
btrfs_csum_item
);
ret
=
0
;
ret
=
btrfs_csum_data
(
root
,
data
,
len
,
item
->
csum
);
mark_buffer_dirty
(
path
.
nodes
[
0
]);
btrfs_
mark_buffer_dirty
(
path
.
nodes
[
0
]);
fail:
btrfs_release_path
(
root
,
&
path
);
return
ret
;
...
...
fs/btrfs/inode-map.c
View file @
d6025579
...
...
@@ -109,7 +109,7 @@ int btrfs_insert_inode_map(struct btrfs_trans_handle *trans,
inode_item
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
.
nodes
[
0
]),
path
.
slots
[
0
],
struct
btrfs_inode_map_item
);
btrfs_cpu_key_to_disk
(
&
inode_item
->
key
,
location
);
mark_buffer_dirty
(
path
.
nodes
[
0
]);
btrfs_
mark_buffer_dirty
(
path
.
nodes
[
0
]);
out:
btrfs_release_path
(
inode_root
,
&
path
);
return
ret
;
...
...
fs/btrfs/root-tree.c
View file @
d6025579
...
...
@@ -45,6 +45,7 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
struct
btrfs_leaf
*
l
;
int
ret
;
int
slot
;
struct
btrfs_root_item
*
update_item
;
btrfs_init_path
(
&
path
);
ret
=
btrfs_search_slot
(
trans
,
root
,
key
,
&
path
,
0
,
1
);
...
...
@@ -53,9 +54,9 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
BUG_ON
(
ret
!=
0
);
l
=
btrfs_buffer_leaf
(
path
.
nodes
[
0
]);
slot
=
path
.
slots
[
0
];
memcpy
(
btrfs_item_ptr
(
l
,
slot
,
struct
btrfs_root_item
),
item
,
sizeof
(
*
item
));
mark_buffer_dirty
(
path
.
nodes
[
0
]);
update_item
=
btrfs_item_ptr
(
l
,
slot
,
struct
btrfs_root_item
);
btrfs_memcpy
(
root
,
l
,
update_item
,
item
,
sizeof
(
*
item
));
btrfs_
mark_buffer_dirty
(
path
.
nodes
[
0
]);
out:
btrfs_release_path
(
root
,
&
path
);
return
ret
;
...
...
fs/btrfs/super.c
View file @
d6025579
...
...
@@ -557,7 +557,7 @@ static int btrfs_update_inode(struct btrfs_trans_handle *trans,
struct
btrfs_inode_item
);
fill_inode_item
(
inode_item
,
inode
);
mark_buffer_dirty
(
path
.
nodes
[
0
]);
btrfs_
mark_buffer_dirty
(
path
.
nodes
[
0
]);
failed:
btrfs_release_path
(
root
,
&
path
);
return
0
;
...
...
fs/btrfs/transaction.c
View file @
d6025579
...
...
@@ -66,6 +66,7 @@ int btrfs_end_transaction(struct btrfs_trans_handle *trans,
cur_trans
->
num_writers
--
;
put_transaction
(
cur_trans
);
mutex_unlock
(
&
root
->
fs_info
->
trans_mutex
);
memset
(
trans
,
0
,
sizeof
(
*
trans
));
kfree
(
trans
);
return
0
;
}
...
...
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