Skip to content

Commit 7205542

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs update from Chris Mason: "This is a large pull, with the bulk of the updates coming from: - Hole punching - send/receive fixes - fsync performance - Disk format extension allowing more hardlinks inside a single directory (btrfs-progs patch required to enable the compat bit for this one) I'm cooking more unrelated RAID code, but I wanted to make sure this original batch makes it in. The largest updates here are relatively old and have been in testing for some time." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: (121 commits) btrfs: init ref_index to zero in add_inode_ref Btrfs: remove repeated eb->pages check in, disk-io.c/csum_dirty_buffer Btrfs: fix page leakage Btrfs: do not warn_on when we cannot alloc a page for an extent buffer Btrfs: don't bug on enomem in readpage Btrfs: cleanup pages properly when ENOMEM in compression Btrfs: make filesystem read-only when submitting barrier fails Btrfs: detect corrupted filesystem after write I/O errors Btrfs: make compress and nodatacow mount options mutually exclusive btrfs: fix message printing Btrfs: don't bother committing delayed inode updates when fsyncing btrfs: move inline function code to header file Btrfs: remove unnecessary IS_ERR in bio_readpage_error() btrfs: remove unused function btrfs_insert_some_items() Btrfs: don't commit instead of overcommitting Btrfs: confirmation of value is added before trace_btrfs_get_extent() is called Btrfs: be smarter about dropping things from the tree log Btrfs: don't lookup csums for prealloc extents Btrfs: cache extent state when writing out dirty metadata pages Btrfs: do not hold the file extent leaf locked when adding extent item ...
2 parents fc81c03 + f46dbe3 commit 7205542

39 files changed

+3574
-1619
lines changed

fs/btrfs/backref.c

Lines changed: 240 additions & 59 deletions
Large diffs are not rendered by default.

fs/btrfs/backref.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,13 @@ struct inode_fs_paths {
3333

3434
typedef int (iterate_extent_inodes_t)(u64 inum, u64 offset, u64 root,
3535
void *ctx);
36-
typedef int (iterate_irefs_t)(u64 parent, struct btrfs_inode_ref *iref,
37-
struct extent_buffer *eb, void *ctx);
3836

3937
int inode_item_info(u64 inum, u64 ioff, struct btrfs_root *fs_root,
4038
struct btrfs_path *path);
4139

4240
int extent_from_logical(struct btrfs_fs_info *fs_info, u64 logical,
43-
struct btrfs_path *path, struct btrfs_key *found_key);
41+
struct btrfs_path *path, struct btrfs_key *found_key,
42+
u64 *flags);
4443

