Skip to content

Commit fe66a05

Browse files
committed
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: Chris Mason <chris.mason@oracle.com>
1 parent 692e575 commit fe66a05

File tree

2 files changed

+26
-7
lines changed

2 files changed

+26
-7
lines changed

fs/btrfs/inode.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4585,14 +4585,32 @@ int btrfs_add_link(struct btrfs_trans_handle *trans,
45854585
ret = btrfs_insert_dir_item(trans, root, name, name_len,
45864586
parent_inode, &key,
45874587
btrfs_inode_type(inode), index);
4588-
BUG_ON(ret);
4588+
if (ret)
4589+
goto fail_dir_item;
45894590

45904591
btrfs_i_size_write(parent_inode, parent_inode->i_size +
45914592
name_len * 2);
45924593
parent_inode->i_mtime = parent_inode->i_ctime = CURRENT_TIME;
45934594
ret = btrfs_update_inode(trans, root, parent_inode);
45944595
}
45954596
return ret;
4597+
4598+
fail_dir_item:
4599+
if (unlikely(ino == BTRFS_FIRST_FREE_OBJECTID)) {
4600+
u64 local_index;
4601+
int err;
4602+
err = btrfs_del_root_ref(trans, root->fs_info->tree_root,
4603+
key.objectid, root->root_key.objectid,
4604+
parent_ino, &local_index, name, name_len);
4605+
4606+
} else if (add_backref) {
4607+
u64 local_index;
4608+
int err;
4609+
4610+
err = btrfs_del_inode_ref(trans, root, name, name_len,
4611+
ino, parent_ino, &local_index);
4612+
}
4613+
return ret;
45964614
}
45974615

45984616
static int btrfs_add_nondir(struct btrfs_trans_handle *trans,

fs/btrfs/transaction.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -915,7 +915,11 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
915915
dentry->d_name.name, dentry->d_name.len,
916916
parent_inode, &key,
917917
BTRFS_FT_DIR, index);
918-
BUG_ON(ret);
918+
if (ret) {
919+
pending->error = -EEXIST;
920+
dput(parent);
921+
goto fail;
922+
}
919923

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

998-
list_for_each_entry(pending, head, list) {
999-
ret = create_pending_snapshot(trans, fs_info, pending);
1000-
BUG_ON(ret);
1001-
}
1001+
list_for_each_entry(pending, head, list)
1002+
create_pending_snapshot(trans, fs_info, pending);
10021003
return 0;
10031004
}
10041005

0 commit comments

Comments
 (0)