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
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 @@ csum:
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