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

Commit a22180d2 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull btrfs update from Chris Mason:
 "A big set of fixes and features.

  In terms of line count, most of the code comes from Stefan, who added
  the ability to replace a single drive in place.  This is different
  from how btrfs normally replaces drives, and is much much much faster.

  Josef is plowing through our synchronous write performance.  This pull
  request does not include the DIO_OWN_WAITING patch that was discussed
  on the list, but it has a number of other improvements to cut down our
  latencies and CPU time during fsync/O_DIRECT writes.

  Miao Xie has a big series of fixes and is spreading out ordered
  operations over more CPUs.  This improves performance and reduces
  contention.

  I've put in fixes for error handling around hash collisions.  These
  are going back to individual stable kernels as I test against them.

  Otherwise we have a lot of fixes and cleanups, thanks everyone!
  raid5/6 is being rebased against the device replacement code.  I'll
  have it posted this Friday along with a nice series of benchmarks."

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: (115 commits)
  Btrfs: fix a bug of per-file nocow
  Btrfs: fix hash overflow handling
  Btrfs: don't take inode delalloc mutex if we're a free space inode
  Btrfs: fix autodefrag and umount lockup
  Btrfs: fix permissions of empty files not affected by umask
  Btrfs: put raid properties into global table
  Btrfs: fix BUG() in scrub when first superblock reading gives EIO
  Btrfs: do not call file_update_time in aio_write
  Btrfs: only unlock and relock if we have to
  Btrfs: use tokens where we can in the tree log
  Btrfs: optimize leaf_space_used
  Btrfs: don't memset new tokens
  Btrfs: only clear dirty on the buffer if it is marked as dirty
  Btrfs: move checks in set_page_dirty under DEBUG
  Btrfs: log changed inodes based on the extent map tree
  Btrfs: add path->really_keep_locks
  Btrfs: do not mark ems as prealloc if we are writing to them
  Btrfs: keep track of the extents original block length
  Btrfs: inline csums if we're fsyncing
  Btrfs: don't bother copying if we're only logging the inode
  ...
parents 2d4dce00 213490b3
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@ btrfs-y += super.o ctree.o extent-tree.o print-tree.o root-tree.o dir-item.o \
	   extent_io.o volumes.o async-thread.o ioctl.o locking.o orphan.o \
	   export.o tree-log.o free-space-cache.o zlib.o lzo.o \
	   compression.o delayed-ref.o relocation.o delayed-inode.o scrub.o \
	   reada.o backref.o ulist.o qgroup.o send.o
	   reada.o backref.o ulist.o qgroup.o send.o dev-replace.o

btrfs-$(CONFIG_BTRFS_FS_POSIX_ACL) += acl.o
btrfs-$(CONFIG_BTRFS_FS_CHECK_INTEGRITY) += check-integrity.o
+2 −0
Original line number Diff line number Diff line
@@ -121,6 +121,8 @@ static int btrfs_set_acl(struct btrfs_trans_handle *trans,
			ret = posix_acl_equiv_mode(acl, &inode->i_mode);
			if (ret < 0)
				return ret;
			if (ret == 0)
				acl = NULL;
		}
		ret = 0;
		break;
+12 −4
Original line number Diff line number Diff line
@@ -461,6 +461,7 @@ static int __merge_refs(struct list_head *head, int mode)
		     pos2 = n2, n2 = pos2->next) {
			struct __prelim_ref *ref2;
			struct __prelim_ref *xchg;
			struct extent_inode_elem *eie;

			ref2 = list_entry(pos2, struct __prelim_ref, list);

@@ -472,12 +473,20 @@ static int __merge_refs(struct list_head *head, int mode)
					ref1 = ref2;
					ref2 = xchg;
				}
				ref1->count += ref2->count;
			} else {
				if (ref1->parent != ref2->parent)
					continue;
				ref1->count += ref2->count;
			}

			eie = ref1->inode_list;
			while (eie && eie->next)
				eie = eie->next;
			if (eie)
				eie->next = ref2->inode_list;
			else
				ref1->inode_list = ref2->inode_list;
			ref1->count += ref2->count;

			list_del(&ref2->list);
			kfree(ref2);
		}
