Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 718f58ad authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull btrfs update from Chris Mason:
 "The dates look like I had to rebase this morning because there was a
  compiler warning for a printk arg that I had missed earlier.

  These are all fixes, including one to prevent using stale pointers for
  device names, and lots of fixes around transaction abort cleanups
  (Josef, Liu Bo).

  Jan Schmidt also sent in a number of fixes for the new reference
  number tracking code.

  Liu Bo beat me to updating the MAINTAINERS file.  Since he thought to
  also fix the git url, I kept his commit."

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: (24 commits)
  Btrfs: update MAINTAINERS info for BTRFS FILE SYSTEM
  Btrfs: destroy the items of the delayed inodes in error handling routine
  Btrfs: make sure that we've made everything in pinned tree clean
  Btrfs: avoid memory leak of extent state in error handling routine
  Btrfs: do not resize a seeding device
  Btrfs: fix missing inherited flag in rename
  Btrfs: fix incompat flags setting
  Btrfs: fix defrag regression
  Btrfs: call filemap_fdatawrite twice for compression
  Btrfs: keep inode pinned when compressing writes
  Btrfs: implement ->show_devname
  Btrfs: use rcu to protect device->name
  Btrfs: unlock everything properly in the error case for nocow
  Btrfs: fix btrfs_destroy_marked_extents
  Btrfs: abort the transaction if the commit fails
  Btrfs: wake up transaction waiters when aborting a transaction
  Btrfs: fix locking in btrfs_destroy_delayed_refs
  Btrfs: pass locked_page into extent_clear_unlock_delalloc if theres an error
  Btrfs: fix race in tree mod log addition
  Btrfs: add btrfs_next_old_leaf
  ...
parents 424d54d2 9c106405
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -1646,11 +1646,11 @@ S: Maintained
F:	drivers/gpio/gpio-bt8xx.c

