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

Commit fe66a05a authored by Chris Mason's avatar Chris Mason
Browse files

Btrfs: improve error handling for btrfs_insert_dir_item callers



This allows us to gracefully continue if we aren't able to insert
directory items, both for normal files/dirs and snapshots.

Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent 692e5759
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -4585,7 +4585,8 @@ int btrfs_add_link(struct btrfs_trans_handle *trans,
		ret = btrfs_insert_dir_item(trans, root, name, name_len,
					    parent_inode, &key,
					    btrfs_inode_type(inode), index);
		BUG_ON(ret);
		if (ret)
			goto fail_dir_item;

		btrfs_i_size_write(parent_inode, parent_inode->i_size +
				   name_len * 2);
@@ -4593,6 +4594,23 @@ int btrfs_add_link(struct btrfs_trans_handle *trans,
		ret = btrfs_update_inode(trans, root, parent_inode);
	}
	return ret;

fail_dir_item:
	if (unlikely(ino == BTRFS_FIRST_FREE_OBJECTID)) {
		u64 local_index;
		int err;
		err = btrfs_del_root_ref(trans, root->fs_info->tree_root,
				 key.objectid, root->root_key.objectid,
				 parent_ino, &local_index, name, name_len);

	} else if (add_backref) {
		u64 local_index;
		int err;

		err = btrfs_del_inode_ref(trans, root, name, name_len,
					  ino, parent_ino, &local_index);
	}
	return ret;
}

static int btrfs_add_nondir(struct btrfs_trans_handle *trans,
+7 −6
Original line number Diff line number Diff line
@@ -915,7 +915,11 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
				dentry->d_name.name, dentry->d_name.len,
				parent_inode, &key,
				BTRFS_FT_DIR, index);
	BUG_ON(ret);
	if (ret) {
		pending->error = -EEXIST;
		dput(parent);
		goto fail;
	}

	btrfs_i_size_write(parent_inode, parent_inode->i_size +
					 dentry->d_name.len * 2);
@@ -993,12 +997,9 @@ static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans,
{
	struct btrfs_pending_snapshot *pending;
	struct list_head *head = &trans->transaction->pending_snapshots;
	int ret;

	list_for_each_entry(pending, head, list) {
		ret = create_pending_snapshot(trans, fs_info, pending);
		BUG_ON(ret);
	}
	list_for_each_entry(pending, head, list)
		create_pending_snapshot(trans, fs_info, pending);
	return 0;
}