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

Commit 988f1f57 authored by Chris Mason's avatar Chris Mason
Browse files

Merge branch 'for-chris-4.5' of...

Merge branch 'for-chris-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/fdmanana/linux

 into for-linus-4.5

Signed-off-by: default avatarChris Mason <clm@fb.com>
parents b28cf572 8cdc7c5b
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -3768,6 +3768,25 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans,
		}
		if (!ret) {
			ret = write_one_cache_group(trans, root, path, cache);
			/*
			 * One of the free space endio workers might have
			 * created a new block group while updating a free space
			 * cache's inode (at inode.c:btrfs_finish_ordered_io())
			 * and hasn't released its transaction handle yet, in
			 * which case the new block group is still attached to
			 * its transaction handle and its creation has not
			 * finished yet (no block group item in the extent tree
			 * yet, etc). If this is the case, wait for all free
			 * space endio workers to finish and retry. This is a
			 * a very rare case so no need for a more efficient and
			 * complex approach.
			 */
			if (ret == -ENOENT) {
				wait_event(cur_trans->writer_wait,
				   atomic_read(&cur_trans->num_writers) == 1);
				ret = write_one_cache_group(trans, root, path,
							    cache);
			}
			if (ret)
				btrfs_abort_transaction(trans, root, ret);
		}
+14 −7
Original line number Diff line number Diff line
@@ -6478,7 +6478,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
		      struct dentry *dentry)
{
	struct btrfs_trans_handle *trans;
	struct btrfs_trans_handle *trans = NULL;
	struct btrfs_root *root = BTRFS_I(dir)->root;
	struct inode *inode = d_inode(old_dentry);
	u64 index;
@@ -6504,6 +6504,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
	trans = btrfs_start_transaction(root, 5);
	if (IS_ERR(trans)) {
		err = PTR_ERR(trans);
		trans = NULL;
		goto fail;
	}

@@ -6537,9 +6538,10 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
		btrfs_log_new_name(trans, inode, NULL, parent);
	}

	btrfs_end_transaction(trans, root);
	btrfs_balance_delayed_items(root);
fail:
	if (trans)
		btrfs_end_transaction(trans, root);
	if (drop_inode) {
		inode_dec_link_count(inode);
		iput(inode);
@@ -9655,9 +9657,11 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
	/*
	 * 2 items for inode item and ref
	 * 2 items for dir items
	 * 1 item for updating parent inode item
	 * 1 item for the inline extent item
	 * 1 item for xattr if selinux is on
	 */
	trans = btrfs_start_transaction(root, 5);
	trans = btrfs_start_transaction(root, 7);
	if (IS_ERR(trans))
		return PTR_ERR(trans);

@@ -9688,10 +9692,6 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
	if (err)
		goto out_unlock_inode;

	err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index);
	if (err)
		goto out_unlock_inode;

	path = btrfs_alloc_path();
	if (!path) {
		err = -ENOMEM;
@@ -9728,6 +9728,13 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
	inode_set_bytes(inode, name_len);
	btrfs_i_size_write(inode, name_len);
	err = btrfs_update_inode(trans, root, inode);
	/*
	 * Last step, add directory indexes for our symlink inode. This is the
	 * last step to avoid extra cleanup of these indexes if an error happens
	 * elsewhere above.
	 */
	if (!err)
		err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index);
	if (err) {
		drop_inode = 1;
		goto out_unlock_inode;
+15 −1
Original line number Diff line number Diff line
@@ -1469,7 +1469,21 @@ static int read_symlink(struct btrfs_root *root,
	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
	if (ret < 0)
		goto out;
	BUG_ON(ret);
	if (ret) {
		/*
		 * An empty symlink inode. Can happen in rare error paths when
		 * creating a symlink (transaction committed before the inode
		 * eviction handler removed the symlink inode items and a crash
		 * happened in between or the subvol was snapshoted in between).
		 * Print an informative message to dmesg/syslog so that the user
		 * can delete the symlink.
		 */
		btrfs_err(root->fs_info,
			  "Found empty symlink inode %llu at root %llu",
			  ino, root->root_key.objectid);
		ret = -EIO;
		goto out;
	}

	ei = btrfs_item_ptr(path->nodes[0], path->slots[0],
			struct btrfs_file_extent_item);
+10 −10
Original line number Diff line number Diff line
@@ -1258,6 +1258,15 @@ int find_free_dev_extent_start(struct btrfs_transaction *transaction,
	int ret;
	int slot;
	struct extent_buffer *l;
	u64 min_search_start;

	/*
	 * We don't want to overwrite the superblock on the drive nor any area
	 * used by the boot loader (grub for example), so we make sure to start
	 * at an offset of at least 1MB.
	 */
	min_search_start = max(root->fs_info->alloc_start, 1024ull * 1024);
	search_start = max(search_start, min_search_start);

	path = btrfs_alloc_path();
	if (!path)
@@ -1398,18 +1407,9 @@ int find_free_dev_extent(struct btrfs_trans_handle *trans,
			 struct btrfs_device *device, u64 num_bytes,
			 u64 *start, u64 *len)
{
	struct btrfs_root *root = device->dev_root;
	u64 search_start;

	/* FIXME use last free of some kind */

	/*
	 * we don't want to overwrite the superblock on the drive,
	 * so we make sure to start at an offset of at least 1MB
	 */
	search_start = max_t(u64, root->fs_info->alloc_start, SZ_1M);
	return find_free_dev_extent_start(trans->transaction, device,
					  num_bytes, search_start, start, len);
					  num_bytes, 0, start, len);
}

static int btrfs_free_dev_extent(struct btrfs_trans_handle *trans,