aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/transaction.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r--fs/btrfs/transaction.c64
1 files changed, 55 insertions, 9 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 0b8f36d4400a..c207e8c32c9b 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -163,8 +163,14 @@ static void wait_current_trans(struct btrfs_root *root)
163 } 163 }
164} 164}
165 165
166enum btrfs_trans_type {
167 TRANS_START,
168 TRANS_JOIN,
169 TRANS_USERSPACE,
170};
171
166static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root, 172static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
167 int num_blocks, int wait) 173 int num_blocks, int type)
168{ 174{
169 struct btrfs_trans_handle *h = 175 struct btrfs_trans_handle *h =
170 kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS); 176 kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS);
@@ -172,7 +178,8 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
172 178
173 mutex_lock(&root->fs_info->trans_mutex); 179 mutex_lock(&root->fs_info->trans_mutex);
174 if (!root->fs_info->log_root_recovering && 180 if (!root->fs_info->log_root_recovering &&
175 ((wait == 1 && !root->fs_info->open_ioctl_trans) || wait == 2)) 181 ((type == TRANS_START && !root->fs_info->open_ioctl_trans) ||
182 type == TRANS_USERSPACE))
176 wait_current_trans(root); 183 wait_current_trans(root);
177 ret = join_transaction(root); 184 ret = join_transaction(root);
178 BUG_ON(ret); 185 BUG_ON(ret);
@@ -186,7 +193,7 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
186 h->alloc_exclude_start = 0; 193 h->alloc_exclude_start = 0;
187 h->delayed_ref_updates = 0; 194 h->delayed_ref_updates = 0;
188 195
189 if (!current->journal_info) 196 if (!current->journal_info && type != TRANS_USERSPACE)
190 current->journal_info = h; 197 current->journal_info = h;
191 198
192 root->fs_info->running_transaction->use_count++; 199 root->fs_info->running_transaction->use_count++;
@@ -198,18 +205,18 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
198struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root, 205struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
199 int num_blocks) 206 int num_blocks)
200{ 207{
201 return start_transaction(root, num_blocks, 1); 208 return start_transaction(root, num_blocks, TRANS_START);
202} 209}
203struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root, 210struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root,
204 int num_blocks) 211 int num_blocks)
205{ 212{
206 return start_transaction(root, num_blocks, 0); 213 return start_transaction(root, num_blocks, TRANS_JOIN);
207} 214}
208 215
209struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *r, 216struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *r,
210 int num_blocks) 217 int num_blocks)
211{ 218{
212 return start_transaction(r, num_blocks, 2); 219 return start_transaction(r, num_blocks, TRANS_USERSPACE);
213} 220}
214 221
215/* wait for a transaction commit to be fully complete */ 222/* wait for a transaction commit to be fully complete */
@@ -344,10 +351,10 @@ int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans,
344/* 351/*
345 * when btree blocks are allocated, they have some corresponding bits set for 352 * when btree blocks are allocated, they have some corresponding bits set for
346 * them in one of two extent_io trees. This is used to make sure all of 353 * them in one of two extent_io trees. This is used to make sure all of
347 * those extents are on disk for transaction or log commit 354 * those extents are sent to disk but does not wait on them
348 */ 355 */
349int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, 356int btrfs_write_marked_extents(struct btrfs_root *root,
350 struct extent_io_tree *dirty_pages) 357 struct extent_io_tree *dirty_pages)
351{ 358{
352 int ret; 359 int ret;
353 int err = 0; 360 int err = 0;
@@ -394,6 +401,29 @@ int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
394 page_cache_release(page); 401 page_cache_release(page);
395 } 402 }
396 } 403 }
404 if (err)
405 werr = err;
406 return werr;
407}
408
409/*
410 * when btree blocks are allocated, they have some corresponding bits set for
411 * them in one of two extent_io trees. This is used to make sure all of
412 * those extents are on disk for transaction or log commit. We wait
413 * on all the pages and clear them from the dirty pages state tree
414 */
415int btrfs_wait_marked_extents(struct btrfs_root *root,
416 struct extent_io_tree *dirty_pages)
417{
418 int ret;
419 int err = 0;
420 int werr = 0;
421 struct page *page;
422 struct inode *btree_inode = root->fs_info->btree_inode;
423 u64 start = 0;
424 u64 end;
425 unsigned long index;
426
397 while (1) { 427 while (1) {
398 ret = find_first_extent_bit(dirty_pages, 0, &start, &end, 428 ret = find_first_extent_bit(dirty_pages, 0, &start, &end,
399 EXTENT_DIRTY); 429 EXTENT_DIRTY);
@@ -424,6 +454,22 @@ int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
424 return werr; 454 return werr;
425} 455}
426 456
457/*
458 * when btree blocks are allocated, they have some corresponding bits set for
459 * them in one of two extent_io trees. This is used to make sure all of
460 * those extents are on disk for transaction or log commit
461 */
462int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
463 struct extent_io_tree *dirty_pages)
464{
465 int ret;
466 int ret2;
467
468 ret = btrfs_write_marked_extents(root, dirty_pages);
469 ret2 = btrfs_wait_marked_extents(root, dirty_pages);
470 return ret || ret2;
471}
472
427int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, 473int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
428 struct btrfs_root *root) 474 struct btrfs_root *root)
429{ 475{