@@ -890,8 +899,7 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans,
	while (!list_empty(&prefs)) {
		ref = list_first_entry(&prefs, struct __prelim_ref, list);
		list_del(&ref->list);
		if (ref->count < 0)
			WARN_ON(1);
		WARN_ON(ref->count < 0);
		if (ref->count && ref->root_id && ref->parent == 0) {
			/* no parent == root of tree */
			ret = ulist_add(roots, ref->root_id, 0, GFP_NOFS);
+4 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@
#define BTRFS_INODE_HAS_ORPHAN_ITEM		5
#define BTRFS_INODE_HAS_ASYNC_EXTENT		6
#define BTRFS_INODE_NEEDS_FULL_SYNC		7
#define BTRFS_INODE_COPY_EVERYTHING		8

/* in memory btrfs inode */
struct btrfs_inode {
@@ -90,6 +91,9 @@ struct btrfs_inode {

	unsigned long runtime_flags;

	/* Keep track of who's O_SYNC/fsycing currently */
	atomic_t sync_writers;

	/* full 64 bit generation number, struct vfs_inode doesn't have a big
	 * enough field for this.
	 */
+21 −10
Original line number Diff line number Diff line
@@ -137,7 +137,7 @@ struct btrfsic_block {
	unsigned int never_written:1;	/* block was added because it was
					 * referenced, not because it was
					 * written */
	unsigned int mirror_num:2;	/* large enough to hold
	unsigned int mirror_num;	/* large enough to hold
					 * BTRFS_SUPER_MIRROR_MAX */
	struct btrfsic_dev_state *dev_state;
	u64 dev_bytenr;		/* key, physical byte num on disk */
@@ -723,7 +723,7 @@ static int btrfsic_process_superblock(struct btrfsic_state *state,
		}

		num_copies =
		    btrfs_num_copies(&state->root->fs_info->mapping_tree,
		    btrfs_num_copies(state->root->fs_info,
				     next_bytenr, state->metablock_size);
		if (state->print_mask & BTRFSIC_PRINT_MASK_NUM_COPIES)
			printk(KERN_INFO "num_copies(log_bytenr=%llu) = %d\n",
@@ -903,7 +903,7 @@ static int btrfsic_process_superblock_dev_mirror(
		}

		num_copies =
		    btrfs_num_copies(&state->root->fs_info->mapping_tree,
		    btrfs_num_copies(state->root->fs_info,
				     next_bytenr, state->metablock_size);
		if (state->print_mask & BTRFSIC_PRINT_MASK_NUM_COPIES)
			printk(KERN_INFO "num_copies(log_bytenr=%llu) = %d\n",
@@ -1287,7 +1287,7 @@ static int btrfsic_create_link_to_next_block(
	*next_blockp = NULL;
	if (0 == *num_copiesp) {
		*num_copiesp =
		    btrfs_num_copies(&state->root->fs_info->mapping_tree,
		    btrfs_num_copies(state->root->fs_info,
				     next_bytenr, state->metablock_size);
		if (state->print_mask & BTRFSIC_PRINT_MASK_NUM_COPIES)
			printk(KERN_INFO "num_copies(log_bytenr=%llu) = %d\n",
@@ -1489,7 +1489,7 @@ static int btrfsic_handle_extent_data(
			chunk_len = num_bytes;

		num_copies =
		    btrfs_num_copies(&state->root->fs_info->mapping_tree,
		    btrfs_num_copies(state->root->fs_info,
				     next_bytenr, state->datablock_size);
		if (state->print_mask & BTRFSIC_PRINT_MASK_NUM_COPIES)
			printk(KERN_INFO "num_copies(log_bytenr=%llu) = %d\n",
@@ -1582,9 +1582,21 @@ static int btrfsic_map_block(struct btrfsic_state *state, u64 bytenr, u32 len,
	struct btrfs_device *device;

	length = len;
	ret = btrfs_map_block(&state->root->fs_info->mapping_tree, READ,
	ret = btrfs_map_block(state->root->fs_info, READ,
			      bytenr, &length, &multi, mirror_num);

	if (ret) {
		block_ctx_out->start = 0;
		block_ctx_out->dev_bytenr = 0;
		block_ctx_out->len = 0;
		block_ctx_out->dev = NULL;
		block_ctx_out->datav = NULL;
		block_ctx_out->pagev = NULL;
		block_ctx_out->mem_to_free = NULL;

		return ret;
	}

	device = multi->stripes[0].dev;
	block_ctx_out->dev = btrfsic_dev_state_lookup(device->bdev);
	block_ctx_out->dev_bytenr = multi->stripes[0].physical;
@@ -1594,7 +1606,6 @@ static int btrfsic_map_block(struct btrfsic_state *state, u64 bytenr, u32 len,
	block_ctx_out->pagev = NULL;
	block_ctx_out->mem_to_free = NULL;

	if (0 == ret)
	kfree(multi);
	if (NULL == block_ctx_out->dev) {
		ret = -ENXIO;
@@ -2463,7 +2474,7 @@ static int btrfsic_process_written_superblock(
		}

		num_copies =
		    btrfs_num_copies(&state->root->fs_info->mapping_tree,
		    btrfs_num_copies(state->root->fs_info,
				     next_bytenr, BTRFS_SUPER_INFO_SIZE);
		if (state->print_mask & BTRFSIC_PRINT_MASK_NUM_COPIES)
			printk(KERN_INFO "num_copies(log_bytenr=%llu) = %d\n",
@@ -2960,7 +2971,7 @@ static void btrfsic_cmp_log_and_dev_bytenr(struct btrfsic_state *state,
	struct btrfsic_block_data_ctx block_ctx;
	int match = 0;

	num_copies = btrfs_num_copies(&state->root->fs_info->mapping_tree,
	num_copies = btrfs_num_copies(state->root->fs_info,
				      bytenr, state->metablock_size);

	for (mirror_num = 1; mirror_num <= num_copies; mirror_num++) {
Loading