diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-06-22 14:16:25 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-06-22 14:16:25 -0400 |
commit | 54aa1f4dfdacd60a19c4471220b24e581be6f774 (patch) | |
tree | 1462277822cc63c00ad31b522457363a5c6be6ab /fs/btrfs/inode.c | |
parent | 11bd143fc8243cf48c934dc1c4479a5aacf58ce3 (diff) |
Btrfs: Audit callers and return codes to make sure -ENOSPC gets up the stack
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 165 |
1 files changed, 107 insertions, 58 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 94f1c28c25b9..6d031daa7779 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -212,7 +212,11 @@ static int btrfs_unlink_trans(struct btrfs_trans_handle *trans, | |||
212 | struct btrfs_dir_item *di; | 212 | struct btrfs_dir_item *di; |
213 | 213 | ||
214 | path = btrfs_alloc_path(); | 214 | path = btrfs_alloc_path(); |
215 | BUG_ON(!path); | 215 | if (!path) { |
216 | ret = -ENOMEM; | ||
217 | goto err; | ||
218 | } | ||
219 | |||
216 | di = btrfs_lookup_dir_item(trans, root, path, dir->i_ino, | 220 | di = btrfs_lookup_dir_item(trans, root, path, dir->i_ino, |
217 | name, name_len, -1); | 221 | name, name_len, -1); |
218 | if (IS_ERR(di)) { | 222 | if (IS_ERR(di)) { |
@@ -225,7 +229,8 @@ static int btrfs_unlink_trans(struct btrfs_trans_handle *trans, | |||
225 | } | 229 | } |
226 | objectid = btrfs_disk_key_objectid(&di->location); | 230 | objectid = btrfs_disk_key_objectid(&di->location); |
227 | ret = btrfs_delete_one_dir_name(trans, root, path, di); | 231 | ret = btrfs_delete_one_dir_name(trans, root, path, di); |
228 | BUG_ON(ret); | 232 | if (ret) |
233 | goto err; | ||
229 | btrfs_release_path(root, path); | 234 | btrfs_release_path(root, path); |
230 | 235 | ||
231 | di = btrfs_lookup_dir_index_item(trans, root, path, dir->i_ino, | 236 | di = btrfs_lookup_dir_index_item(trans, root, path, dir->i_ino, |
@@ -239,7 +244,6 @@ static int btrfs_unlink_trans(struct btrfs_trans_handle *trans, | |||
239 | goto err; | 244 | goto err; |
240 | } | 245 | } |
241 | ret = btrfs_delete_one_dir_name(trans, root, path, di); | 246 | ret = btrfs_delete_one_dir_name(trans, root, path, di); |
242 | BUG_ON(ret); | ||
243 | 247 | ||
244 | dentry->d_inode->i_ctime = dir->i_ctime; | 248 | dentry->d_inode->i_ctime = dir->i_ctime; |
245 | err: | 249 | err: |
@@ -248,7 +252,7 @@ err: | |||
248 | dir->i_size -= name_len * 2; | 252 | dir->i_size -= name_len * 2; |
249 | btrfs_update_inode(trans, root, dir); | 253 | btrfs_update_inode(trans, root, dir); |
250 | drop_nlink(dentry->d_inode); | 254 | drop_nlink(dentry->d_inode); |
251 | btrfs_update_inode(trans, root, dentry->d_inode); | 255 | ret = btrfs_update_inode(trans, root, dentry->d_inode); |
252 | dir->i_sb->s_dirt = 1; | 256 | dir->i_sb->s_dirt = 1; |
253 | } | 257 | } |
254 | return ret; | 258 | return ret; |
@@ -359,9 +363,10 @@ static int btrfs_free_inode(struct btrfs_trans_handle *trans, | |||
359 | BUG_ON(!path); | 363 | BUG_ON(!path); |
360 | ret = btrfs_lookup_inode(trans, root, path, | 364 | ret = btrfs_lookup_inode(trans, root, path, |
361 | &BTRFS_I(inode)->location, -1); | 365 | &BTRFS_I(inode)->location, -1); |
362 | BUG_ON(ret); | 366 | if (ret > 0) |
363 | ret = btrfs_del_item(trans, root, path); | 367 | ret = -ENOENT; |
364 | BUG_ON(ret); | 368 | if (!ret) |
369 | ret = btrfs_del_item(trans, root, path); | ||
365 | btrfs_free_path(path); | 370 | btrfs_free_path(path); |
366 | return ret; | 371 | return ret; |
367 | } | 372 | } |
@@ -516,7 +521,8 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans, | |||
516 | } | 521 | } |
517 | if (del_item) { | 522 | if (del_item) { |
518 | ret = btrfs_del_item(trans, root, path); | 523 | ret = btrfs_del_item(trans, root, path); |
519 | BUG_ON(ret); | 524 | if (ret) |
525 | goto error; | ||
520 | } else { | 526 | } else { |
521 | break; | 527 | break; |
522 | } | 528 | } |
@@ -577,19 +583,22 @@ static int btrfs_truncate_page(struct address_space *mapping, loff_t from) | |||
577 | page->index << PAGE_CACHE_SHIFT, | 583 | page->index << PAGE_CACHE_SHIFT, |
578 | (page->index + 1) << PAGE_CACHE_SHIFT, | 584 | (page->index + 1) << PAGE_CACHE_SHIFT, |
579 | &alloc_hint); | 585 | &alloc_hint); |
580 | BUG_ON(ret); | 586 | if (ret) |
587 | goto out; | ||
581 | ret = btrfs_alloc_extent(trans, root, inode->i_ino, 1, | 588 | ret = btrfs_alloc_extent(trans, root, inode->i_ino, 1, |
582 | alloc_hint, (u64)-1, &ins, 1); | 589 | alloc_hint, (u64)-1, &ins, 1); |
583 | BUG_ON(ret); | 590 | if (ret) |
591 | goto out; | ||
584 | ret = btrfs_insert_file_extent(trans, root, inode->i_ino, | 592 | ret = btrfs_insert_file_extent(trans, root, inode->i_ino, |
585 | page->index << PAGE_CACHE_SHIFT, | 593 | page->index << PAGE_CACHE_SHIFT, |
586 | ins.objectid, 1, 1); | 594 | ins.objectid, 1, 1); |
587 | BUG_ON(ret); | 595 | if (ret) |
596 | goto out; | ||
588 | SetPageChecked(page); | 597 | SetPageChecked(page); |
589 | kaddr = kmap(page); | 598 | kaddr = kmap(page); |
590 | memset(kaddr + offset, 0, PAGE_CACHE_SIZE - offset); | 599 | memset(kaddr + offset, 0, PAGE_CACHE_SIZE - offset); |
591 | flush_dcache_page(page); | 600 | flush_dcache_page(page); |
592 | btrfs_csum_file_block(trans, root, inode->i_ino, | 601 | ret = btrfs_csum_file_block(trans, root, inode->i_ino, |
593 | page->index << PAGE_CACHE_SHIFT, | 602 | page->index << PAGE_CACHE_SHIFT, |
594 | kaddr, PAGE_CACHE_SIZE); | 603 | kaddr, PAGE_CACHE_SIZE); |
595 | kunmap(page); | 604 | kunmap(page); |
@@ -633,9 +642,10 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
633 | btrfs_set_trans_block_group(trans, inode); | 642 | btrfs_set_trans_block_group(trans, inode); |
634 | err = btrfs_insert_file_extent(trans, root, inode->i_ino, | 643 | err = btrfs_insert_file_extent(trans, root, inode->i_ino, |
635 | pos, 0, 0, hole_size); | 644 | pos, 0, 0, hole_size); |
636 | BUG_ON(err); | ||
637 | btrfs_end_transaction(trans, root); | 645 | btrfs_end_transaction(trans, root); |
638 | mutex_unlock(&root->fs_info->fs_mutex); | 646 | mutex_unlock(&root->fs_info->fs_mutex); |
647 | if (err) | ||
648 | return err; | ||
639 | } | 649 | } |
640 | out: | 650 | out: |
641 | err = inode_setattr(inode, attr); | 651 | err = inode_setattr(inode, attr); |
@@ -657,12 +667,20 @@ void btrfs_delete_inode(struct inode *inode) | |||
657 | trans = btrfs_start_transaction(root, 1); | 667 | trans = btrfs_start_transaction(root, 1); |
658 | btrfs_set_trans_block_group(trans, inode); | 668 | btrfs_set_trans_block_group(trans, inode); |
659 | ret = btrfs_truncate_in_trans(trans, root, inode); | 669 | ret = btrfs_truncate_in_trans(trans, root, inode); |
660 | BUG_ON(ret); | 670 | if (ret) |
661 | btrfs_free_inode(trans, root, inode); | 671 | goto no_delete_lock; |
672 | ret = btrfs_free_inode(trans, root, inode); | ||
673 | if (ret) | ||
674 | goto no_delete_lock; | ||
662 | btrfs_end_transaction(trans, root); | 675 | btrfs_end_transaction(trans, root); |
663 | mutex_unlock(&root->fs_info->fs_mutex); | 676 | mutex_unlock(&root->fs_info->fs_mutex); |
664 | btrfs_btree_balance_dirty(root); | 677 | btrfs_btree_balance_dirty(root); |
665 | return; | 678 | return; |
679 | |||
680 | no_delete_lock: | ||
681 | btrfs_end_transaction(trans, root); | ||
682 | mutex_unlock(&root->fs_info->fs_mutex); | ||
683 | btrfs_btree_balance_dirty(root); | ||
666 | no_delete: | 684 | no_delete: |
667 | clear_inode(inode); | 685 | clear_inode(inode); |
668 | } | 686 | } |
@@ -946,7 +964,7 @@ int btrfs_write_inode(struct inode *inode, int wait) | |||
946 | } | 964 | } |
947 | 965 | ||
948 | /* | 966 | /* |
949 | * This is somewhat expense, updating the tree every time the | 967 | * This is somewhat expensive, updating the tree every time the |
950 | * inode changes. But, it is most likely to find the inode in cache. | 968 | * inode changes. But, it is most likely to find the inode in cache. |
951 | * FIXME, needs more benchmarking...there are no reasons other than performance | 969 | * FIXME, needs more benchmarking...there are no reasons other than performance |
952 | * to keep or drop this code. | 970 | * to keep or drop this code. |
@@ -1002,8 +1020,8 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
1002 | btrfs_set_key_type(location, BTRFS_INODE_ITEM_KEY); | 1020 | btrfs_set_key_type(location, BTRFS_INODE_ITEM_KEY); |
1003 | 1021 | ||
1004 | ret = btrfs_insert_inode(trans, root, objectid, &inode_item); | 1022 | ret = btrfs_insert_inode(trans, root, objectid, &inode_item); |
1005 | BUG_ON(ret); | 1023 | if (ret) |
1006 | 1024 | return ERR_PTR(ret); | |
1007 | insert_inode_hash(inode); | 1025 | insert_inode_hash(inode); |
1008 | return inode; | 1026 | return inode; |
1009 | } | 1027 | } |
@@ -1121,7 +1139,9 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
1121 | drop_inode = 1; | 1139 | drop_inode = 1; |
1122 | dir->i_sb->s_dirt = 1; | 1140 | dir->i_sb->s_dirt = 1; |
1123 | btrfs_update_inode_block_group(trans, dir); | 1141 | btrfs_update_inode_block_group(trans, dir); |
1124 | btrfs_update_inode(trans, root, inode); | 1142 | err = btrfs_update_inode(trans, root, inode); |
1143 | if (err) | ||
1144 | drop_inode = 1; | ||
1125 | 1145 | ||
1126 | btrfs_end_transaction(trans, root); | 1146 | btrfs_end_transaction(trans, root); |
1127 | mutex_unlock(&root->fs_info->fs_mutex); | 1147 | mutex_unlock(&root->fs_info->fs_mutex); |
@@ -1349,17 +1369,26 @@ not_found: | |||
1349 | ret = btrfs_alloc_extent(trans, root, inode->i_ino, | 1369 | ret = btrfs_alloc_extent(trans, root, inode->i_ino, |
1350 | 1, alloc_hint, (u64)-1, | 1370 | 1, alloc_hint, (u64)-1, |
1351 | &ins, 1); | 1371 | &ins, 1); |
1352 | BUG_ON(ret); | 1372 | if (ret) { |
1373 | err = ret; | ||
1374 | goto out; | ||
1375 | } | ||
1353 | ret = btrfs_insert_file_extent(trans, root, inode->i_ino, | 1376 | ret = btrfs_insert_file_extent(trans, root, inode->i_ino, |
1354 | iblock << inode->i_blkbits, | 1377 | iblock << inode->i_blkbits, |
1355 | ins.objectid, ins.offset, | 1378 | ins.objectid, ins.offset, |
1356 | ins.offset); | 1379 | ins.offset); |
1357 | BUG_ON(ret); | 1380 | if (ret) { |
1381 | err = ret; | ||
1382 | goto out; | ||
1383 | } | ||
1358 | btrfs_map_bh_to_logical(root, result, ins.objectid); | 1384 | btrfs_map_bh_to_logical(root, result, ins.objectid); |
1359 | } | 1385 | } |
1360 | out: | 1386 | out: |
1361 | if (trans) | 1387 | if (trans) { |
1362 | err = btrfs_end_transaction(trans, root); | 1388 | ret = btrfs_end_transaction(trans, root); |
1389 | if (!err) | ||
1390 | err = ret; | ||
1391 | } | ||
1363 | btrfs_free_path(path); | 1392 | btrfs_free_path(path); |
1364 | return err; | 1393 | return err; |
1365 | } | 1394 | } |
@@ -1375,8 +1404,8 @@ int btrfs_get_block(struct inode *inode, sector_t iblock, | |||
1375 | return err; | 1404 | return err; |
1376 | } | 1405 | } |
1377 | 1406 | ||
1378 | int btrfs_get_block_csum(struct inode *inode, sector_t iblock, | 1407 | static int btrfs_get_block_csum(struct inode *inode, sector_t iblock, |
1379 | struct buffer_head *result, int create) | 1408 | struct buffer_head *result, int create) |
1380 | { | 1409 | { |
1381 | int ret; | 1410 | int ret; |
1382 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1411 | struct btrfs_root *root = BTRFS_I(inode)->root; |
@@ -1397,7 +1426,7 @@ int btrfs_get_block_csum(struct inode *inode, sector_t iblock, | |||
1397 | /* a csum that isn't present is a preallocated region. */ | 1426 | /* a csum that isn't present is a preallocated region. */ |
1398 | if (ret == -ENOENT || ret == -EFBIG) | 1427 | if (ret == -ENOENT || ret == -EFBIG) |
1399 | ret = 0; | 1428 | ret = 0; |
1400 | result->b_private = 0; | 1429 | result->b_private = NULL; |
1401 | goto out; | 1430 | goto out; |
1402 | } | 1431 | } |
1403 | memcpy((char *)&result->b_private, &item->csum, BTRFS_CRC32_SIZE); | 1432 | memcpy((char *)&result->b_private, &item->csum, BTRFS_CRC32_SIZE); |
@@ -1736,11 +1765,10 @@ static int __btrfs_write_full_page(struct inode *inode, struct page *page, | |||
1736 | trans = btrfs_start_transaction(root, 1); | 1765 | trans = btrfs_start_transaction(root, 1); |
1737 | btrfs_set_trans_block_group(trans, inode); | 1766 | btrfs_set_trans_block_group(trans, inode); |
1738 | kaddr = kmap(page); | 1767 | kaddr = kmap(page); |
1739 | ret = btrfs_csum_file_block(trans, root, inode->i_ino, | 1768 | btrfs_csum_file_block(trans, root, inode->i_ino, |
1740 | off, kaddr + bh_offset(bh), | 1769 | off, kaddr + bh_offset(bh), |
1741 | bh->b_size); | 1770 | bh->b_size); |
1742 | kunmap(page); | 1771 | kunmap(page); |
1743 | BUG_ON(ret); | ||
1744 | ret = btrfs_end_transaction(trans, root); | 1772 | ret = btrfs_end_transaction(trans, root); |
1745 | BUG_ON(ret); | 1773 | BUG_ON(ret); |
1746 | mutex_unlock(&root->fs_info->fs_mutex); | 1774 | mutex_unlock(&root->fs_info->fs_mutex); |
@@ -1930,7 +1958,6 @@ static void btrfs_truncate(struct inode *inode) | |||
1930 | 1958 | ||
1931 | /* FIXME, add redo link to tree so we don't leak on crash */ | 1959 | /* FIXME, add redo link to tree so we don't leak on crash */ |
1932 | ret = btrfs_truncate_in_trans(trans, root, inode); | 1960 | ret = btrfs_truncate_in_trans(trans, root, inode); |
1933 | BUG_ON(ret); | ||
1934 | btrfs_update_inode(trans, root, inode); | 1961 | btrfs_update_inode(trans, root, inode); |
1935 | ret = btrfs_end_transaction(trans, root); | 1962 | ret = btrfs_end_transaction(trans, root); |
1936 | BUG_ON(ret); | 1963 | BUG_ON(ret); |
@@ -1970,6 +1997,7 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen) | |||
1970 | struct inode *inode; | 1997 | struct inode *inode; |
1971 | struct inode *dir; | 1998 | struct inode *dir; |
1972 | int ret; | 1999 | int ret; |
2000 | int err; | ||
1973 | u64 objectid; | 2001 | u64 objectid; |
1974 | u64 new_dirid = BTRFS_FIRST_FREE_OBJECTID; | 2002 | u64 new_dirid = BTRFS_FIRST_FREE_OBJECTID; |
1975 | 2003 | ||
@@ -1978,8 +2006,8 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen) | |||
1978 | BUG_ON(!trans); | 2006 | BUG_ON(!trans); |
1979 | 2007 | ||
1980 | subvol = btrfs_alloc_free_block(trans, root, 0); | 2008 | subvol = btrfs_alloc_free_block(trans, root, 0); |
1981 | if (subvol == NULL) | 2009 | if (IS_ERR(subvol)) |
1982 | return -ENOSPC; | 2010 | return PTR_ERR(subvol); |
1983 | leaf = btrfs_buffer_leaf(subvol); | 2011 | leaf = btrfs_buffer_leaf(subvol); |
1984 | btrfs_set_header_nritems(&leaf->header, 0); | 2012 | btrfs_set_header_nritems(&leaf->header, 0); |
1985 | btrfs_set_header_level(&leaf->header, 0); | 2013 | btrfs_set_header_level(&leaf->header, 0); |
@@ -2005,7 +2033,8 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen) | |||
2005 | 2033 | ||
2006 | ret = btrfs_find_free_objectid(trans, root->fs_info->tree_root, | 2034 | ret = btrfs_find_free_objectid(trans, root->fs_info->tree_root, |
2007 | 0, &objectid); | 2035 | 0, &objectid); |
2008 | BUG_ON(ret); | 2036 | if (ret) |
2037 | goto fail; | ||
2009 | 2038 | ||
2010 | btrfs_set_root_dirid(&root_item, new_dirid); | 2039 | btrfs_set_root_dirid(&root_item, new_dirid); |
2011 | 2040 | ||
@@ -2015,7 +2044,8 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen) | |||
2015 | btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); | 2044 | btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); |
2016 | ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, | 2045 | ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, |
2017 | &root_item); | 2046 | &root_item); |
2018 | BUG_ON(ret); | 2047 | if (ret) |
2048 | goto fail; | ||
2019 | 2049 | ||
2020 | /* | 2050 | /* |
2021 | * insert the directory item | 2051 | * insert the directory item |
@@ -2025,10 +2055,12 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen) | |||
2025 | ret = btrfs_insert_dir_item(trans, root->fs_info->tree_root, | 2055 | ret = btrfs_insert_dir_item(trans, root->fs_info->tree_root, |
2026 | name, namelen, dir->i_ino, &key, | 2056 | name, namelen, dir->i_ino, &key, |
2027 | BTRFS_FT_DIR); | 2057 | BTRFS_FT_DIR); |
2028 | BUG_ON(ret); | 2058 | if (ret) |
2059 | goto fail; | ||
2029 | 2060 | ||
2030 | ret = btrfs_commit_transaction(trans, root); | 2061 | ret = btrfs_commit_transaction(trans, root); |
2031 | BUG_ON(ret); | 2062 | if (ret) |
2063 | goto fail_commit; | ||
2032 | 2064 | ||
2033 | new_root = btrfs_read_fs_root(root->fs_info, &key); | 2065 | new_root = btrfs_read_fs_root(root->fs_info, &key); |
2034 | BUG_ON(!new_root); | 2066 | BUG_ON(!new_root); |
@@ -2038,24 +2070,29 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen) | |||
2038 | 2070 | ||
2039 | inode = btrfs_new_inode(trans, new_root, new_dirid, | 2071 | inode = btrfs_new_inode(trans, new_root, new_dirid, |
2040 | BTRFS_I(dir)->block_group, S_IFDIR | 0700); | 2072 | BTRFS_I(dir)->block_group, S_IFDIR | 0700); |
2073 | if (IS_ERR(inode)) | ||
2074 | goto fail; | ||
2041 | inode->i_op = &btrfs_dir_inode_operations; | 2075 | inode->i_op = &btrfs_dir_inode_operations; |
2042 | inode->i_fop = &btrfs_dir_file_operations; | 2076 | inode->i_fop = &btrfs_dir_file_operations; |
2043 | new_root->inode = inode; | 2077 | new_root->inode = inode; |
2044 | 2078 | ||
2045 | ret = btrfs_make_empty_dir(trans, new_root, new_dirid, new_dirid); | 2079 | ret = btrfs_make_empty_dir(trans, new_root, new_dirid, new_dirid); |
2046 | BUG_ON(ret); | 2080 | if (ret) |
2081 | goto fail; | ||
2047 | 2082 | ||
2048 | inode->i_nlink = 1; | 2083 | inode->i_nlink = 1; |
2049 | inode->i_size = 6; | 2084 | inode->i_size = 6; |
2050 | ret = btrfs_update_inode(trans, new_root, inode); | 2085 | ret = btrfs_update_inode(trans, new_root, inode); |
2051 | BUG_ON(ret); | 2086 | if (ret) |
2052 | 2087 | goto fail; | |
2053 | ret = btrfs_commit_transaction(trans, new_root); | 2088 | fail: |
2054 | BUG_ON(ret); | 2089 | err = btrfs_commit_transaction(trans, root); |
2055 | 2090 | if (err && !ret) | |
2091 | ret = err; | ||
2092 | fail_commit: | ||
2056 | mutex_unlock(&root->fs_info->fs_mutex); | 2093 | mutex_unlock(&root->fs_info->fs_mutex); |
2057 | btrfs_btree_balance_dirty(root); | 2094 | btrfs_btree_balance_dirty(root); |
2058 | return 0; | 2095 | return ret; |
2059 | } | 2096 | } |
2060 | 2097 | ||
2061 | static int create_snapshot(struct btrfs_root *root, char *name, int namelen) | 2098 | static int create_snapshot(struct btrfs_root *root, char *name, int namelen) |
@@ -2064,6 +2101,7 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen) | |||
2064 | struct btrfs_key key; | 2101 | struct btrfs_key key; |
2065 | struct btrfs_root_item new_root_item; | 2102 | struct btrfs_root_item new_root_item; |
2066 | int ret; | 2103 | int ret; |
2104 | int err; | ||
2067 | u64 objectid; | 2105 | u64 objectid; |
2068 | 2106 | ||
2069 | if (!root->ref_cows) | 2107 | if (!root->ref_cows) |
@@ -2074,11 +2112,13 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen) | |||
2074 | BUG_ON(!trans); | 2112 | BUG_ON(!trans); |
2075 | 2113 | ||
2076 | ret = btrfs_update_inode(trans, root, root->inode); | 2114 | ret = btrfs_update_inode(trans, root, root->inode); |
2077 | BUG_ON(ret); | 2115 | if (ret) |
2116 | goto fail; | ||
2078 | 2117 | ||
2079 | ret = btrfs_find_free_objectid(trans, root->fs_info->tree_root, | 2118 | ret = btrfs_find_free_objectid(trans, root->fs_info->tree_root, |
2080 | 0, &objectid); | 2119 | 0, &objectid); |
2081 | BUG_ON(ret); | 2120 | if (ret) |
2121 | goto fail; | ||
2082 | 2122 | ||
2083 | memcpy(&new_root_item, &root->root_item, | 2123 | memcpy(&new_root_item, &root->root_item, |
2084 | sizeof(new_root_item)); | 2124 | sizeof(new_root_item)); |
@@ -2091,7 +2131,8 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen) | |||
2091 | 2131 | ||
2092 | ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, | 2132 | ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, |
2093 | &new_root_item); | 2133 | &new_root_item); |
2094 | BUG_ON(ret); | 2134 | if (ret) |
2135 | goto fail; | ||
2095 | 2136 | ||
2096 | /* | 2137 | /* |
2097 | * insert the directory item | 2138 | * insert the directory item |
@@ -2102,16 +2143,20 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen) | |||
2102 | root->fs_info->sb->s_root->d_inode->i_ino, | 2143 | root->fs_info->sb->s_root->d_inode->i_ino, |
2103 | &key, BTRFS_FT_DIR); | 2144 | &key, BTRFS_FT_DIR); |
2104 | 2145 | ||
2105 | BUG_ON(ret); | 2146 | if (ret) |
2147 | goto fail; | ||
2106 | 2148 | ||
2107 | ret = btrfs_inc_root_ref(trans, root); | 2149 | ret = btrfs_inc_root_ref(trans, root); |
2108 | BUG_ON(ret); | 2150 | if (ret) |
2151 | goto fail; | ||
2109 | 2152 | ||
2110 | ret = btrfs_commit_transaction(trans, root); | 2153 | fail: |
2111 | BUG_ON(ret); | 2154 | err = btrfs_commit_transaction(trans, root); |
2155 | if (err && !ret) | ||
2156 | ret = err; | ||
2112 | mutex_unlock(&root->fs_info->fs_mutex); | 2157 | mutex_unlock(&root->fs_info->fs_mutex); |
2113 | btrfs_btree_balance_dirty(root); | 2158 | btrfs_btree_balance_dirty(root); |
2114 | return 0; | 2159 | return ret; |
2115 | } | 2160 | } |
2116 | 2161 | ||
2117 | int btrfs_ioctl(struct inode *inode, struct file *filp, unsigned int | 2162 | int btrfs_ioctl(struct inode *inode, struct file *filp, unsigned int |
@@ -2148,12 +2193,13 @@ int btrfs_ioctl(struct inode *inode, struct file *filp, unsigned int | |||
2148 | btrfs_free_path(path); | 2193 | btrfs_free_path(path); |
2149 | if (di && !IS_ERR(di)) | 2194 | if (di && !IS_ERR(di)) |
2150 | return -EEXIST; | 2195 | return -EEXIST; |
2196 | if (IS_ERR(di)) | ||
2197 | return PTR_ERR(di); | ||
2151 | 2198 | ||
2152 | if (root == root->fs_info->tree_root) | 2199 | if (root == root->fs_info->tree_root) |
2153 | ret = create_subvol(root, vol_args.name, namelen); | 2200 | ret = create_subvol(root, vol_args.name, namelen); |
2154 | else | 2201 | else |
2155 | ret = create_snapshot(root, vol_args.name, namelen); | 2202 | ret = create_snapshot(root, vol_args.name, namelen); |
2156 | WARN_ON(ret); | ||
2157 | break; | 2203 | break; |
2158 | default: | 2204 | default: |
2159 | return -ENOTTY; | 2205 | return -ENOTTY; |
@@ -2316,7 +2362,6 @@ static int btrfs_rename(struct inode * old_dir, struct dentry *old_dentry, | |||
2316 | old_parent_oid = btrfs_disk_key_objectid(&di->location); | 2362 | old_parent_oid = btrfs_disk_key_objectid(&di->location); |
2317 | ret = btrfs_del_item(trans, root, path); | 2363 | ret = btrfs_del_item(trans, root, path); |
2318 | if (ret) { | 2364 | if (ret) { |
2319 | ret = -EIO; | ||
2320 | goto out_fail; | 2365 | goto out_fail; |
2321 | } | 2366 | } |
2322 | btrfs_release_path(root, path); | 2367 | btrfs_release_path(root, path); |
@@ -2335,7 +2380,6 @@ static int btrfs_rename(struct inode * old_dir, struct dentry *old_dentry, | |||
2335 | } | 2380 | } |
2336 | ret = btrfs_del_item(trans, root, path); | 2381 | ret = btrfs_del_item(trans, root, path); |
2337 | if (ret) { | 2382 | if (ret) { |
2338 | ret = -EIO; | ||
2339 | goto out_fail; | 2383 | goto out_fail; |
2340 | } | 2384 | } |
2341 | btrfs_release_path(root, path); | 2385 | btrfs_release_path(root, path); |
@@ -2361,7 +2405,9 @@ static int btrfs_rename(struct inode * old_dir, struct dentry *old_dentry, | |||
2361 | clear_nlink(new_inode); | 2405 | clear_nlink(new_inode); |
2362 | else | 2406 | else |
2363 | drop_nlink(new_inode); | 2407 | drop_nlink(new_inode); |
2364 | btrfs_update_inode(trans, root, new_inode); | 2408 | ret = btrfs_update_inode(trans, root, new_inode); |
2409 | if (ret) | ||
2410 | goto out_fail; | ||
2365 | } | 2411 | } |
2366 | ret = btrfs_add_link(trans, new_dentry, old_inode); | 2412 | ret = btrfs_add_link(trans, new_dentry, old_inode); |
2367 | if (ret) | 2413 | if (ret) |
@@ -2433,7 +2479,10 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
2433 | datasize = btrfs_file_extent_calc_inline_size(name_len); | 2479 | datasize = btrfs_file_extent_calc_inline_size(name_len); |
2434 | err = btrfs_insert_empty_item(trans, root, path, &key, | 2480 | err = btrfs_insert_empty_item(trans, root, path, &key, |
2435 | datasize); | 2481 | datasize); |
2436 | BUG_ON(err); | 2482 | if (err) { |
2483 | drop_inode = 1; | ||
2484 | goto out_unlock; | ||
2485 | } | ||
2437 | ei = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), | 2486 | ei = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), |
2438 | path->slots[0], struct btrfs_file_extent_item); | 2487 | path->slots[0], struct btrfs_file_extent_item); |
2439 | btrfs_set_file_extent_generation(ei, trans->transid); | 2488 | btrfs_set_file_extent_generation(ei, trans->transid); |
@@ -2447,13 +2496,13 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
2447 | inode->i_op = &btrfs_symlink_inode_operations; | 2496 | inode->i_op = &btrfs_symlink_inode_operations; |
2448 | inode->i_mapping->a_ops = &btrfs_symlink_aops; | 2497 | inode->i_mapping->a_ops = &btrfs_symlink_aops; |
2449 | inode->i_size = name_len - 1; | 2498 | inode->i_size = name_len - 1; |
2450 | btrfs_update_inode(trans, root, inode); | 2499 | err = btrfs_update_inode(trans, root, inode); |
2451 | err = 0; | 2500 | if (err) |
2501 | drop_inode = 1; | ||
2452 | 2502 | ||
2453 | out_unlock: | 2503 | out_unlock: |
2454 | btrfs_end_transaction(trans, root); | 2504 | btrfs_end_transaction(trans, root); |
2455 | mutex_unlock(&root->fs_info->fs_mutex); | 2505 | mutex_unlock(&root->fs_info->fs_mutex); |
2456 | |||
2457 | if (drop_inode) { | 2506 | if (drop_inode) { |
2458 | inode_dec_link_count(inode); | 2507 | inode_dec_link_count(inode); |
2459 | iput(inode); | 2508 | iput(inode); |