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
b18c6685
Commit
b18c6685
authored
Apr 17, 2007
by
Chris Mason
Committed by
David Woodhouse
Apr 17, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Btrfs: progress on file_write
Signed-off-by:
Chris Mason
<
chris.mason@oracle.com
>
parent
6567e837
Changes
5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
394 additions
and
49 deletions
+394
-49
fs/btrfs/ctree.c
fs/btrfs/ctree.c
+57
-0
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+16
-5
fs/btrfs/extent-tree.c
fs/btrfs/extent-tree.c
+11
-9
fs/btrfs/file-item.c
fs/btrfs/file-item.c
+41
-20
fs/btrfs/super.c
fs/btrfs/super.c
+269
-15
No files found.
fs/btrfs/ctree.c
View file @
b18c6685
...
...
@@ -1249,6 +1249,63 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
return
ret
;
}
int
btrfs_truncate_item
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
u32
new_size
)
{
int
ret
=
0
;
int
slot
;
int
slot_orig
;
struct
btrfs_leaf
*
leaf
;
struct
buffer_head
*
leaf_buf
;
u32
nritems
;
unsigned
int
data_end
;
unsigned
int
old_data_start
;
unsigned
int
old_size
;
unsigned
int
size_diff
;
int
i
;
slot_orig
=
path
->
slots
[
0
];
leaf_buf
=
path
->
nodes
[
0
];
leaf
=
btrfs_buffer_leaf
(
leaf_buf
);
nritems
=
btrfs_header_nritems
(
&
leaf
->
header
);
data_end
=
leaf_data_end
(
root
,
leaf
);
slot
=
path
->
slots
[
0
];
old_data_start
=
btrfs_item_offset
(
leaf
->
items
+
slot
);
old_size
=
btrfs_item_size
(
leaf
->
items
+
slot
);
BUG_ON
(
old_size
<=
new_size
);
size_diff
=
old_size
-
new_size
;
BUG_ON
(
slot
<
0
);
BUG_ON
(
slot
>=
nritems
);
/*
* item0..itemN ... dataN.offset..dataN.size .. data0.size
*/
/* first correct the data pointers */
for
(
i
=
slot
;
i
<
nritems
;
i
++
)
{
u32
ioff
=
btrfs_item_offset
(
leaf
->
items
+
i
);
btrfs_set_item_offset
(
leaf
->
items
+
i
,
ioff
+
size_diff
);
}
/* shift the data */
printk
(
"truncate item, new_size %u old_size %u, diff %u, bufp %p, dst, %p, num %u, old_data_start %u, data_end %u
\n
"
,
new_size
,
old_size
,
size_diff
,
leaf
,
btrfs_leaf_data
(
leaf
)
+
data_end
+
size_diff
,
old_data_start
-
data_end
,
old_data_start
,
data_end
);
btrfs_memmove
(
root
,
leaf
,
btrfs_leaf_data
(
leaf
)
+
data_end
+
size_diff
,
btrfs_leaf_data
(
leaf
)
+
data_end
,
old_data_start
+
new_size
-
data_end
);
btrfs_set_item_size
(
leaf
->
items
+
slot
,
new_size
);
btrfs_mark_buffer_dirty
(
leaf_buf
);
ret
=
0
;
if
(
btrfs_leaf_free_space
(
root
,
leaf
)
<
0
)
BUG
();
check_leaf
(
root
,
path
,
0
);
return
ret
;
}
int
btrfs_extend_item
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
u32
data_size
)
{
...
...
fs/btrfs/ctree.h
View file @
b18c6685
...
...
@@ -999,7 +999,7 @@ static inline void btrfs_mark_buffer_dirty(struct buffer_head *bh)
((type *)(btrfs_leaf_data(leaf) + \
btrfs_item_offset((leaf)->items + (slot))))
/* extent-
item
.c */
/* extent-
tree
.c */
int
btrfs_inc_root_ref
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
);
struct
buffer_head
*
btrfs_alloc_free_block
(
struct
btrfs_trans_handle
*
trans
,
...
...
@@ -1013,9 +1013,16 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
*
root
,
u64
blocknr
,
u64
num_blocks
,
int
pin
);
int
btrfs_finish_extent_commit
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
);
int
btrfs_inc_extent_ref
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u64
blocknr
,
u64
num_blocks
);
/* ctree.c */
int
btrfs_extend_item
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
u32
data_size
);
int
btrfs_truncate_item
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
u32
new_size
);
int
btrfs_search_slot
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_key
*
key
,
struct
btrfs_path
*
p
,
int
ins_len
,
int
cow
);
...
...
@@ -1073,11 +1080,10 @@ int btrfs_lookup_inode(struct btrfs_trans_handle *trans, struct btrfs_root
struct
btrfs_key
*
location
,
int
mod
);
/* file-item.c */
int
btrfs_
alloc
_file_extent
(
struct
btrfs_trans_handle
*
trans
,
int
btrfs_
insert
_file_extent
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u64
objectid
,
u64
offset
,
u64
num_blocks
,
u64
hint_block
,
u64
*
result
);
u64
objectid
,
u64
pos
,
u64
offset
,
u64
num_blocks
);
int
btrfs_lookup_file_extent
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
u64
objectid
,
...
...
@@ -1090,6 +1096,11 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
int
btrfs_csum_verify_file_block
(
struct
btrfs_root
*
root
,
u64
objectid
,
u64
offset
,
char
*
data
,
size_t
len
);
struct
btrfs_csum_item
*
btrfs_lookup_csum
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
u64
objectid
,
u64
offset
,
int
cow
);
/* super.c */
extern
struct
subsystem
btrfs_subsys
;
...
...
fs/btrfs/extent-tree.c
View file @
b18c6685
...
...
@@ -12,8 +12,9 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct
static
int
del_pending_extents
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
extent_root
);
static
int
inc_block_ref
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u64
blocknr
,
u64
num_blocks
)
int
btrfs_inc_extent_ref
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u64
blocknr
,
u64
num_blocks
)
{
struct
btrfs_path
*
path
;
int
ret
;
...
...
@@ -50,8 +51,9 @@ static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
return
0
;
}
static
int
lookup_block_ref
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u64
blocknr
,
u64
num_blocks
,
u32
*
refs
)
static
int
lookup_extent_ref
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u64
blocknr
,
u64
num_blocks
,
u32
*
refs
)
{
struct
btrfs_path
*
path
;
int
ret
;
...
...
@@ -80,7 +82,7 @@ static int lookup_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
int
btrfs_inc_root_ref
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
)
{
return
inc_block
_ref
(
trans
,
root
,
bh_blocknr
(
root
->
node
),
1
);
return
btrfs_inc_extent
_ref
(
trans
,
root
,
bh_blocknr
(
root
->
node
),
1
);
}
int
btrfs_inc_ref
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
...
...
@@ -107,13 +109,13 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
continue
;
fi
=
btrfs_item_ptr
(
buf_leaf
,
i
,
struct
btrfs_file_extent_item
);
ret
=
inc_block
_ref
(
trans
,
root
,
ret
=
btrfs_inc_extent
_ref
(
trans
,
root
,
btrfs_file_extent_disk_blocknr
(
fi
),
btrfs_file_extent_disk_num_blocks
(
fi
));
BUG_ON
(
ret
);
}
else
{
blocknr
=
btrfs_node_blockptr
(
buf_node
,
i
);
ret
=
inc_block
_ref
(
trans
,
root
,
blocknr
,
1
);
ret
=
btrfs_inc_extent
_ref
(
trans
,
root
,
blocknr
,
1
);
BUG_ON
(
ret
);
}
}
...
...
@@ -563,7 +565,7 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root
WARN_ON
(
*
level
<
0
);
WARN_ON
(
*
level
>=
BTRFS_MAX_LEVEL
);
ret
=
lookup_
block
_ref
(
trans
,
root
,
bh_blocknr
(
path
->
nodes
[
*
level
]),
ret
=
lookup_
extent
_ref
(
trans
,
root
,
bh_blocknr
(
path
->
nodes
[
*
level
]),
1
,
&
refs
);
BUG_ON
(
ret
);
if
(
refs
>
1
)
...
...
@@ -587,7 +589,7 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root
}
blocknr
=
btrfs_node_blockptr
(
btrfs_buffer_node
(
cur
),
path
->
slots
[
*
level
]);
ret
=
lookup_
block
_ref
(
trans
,
root
,
blocknr
,
1
,
&
refs
);
ret
=
lookup_
extent
_ref
(
trans
,
root
,
blocknr
,
1
,
&
refs
);
BUG_ON
(
ret
);
if
(
refs
!=
1
)
{
path
->
slots
[
*
level
]
++
;
...
...
fs/btrfs/file-item.c
View file @
b18c6685
...
...
@@ -6,13 +6,11 @@
#define MAX_CSUM_ITEMS(r) ((((BTRFS_LEAF_DATA_SIZE(r) - \
sizeof(struct btrfs_item)) / \
sizeof(struct btrfs_csum_item)) - 1))
int
btrfs_
alloc
_file_extent
(
struct
btrfs_trans_handle
*
trans
,
int
btrfs_
insert
_file_extent
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u64
objectid
,
u64
offset
,
u64
num_blocks
,
u64
hint_block
,
u64
*
result
)
u64
objectid
,
u64
pos
,
u64
offset
,
u64
num_blocks
)
{
struct
btrfs_key
ins
;
int
ret
=
0
;
struct
btrfs_file_extent_item
*
item
;
struct
btrfs_key
file_key
;
...
...
@@ -21,11 +19,13 @@ int btrfs_alloc_file_extent(struct btrfs_trans_handle *trans,
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
btrfs_init_path
(
path
);
/*
ret = btrfs_alloc_extent(trans, root, num_blocks, hint_block,
(u64)-1, &ins);
*/
BUG_ON
(
ret
);
file_key
.
objectid
=
objectid
;
file_key
.
offset
=
offset
;
file_key
.
offset
=
pos
;
file_key
.
flags
=
0
;
btrfs_set_key_type
(
&
file_key
,
BTRFS_EXTENT_DATA_KEY
);
...
...
@@ -34,21 +34,22 @@ int btrfs_alloc_file_extent(struct btrfs_trans_handle *trans,
BUG_ON
(
ret
);
item
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
path
->
slots
[
0
],
struct
btrfs_file_extent_item
);
btrfs_set_file_extent_disk_blocknr
(
item
,
ins
.
objectid
);
btrfs_set_file_extent_disk_num_blocks
(
item
,
ins
.
offset
);
btrfs_set_file_extent_disk_blocknr
(
item
,
offset
);
btrfs_set_file_extent_disk_num_blocks
(
item
,
num_blocks
);
btrfs_set_file_extent_offset
(
item
,
0
);
btrfs_set_file_extent_num_blocks
(
item
,
ins
.
offset
);
btrfs_set_file_extent_num_blocks
(
item
,
num_blocks
);
btrfs_set_file_extent_generation
(
item
,
trans
->
transid
);
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
*
result
=
ins
.
objectid
;
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
return
0
;
}
static
struct
btrfs_csum_item
*
__lookup_csum_item
(
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
u64
objectid
,
u64
offset
)
struct
btrfs_csum_item
*
btrfs_lookup_csum
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
u64
objectid
,
u64
offset
,
int
cow
)
{
int
ret
;
struct
btrfs_key
file_key
;
...
...
@@ -61,19 +62,23 @@ static struct btrfs_csum_item *__lookup_csum_item(struct btrfs_root *root,
file_key
.
offset
=
offset
;
file_key
.
flags
=
0
;
btrfs_set_key_type
(
&
file_key
,
BTRFS_CSUM_ITEM_KEY
);
ret
=
btrfs_search_slot
(
NULL
,
root
,
&
file_key
,
path
,
0
,
0
);
printk
(
"__lookup for %Lu
\n
"
,
offset
);
ret
=
btrfs_search_slot
(
trans
,
root
,
&
file_key
,
path
,
0
,
cow
);
if
(
ret
<
0
)
goto
fail
;
leaf
=
btrfs_buffer_leaf
(
path
->
nodes
[
0
]);
if
(
ret
>
0
)
{
ret
=
1
;
if
(
path
->
slots
[
0
]
==
0
)
if
(
path
->
slots
[
0
]
==
0
)
{
printk
(
"fail1
\n
"
);
goto
fail
;
}
path
->
slots
[
0
]
--
;
btrfs_disk_key_to_cpu
(
&
found_key
,
&
leaf
->
items
[
path
->
slots
[
0
]].
key
);
if
(
btrfs_key_type
(
&
found_key
)
!=
BTRFS_CSUM_ITEM_KEY
||
found_key
.
objectid
!=
objectid
)
{
printk
(
"fail2 type %u %Lu %Lu
\n
"
,
btrfs_key_type
(
&
found_key
),
found_key
.
objectid
,
objectid
);
goto
fail
;
}
csum_offset
=
(
offset
-
found_key
.
offset
)
>>
...
...
@@ -81,6 +86,7 @@ static struct btrfs_csum_item *__lookup_csum_item(struct btrfs_root *root,
if
(
csum_offset
>=
btrfs_item_size
(
leaf
->
items
+
path
->
slots
[
0
])
/
sizeof
(
struct
btrfs_csum_item
))
{
printk
(
"fail3, csum offset %lu size %u
\n
"
,
csum_offset
,
btrfs_item_size
(
leaf
->
items
+
path
->
slots
[
0
])
/
sizeof
(
struct
btrfs_csum_item
));
goto
fail
;
}
}
...
...
@@ -89,7 +95,7 @@ static struct btrfs_csum_item *__lookup_csum_item(struct btrfs_root *root,
return
item
;
fail:
if
(
ret
>
0
)
ret
=
-
E
IO
;
ret
=
-
E
NOENT
;
return
ERR_PTR
(
ret
);
}
...
...
@@ -105,7 +111,7 @@ int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans,
int
cow
=
mod
!=
0
;
struct
btrfs_csum_item
*
csum_item
;
csum_item
=
__lookup_csum_item
(
root
,
path
,
objectid
,
offset
);
csum_item
=
btrfs_lookup_csum
(
trans
,
root
,
path
,
objectid
,
offset
,
0
);
if
(
IS_ERR
(
csum_item
))
return
PTR_ERR
(
csum_item
);
file_key
.
objectid
=
objectid
;
...
...
@@ -113,7 +119,9 @@ int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans,
file_key
.
flags
=
0
;
btrfs_set_key_type
(
&
file_key
,
BTRFS_EXTENT_DATA_KEY
);
btrfs_release_path
(
root
,
path
);
printk
(
"lookup file extent searches for %Lu
\n
"
,
file_key
.
offset
);
ret
=
btrfs_search_slot
(
trans
,
root
,
&
file_key
,
path
,
ins_len
,
cow
);
printk
(
"ret is %d
\n
"
,
ret
);
return
ret
;
}
...
...
@@ -134,17 +142,23 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
btrfs_init_path
(
path
);
item
=
btrfs_lookup_csum
(
trans
,
root
,
path
,
objectid
,
offset
,
0
);
if
(
!
IS_ERR
(
item
))
goto
found
;
btrfs_release_path
(
root
,
path
);
file_key
.
objectid
=
objectid
;
file_key
.
offset
=
offset
;
file_key
.
flags
=
0
;
btrfs_set_key_type
(
&
file_key
,
BTRFS_CSUM_ITEM_KEY
);
printk
(
"searching for csum %Lu %Lu
\n
"
,
objectid
,
offset
);
ret
=
btrfs_search_slot
(
trans
,
root
,
&
file_key
,
path
,
sizeof
(
struct
btrfs_csum_item
),
1
);
printk
(
"ret %d
\n
"
,
ret
);
if
(
ret
<
0
)
goto
fail
;
if
(
ret
==
0
)
{
csum_offset
=
0
;
goto
csum
;
BUG
();
}
if
(
path
->
slots
[
0
]
==
0
)
{
btrfs_release_path
(
root
,
path
);
...
...
@@ -153,12 +167,15 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
path
->
slots
[
0
]
--
;
leaf
=
btrfs_buffer_leaf
(
path
->
nodes
[
0
]);
btrfs_disk_key_to_cpu
(
&
found_key
,
&
leaf
->
items
[
path
->
slots
[
0
]].
key
);
printk
(
"found key %Lu %Lu %u
\n
"
,
found_key
.
objectid
,
found_key
.
offset
,
found_key
.
flags
);
csum_offset
=
(
offset
-
found_key
.
offset
)
>>
root
->
fs_info
->
sb
->
s_blocksize_bits
;
printk
(
"csum_offset %Lu
\n
"
,
csum_offset
);
if
(
btrfs_key_type
(
&
found_key
)
!=
BTRFS_CSUM_ITEM_KEY
||
found_key
.
objectid
!=
objectid
||
csum_offset
>=
MAX_CSUM_ITEMS
(
root
))
{
btrfs_release_path
(
root
,
path
);
printk
(
"insert1
\n
"
);
goto
insert
;
}
if
(
csum_offset
>=
btrfs_item_size
(
leaf
->
items
+
path
->
slots
[
0
])
/
...
...
@@ -166,11 +183,13 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
ret
=
btrfs_extend_item
(
trans
,
root
,
path
,
sizeof
(
struct
btrfs_csum_item
));
BUG_ON
(
ret
);
printk
(
"item extended
\n
"
);
goto
csum
;
}
insert:
csum_offset
=
0
;
printk
(
"inserting item %Lu %Lu %u
\n
"
,
file_key
.
objectid
,
file_key
.
offset
,
file_key
.
flags
);
ret
=
btrfs_insert_empty_item
(
trans
,
root
,
path
,
&
file_key
,
sizeof
(
struct
btrfs_csum_item
));
if
(
ret
!=
0
&&
ret
!=
-
EEXIST
)
...
...
@@ -180,12 +199,14 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
struct
btrfs_csum_item
);
ret
=
0
;
item
+=
csum_offset
;
found:
ret
=
btrfs_csum_data
(
root
,
data
,
len
,
item
->
csum
);
btrfs_set_csum_extent_offset
(
item
,
extent_offset
);
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
fail:
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
printk
(
"return ret %d
\n
"
,
ret
);
return
ret
;
}
...
...
@@ -208,7 +229,7 @@ int btrfs_csum_verify_file_block(struct btrfs_root *root,
btrfs_set_key_type
(
&
file_key
,
BTRFS_CSUM_ITEM_KEY
);
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
item
=
__lookup_csum_item
(
root
,
path
,
objectid
,
offset
);
item
=
btrfs_lookup_csum
(
NULL
,
root
,
path
,
objectid
,
offset
,
0
);
if
(
IS_ERR
(
item
))
{
ret
=
PTR_ERR
(
item
);
goto
fail
;
...
...
fs/btrfs/super.c
View file @
b18c6685
This diff is collapsed.
Click to expand it.
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