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
nexedi
linux
Commits
9c58309d
Commit
9c58309d
authored
16 years ago
by
Chris Mason
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Btrfs: Add inode item and backref in one insert, reducing cpu usage
Signed-off-by:
Chris Mason
<
chris.mason@oracle.com
>
parent
85e21bac
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
102 additions
and
39 deletions
+102
-39
fs/btrfs/ctree.c
fs/btrfs/ctree.c
+25
-14
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+14
-3
fs/btrfs/inode.c
fs/btrfs/inode.c
+63
-22
No files found.
fs/btrfs/ctree.c
View file @
9c58309d
...
...
@@ -2332,27 +2332,34 @@ int btrfs_extend_item(struct btrfs_trans_handle *trans,
* Given a key and some data, insert an item into the tree.
* This does all the path init required, making room in the tree if needed.
*/
int
btrfs_insert_empty_item
(
struct
btrfs_trans_handle
*
trans
,
int
btrfs_insert_empty_item
s
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
struct
btrfs_key
*
cpu_key
,
u32
data_size
)
struct
btrfs_key
*
cpu_key
,
u32
*
data_size
,
int
nr
)
{
struct
extent_buffer
*
leaf
;
struct
btrfs_item
*
item
;
int
ret
=
0
;
int
slot
;
int
slot_orig
;
int
i
;
u32
nritems
;
u32
total_size
=
0
;
u32
total_data
=
0
;
unsigned
int
data_end
;
struct
btrfs_disk_key
disk_key
;
btrfs_cpu_key_to_disk
(
&
disk_key
,
cpu_key
);
for
(
i
=
0
;
i
<
nr
;
i
++
)
{
total_data
+=
data_size
[
i
];
}
/* create a root if there isn't one */
if
(
!
root
->
node
)
BUG
();
ret
=
btrfs_search_slot
(
trans
,
root
,
cpu_key
,
path
,
data_size
,
1
);
total_size
=
total_data
+
(
nr
-
1
)
*
sizeof
(
struct
btrfs_item
);
ret
=
btrfs_search_slot
(
trans
,
root
,
cpu_key
,
path
,
total_size
,
1
);
if
(
ret
==
0
)
{
return
-
EEXIST
;
}
...
...
@@ -2366,10 +2373,10 @@ int btrfs_insert_empty_item(struct btrfs_trans_handle *trans,
data_end
=
leaf_data_end
(
root
,
leaf
);
if
(
btrfs_leaf_free_space
(
root
,
leaf
)
<
sizeof
(
struct
btrfs_item
)
+
data
_size
)
{
sizeof
(
struct
btrfs_item
)
+
total
_size
)
{
btrfs_print_leaf
(
root
,
leaf
);
printk
(
"not enough freespace need %u have %d
\n
"
,
data
_size
,
btrfs_leaf_free_space
(
root
,
leaf
));
total
_size
,
btrfs_leaf_free_space
(
root
,
leaf
));
BUG
();
}
...
...
@@ -2404,7 +2411,7 @@ int btrfs_insert_empty_item(struct btrfs_trans_handle *trans,
}
ioff
=
btrfs_item_offset
(
leaf
,
item
);
btrfs_set_item_offset
(
leaf
,
item
,
ioff
-
data_size
);
btrfs_set_item_offset
(
leaf
,
item
,
ioff
-
total_data
);
}
if
(
leaf
->
map_token
)
{
unmap_extent_buffer
(
leaf
,
leaf
->
map_token
,
KM_USER1
);
...
...
@@ -2412,23 +2419,27 @@ int btrfs_insert_empty_item(struct btrfs_trans_handle *trans,
}
/* shift the items */
memmove_extent_buffer
(
leaf
,
btrfs_item_nr_offset
(
slot
+
1
),
memmove_extent_buffer
(
leaf
,
btrfs_item_nr_offset
(
slot
+
nr
),
btrfs_item_nr_offset
(
slot
),
(
nritems
-
slot
)
*
sizeof
(
struct
btrfs_item
));
/* shift the data */
memmove_extent_buffer
(
leaf
,
btrfs_leaf_data
(
leaf
)
+
data_end
-
data_size
,
btrfs_leaf_data
(
leaf
)
+
data_end
-
total_data
,
btrfs_leaf_data
(
leaf
)
+
data_end
,
old_data
-
data_end
);
data_end
=
old_data
;
}
/* setup the item for the new data */
btrfs_set_item_key
(
leaf
,
&
disk_key
,
slot
);
item
=
btrfs_item_nr
(
leaf
,
slot
);
btrfs_set_item_offset
(
leaf
,
item
,
data_end
-
data_size
);
btrfs_set_item_size
(
leaf
,
item
,
data_size
);
btrfs_set_header_nritems
(
leaf
,
nritems
+
1
);
for
(
i
=
0
;
i
<
nr
;
i
++
)
{
btrfs_cpu_key_to_disk
(
&
disk_key
,
cpu_key
+
i
);
btrfs_set_item_key
(
leaf
,
&
disk_key
,
slot
+
i
);
item
=
btrfs_item_nr
(
leaf
,
slot
+
i
);
btrfs_set_item_offset
(
leaf
,
item
,
data_end
-
data_size
[
i
]);
data_end
-=
data_size
[
i
];
btrfs_set_item_size
(
leaf
,
item
,
data_size
[
i
]);
}
btrfs_set_header_nritems
(
leaf
,
nritems
+
nr
);
btrfs_mark_buffer_dirty
(
leaf
);
ret
=
0
;
...
...
This diff is collapsed.
Click to expand it.
fs/btrfs/ctree.h
View file @
9c58309d
...
...
@@ -1050,9 +1050,20 @@ static inline int btrfs_del_item(struct btrfs_trans_handle *trans,
int
btrfs_insert_item
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_key
*
key
,
void
*
data
,
u32
data_size
);
int
btrfs_insert_empty_item
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
struct
btrfs_key
*
cpu_key
,
u32
data_size
);
int
btrfs_insert_empty_items
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
struct
btrfs_key
*
cpu_key
,
u32
*
data_size
,
int
nr
);
static
inline
int
btrfs_insert_empty_item
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
struct
btrfs_key
*
key
,
u32
data_size
)
{
return
btrfs_insert_empty_items
(
trans
,
root
,
path
,
key
,
&
data_size
,
1
);
}
int
btrfs_next_leaf
(
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
);
int
btrfs_prev_leaf
(
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
);
int
btrfs_leaf_free_space
(
struct
btrfs_root
*
root
,
struct
extent_buffer
*
leaf
);
...
...
This diff is collapsed.
Click to expand it.
fs/btrfs/inode.c
View file @
9c58309d
...
...
@@ -1500,6 +1500,8 @@ void btrfs_dirty_inode(struct inode *inode)
static
struct
inode
*
btrfs_new_inode
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
const
char
*
name
,
int
name_len
,
u64
ref_objectid
,
u64
objectid
,
struct
btrfs_block_group_cache
*
group
,
int
mode
)
...
...
@@ -1508,6 +1510,10 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
struct
btrfs_inode_item
*
inode_item
;
struct
btrfs_key
*
location
;
struct
btrfs_path
*
path
;
struct
btrfs_inode_ref
*
ref
;
struct
btrfs_key
key
[
2
];
u32
sizes
[
2
];
unsigned
long
ptr
;
int
ret
;
int
owner
;
...
...
@@ -1530,10 +1536,25 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
group
=
btrfs_find_block_group
(
root
,
group
,
0
,
0
,
owner
);
BTRFS_I
(
inode
)
->
block_group
=
group
;
BTRFS_I
(
inode
)
->
flags
=
0
;
ret
=
btrfs_insert_empty_inode
(
trans
,
root
,
path
,
objectid
);
if
(
ret
)
key
[
0
].
objectid
=
objectid
;
btrfs_set_key_type
(
&
key
[
0
],
BTRFS_INODE_ITEM_KEY
);
key
[
0
].
offset
=
0
;
key
[
1
].
objectid
=
objectid
;
btrfs_set_key_type
(
&
key
[
1
],
BTRFS_INODE_REF_KEY
);
key
[
1
].
offset
=
ref_objectid
;
sizes
[
0
]
=
sizeof
(
struct
btrfs_inode_item
);
sizes
[
1
]
=
name_len
+
sizeof
(
*
ref
);
ret
=
btrfs_insert_empty_items
(
trans
,
root
,
path
,
key
,
sizes
,
2
);
if
(
ret
!=
0
)
goto
fail
;
if
(
objectid
>
root
->
highest_inode
)
root
->
highest_inode
=
objectid
;
inode
->
i_uid
=
current
->
fsuid
;
inode
->
i_gid
=
current
->
fsgid
;
inode
->
i_mode
=
mode
;
...
...
@@ -1543,6 +1564,13 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
inode_item
=
btrfs_item_ptr
(
path
->
nodes
[
0
],
path
->
slots
[
0
],
struct
btrfs_inode_item
);
fill_inode_item
(
path
->
nodes
[
0
],
inode_item
,
inode
);
ref
=
btrfs_item_ptr
(
path
->
nodes
[
0
],
path
->
slots
[
0
]
+
1
,
struct
btrfs_inode_ref
);
btrfs_set_inode_ref_name_len
(
path
->
nodes
[
0
],
ref
,
name_len
);
ptr
=
(
unsigned
long
)(
ref
+
1
);
write_extent_buffer
(
path
->
nodes
[
0
],
name
,
ptr
,
name_len
);
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
btrfs_free_path
(
path
);
...
...
@@ -1564,7 +1592,8 @@ static inline u8 btrfs_inode_type(struct inode *inode)
}
static
int
btrfs_add_link
(
struct
btrfs_trans_handle
*
trans
,
struct
dentry
*
dentry
,
struct
inode
*
inode
)
struct
dentry
*
dentry
,
struct
inode
*
inode
,
int
add_backref
)
{
int
ret
;
struct
btrfs_key
key
;
...
...
@@ -1580,11 +1609,13 @@ static int btrfs_add_link(struct btrfs_trans_handle *trans,
dentry
->
d_parent
->
d_inode
->
i_ino
,
&
key
,
btrfs_inode_type
(
inode
));
if
(
ret
==
0
)
{
if
(
add_backref
)
{
ret
=
btrfs_insert_inode_ref
(
trans
,
root
,
dentry
->
d_name
.
name
,
dentry
->
d_name
.
len
,
inode
->
i_ino
,
dentry
->
d_parent
->
d_inode
->
i_ino
);
}
parent_inode
=
dentry
->
d_parent
->
d_inode
;
parent_inode
->
i_size
+=
dentry
->
d_name
.
len
*
2
;
parent_inode
->
i_mtime
=
parent_inode
->
i_ctime
=
CURRENT_TIME
;
...
...
@@ -1595,9 +1626,10 @@ static int btrfs_add_link(struct btrfs_trans_handle *trans,
}
static
int
btrfs_add_nondir
(
struct
btrfs_trans_handle
*
trans
,
struct
dentry
*
dentry
,
struct
inode
*
inode
)
struct
dentry
*
dentry
,
struct
inode
*
inode
,
int
backref
)
{
int
err
=
btrfs_add_link
(
trans
,
dentry
,
inode
);
int
err
=
btrfs_add_link
(
trans
,
dentry
,
inode
,
backref
);
if
(
!
err
)
{
d_instantiate
(
dentry
,
inode
);
return
0
;
...
...
@@ -1635,14 +1667,16 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
goto
out_unlock
;
}
inode
=
btrfs_new_inode
(
trans
,
root
,
objectid
,
inode
=
btrfs_new_inode
(
trans
,
root
,
dentry
->
d_name
.
name
,
dentry
->
d_name
.
len
,
dentry
->
d_parent
->
d_inode
->
i_ino
,
objectid
,
BTRFS_I
(
dir
)
->
block_group
,
mode
);
err
=
PTR_ERR
(
inode
);
if
(
IS_ERR
(
inode
))
goto
out_unlock
;
btrfs_set_trans_block_group
(
trans
,
inode
);
err
=
btrfs_add_nondir
(
trans
,
dentry
,
inode
);
err
=
btrfs_add_nondir
(
trans
,
dentry
,
inode
,
0
);
if
(
err
)
drop_inode
=
1
;
else
{
...
...
@@ -1692,14 +1726,16 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
goto
out_unlock
;
}
inode
=
btrfs_new_inode
(
trans
,
root
,
objectid
,
BTRFS_I
(
dir
)
->
block_group
,
mode
);
inode
=
btrfs_new_inode
(
trans
,
root
,
dentry
->
d_name
.
name
,
dentry
->
d_name
.
len
,
dentry
->
d_parent
->
d_inode
->
i_ino
,
objectid
,
BTRFS_I
(
dir
)
->
block_group
,
mode
);
err
=
PTR_ERR
(
inode
);
if
(
IS_ERR
(
inode
))
goto
out_unlock
;
btrfs_set_trans_block_group
(
trans
,
inode
);
err
=
btrfs_add_nondir
(
trans
,
dentry
,
inode
);
err
=
btrfs_add_nondir
(
trans
,
dentry
,
inode
,
0
);
if
(
err
)
drop_inode
=
1
;
else
{
...
...
@@ -1755,7 +1791,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
btrfs_set_trans_block_group
(
trans
,
dir
);
atomic_inc
(
&
inode
->
i_count
);
err
=
btrfs_add_nondir
(
trans
,
dentry
,
inode
);
err
=
btrfs_add_nondir
(
trans
,
dentry
,
inode
,
1
);
if
(
err
)
drop_inode
=
1
;
...
...
@@ -1810,7 +1846,9 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
goto
out_unlock
;
}
inode
=
btrfs_new_inode
(
trans
,
root
,
objectid
,
inode
=
btrfs_new_inode
(
trans
,
root
,
dentry
->
d_name
.
name
,
dentry
->
d_name
.
len
,
dentry
->
d_parent
->
d_inode
->
i_ino
,
objectid
,
BTRFS_I
(
dir
)
->
block_group
,
S_IFDIR
|
mode
);
if
(
IS_ERR
(
inode
))
{
err
=
PTR_ERR
(
inode
);
...
...
@@ -1827,7 +1865,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
if
(
err
)
goto
out_fail
;
err
=
btrfs_add_link
(
trans
,
dentry
,
inode
);
err
=
btrfs_add_link
(
trans
,
dentry
,
inode
,
0
);
if
(
err
)
goto
out_fail
;
...
...
@@ -2320,7 +2358,8 @@ static int noinline create_subvol(struct btrfs_root *root, char *name,
trans
=
btrfs_start_transaction
(
new_root
,
1
);
BUG_ON
(
!
trans
);
inode
=
btrfs_new_inode
(
trans
,
new_root
,
new_dirid
,
inode
=
btrfs_new_inode
(
trans
,
new_root
,
".."
,
2
,
new_dirid
,
new_dirid
,
BTRFS_I
(
dir
)
->
block_group
,
S_IFDIR
|
0700
);
if
(
IS_ERR
(
inode
))
goto
fail
;
...
...
@@ -2817,7 +2856,7 @@ static int btrfs_rename(struct inode * old_dir, struct dentry *old_dentry,
if
(
ret
)
goto
out_fail
;
}
ret
=
btrfs_add_link
(
trans
,
new_dentry
,
old_inode
);
ret
=
btrfs_add_link
(
trans
,
new_dentry
,
old_inode
,
1
);
if
(
ret
)
goto
out_fail
;
...
...
@@ -2865,14 +2904,16 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
goto
out_unlock
;
}
inode
=
btrfs_new_inode
(
trans
,
root
,
objectid
,
inode
=
btrfs_new_inode
(
trans
,
root
,
dentry
->
d_name
.
name
,
dentry
->
d_name
.
len
,
dentry
->
d_parent
->
d_inode
->
i_ino
,
objectid
,
BTRFS_I
(
dir
)
->
block_group
,
S_IFLNK
|
S_IRWXUGO
);
err
=
PTR_ERR
(
inode
);
if
(
IS_ERR
(
inode
))
goto
out_unlock
;
btrfs_set_trans_block_group
(
trans
,
inode
);
err
=
btrfs_add_nondir
(
trans
,
dentry
,
inode
);
err
=
btrfs_add_nondir
(
trans
,
dentry
,
inode
,
0
);
if
(
err
)
drop_inode
=
1
;
else
{
...
...
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