BTRFS FILE SYSTEM
M:	Chris Mason <chris.mason@oracle.com>
M:	Chris Mason <chris.mason@fusionio.com>
L:	linux-btrfs@vger.kernel.org
W:	http://btrfs.wiki.kernel.org/
Q:	http://patchwork.kernel.org/project/linux-btrfs/list/
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable.git
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs.git
S:	Maintained
F:	Documentation/filesystems/btrfs.txt
F:	fs/btrfs/
+5 −12
Original line number Diff line number Diff line
@@ -179,7 +179,8 @@ static int __add_prelim_ref(struct list_head *head, u64 root_id,

static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
				struct ulist *parents, int level,
				struct btrfs_key *key, u64 wanted_disk_byte,
				struct btrfs_key *key, u64 time_seq,
				u64 wanted_disk_byte,
				const u64 *extent_item_pos)
{
	int ret;
@@ -212,7 +213,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
	 */
	while (1) {
		eie = NULL;
		ret = btrfs_next_leaf(root, path);
		ret = btrfs_next_old_leaf(root, path, time_seq);
		if (ret < 0)
			return ret;
		if (ret)
@@ -294,18 +295,10 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info,
		goto out;
	}

	if (level == 0) {
		if (ret == 1 && path->slots[0] >= btrfs_header_nritems(eb)) {
			ret = btrfs_next_leaf(root, path);
			if (ret)
				goto out;
			eb = path->nodes[0];
		}

	if (level == 0)
		btrfs_item_key_to_cpu(eb, &key, path->slots[0]);
	}

	ret = add_all_parents(root, path, parents, level, &key,
	ret = add_all_parents(root, path, parents, level, &key, time_seq,
				ref->wanted_disk_byte, extent_item_pos);
out:
	btrfs_free_path(path);
+1 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@
#define BTRFS_INODE_IN_DEFRAG			3
#define BTRFS_INODE_DELALLOC_META_RESERVED	4
#define BTRFS_INODE_HAS_ORPHAN_ITEM		5
#define BTRFS_INODE_HAS_ASYNC_EXTENT		6

/* in memory btrfs inode */
struct btrfs_inode {
+9 −7
Original line number Diff line number Diff line
@@ -93,6 +93,7 @@
#include "print-tree.h"
#include "locking.h"
#include "check-integrity.h"
#include "rcu-string.h"

#define BTRFSIC_BLOCK_HASHTABLE_SIZE 0x10000
#define BTRFSIC_BLOCK_LINK_HASHTABLE_SIZE 0x10000
@@ -843,9 +844,10 @@ static int btrfsic_process_superblock_dev_mirror(
		superblock_tmp->never_written = 0;
		superblock_tmp->mirror_num = 1 + superblock_mirror_num;
		if (state->print_mask & BTRFSIC_PRINT_MASK_SUPERBLOCK_WRITE)
			printk(KERN_INFO "New initial S-block (bdev %p, %s)"
			printk_in_rcu(KERN_INFO "New initial S-block (bdev %p, %s)"
				     " @%llu (%s/%llu/%d)\n",
			       superblock_bdev, device->name,
				     superblock_bdev,
				     rcu_str_deref(device->name),
				     (unsigned long long)dev_bytenr,
				     dev_state->name,
				     (unsigned long long)dev_bytenr,
+63 −23
Original line number Diff line number Diff line
@@ -467,6 +467,15 @@ static inline int tree_mod_dont_log(struct btrfs_fs_info *fs_info,
	return 0;
}

/*
 * This allocates memory and gets a tree modification sequence number when
 * needed.
 *
 * Returns 0 when no sequence number is needed, < 0 on error.
 * Returns 1 when a sequence number was added. In this case,
 * fs_info->tree_mod_seq_lock was acquired and must be released by the caller
 * after inserting into the rb tree.
 */
static inline int tree_mod_alloc(struct btrfs_fs_info *fs_info, gfp_t flags,
				 struct tree_mod_elem **tm_ret)
{
@@ -491,11 +500,11 @@ static inline int tree_mod_alloc(struct btrfs_fs_info *fs_info, gfp_t flags,
		 */
		kfree(tm);
		seq = 0;
		spin_unlock(&fs_info->tree_mod_seq_lock);
	} else {
		__get_tree_mod_seq(fs_info, &tm->elem);
		seq = tm->elem.seq;
	}
	spin_unlock(&fs_info->tree_mod_seq_lock);

	return seq;
}
@@ -521,7 +530,9 @@ tree_mod_log_insert_key_mask(struct btrfs_fs_info *fs_info,
	tm->slot = slot;
	tm->generation = btrfs_node_ptr_generation(eb, slot);

	return __tree_mod_log_insert(fs_info, tm);
	ret = __tree_mod_log_insert(fs_info, tm);
	spin_unlock(&fs_info->tree_mod_seq_lock);
	return ret;
}

static noinline int
@@ -559,7 +570,9 @@ tree_mod_log_insert_move(struct btrfs_fs_info *fs_info,
	tm->move.nr_items = nr_items;
	tm->op = MOD_LOG_MOVE_KEYS;

	return __tree_mod_log_insert(fs_info, tm);
	ret = __tree_mod_log_insert(fs_info, tm);
	spin_unlock(&fs_info->tree_mod_seq_lock);
	return ret;
}

static noinline int
@@ -580,7 +593,9 @@ tree_mod_log_insert_root(struct btrfs_fs_info *fs_info,
	tm->generation = btrfs_header_generation(old_root);
	tm->op = MOD_LOG_ROOT_REPLACE;

	return __tree_mod_log_insert(fs_info, tm);
	ret = __tree_mod_log_insert(fs_info, tm);
	spin_unlock(&fs_info->tree_mod_seq_lock);
	return ret;
}

static struct tree_mod_elem *
@@ -1023,6 +1038,10 @@ __tree_mod_log_oldest_root(struct btrfs_fs_info *fs_info,
		looped = 1;
	}

	/* if there's no old root to return, return what we found instead */
	if (!found)
		found = tm;

	return found;
}

@@ -1143,22 +1162,36 @@ tree_mod_log_rewind(struct btrfs_fs_info *fs_info, struct extent_buffer *eb,
	return eb_rewin;
}

/*
 * get_old_root() rewinds the state of @root's root node to the given @time_seq
 * value. If there are no changes, the current root->root_node is returned. If
 * anything changed in between, there's a fresh buffer allocated on which the
 * rewind operations are done. In any case, the returned buffer is read locked.
 * Returns NULL on error (with no locks held).
 */
static inline struct extent_buffer *
get_old_root(struct btrfs_root *root, u64 time_seq)
{
	struct tree_mod_elem *tm;
	struct extent_buffer *eb;
	struct tree_mod_root *old_root;
	struct tree_mod_root *old_root = NULL;
	u64 old_generation;
	u64 logical;

	eb = btrfs_read_lock_root_node(root);
	tm = __tree_mod_log_oldest_root(root->fs_info, root, time_seq);
	if (!tm)
		return root->node;

	if (tm->op == MOD_LOG_ROOT_REPLACE) {
		old_root = &tm->old_root;
		old_generation = tm->generation;
		logical = old_root->logical;
	} else {
		logical = root->node->start;
	}

	tm = tree_mod_log_search(root->fs_info, old_root->logical, time_seq);
	tm = tree_mod_log_search(root->fs_info, logical, time_seq);
	/*
	 * there was an item in the log when __tree_mod_log_oldest_root
	 * returned. this one must not go away, because the time_seq passed to
@@ -1166,22 +1199,25 @@ get_old_root(struct btrfs_root *root, u64 time_seq)
	 */
	BUG_ON(!tm);

	if (old_root->logical == root->node->start) {
		/* there are logged operations for the current root */
		eb = btrfs_clone_extent_buffer(root->node);
	} else {
		/* there's a root replace operation for the current root */
	if (old_root)
		eb = alloc_dummy_extent_buffer(tm->index << PAGE_CACHE_SHIFT,
					       root->nodesize);
	else
		eb = btrfs_clone_extent_buffer(root->node);
	btrfs_tree_read_unlock(root->node);
	free_extent_buffer(root->node);
	if (!eb)
		return NULL;
	btrfs_tree_read_lock(eb);
	if (old_root) {
		btrfs_set_header_bytenr(eb, eb->start);
		btrfs_set_header_backref_rev(eb, BTRFS_MIXED_BACKREF_REV);
		btrfs_set_header_owner(eb, root->root_key.objectid);
	}
	if (!eb)
		return NULL;
		btrfs_set_header_level(eb, old_root->level);
		btrfs_set_header_generation(eb, old_generation);
	}
	__tree_mod_log_rewind(eb, time_seq, tm);
	extent_buffer_get(eb);

	return eb;
}
@@ -1650,8 +1686,6 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
	    BTRFS_NODEPTRS_PER_BLOCK(root) / 4)
		return 0;

	btrfs_header_nritems(mid);

	left = read_node_slot(root, parent, pslot - 1);
	if (left) {
		btrfs_tree_lock(left);
@@ -1681,7 +1715,6 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
		wret = push_node_left(trans, root, left, mid, 1);
		if (wret < 0)
			ret = wret;
		btrfs_header_nritems(mid);
	}

	/*
@@ -2615,9 +2648,7 @@ int btrfs_search_old_slot(struct btrfs_root *root, struct btrfs_key *key,

again:
	b = get_old_root(root, time_seq);
	extent_buffer_get(b);
	level = btrfs_header_level(b);
	btrfs_tree_read_lock(b);
	p->locks[level] = BTRFS_READ_LOCK;

	while (b) {
@@ -5000,6 +5031,12 @@ int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path,
 * returns < 0 on io errors.
 */
int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
{
	return btrfs_next_old_leaf(root, path, 0);
}

int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path,
			u64 time_seq)
{
	int slot;
	int level;
@@ -5025,6 +5062,9 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
	path->keep_locks = 1;
	path->leave_spinning = 1;

	if (time_seq)
		ret = btrfs_search_old_slot(root, &key, path, time_seq);
	else
		ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
	path->keep_locks = 0;

Loading