Commit d3f71ae7 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull btrfs fixes from Chris Mason:
 "Dave had a small collection of fixes to the new free space tree code,
  one of which was keeping our sysfs files more up to date with feature
  bits as different things get enabled (lzo, raid5/6, etc).

  I should have kept the sysfs stuff for rc3, since we always manage to
  trip over something.  This time it was GFP_KERNEL from somewhere that
  is NOFS only.  Instead of rebasing it out I've put a revert in, and
  we'll fix it properly for rc3.

  Otherwise, Filipe fixed a btrfs DIO race and Qu Wenruo fixed up a
  use-after-free in our tracepoints that Dave Jones reported"

* 'for-linus-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
  Revert "btrfs: synchronize incompat feature bits with sysfs files"
  btrfs: don't use GFP_HIGHMEM for free-space-tree bitmap kzalloc
  btrfs: sysfs: check initialization state before updating features
  Revert "btrfs: clear PF_NOFREEZE in cleaner_kthread()"
  btrfs: async-thread: Fix a use-after-free error for trace
  Btrfs: fix race between fsync and lockless direct IO writes
  btrfs: add free space tree to the cow-only list
  btrfs: add free space tree to lockdep classes
  btrfs: tweak free space tree bitmap allocation
  btrfs: tests: switch to GFP_KERNEL
  btrfs: synchronize incompat feature bits with sysfs files
  btrfs: sysfs: introduce helper for syncing bits with sysfs files
  btrfs: sysfs: add free-space-tree bit attribute
  btrfs: sysfs: fix typo in compat_ro attribute definition
parents 46552e68 e410e34f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -328,8 +328,8 @@ static inline void __btrfs_queue_work(struct __btrfs_workqueue *wq,
		list_add_tail(&work->ordered_list, &wq->ordered_list);
		spin_unlock_irqrestore(&wq->list_lock, flags);
	}
	queue_work(wq->normal_wq, &work->normal_work);
	trace_btrfs_work_queued(work);
	queue_work(wq->normal_wq, &work->normal_work);
}

void btrfs_queue_work(struct btrfs_workqueue *wq,
+1 −1
Original line number Diff line number Diff line
@@ -182,6 +182,7 @@ static struct btrfs_lockdep_keyset {
	{ .id = BTRFS_TREE_RELOC_OBJECTID,	.name_stem = "treloc"	},
	{ .id = BTRFS_DATA_RELOC_TREE_OBJECTID,	.name_stem = "dreloc"	},
	{ .id = BTRFS_UUID_TREE_OBJECTID,	.name_stem = "uuid"	},
	{ .id = BTRFS_FREE_SPACE_TREE_OBJECTID,	.name_stem = "free-space" },
	{ .id = 0,				.name_stem = "tree"	},
};

@@ -1787,7 +1788,6 @@ static int cleaner_kthread(void *arg)
	int again;
	struct btrfs_trans_handle *trans;

	set_freezable();
	do {
		again = 0;

+16 −2
Original line number Diff line number Diff line
@@ -153,6 +153,20 @@ static inline u32 free_space_bitmap_size(u64 size, u32 sectorsize)

static unsigned long *alloc_bitmap(u32 bitmap_size)
{
	void *mem;

	/*
	 * The allocation size varies, observed numbers were < 4K up to 16K.
	 * Using vmalloc unconditionally would be too heavy, we'll try
	 * contiguous allocations first.
	 */
	if  (bitmap_size <= PAGE_SIZE)
		return kzalloc(bitmap_size, GFP_NOFS);

	mem = kzalloc(bitmap_size, GFP_NOFS | __GFP_NOWARN);
	if (mem)
		return mem;

	return __vmalloc(bitmap_size, GFP_NOFS | __GFP_HIGHMEM | __GFP_ZERO,
			 PAGE_KERNEL);
}
@@ -289,7 +303,7 @@ int convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans,

	ret = 0;
out:
	vfree(bitmap);
	kvfree(bitmap);
	if (ret)
		btrfs_abort_transaction(trans, root, ret);
	return ret;
@@ -438,7 +452,7 @@ int convert_free_space_to_extents(struct btrfs_trans_handle *trans,

	ret = 0;
out:
	vfree(bitmap);
	kvfree(bitmap);
	if (ret)
		btrfs_abort_transaction(trans, root, ret);
	return ret;
+28 −8
Original line number Diff line number Diff line
@@ -7116,21 +7116,41 @@ static struct extent_map *btrfs_new_extent_direct(struct inode *inode,
	if (ret)
		return ERR_PTR(ret);

	em = create_pinned_em(inode, start, ins.offset, start, ins.objectid,
			      ins.offset, ins.offset, ins.offset, 0);
	if (IS_ERR(em)) {
		btrfs_free_reserved_extent(root, ins.objectid, ins.offset, 1);
		return em;
	}

	/*
	 * Create the ordered extent before the extent map. This is to avoid
	 * races with the fast fsync path that would lead to it logging file
	 * extent items that point to disk extents that were not yet written to.
	 * The fast fsync path collects ordered extents into a local list and
	 * then collects all the new extent maps, so we must create the ordered
	 * extent first and make sure the fast fsync path collects any new
	 * ordered extents after collecting new extent maps as well.
	 * The fsync path simply can not rely on inode_dio_wait() because it
	 * causes deadlock with AIO.
	 */
	ret = btrfs_add_ordered_extent_dio(inode, start, ins.objectid,
					   ins.offset, ins.offset, 0);
	if (ret) {
		btrfs_free_reserved_extent(root, ins.objectid, ins.offset, 1);
		free_extent_map(em);
		return ERR_PTR(ret);
	}

	em = create_pinned_em(inode, start, ins.offset, start, ins.objectid,
			      ins.offset, ins.offset, ins.offset, 0);
	if (IS_ERR(em)) {
		struct btrfs_ordered_extent *oe;

		btrfs_free_reserved_extent(root, ins.objectid, ins.offset, 1);
		oe = btrfs_lookup_ordered_extent(inode, start);
		ASSERT(oe);
		if (WARN_ON(!oe))
			return em;
		set_bit(BTRFS_ORDERED_IOERR, &oe->flags);
		set_bit(BTRFS_ORDERED_IO_DONE, &oe->flags);
		btrfs_remove_ordered_extent(inode, oe);
		/* Once for our lookup and once for the ordered extents tree. */
		btrfs_put_ordered_extent(oe);
		btrfs_put_ordered_extent(oe);
	}
	return em;
}

+2 −1
Original line number Diff line number Diff line
@@ -575,7 +575,8 @@ static int is_cowonly_root(u64 root_objectid)
	    root_objectid == BTRFS_TREE_LOG_OBJECTID ||
	    root_objectid == BTRFS_CSUM_TREE_OBJECTID ||
	    root_objectid == BTRFS_UUID_TREE_OBJECTID ||
	    root_objectid == BTRFS_QUOTA_TREE_OBJECTID)
	    root_objectid == BTRFS_QUOTA_TREE_OBJECTID ||
	    root_objectid == BTRFS_FREE_SPACE_TREE_OBJECTID)
		return 1;
	return 0;
}
Loading