Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/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
  ...
  • Loading branch information
torvalds committed Oct 10, 2012
2 parents fc81c03 + f46dbe3 commit 7205542
Show file tree
Hide file tree
Showing 39 changed files with 3,574 additions and 1,619 deletions.
299 changes: 240 additions & 59 deletions fs/btrfs/backref.c

Large diffs are not rendered by default.

10 changes: 7 additions & 3 deletions fs/btrfs/backref.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,13 @@ struct inode_fs_paths {

typedef int (iterate_extent_inodes_t)(u64 inum, u64 offset, u64 root,
void *ctx);
typedef int (iterate_irefs_t)(u64 parent, struct btrfs_inode_ref *iref,
struct extent_buffer *eb, void *ctx);

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

int extent_from_logical(struct btrfs_fs_info *fs_info, u64 logical,
struct btrfs_path *path, struct btrfs_key *found_key);
struct btrfs_path *path, struct btrfs_key *found_key,
u64 *flags);

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

int btrfs_find_one_extref(struct btrfs_root *root, u64 inode_objectid,
u64 start_off, struct btrfs_path *path,
struct btrfs_inode_extref **ret_extref,
u64 *found_off);

#endif
15 changes: 7 additions & 8 deletions fs/btrfs/btrfs_inode.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#define BTRFS_INODE_DELALLOC_META_RESERVED 4
#define BTRFS_INODE_HAS_ORPHAN_ITEM 5
#define BTRFS_INODE_HAS_ASYNC_EXTENT 6
#define BTRFS_INODE_NEEDS_FULL_SYNC 7

