aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/tree-log.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2010-08-06 13:13:54 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-08-06 13:13:54 -0400
commit11e4afb49b7fa1fc8e1ffd850c1806dd86a08204 (patch)
tree9e57efcb106ae912f7bec718feb3f8ec607559bb /fs/btrfs/tree-log.c
parent162500b3a3ff39d941d29db49b41a16667ae44f0 (diff)
parent9b2a606d3898fcb2eedb6faded3bb37549590ac4 (diff)
Merge branches 'gemini' and 'misc' into devel
Diffstat (limited to 'fs/btrfs/tree-log.c')
-rw-r--r--fs/btrfs/tree-log.c242
1 files changed, 152 insertions, 90 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 1255fcc8ade5..fb102a9aee9c 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -17,6 +17,7 @@
17 */ 17 */
18 18
19#include <linux/sched.h> 19#include <linux/sched.h>
20#include <linux/slab.h>
20#include "ctree.h" 21#include "ctree.h"
21#include "transaction.h" 22#include "transaction.h"
22#include "disk-io.h" 23#include "disk-io.h"
@@ -134,6 +135,7 @@ static int start_log_trans(struct btrfs_trans_handle *trans,
134 struct btrfs_root *root) 135 struct btrfs_root *root)
135{ 136{
136 int ret; 137 int ret;
138 int err = 0;
137 139
138 mutex_lock(&root->log_mutex); 140 mutex_lock(&root->log_mutex);
139 if (root->log_root) { 141 if (root->log_root) {
@@ -154,17 +156,19 @@ static int start_log_trans(struct btrfs_trans_handle *trans,
154 mutex_lock(&root->fs_info->tree_log_mutex); 156 mutex_lock(&root->fs_info->tree_log_mutex);
155 if (!root->fs_info->log_root_tree) { 157 if (!root->fs_info->log_root_tree) {
156 ret = btrfs_init_log_root_tree(trans, root->fs_info); 158 ret = btrfs_init_log_root_tree(trans, root->fs_info);
157 BUG_ON(ret); 159 if (ret)
160 err = ret;
158 } 161 }
159 if (!root->log_root) { 162 if (err == 0 && !root->log_root) {
160 ret = btrfs_add_log_tree(trans, root); 163 ret = btrfs_add_log_tree(trans, root);
161 BUG_ON(ret); 164 if (ret)
165 err = ret;
162 } 166 }
163 mutex_unlock(&root->fs_info->tree_log_mutex); 167 mutex_unlock(&root->fs_info->tree_log_mutex);
164 root->log_batch++; 168 root->log_batch++;
165 atomic_inc(&root->log_writers); 169 atomic_inc(&root->log_writers);
166 mutex_unlock(&root->log_mutex); 170 mutex_unlock(&root->log_mutex);
167 return 0; 171 return err;
168} 172}
169 173
170/* 174/*
@@ -375,7 +379,7 @@ insert:
375 BUG_ON(ret); 379 BUG_ON(ret);
376 } 380 }
377 } else if (ret) { 381 } else if (ret) {
378 BUG(); 382 return ret;
379 } 383 }
380 dst_ptr = btrfs_item_ptr_offset(path->nodes[0], 384 dst_ptr = btrfs_item_ptr_offset(path->nodes[0],
381 path->slots[0]); 385 path->slots[0]);
@@ -1698,9 +1702,9 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,
1698 1702
1699 next = btrfs_find_create_tree_block(root, bytenr, blocksize); 1703 next = btrfs_find_create_tree_block(root, bytenr, blocksize);
1700 1704
1701 wc->process_func(root, next, wc, ptr_gen);
1702
1703 if (*level == 1) { 1705 if (*level == 1) {
1706 wc->process_func(root, next, wc, ptr_gen);
1707
1704 path->slots[*level]++; 1708 path->slots[*level]++;
1705 if (wc->free) { 1709 if (wc->free) {
1706 btrfs_read_buffer(next, ptr_gen); 1710 btrfs_read_buffer(next, ptr_gen);
@@ -1733,35 +1737,7 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,
1733 WARN_ON(*level < 0); 1737 WARN_ON(*level < 0);
1734 WARN_ON(*level >= BTRFS_MAX_LEVEL); 1738 WARN_ON(*level >= BTRFS_MAX_LEVEL);
1735 1739
1736 if (path->nodes[*level] == root->node) 1740 path->slots[*level] = btrfs_header_nritems(path->nodes[*level]);
1737 parent = path->nodes[*level];
1738 else
1739 parent = path->nodes[*level + 1];
1740
1741 bytenr = path->nodes[*level]->start;
1742
1743 blocksize = btrfs_level_size(root, *level);
1744 root_owner = btrfs_header_owner(parent);
1745 root_gen = btrfs_header_generation(parent);
1746
1747 wc->process_func(root, path->nodes[*level], wc,
1748 btrfs_header_generation(path->nodes[*level]));
1749
1750 if (wc->free) {
1751 next = path->nodes[*level];
1752 btrfs_tree_lock(next);
1753 clean_tree_block(trans, root, next);
1754 btrfs_set_lock_blocking(next);
1755 btrfs_wait_tree_block_writeback(next);
1756 btrfs_tree_unlock(next);
1757
1758 WARN_ON(root_owner != BTRFS_TREE_LOG_OBJECTID);
1759 ret = btrfs_free_reserved_extent(root, bytenr, blocksize);
1760 BUG_ON(ret);
1761 }
1762 free_extent_buffer(path->nodes[*level]);
1763 path->nodes[*level] = NULL;
1764 *level += 1;
1765 1741
1766 cond_resched(); 1742 cond_resched();
1767 return 0; 1743 return 0;
@@ -1780,7 +1756,7 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans,
1780 1756
1781 for (i = *level; i < BTRFS_MAX_LEVEL - 1 && path->nodes[i]; i++) { 1757 for (i = *level; i < BTRFS_MAX_LEVEL - 1 && path->nodes[i]; i++) {
1782 slot = path->slots[i]; 1758 slot = path->slots[i];
1783 if (slot < btrfs_header_nritems(path->nodes[i]) - 1) { 1759 if (slot + 1 < btrfs_header_nritems(path->nodes[i])) {
1784 struct extent_buffer *node; 1760 struct extent_buffer *node;
1785 node = path->nodes[i]; 1761 node = path->nodes[i];
1786 path->slots[i]++; 1762 path->slots[i]++;
@@ -2046,7 +2022,6 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
2046 mutex_unlock(&log_root_tree->log_mutex); 2022 mutex_unlock(&log_root_tree->log_mutex);
2047 2023
2048 ret = update_log_root(trans, log); 2024 ret = update_log_root(trans, log);
2049 BUG_ON(ret);
2050 2025
2051 mutex_lock(&log_root_tree->log_mutex); 2026 mutex_lock(&log_root_tree->log_mutex);
2052 if (atomic_dec_and_test(&log_root_tree->log_writers)) { 2027 if (atomic_dec_and_test(&log_root_tree->log_writers)) {
@@ -2055,6 +2030,15 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
2055 wake_up(&log_root_tree->log_writer_wait); 2030 wake_up(&log_root_tree->log_writer_wait);
2056 } 2031 }
2057 2032
2033 if (ret) {
2034 BUG_ON(ret != -ENOSPC);
2035 root->fs_info->last_trans_log_full_commit = trans->transid;
2036 btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
2037 mutex_unlock(&log_root_tree->log_mutex);
2038 ret = -EAGAIN;
2039 goto out;
2040 }
2041
2058 index2 = log_root_tree->log_transid % 2; 2042 index2 = log_root_tree->log_transid % 2;
2059 if (atomic_read(&log_root_tree->log_commit[index2])) { 2043 if (atomic_read(&log_root_tree->log_commit[index2])) {
2060 btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); 2044 btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
@@ -2128,15 +2112,10 @@ out:
2128 return 0; 2112 return 0;
2129} 2113}
2130 2114
2131/* 2115static void free_log_tree(struct btrfs_trans_handle *trans,
2132 * free all the extents used by the tree log. This should be called 2116 struct btrfs_root *log)
2133 * at commit time of the full transaction
2134 */
2135int btrfs_free_log(struct btrfs_trans_handle *trans, struct btrfs_root *root)
2136{ 2117{
2137 int ret; 2118 int ret;
2138 struct btrfs_root *log;
2139 struct key;
2140 u64 start; 2119 u64 start;
2141 u64 end; 2120 u64 end;
2142 struct walk_control wc = { 2121 struct walk_control wc = {
@@ -2144,10 +2123,6 @@ int btrfs_free_log(struct btrfs_trans_handle *trans, struct btrfs_root *root)
2144 .process_func = process_one_buffer 2123 .process_func = process_one_buffer
2145 }; 2124 };
2146 2125
2147 if (!root->log_root || root->fs_info->log_root_recovering)
2148 return 0;
2149
2150 log = root->log_root;
2151 ret = walk_log_tree(trans, log, &wc); 2126 ret = walk_log_tree(trans, log, &wc);
2152 BUG_ON(ret); 2127 BUG_ON(ret);
2153 2128
@@ -2161,14 +2136,30 @@ int btrfs_free_log(struct btrfs_trans_handle *trans, struct btrfs_root *root)
2161 EXTENT_DIRTY | EXTENT_NEW, GFP_NOFS); 2136 EXTENT_DIRTY | EXTENT_NEW, GFP_NOFS);
2162 } 2137 }
2163 2138
2164 if (log->log_transid > 0) {
2165 ret = btrfs_del_root(trans, root->fs_info->log_root_tree,
2166 &log->root_key);
2167 BUG_ON(ret);
2168 }
2169 root->log_root = NULL;
2170 free_extent_buffer(log->node); 2139 free_extent_buffer(log->node);
2171 kfree(log); 2140 kfree(log);
2141}
2142
2143/*
2144 * free all the extents used by the tree log. This should be called
2145 * at commit time of the full transaction
2146 */
2147int btrfs_free_log(struct btrfs_trans_handle *trans, struct btrfs_root *root)
2148{
2149 if (root->log_root) {
2150 free_log_tree(trans, root->log_root);
2151 root->log_root = NULL;
2152 }
2153 return 0;
2154}
2155
2156int btrfs_free_log_root_tree(struct btrfs_trans_handle *trans,
2157 struct btrfs_fs_info *fs_info)
2158{
2159 if (fs_info->log_root_tree) {
2160 free_log_tree(trans, fs_info->log_root_tree);
2161 fs_info->log_root_tree = NULL;
2162 }
2172 return 0; 2163 return 0;
2173} 2164}
2174 2165
@@ -2202,6 +2193,7 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans,
2202 struct btrfs_dir_item *di; 2193 struct btrfs_dir_item *di;
2203 struct btrfs_path *path; 2194 struct btrfs_path *path;
2204 int ret; 2195 int ret;
2196 int err = 0;
2205 int bytes_del = 0; 2197 int bytes_del = 0;
2206 2198
2207 if (BTRFS_I(dir)->logged_trans < trans->transid) 2199 if (BTRFS_I(dir)->logged_trans < trans->transid)
@@ -2217,7 +2209,11 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans,
2217 path = btrfs_alloc_path(); 2209 path = btrfs_alloc_path();
2218 di = btrfs_lookup_dir_item(trans, log, path, dir->i_ino, 2210 di = btrfs_lookup_dir_item(trans, log, path, dir->i_ino,
2219 name, name_len, -1); 2211 name, name_len, -1);
2220 if (di && !IS_ERR(di)) { 2212 if (IS_ERR(di)) {
2213 err = PTR_ERR(di);
2214 goto fail;
2215 }
2216 if (di) {
2221 ret = btrfs_delete_one_dir_name(trans, log, path, di); 2217 ret = btrfs_delete_one_dir_name(trans, log, path, di);
2222 bytes_del += name_len; 2218 bytes_del += name_len;
2223 BUG_ON(ret); 2219 BUG_ON(ret);
@@ -2225,7 +2221,11 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans,
2225 btrfs_release_path(log, path); 2221 btrfs_release_path(log, path);
2226 di = btrfs_lookup_dir_index_item(trans, log, path, dir->i_ino, 2222 di = btrfs_lookup_dir_index_item(trans, log, path, dir->i_ino,
2227 index, name, name_len, -1); 2223 index, name, name_len, -1);
2228 if (di && !IS_ERR(di)) { 2224 if (IS_ERR(di)) {
2225 err = PTR_ERR(di);
2226 goto fail;
2227 }
2228 if (di) {
2229 ret = btrfs_delete_one_dir_name(trans, log, path, di); 2229 ret = btrfs_delete_one_dir_name(trans, log, path, di);
2230 bytes_del += name_len; 2230 bytes_del += name_len;
2231 BUG_ON(ret); 2231 BUG_ON(ret);
@@ -2243,6 +2243,10 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans,
2243 btrfs_release_path(log, path); 2243 btrfs_release_path(log, path);
2244 2244
2245 ret = btrfs_search_slot(trans, log, &key, path, 0, 1); 2245 ret = btrfs_search_slot(trans, log, &key, path, 0, 1);
2246 if (ret < 0) {
2247 err = ret;
2248 goto fail;
2249 }
2246 if (ret == 0) { 2250 if (ret == 0) {
2247 struct btrfs_inode_item *item; 2251 struct btrfs_inode_item *item;
2248 u64 i_size; 2252 u64 i_size;
@@ -2260,9 +2264,13 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans,
2260 ret = 0; 2264 ret = 0;
2261 btrfs_release_path(log, path); 2265 btrfs_release_path(log, path);
2262 } 2266 }
2263 2267fail:
2264 btrfs_free_path(path); 2268 btrfs_free_path(path);
2265 mutex_unlock(&BTRFS_I(dir)->log_mutex); 2269 mutex_unlock(&BTRFS_I(dir)->log_mutex);
2270 if (ret == -ENOSPC) {
2271 root->fs_info->last_trans_log_full_commit = trans->transid;
2272 ret = 0;
2273 }
2266 btrfs_end_log_trans(root); 2274 btrfs_end_log_trans(root);
2267 2275
2268 return 0; 2276 return 0;
@@ -2290,6 +2298,10 @@ int btrfs_del_inode_ref_in_log(struct btrfs_trans_handle *trans,
2290 ret = btrfs_del_inode_ref(trans, log, name, name_len, inode->i_ino, 2298 ret = btrfs_del_inode_ref(trans, log, name, name_len, inode->i_ino,
2291 dirid, &index); 2299 dirid, &index);
2292 mutex_unlock(&BTRFS_I(inode)->log_mutex); 2300 mutex_unlock(&BTRFS_I(inode)->log_mutex);
2301 if (ret == -ENOSPC) {
2302 root->fs_info->last_trans_log_full_commit = trans->transid;
2303 ret = 0;
2304 }
2293 btrfs_end_log_trans(root); 2305 btrfs_end_log_trans(root);
2294 2306
2295 return ret; 2307 return ret;
@@ -2317,7 +2329,8 @@ static noinline int insert_dir_log_key(struct btrfs_trans_handle *trans,
2317 else 2329 else
2318 key.type = BTRFS_DIR_LOG_INDEX_KEY; 2330 key.type = BTRFS_DIR_LOG_INDEX_KEY;
2319 ret = btrfs_insert_empty_item(trans, log, path, &key, sizeof(*item)); 2331 ret = btrfs_insert_empty_item(trans, log, path, &key, sizeof(*item));
2320 BUG_ON(ret); 2332 if (ret)
2333 return ret;
2321 2334
2322 item = btrfs_item_ptr(path->nodes[0], path->slots[0], 2335 item = btrfs_item_ptr(path->nodes[0], path->slots[0],
2323 struct btrfs_dir_log_item); 2336 struct btrfs_dir_log_item);
@@ -2342,6 +2355,7 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans,
2342 struct btrfs_key max_key; 2355 struct btrfs_key max_key;
2343 struct btrfs_root *log = root->log_root; 2356 struct btrfs_root *log = root->log_root;
2344 struct extent_buffer *src; 2357 struct extent_buffer *src;
2358 int err = 0;
2345 int ret; 2359 int ret;
2346 int i; 2360 int i;
2347 int nritems; 2361 int nritems;
@@ -2404,6 +2418,10 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans,
2404 ret = overwrite_item(trans, log, dst_path, 2418 ret = overwrite_item(trans, log, dst_path,
2405 path->nodes[0], path->slots[0], 2419 path->nodes[0], path->slots[0],
2406 &tmp); 2420 &tmp);
2421 if (ret) {
2422 err = ret;
2423 goto done;
2424 }
2407 } 2425 }
2408 } 2426 }
2409 btrfs_release_path(root, path); 2427 btrfs_release_path(root, path);
@@ -2431,7 +2449,10 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans,
2431 goto done; 2449 goto done;
2432 ret = overwrite_item(trans, log, dst_path, src, i, 2450 ret = overwrite_item(trans, log, dst_path, src, i,
2433 &min_key); 2451 &min_key);
2434 BUG_ON(ret); 2452 if (ret) {
2453 err = ret;
2454 goto done;
2455 }
2435 } 2456 }
2436 path->slots[0] = nritems; 2457 path->slots[0] = nritems;
2437 2458
@@ -2453,22 +2474,30 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans,
2453 ret = overwrite_item(trans, log, dst_path, 2474 ret = overwrite_item(trans, log, dst_path,
2454 path->nodes[0], path->slots[0], 2475 path->nodes[0], path->slots[0],
2455 &tmp); 2476 &tmp);
2456 2477 if (ret)
2457 BUG_ON(ret); 2478 err = ret;
2458 last_offset = tmp.offset; 2479 else
2480 last_offset = tmp.offset;
2459 goto done; 2481 goto done;
2460 } 2482 }
2461 } 2483 }
2462done: 2484done:
2463 *last_offset_ret = last_offset;
2464 btrfs_release_path(root, path); 2485 btrfs_release_path(root, path);
2465 btrfs_release_path(log, dst_path); 2486 btrfs_release_path(log, dst_path);
2466 2487
2467 /* insert the log range keys to indicate where the log is valid */ 2488 if (err == 0) {
2468 ret = insert_dir_log_key(trans, log, path, key_type, inode->i_ino, 2489 *last_offset_ret = last_offset;
2469 first_offset, last_offset); 2490 /*
2470 BUG_ON(ret); 2491 * insert the log range keys to indicate where the log
2471 return 0; 2492 * is valid
2493 */
2494 ret = insert_dir_log_key(trans, log, path, key_type,
2495 inode->i_ino, first_offset,
2496 last_offset);
2497 if (ret)
2498 err = ret;
2499 }
2500 return err;
2472} 2501}
2473 2502
2474/* 2503/*
@@ -2500,7 +2529,8 @@ again:
2500 ret = log_dir_items(trans, root, inode, path, 2529 ret = log_dir_items(trans, root, inode, path,
2501 dst_path, key_type, min_key, 2530 dst_path, key_type, min_key,
2502 &max_key); 2531 &max_key);
2503 BUG_ON(ret); 2532 if (ret)
2533 return ret;
2504 if (max_key == (u64)-1) 2534 if (max_key == (u64)-1)
2505 break; 2535 break;
2506 min_key = max_key + 1; 2536 min_key = max_key + 1;
@@ -2534,8 +2564,8 @@ static int drop_objectid_items(struct btrfs_trans_handle *trans,
2534 2564
2535 while (1) { 2565 while (1) {
2536 ret = btrfs_search_slot(trans, log, &key, path, -1, 1); 2566 ret = btrfs_search_slot(trans, log, &key, path, -1, 1);
2537 2567 BUG_ON(ret == 0);
2538 if (ret != 1) 2568 if (ret < 0)
2539 break; 2569 break;
2540 2570
2541 if (path->slots[0] == 0) 2571 if (path->slots[0] == 0)
@@ -2553,7 +2583,7 @@ static int drop_objectid_items(struct btrfs_trans_handle *trans,
2553 btrfs_release_path(log, path); 2583 btrfs_release_path(log, path);
2554 } 2584 }
2555 btrfs_release_path(log, path); 2585 btrfs_release_path(log, path);
2556 return 0; 2586 return ret;
2557} 2587}
2558 2588
2559static noinline int copy_items(struct btrfs_trans_handle *trans, 2589static noinline int copy_items(struct btrfs_trans_handle *trans,
@@ -2586,7 +2616,10 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
2586 } 2616 }
2587 ret = btrfs_insert_empty_items(trans, log, dst_path, 2617 ret = btrfs_insert_empty_items(trans, log, dst_path,
2588 ins_keys, ins_sizes, nr); 2618 ins_keys, ins_sizes, nr);
2589 BUG_ON(ret); 2619 if (ret) {
2620 kfree(ins_data);
2621 return ret;
2622 }
2590 2623
2591 for (i = 0; i < nr; i++, dst_path->slots[0]++) { 2624 for (i = 0; i < nr; i++, dst_path->slots[0]++) {
2592 dst_offset = btrfs_item_ptr_offset(dst_path->nodes[0], 2625 dst_offset = btrfs_item_ptr_offset(dst_path->nodes[0],
@@ -2659,16 +2692,17 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
2659 * we have to do this after the loop above to avoid changing the 2692 * we have to do this after the loop above to avoid changing the
2660 * log tree while trying to change the log tree. 2693 * log tree while trying to change the log tree.
2661 */ 2694 */
2695 ret = 0;
2662 while (!list_empty(&ordered_sums)) { 2696 while (!list_empty(&ordered_sums)) {
2663 struct btrfs_ordered_sum *sums = list_entry(ordered_sums.next, 2697 struct btrfs_ordered_sum *sums = list_entry(ordered_sums.next,
2664 struct btrfs_ordered_sum, 2698 struct btrfs_ordered_sum,
2665 list); 2699 list);
2666 ret = btrfs_csum_file_blocks(trans, log, sums); 2700 if (!ret)
2667 BUG_ON(ret); 2701 ret = btrfs_csum_file_blocks(trans, log, sums);
2668 list_del(&sums->list); 2702 list_del(&sums->list);
2669 kfree(sums); 2703 kfree(sums);
2670 } 2704 }
2671 return 0; 2705 return ret;
2672} 2706}
2673 2707
2674/* log a single inode in the tree log. 2708/* log a single inode in the tree log.
@@ -2696,6 +2730,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
2696 struct btrfs_root *log = root->log_root; 2730 struct btrfs_root *log = root->log_root;
2697 struct extent_buffer *src = NULL; 2731 struct extent_buffer *src = NULL;
2698 u32 size; 2732 u32 size;
2733 int err = 0;
2699 int ret; 2734 int ret;
2700 int nritems; 2735 int nritems;
2701 int ins_start_slot = 0; 2736 int ins_start_slot = 0;
@@ -2738,7 +2773,10 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
2738 } else { 2773 } else {
2739 ret = btrfs_truncate_inode_items(trans, log, inode, 0, 0); 2774 ret = btrfs_truncate_inode_items(trans, log, inode, 0, 0);
2740 } 2775 }
2741 BUG_ON(ret); 2776 if (ret) {
2777 err = ret;
2778 goto out_unlock;
2779 }
2742 path->keep_locks = 1; 2780 path->keep_locks = 1;
2743 2781
2744 while (1) { 2782 while (1) {
@@ -2767,7 +2805,10 @@ again:
2767 2805
2768 ret = copy_items(trans, log, dst_path, src, ins_start_slot, 2806 ret = copy_items(trans, log, dst_path, src, ins_start_slot,
2769 ins_nr, inode_only); 2807 ins_nr, inode_only);
2770 BUG_ON(ret); 2808 if (ret) {
2809 err = ret;
2810 goto out_unlock;
2811 }
2771 ins_nr = 1; 2812 ins_nr = 1;
2772 ins_start_slot = path->slots[0]; 2813 ins_start_slot = path->slots[0];
2773next_slot: 2814next_slot:
@@ -2783,7 +2824,10 @@ next_slot:
2783 ret = copy_items(trans, log, dst_path, src, 2824 ret = copy_items(trans, log, dst_path, src,
2784 ins_start_slot, 2825 ins_start_slot,
2785 ins_nr, inode_only); 2826 ins_nr, inode_only);
2786 BUG_ON(ret); 2827 if (ret) {
2828 err = ret;
2829 goto out_unlock;
2830 }
2787 ins_nr = 0; 2831 ins_nr = 0;
2788 } 2832 }
2789 btrfs_release_path(root, path); 2833 btrfs_release_path(root, path);
@@ -2801,7 +2845,10 @@ next_slot:
2801 ret = copy_items(trans, log, dst_path, src, 2845 ret = copy_items(trans, log, dst_path, src,
2802 ins_start_slot, 2846 ins_start_slot,
2803 ins_nr, inode_only); 2847 ins_nr, inode_only);
2804 BUG_ON(ret); 2848 if (ret) {
2849 err = ret;
2850 goto out_unlock;
2851 }
2805 ins_nr = 0; 2852 ins_nr = 0;
2806 } 2853 }
2807 WARN_ON(ins_nr); 2854 WARN_ON(ins_nr);
@@ -2809,14 +2856,18 @@ next_slot:
2809 btrfs_release_path(root, path); 2856 btrfs_release_path(root, path);
2810 btrfs_release_path(log, dst_path); 2857 btrfs_release_path(log, dst_path);
2811 ret = log_directory_changes(trans, root, inode, path, dst_path); 2858 ret = log_directory_changes(trans, root, inode, path, dst_path);
2812 BUG_ON(ret); 2859 if (ret) {
2860 err = ret;
2861 goto out_unlock;
2862 }
2813 } 2863 }
2814 BTRFS_I(inode)->logged_trans = trans->transid; 2864 BTRFS_I(inode)->logged_trans = trans->transid;
2865out_unlock:
2815 mutex_unlock(&BTRFS_I(inode)->log_mutex); 2866 mutex_unlock(&BTRFS_I(inode)->log_mutex);
2816 2867
2817 btrfs_free_path(path); 2868 btrfs_free_path(path);
2818 btrfs_free_path(dst_path); 2869 btrfs_free_path(dst_path);
2819 return 0; 2870 return err;
2820} 2871}
2821 2872
2822/* 2873/*
@@ -2941,10 +2992,13 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
2941 goto end_no_trans; 2992 goto end_no_trans;
2942 } 2993 }
2943 2994
2944 start_log_trans(trans, root); 2995 ret = start_log_trans(trans, root);
2996 if (ret)
2997 goto end_trans;
2945 2998
2946 ret = btrfs_log_inode(trans, root, inode, inode_only); 2999 ret = btrfs_log_inode(trans, root, inode, inode_only);
2947 BUG_ON(ret); 3000 if (ret)
3001 goto end_trans;
2948 3002
2949 /* 3003 /*
2950 * for regular files, if its inode is already on disk, we don't 3004 * for regular files, if its inode is already on disk, we don't
@@ -2954,8 +3008,10 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
2954 */ 3008 */
2955 if (S_ISREG(inode->i_mode) && 3009 if (S_ISREG(inode->i_mode) &&
2956 BTRFS_I(inode)->generation <= last_committed && 3010 BTRFS_I(inode)->generation <= last_committed &&
2957 BTRFS_I(inode)->last_unlink_trans <= last_committed) 3011 BTRFS_I(inode)->last_unlink_trans <= last_committed) {
2958 goto no_parent; 3012 ret = 0;
3013 goto end_trans;
3014 }
2959 3015
2960 inode_only = LOG_INODE_EXISTS; 3016 inode_only = LOG_INODE_EXISTS;
2961 while (1) { 3017 while (1) {
@@ -2969,15 +3025,21 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
2969 if (BTRFS_I(inode)->generation > 3025 if (BTRFS_I(inode)->generation >
2970 root->fs_info->last_trans_committed) { 3026 root->fs_info->last_trans_committed) {
2971 ret = btrfs_log_inode(trans, root, inode, inode_only); 3027 ret = btrfs_log_inode(trans, root, inode, inode_only);
2972 BUG_ON(ret); 3028 if (ret)
3029 goto end_trans;
2973 } 3030 }
2974 if (IS_ROOT(parent)) 3031 if (IS_ROOT(parent))
2975 break; 3032 break;
2976 3033
2977 parent = parent->d_parent; 3034 parent = parent->d_parent;
2978 } 3035 }
2979no_parent:
2980 ret = 0; 3036 ret = 0;
3037end_trans:
3038 if (ret < 0) {
3039 BUG_ON(ret != -ENOSPC);
3040 root->fs_info->last_trans_log_full_commit = trans->transid;
3041 ret = 1;
3042 }
2981 btrfs_end_log_trans(root); 3043 btrfs_end_log_trans(root);
2982end_no_trans: 3044end_no_trans:
2983 return ret; 3045 return ret;
@@ -3019,7 +3081,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
3019 path = btrfs_alloc_path(); 3081 path = btrfs_alloc_path();
3020 BUG_ON(!path); 3082 BUG_ON(!path);
3021 3083
3022 trans = btrfs_start_transaction(fs_info->tree_root, 1); 3084 trans = btrfs_start_transaction(fs_info->tree_root, 0);
3023 3085
3024 wc.trans = trans; 3086 wc.trans = trans;
3025 wc.pin = 1; 3087 wc.pin = 1;