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
e66f709b
Commit
e66f709b
authored
Apr 20, 2007
by
Chris Mason
Committed by
David Woodhouse
Apr 20, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Btrfs: write barriers on commit, balance level before split
Signed-off-by:
Chris Mason
<
chris.mason@oracle.com
>
parent
8fd17795
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
131 additions
and
1 deletion
+131
-1
fs/btrfs/ctree.c
fs/btrfs/ctree.c
+119
-0
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+1
-0
fs/btrfs/disk-io.c
fs/btrfs/disk-io.c
+11
-1
No files found.
fs/btrfs/ctree.c
View file @
e66f709b
...
...
@@ -151,6 +151,11 @@ static int check_node(struct btrfs_root *root, struct btrfs_path *path,
for
(
i
=
0
;
nritems
>
1
&&
i
<
nritems
-
2
;
i
++
)
{
struct
btrfs_key
cpukey
;
btrfs_disk_key_to_cpu
(
&
cpukey
,
&
node
->
ptrs
[
i
+
1
].
key
);
if
(
comp_keys
(
&
node
->
ptrs
[
i
].
key
,
&
cpukey
)
>=
0
)
{
struct
btrfs_key
bad
;
btrfs_disk_key_to_cpu
(
&
bad
,
&
node
->
ptrs
[
i
].
key
);
printk
(
"check_node level %d i is %d bad comp %Lu %u %Lu, %Lu %u %Lu
\n
"
,
level
,
i
,
bad
.
objectid
,
bad
.
flags
,
bad
.
offset
,
cpukey
.
objectid
,
cpukey
.
flags
,
cpukey
.
offset
);
}
BUG_ON
(
comp_keys
(
&
node
->
ptrs
[
i
].
key
,
&
cpukey
)
>=
0
);
}
return
0
;
...
...
@@ -448,6 +453,111 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
return
ret
;
}
/* returns zero if the push worked, non-zero otherwise */
static
int
push_nodes_for_insert
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
int
level
)
{
struct
buffer_head
*
right_buf
;
struct
buffer_head
*
mid_buf
;
struct
buffer_head
*
left_buf
;
struct
buffer_head
*
parent_buf
=
NULL
;
struct
btrfs_node
*
right
=
NULL
;
struct
btrfs_node
*
mid
;
struct
btrfs_node
*
left
=
NULL
;
struct
btrfs_node
*
parent
=
NULL
;
int
ret
=
0
;
int
wret
;
int
pslot
;
int
orig_slot
=
path
->
slots
[
level
];
u64
orig_ptr
;
if
(
level
==
0
)
return
1
;
mid_buf
=
path
->
nodes
[
level
];
mid
=
btrfs_buffer_node
(
mid_buf
);
orig_ptr
=
btrfs_node_blockptr
(
mid
,
orig_slot
);
if
(
level
<
BTRFS_MAX_LEVEL
-
1
)
parent_buf
=
path
->
nodes
[
level
+
1
];
pslot
=
path
->
slots
[
level
+
1
];
if
(
!
parent_buf
)
return
1
;
parent
=
btrfs_buffer_node
(
parent_buf
);
left_buf
=
read_node_slot
(
root
,
parent_buf
,
pslot
-
1
);
/* first, try to make some room in the middle buffer */
if
(
left_buf
)
{
u32
left_nr
;
btrfs_cow_block
(
trans
,
root
,
left_buf
,
parent_buf
,
pslot
-
1
,
&
left_buf
);
left
=
btrfs_buffer_node
(
left_buf
);
left_nr
=
btrfs_header_nritems
(
&
left
->
header
);
wret
=
push_node_left
(
trans
,
root
,
left_buf
,
mid_buf
);
if
(
wret
<
0
)
ret
=
wret
;
if
(
wret
==
0
)
{
orig_slot
+=
left_nr
;
btrfs_memcpy
(
root
,
parent
,
&
parent
->
ptrs
[
pslot
].
key
,
&
mid
->
ptrs
[
0
].
key
,
sizeof
(
struct
btrfs_disk_key
));
btrfs_mark_buffer_dirty
(
parent_buf
);
if
(
btrfs_header_nritems
(
&
left
->
header
)
>
orig_slot
)
{
path
->
nodes
[
level
]
=
left_buf
;
path
->
slots
[
level
+
1
]
-=
1
;
path
->
slots
[
level
]
=
orig_slot
;
btrfs_block_release
(
root
,
mid_buf
);
}
else
{
orig_slot
-=
btrfs_header_nritems
(
&
left
->
header
);
path
->
slots
[
level
]
=
orig_slot
;
btrfs_block_release
(
root
,
left_buf
);
}
check_node
(
root
,
path
,
level
);
return
0
;
}
btrfs_block_release
(
root
,
left_buf
);
}
right_buf
=
read_node_slot
(
root
,
parent_buf
,
pslot
+
1
);
/*
* then try to empty the right most buffer into the middle
*/
if
(
right_buf
)
{
btrfs_cow_block
(
trans
,
root
,
right_buf
,
parent_buf
,
pslot
+
1
,
&
right_buf
);
right
=
btrfs_buffer_node
(
right_buf
);
wret
=
balance_node_right
(
trans
,
root
,
right_buf
,
mid_buf
);
if
(
wret
<
0
)
ret
=
wret
;
if
(
wret
==
0
)
{
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
)
<=
orig_slot
)
{
path
->
nodes
[
level
]
=
right_buf
;
path
->
slots
[
level
+
1
]
+=
1
;
path
->
slots
[
level
]
=
orig_slot
-
btrfs_header_nritems
(
&
mid
->
header
);
btrfs_block_release
(
root
,
mid_buf
);
}
else
{
btrfs_block_release
(
root
,
right_buf
);
}
check_node
(
root
,
path
,
level
);
return
0
;
}
btrfs_block_release
(
root
,
right_buf
);
}
check_node
(
root
,
path
,
level
);
return
1
;
}
/*
* look for key in the tree. path is filled in with nodes along the way
* if key is found, we return zero and you can find the item in the leaf
...
...
@@ -774,7 +884,16 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
ret
=
insert_new_root
(
trans
,
root
,
path
,
level
+
1
);
if
(
ret
)
return
ret
;
}
else
{
ret
=
push_nodes_for_insert
(
trans
,
root
,
path
,
level
);
t
=
path
->
nodes
[
level
];
c
=
btrfs_buffer_node
(
t
);
if
(
!
ret
&&
btrfs_header_nritems
(
&
c
->
header
)
<
BTRFS_NODEPTRS_PER_BLOCK
(
root
)
-
1
)
return
0
;
}
c_nritems
=
btrfs_header_nritems
(
&
c
->
header
);
split_buffer
=
btrfs_alloc_free_block
(
trans
,
root
);
split
=
btrfs_buffer_node
(
split_buffer
);
...
...
fs/btrfs/ctree.h
View file @
e66f709b
...
...
@@ -259,6 +259,7 @@ struct btrfs_fs_info {
struct
list_head
trans_list
;
struct
crypto_hash
*
hash_tfm
;
spinlock_t
hash_lock
;
int
do_barriers
;
struct
kobject
kobj
;
};
...
...
fs/btrfs/disk-io.c
View file @
e66f709b
...
...
@@ -540,6 +540,7 @@ struct btrfs_root *open_ctree(struct super_block *sb)
fs_info
->
btree_inode
->
i_nlink
=
1
;
fs_info
->
btree_inode
->
i_size
=
sb
->
s_bdev
->
bd_inode
->
i_size
;
fs_info
->
btree_inode
->
i_mapping
->
a_ops
=
&
btree_aops
;
fs_info
->
do_barriers
=
1
;
BTRFS_I
(
fs_info
->
btree_inode
)
->
root
=
tree_root
;
memset
(
&
BTRFS_I
(
fs_info
->
btree_inode
)
->
location
,
0
,
sizeof
(
struct
btrfs_key
));
...
...
@@ -622,6 +623,7 @@ struct btrfs_root *open_ctree(struct super_block *sb)
int
write_ctree_super
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
)
{
int
ret
;
struct
buffer_head
*
bh
=
root
->
fs_info
->
sb_buffer
;
btrfs_set_super_root
(
root
->
fs_info
->
disk_super
,
...
...
@@ -632,7 +634,15 @@ int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root
csum_tree_block
(
root
,
bh
,
0
);
bh
->
b_end_io
=
end_buffer_write_sync
;
get_bh
(
bh
);
submit_bh
(
WRITE
,
bh
);
if
(
root
->
fs_info
->
do_barriers
)
ret
=
submit_bh
(
WRITE_BARRIER
,
bh
);
else
ret
=
submit_bh
(
WRITE
,
bh
);
if
(
ret
==
-
EOPNOTSUPP
)
{
set_buffer_uptodate
(
bh
);
root
->
fs_info
->
do_barriers
=
0
;
ret
=
submit_bh
(
WRITE
,
bh
);
}
wait_on_buffer
(
bh
);
if
(
!
buffer_uptodate
(
bh
))
{
WARN_ON
(
1
);
...
...
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