diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-10-25 15:42:56 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:03:57 -0400 |
commit | f578d4bd7e141dd03ca7e8695c1cc118c326e69e (patch) | |
tree | bb89f7548f3c537ed34ddf9d0ac71f3a6fefff85 /fs/btrfs/file-item.c | |
parent | 5ee78ac70f6c01f2a5acf662c2af975665710edc (diff) |
Btrfs: Optimize csum insertion to create larger items when possible
This reduces the number of calls to btrfs_extend_item and greatly lowers
the cpu usage while writing large files.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/file-item.c')
-rw-r--r-- | fs/btrfs/file-item.c | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index 10a4c7408600..482a2b615327 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c | |||
@@ -133,17 +133,22 @@ int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans, | |||
133 | 133 | ||
134 | int btrfs_csum_file_block(struct btrfs_trans_handle *trans, | 134 | int btrfs_csum_file_block(struct btrfs_trans_handle *trans, |
135 | struct btrfs_root *root, | 135 | struct btrfs_root *root, |
136 | struct inode *inode, | ||
136 | u64 objectid, u64 offset, | 137 | u64 objectid, u64 offset, |
137 | char *data, size_t len) | 138 | char *data, size_t len) |
138 | { | 139 | { |
139 | int ret; | 140 | int ret; |
140 | struct btrfs_key file_key; | 141 | struct btrfs_key file_key; |
141 | struct btrfs_key found_key; | 142 | struct btrfs_key found_key; |
143 | u64 next_offset = (u64)-1; | ||
144 | int found_next = 0; | ||
142 | struct btrfs_path *path; | 145 | struct btrfs_path *path; |
143 | struct btrfs_csum_item *item; | 146 | struct btrfs_csum_item *item; |
144 | struct extent_buffer *leaf = NULL; | 147 | struct extent_buffer *leaf = NULL; |
145 | u64 csum_offset; | 148 | u64 csum_offset; |
146 | u32 csum_result = ~(u32)0; | 149 | u32 csum_result = ~(u32)0; |
150 | u32 nritems; | ||
151 | u32 ins_size; | ||
147 | 152 | ||
148 | path = btrfs_alloc_path(); | 153 | path = btrfs_alloc_path(); |
149 | BUG_ON(!path); | 154 | BUG_ON(!path); |
@@ -168,7 +173,27 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans, | |||
168 | goto insert; | 173 | goto insert; |
169 | } | 174 | } |
170 | } else { | 175 | } else { |
176 | int slot = path->slots[0] + 1; | ||
171 | /* we didn't find a csum item, insert one */ | 177 | /* we didn't find a csum item, insert one */ |
178 | nritems = btrfs_header_nritems(path->nodes[0]); | ||
179 | if (path->slots[0] >= nritems - 1) { | ||
180 | ret = btrfs_next_leaf(root, path); | ||
181 | if (ret == 1) { | ||
182 | found_next = 1; | ||
183 | } else if (ret == 0) { | ||
184 | slot = 0; | ||
185 | } else { | ||
186 | goto insert; | ||
187 | } | ||
188 | } | ||
189 | btrfs_item_key_to_cpu(path->nodes[0], &found_key, slot); | ||
190 | if (found_key.objectid != objectid || | ||
191 | found_key.type != BTRFS_CSUM_ITEM_KEY) { | ||
192 | found_next = 1; | ||
193 | goto insert; | ||
194 | } | ||
195 | next_offset = found_key.offset; | ||
196 | found_next = 1; | ||
172 | goto insert; | 197 | goto insert; |
173 | } | 198 | } |
174 | 199 | ||
@@ -211,8 +236,18 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans, | |||
211 | insert: | 236 | insert: |
212 | btrfs_release_path(root, path); | 237 | btrfs_release_path(root, path); |
213 | csum_offset = 0; | 238 | csum_offset = 0; |
239 | if (found_next) { | ||
240 | u64 tmp = min((u64)i_size_read(inode), next_offset); | ||
241 | tmp -= offset + root->sectorsize - 1; | ||
242 | tmp >>= root->fs_info->sb->s_blocksize_bits; | ||
243 | tmp = max((u64)1, tmp); | ||
244 | tmp = min(tmp, (u64)MAX_CSUM_ITEMS(root)); | ||
245 | ins_size = BTRFS_CRC32_SIZE * tmp; | ||
246 | } else { | ||
247 | ins_size = BTRFS_CRC32_SIZE; | ||
248 | } | ||
214 | ret = btrfs_insert_empty_item(trans, root, path, &file_key, | 249 | ret = btrfs_insert_empty_item(trans, root, path, &file_key, |
215 | BTRFS_CRC32_SIZE); | 250 | ins_size); |
216 | if (ret < 0) | 251 | if (ret < 0) |
217 | goto fail; | 252 | goto fail; |
218 | if (ret != 0) { | 253 | if (ret != 0) { |