/* in memory btrfs inode */
struct btrfs_inode {
Expand Down Expand Up @@ -143,6 +144,9 @@ struct btrfs_inode {
/* flags field from the on disk inode */
u32 flags;

/* a local copy of root's last_log_commit */
unsigned long last_log_commit;

/*
* Counters to keep track of the number of extent item's we may use due
* to delalloc and such. outstanding_extents is the number of extent
Expand Down Expand Up @@ -202,15 +206,10 @@ static inline bool btrfs_is_free_space_inode(struct inode *inode)

static inline int btrfs_inode_in_log(struct inode *inode, u64 generation)
{
struct btrfs_root *root = BTRFS_I(inode)->root;
int ret = 0;

mutex_lock(&root->log_mutex);
if (BTRFS_I(inode)->logged_trans == generation &&
BTRFS_I(inode)->last_sub_trans <= root->last_log_commit)
ret = 1;
mutex_unlock(&root->log_mutex);
return ret;
BTRFS_I(inode)->last_sub_trans <= BTRFS_I(inode)->last_log_commit)
return 1;
return 0;
}

#endif
16 changes: 14 additions & 2 deletions fs/btrfs/check-integrity.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@
* the file system was mounted, (i.e., they have been
* referenced by the super block) or they have been
* written since then and the write completion callback
* was called and a FLUSH request to the device where
* these blocks are located was received and completed.
* was called and no write error was indicated and a
* FLUSH request to the device where these blocks are
* located was received and completed.
* 2b. All referenced blocks need to have a generation
* number which is equal to the parent's number.
*
Expand Down Expand Up @@ -2601,6 +2602,17 @@ static int btrfsic_check_all_ref_blocks(struct btrfsic_state *state,
(unsigned long long)l->block_ref_to->dev_bytenr,
l->block_ref_to->mirror_num);
ret = -1;
} else if (l->block_ref_to->iodone_w_error) {
printk(KERN_INFO "btrfs: attempt to write superblock"
" which references block %c @%llu (%s/%llu/%d)"
" which has write error!\n",
btrfsic_get_block_type(state, l->block_ref_to),
(unsigned long long)
l->block_ref_to->logical_bytenr,
l->block_ref_to->dev_state->name,
(unsigned long long)l->block_ref_to->dev_bytenr,
l->block_ref_to->mirror_num);
ret = -1;
} else if (l->parent_generation !=
l->block_ref_to->generation &&
BTRFSIC_GENERATION_UNKNOWN !=
Expand Down
13 changes: 10 additions & 3 deletions fs/btrfs/compression.c
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
u64 em_start;
struct extent_map *em;
int ret = -ENOMEM;
int faili = 0;
u32 *sums;

tree = &BTRFS_I(inode)->io_tree;
Expand Down Expand Up @@ -626,9 +627,13 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
for (pg_index = 0; pg_index < nr_pages; pg_index++) {
cb->compressed_pages[pg_index] = alloc_page(GFP_NOFS |
__GFP_HIGHMEM);
if (!cb->compressed_pages[pg_index])
if (!cb->compressed_pages[pg_index]) {
faili = pg_index - 1;
ret = -ENOMEM;
goto fail2;
}
}
faili = nr_pages - 1;
cb->nr_pages = nr_pages;

add_ra_bio_pages(inode, em_start + em_len, cb);
Expand Down Expand Up @@ -713,8 +718,10 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
return 0;

fail2:
for (pg_index = 0; pg_index < nr_pages; pg_index++)
free_page((unsigned long)cb->compressed_pages[pg_index]);
while (faili >= 0) {
__free_page(cb->compressed_pages[faili]);
faili--;
}

kfree(cb->compressed_pages);
fail1:
Expand Down
148 changes: 4 additions & 144 deletions fs/btrfs/ctree.c
Original file line number Diff line number Diff line change
Expand Up @@ -4401,149 +4401,6 @@ void btrfs_extend_item(struct btrfs_trans_handle *trans,
}
}

/*
* Given a key and some data, insert items into the tree.
* This does all the path init required, making room in the tree if needed.
* Returns the number of keys that were inserted.
*/
int btrfs_insert_some_items(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
struct btrfs_path *path,
struct btrfs_key *cpu_key, u32 *data_size,
int nr)
{
struct extent_buffer *leaf;
struct btrfs_item *item;
int ret = 0;
int slot;
int i;
u32 nritems;
u32 total_data = 0;
u32 total_size = 0;
unsigned int data_end;
struct btrfs_disk_key disk_key;
struct btrfs_key found_key;
struct btrfs_map_token token;

btrfs_init_map_token(&token);

for (i = 0; i < nr; i++) {
if (total_size + data_size[i] + sizeof(struct btrfs_item) >
BTRFS_LEAF_DATA_SIZE(root)) {
break;
nr = i;
}
total_data += data_size[i];
total_size += data_size[i] + sizeof(struct btrfs_item);
}
BUG_ON(nr == 0);

ret = btrfs_search_slot(trans, root, cpu_key, path, total_size, 1);
if (ret == 0)
return -EEXIST;
if (ret < 0)
goto out;

leaf = path->nodes[0];

nritems = btrfs_header_nritems(leaf);
data_end = leaf_data_end(root, leaf);

if (btrfs_leaf_free_space(root, leaf) < total_size) {
for (i = nr; i >= 0; i--) {
total_data -= data_size[i];
total_size -= data_size[i] + sizeof(struct btrfs_item);
if (total_size < btrfs_leaf_free_space(root, leaf))
break;
}
nr = i;
}

slot = path->slots[0];
BUG_ON(slot < 0);

if (slot != nritems) {
unsigned int old_data = btrfs_item_end_nr(leaf, slot);

item = btrfs_item_nr(leaf, slot);
btrfs_item_key_to_cpu(leaf, &found_key, slot);

/* figure out how many keys we can insert in here */
total_data = data_size[0];
for (i = 1; i < nr; i++) {
if (btrfs_comp_cpu_keys(&found_key, cpu_key + i) <= 0)
break;
total_data += data_size[i];
}
nr = i;

if (old_data < data_end) {
btrfs_print_leaf(root, leaf);
printk(KERN_CRIT "slot %d old_data %d data_end %d\n",
slot, old_data, data_end);
BUG_ON(1);
}
/*
* item0..itemN ... dataN.offset..dataN.size .. data0.size
*/
/* first correct the data pointers */
for (i = slot; i < nritems; i++) {
u32 ioff;

item = btrfs_item_nr(leaf, i);
ioff = btrfs_token_item_offset(leaf, item, &token);
btrfs_set_token_item_offset(leaf, item,
ioff - total_data, &token);
}
/* shift the items */
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 - total_data, btrfs_leaf_data(leaf) +
data_end, old_data - data_end);
data_end = old_data;
} else {
/*
* this sucks but it has to be done, if we are inserting at
* the end of the leaf only insert 1 of the items, since we
* have no way of knowing whats on the next leaf and we'd have
* to drop our current locks to figure it out
*/
nr = 1;
}

/* setup the item for the new data */
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_token_item_offset(leaf, item,
data_end - data_size[i], &token);
data_end -= data_size[i];
btrfs_set_token_item_size(leaf, item, data_size[i], &token);
}
btrfs_set_header_nritems(leaf, nritems + nr);
btrfs_mark_buffer_dirty(leaf);

ret = 0;
if (slot == 0) {
btrfs_cpu_key_to_disk(&disk_key, cpu_key);
fixup_low_keys(trans, root, path, &disk_key, 1);
}

if (btrfs_leaf_free_space(root, leaf) < 0) {
btrfs_print_leaf(root, leaf);
BUG();
}
out:
if (!ret)
ret = nr;
return ret;
}

/*
* this is a helper for btrfs_insert_empty_items, the main goal here is
* to save stack depth by doing the bulk of the work in a function
Expand Down Expand Up @@ -5073,6 +4930,7 @@ static void tree_move_down(struct btrfs_root *root,
struct btrfs_path *path,
int *level, int root_level)
{
BUG_ON(*level == 0);
path->nodes[*level - 1] = read_node_slot(root, path->nodes[*level],
path->slots[*level]);
path->slots[*level - 1] = 0;
Expand All @@ -5089,7 +4947,7 @@ static int tree_move_next_or_upnext(struct btrfs_root *root,

path->slots[*level]++;

while (path->slots[*level] == nritems) {
while (path->slots[*level] >= nritems) {
if (*level == root_level)
return -1;

Expand Down Expand Up @@ -5433,9 +5291,11 @@ int btrfs_compare_trees(struct btrfs_root *left_root,
goto out;
advance_right = ADVANCE;
} else {
WARN_ON(!extent_buffer_uptodate(left_path->nodes[0]));
ret = tree_compare_item(left_root, left_path,
right_path, tmp_buf);
if (ret) {
WARN_ON(!extent_buffer_uptodate(left_path->nodes[0]));
ret = changed_cb(left_root, right_root,
left_path, right_path,
&left_key,
Expand Down
Loading

0 comments on commit 7205542

Please sign in to comment.