4544
int tree_backref_for_extent(unsigned long *ptr, struct extent_buffer *eb,
4645
struct btrfs_extent_item *ei, u32 item_size,
@@ -69,4 +68,9 @@ struct inode_fs_paths *init_ipath(s32 total_bytes, struct btrfs_root *fs_root,
6968
struct btrfs_path *path);
7069
void free_ipath(struct inode_fs_paths *ipath);
7170

71+
int btrfs_find_one_extref(struct btrfs_root *root, u64 inode_objectid,
72+
u64 start_off, struct btrfs_path *path,
73+
struct btrfs_inode_extref **ret_extref,
74+
u64 *found_off);
75+
7276
#endif

fs/btrfs/btrfs_inode.h

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#define BTRFS_INODE_DELALLOC_META_RESERVED 4
3939
#define BTRFS_INODE_HAS_ORPHAN_ITEM 5
4040
#define BTRFS_INODE_HAS_ASYNC_EXTENT 6
41+
#define BTRFS_INODE_NEEDS_FULL_SYNC 7
4142

4243
/* in memory btrfs inode */
4344
struct btrfs_inode {
@@ -143,6 +144,9 @@ struct btrfs_inode {
143144
/* flags field from the on disk inode */
144145
u32 flags;
145146

147+
/* a local copy of root's last_log_commit */
148+
unsigned long last_log_commit;
149+
146150
/*
147151
* Counters to keep track of the number of extent item's we may use due
148152
* to delalloc and such. outstanding_extents is the number of extent
@@ -202,15 +206,10 @@ static inline bool btrfs_is_free_space_inode(struct inode *inode)
202206

203207
static inline int btrfs_inode_in_log(struct inode *inode, u64 generation)
204208
{
205-
struct btrfs_root *root = BTRFS_I(inode)->root;
206-
int ret = 0;
207-
208-
mutex_lock(&root->log_mutex);
209209
if (BTRFS_I(inode)->logged_trans == generation &&
210-
BTRFS_I(inode)->last_sub_trans <= root->last_log_commit)
211-
ret = 1;
212-
mutex_unlock(&root->log_mutex);
213-
return ret;
210+
BTRFS_I(inode)->last_sub_trans <= BTRFS_I(inode)->last_log_commit)
211+
return 1;
212+
return 0;
214213
}
215214

216215
#endif

fs/btrfs/check-integrity.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@
3737
* the file system was mounted, (i.e., they have been
3838
* referenced by the super block) or they have been
3939
* written since then and the write completion callback
40-
* was called and a FLUSH request to the device where
41-
* these blocks are located was received and completed.
40+
* was called and no write error was indicated and a
41+
* FLUSH request to the device where these blocks are
42+
* located was received and completed.
4243
* 2b. All referenced blocks need to have a generation
4344
* number which is equal to the parent's number.
4445
*
@@ -2601,6 +2602,17 @@ static int btrfsic_check_all_ref_blocks(struct btrfsic_state *state,
26012602
(unsigned long long)l->block_ref_to->dev_bytenr,
26022603
l->block_ref_to->mirror_num);
26032604
ret = -1;
2605+
} else if (l->block_ref_to->iodone_w_error) {
2606+
printk(KERN_INFO "btrfs: attempt to write superblock"
2607+
" which references block %c @%llu (%s/%llu/%d)"
2608+
" which has write error!\n",
2609+
btrfsic_get_block_type(state, l->block_ref_to),
2610+
(unsigned long long)
2611+
l->block_ref_to->logical_bytenr,
2612+
l->block_ref_to->dev_state->name,
2613+
(unsigned long long)l->block_ref_to->dev_bytenr,
2614+
l->block_ref_to->mirror_num);
2615+
ret = -1;
26042616
} else if (l->parent_generation !=
26052617
l->block_ref_to->generation &&
26062618
BTRFSIC_GENERATION_UNKNOWN !=

fs/btrfs/compression.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
577577
u64 em_start;
578578
struct extent_map *em;
579579
int ret = -ENOMEM;
580+
int faili = 0;
580581
u32 *sums;
581582

582583
tree = &BTRFS_I(inode)->io_tree;
@@ -626,9 +627,13 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
626627
for (pg_index = 0; pg_index < nr_pages; pg_index++) {
627628
cb->compressed_pages[pg_index] = alloc_page(GFP_NOFS |
628629
__GFP_HIGHMEM);
629-
if (!cb->compressed_pages[pg_index])
630+
if (!cb->compressed_pages[pg_index]) {
631+
faili = pg_index - 1;
632+
ret = -ENOMEM;
630633
goto fail2;
634+
}
631635
}
636+
faili = nr_pages - 1;
632637
cb->nr_pages = nr_pages;
633638

634639
add_ra_bio_pages(inode, em_start + em_len, cb);
@@ -713,8 +718,10 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
713718
return 0;
714719

715720
fail2:
716-
for (pg_index = 0; pg_index < nr_pages; pg_index++)
717-
free_page((unsigned long)cb->compressed_pages[pg_index]);
721+
while (faili >= 0) {
722+
__free_page(cb->compressed_pages[faili]);
723+
faili--;
724+
}
718725

719726
kfree(cb->compressed_pages);
720727
fail1:

fs/btrfs/ctree.c

Lines changed: 4 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -4401,149 +4401,6 @@ void btrfs_extend_item(struct btrfs_trans_handle *trans,
44014401
}
44024402
}
44034403

4404-
/*
4405-
* Given a key and some data, insert items into the tree.
4406-
* This does all the path init required, making room in the tree if needed.
4407-
* Returns the number of keys that were inserted.
4408-
*/
4409-
int btrfs_insert_some_items(struct btrfs_trans_handle *trans,
4410-
struct btrfs_root *root,
4411-
struct btrfs_path *path,
4412-
struct btrfs_key *cpu_key, u32 *data_size,
4413-
int nr)
4414-
{
4415-
struct extent_buffer *leaf;
4416-
struct btrfs_item *item;
4417-
int ret = 0;
4418-
int slot;
4419-
int i;
4420-
u32 nritems;
4421-
u32 total_data = 0;
4422-
u32 total_size = 0;
4423-
unsigned int data_end;
4424-
struct btrfs_disk_key disk_key;
4425-
struct btrfs_key found_key;
4426-
struct btrfs_map_token token;
4427-
4428-
btrfs_init_map_token(&token);
4429-
4430-
for (i = 0; i < nr; i++) {
4431-
if (total_size + data_size[i] + sizeof(struct btrfs_item) >
4432-
BTRFS_LEAF_DATA_SIZE(root)) {
4433-
break;
4434-
nr = i;
4435-
}
4436-
total_data += data_size[i];
4437-
total_size += data_size[i] + sizeof(struct btrfs_item);
4438-
}
4439-
BUG_ON(nr == 0);
4440-
4441-
ret = btrfs_search_slot(trans, root, cpu_key, path, total_size, 1);
4442-
if (ret == 0)
4443-
return -EEXIST;
4444-
if (ret < 0)
4445-
goto out;
4446-
4447-
leaf = path->nodes[0];
4448-
4449-
nritems = btrfs_header_nritems(leaf);
4450-
data_end = leaf_data_end(root, leaf);
4451-
4452-
if (btrfs_leaf_free_space(root, leaf) < total_size) {
4453-
for (i = nr; i >= 0; i--) {
4454-
total_data -= data_size[i];
4455-
total_size -= data_size[i] + sizeof(struct btrfs_item);
4456-
if (total_size < btrfs_leaf_free_space(root, leaf))
4457-
break;
4458-
}
4459-
nr = i;
4460-
}
4461-
4462-
slot = path->slots[0];
4463-
BUG_ON(slot < 0);
4464-
4465-
if (slot != nritems) {
4466-
unsigned int old_data = btrfs_item_end_nr(leaf, slot);
4467-
4468-
item = btrfs_item_nr(leaf, slot);
4469-
btrfs_item_key_to_cpu(leaf, &found_key, slot);
4470-
4471-
/* figure out how many keys we can insert in here */
4472-
total_data = data_size[0];
4473-
for (i = 1; i < nr; i++) {
4474-
if (btrfs_comp_cpu_keys(&found_key, cpu_key + i) <= 0)
4475-
break;
4476-
total_data += data_size[i];
4477-
}
4478-
nr = i;
4479-
4480-
if (old_data < data_end) {
4481-
btrfs_print_leaf(root, leaf);
4482-
printk(KERN_CRIT "slot %d old_data %d data_end %d\n",
4483-
slot, old_data, data_end);
4484-
BUG_ON(1);
4485-
}
4486-
/*
4487-
* item0..itemN ... dataN.offset..dataN.size .. data0.size
4488-
*/
4489-
/* first correct the data pointers */
4490-
for (i = slot; i < nritems; i++) {
4491-
u32 ioff;
4492-
4493-
item = btrfs_item_nr(leaf, i);
4494-
ioff = btrfs_token_item_offset(leaf, item, &token);
4495-
btrfs_set_token_item_offset(leaf, item,
4496-
ioff - total_data, &token);
4497-
}
4498-
/* shift the items */
4499-
memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot + nr),
4500-
btrfs_item_nr_offset(slot),
4501-
(nritems - slot) * sizeof(struct btrfs_item));
4502-
4503-
/* shift the data */
4504-
memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) +
4505-
data_end - total_data, btrfs_leaf_data(leaf) +
4506-
data_end, old_data - data_end);
4507-
data_end = old_data;
4508-
} else {
4509-
/*
4510-
* this sucks but it has to be done, if we are inserting at
4511-
* the end of the leaf only insert 1 of the items, since we
4512-
* have no way of knowing whats on the next leaf and we'd have
4513-
* to drop our current locks to figure it out
4514-
*/
4515-
nr = 1;
4516-
}
4517-
4518-
/* setup the item for the new data */
4519-
for (i = 0; i < nr; i++) {
4520-
btrfs_cpu_key_to_disk(&disk_key, cpu_key + i);
4521-
btrfs_set_item_key(leaf, &disk_key, slot + i);
4522-
item = btrfs_item_nr(leaf, slot + i);
4523-
btrfs_set_token_item_offset(leaf, item,
4524-
data_end - data_size[i], &token);
4525-
data_end -= data_size[i];
4526-
btrfs_set_token_item_size(leaf, item, data_size[i], &token);
4527-
}
4528-
btrfs_set_header_nritems(leaf, nritems + nr);
4529-
btrfs_mark_buffer_dirty(leaf);
4530-
4531-
ret = 0;
4532-
if (slot == 0) {
4533-
btrfs_cpu_key_to_disk(&disk_key, cpu_key);
4534-
fixup_low_keys(trans, root, path, &disk_key, 1);
4535-
}
4536-
4537-
if (btrfs_leaf_free_space(root, leaf) < 0) {
4538-
btrfs_print_leaf(root, leaf);
4539-
BUG();
4540-
}
4541-
out:
4542-
if (!ret)
4543-
ret = nr;
4544-
return ret;
4545-
}
4546-
45474404
/*
45484405
* this is a helper for btrfs_insert_empty_items, the main goal here is
45494406
* to save stack depth by doing the bulk of the work in a function
@@ -5073,6 +4930,7 @@ static void tree_move_down(struct btrfs_root *root,
50734930
struct btrfs_path *path,
50744931
int *level, int root_level)
50754932
{
4933+
BUG_ON(*level == 0);
50764934
path->nodes[*level - 1] = read_node_slot(root, path->nodes[*level],
50774935
path->slots[*level]);
50784936
path->slots[*level - 1] = 0;
@@ -5089,7 +4947,7 @@ static int tree_move_next_or_upnext(struct btrfs_root *root,
50894947

50904948
path->slots[*level]++;
50914949

5092-
while (path->slots[*level] == nritems) {
4950+
while (path->slots[*level] >= nritems) {
50934951
if (*level == root_level)
50944952
return -1;
50954953

@@ -5433,9 +5291,11 @@ int btrfs_compare_trees(struct btrfs_root *left_root,
54335291
goto out;
54345292
advance_right = ADVANCE;
54355293
} else {
5294+
WARN_ON(!extent_buffer_uptodate(left_path->nodes[0]));
54365295
ret = tree_compare_item(left_root, left_path,
54375296
right_path, tmp_buf);
54385297
if (ret) {
5298+
WARN_ON(!extent_buffer_uptodate(left_path->nodes[0]));
54395299
ret = changed_cb(left_root, right_root,
54405300
left_path, right_path,
54415301
&left_key,

0 commit comments

Comments
 (0)