tree-log.c (e6b430f817ca7c44a083deab8c54ab8d56e99d54) | tree-log.c (fa4b8cb1738097586f49ec66cd3656cef47ac143) |
---|---|
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2008 Oracle. All rights reserved. 4 */ 5 6#include <linux/sched.h> 7#include <linux/slab.h> 8#include <linux/blkdev.h> --- 3604 unchanged lines hidden (view full) --- 3613 /* 3614 * If for some unexpected reason the last item's index is not greater 3615 * than the last index we logged, warn and force a transaction commit. 3616 */ 3617 if (WARN_ON(last_index <= inode->last_dir_index_offset)) 3618 ret = BTRFS_LOG_FORCE_COMMIT; 3619 else 3620 inode->last_dir_index_offset = last_index; | 1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2008 Oracle. All rights reserved. 4 */ 5 6#include <linux/sched.h> 7#include <linux/slab.h> 8#include <linux/blkdev.h> --- 3604 unchanged lines hidden (view full) --- 3613 /* 3614 * If for some unexpected reason the last item's index is not greater 3615 * than the last index we logged, warn and force a transaction commit. 3616 */ 3617 if (WARN_ON(last_index <= inode->last_dir_index_offset)) 3618 ret = BTRFS_LOG_FORCE_COMMIT; 3619 else 3620 inode->last_dir_index_offset = last_index; |
3621 3622 if (btrfs_get_first_dir_index_to_log(inode) == 0) 3623 btrfs_set_first_dir_index_to_log(inode, batch.keys[0].offset); |
|
3621out: 3622 kfree(ins_data); 3623 3624 return ret; 3625} 3626 3627static int process_dir_items_leaf(struct btrfs_trans_handle *trans, 3628 struct btrfs_inode *inode, --- 1742 unchanged lines hidden (view full) --- 5371 struct btrfs_log_ctx *ctx) 5372{ 5373 struct btrfs_root *root = start_inode->root; 5374 struct btrfs_fs_info *fs_info = root->fs_info; 5375 struct btrfs_path *path; 5376 LIST_HEAD(dir_list); 5377 struct btrfs_dir_list *dir_elem; 5378 u64 ino = btrfs_ino(start_inode); | 3624out: 3625 kfree(ins_data); 3626 3627 return ret; 3628} 3629 3630static int process_dir_items_leaf(struct btrfs_trans_handle *trans, 3631 struct btrfs_inode *inode, --- 1742 unchanged lines hidden (view full) --- 5374 struct btrfs_log_ctx *ctx) 5375{ 5376 struct btrfs_root *root = start_inode->root; 5377 struct btrfs_fs_info *fs_info = root->fs_info; 5378 struct btrfs_path *path; 5379 LIST_HEAD(dir_list); 5380 struct btrfs_dir_list *dir_elem; 5381 u64 ino = btrfs_ino(start_inode); |
5382 struct btrfs_inode *curr_inode = start_inode; |
|
5379 int ret = 0; 5380 5381 /* 5382 * If we are logging a new name, as part of a link or rename operation, 5383 * don't bother logging new dentries, as we just want to log the names 5384 * of an inode and that any new parents exist. 5385 */ 5386 if (ctx->logging_new_name) 5387 return 0; 5388 5389 path = btrfs_alloc_path(); 5390 if (!path) 5391 return -ENOMEM; 5392 | 5383 int ret = 0; 5384 5385 /* 5386 * If we are logging a new name, as part of a link or rename operation, 5387 * don't bother logging new dentries, as we just want to log the names 5388 * of an inode and that any new parents exist. 5389 */ 5390 if (ctx->logging_new_name) 5391 return 0; 5392 5393 path = btrfs_alloc_path(); 5394 if (!path) 5395 return -ENOMEM; 5396 |
5397 /* Pairs with btrfs_add_delayed_iput below. */ 5398 ihold(&curr_inode->vfs_inode); 5399 |
|
5393 while (true) { | 5400 while (true) { |
5401 struct inode *vfs_inode; |
|
5394 struct extent_buffer *leaf; 5395 struct btrfs_key min_key; | 5402 struct extent_buffer *leaf; 5403 struct btrfs_key min_key; |
5404 u64 next_index; |
|
5396 bool continue_curr_inode = true; 5397 int nritems; 5398 int i; 5399 5400 min_key.objectid = ino; 5401 min_key.type = BTRFS_DIR_INDEX_KEY; | 5405 bool continue_curr_inode = true; 5406 int nritems; 5407 int i; 5408 5409 min_key.objectid = ino; 5410 min_key.type = BTRFS_DIR_INDEX_KEY; |
5402 min_key.offset = 0; | 5411 min_key.offset = btrfs_get_first_dir_index_to_log(curr_inode); 5412 next_index = min_key.offset; |
5403again: | 5413again: |
5404 btrfs_release_path(path); | |
5405 ret = btrfs_search_forward(root, &min_key, path, trans->transid); 5406 if (ret < 0) { 5407 break; 5408 } else if (ret > 0) { 5409 ret = 0; 5410 goto next; 5411 } 5412 --- 8 unchanged lines hidden (view full) --- 5421 5422 btrfs_item_key_to_cpu(leaf, &min_key, i); 5423 if (min_key.objectid != ino || 5424 min_key.type != BTRFS_DIR_INDEX_KEY) { 5425 continue_curr_inode = false; 5426 break; 5427 } 5428 | 5414 ret = btrfs_search_forward(root, &min_key, path, trans->transid); 5415 if (ret < 0) { 5416 break; 5417 } else if (ret > 0) { 5418 ret = 0; 5419 goto next; 5420 } 5421 --- 8 unchanged lines hidden (view full) --- 5430 5431 btrfs_item_key_to_cpu(leaf, &min_key, i); 5432 if (min_key.objectid != ino || 5433 min_key.type != BTRFS_DIR_INDEX_KEY) { 5434 continue_curr_inode = false; 5435 break; 5436 } 5437 |
5438 next_index = min_key.offset + 1; 5439 |
|
5429 di = btrfs_item_ptr(leaf, i, struct btrfs_dir_item); 5430 type = btrfs_dir_ftype(leaf, di); 5431 if (btrfs_dir_transid(leaf, di) < trans->transid) 5432 continue; 5433 btrfs_dir_item_key_to_cpu(leaf, di, &di_key); 5434 if (di_key.type == BTRFS_ROOT_ITEM_KEY) 5435 continue; 5436 --- 24 unchanged lines hidden (view full) --- 5461 goto out; 5462 } 5463 dir_elem->ino = di_key.objectid; 5464 list_add_tail(&dir_elem->list, &dir_list); 5465 } 5466 break; 5467 } 5468 | 5440 di = btrfs_item_ptr(leaf, i, struct btrfs_dir_item); 5441 type = btrfs_dir_ftype(leaf, di); 5442 if (btrfs_dir_transid(leaf, di) < trans->transid) 5443 continue; 5444 btrfs_dir_item_key_to_cpu(leaf, di, &di_key); 5445 if (di_key.type == BTRFS_ROOT_ITEM_KEY) 5446 continue; 5447 --- 24 unchanged lines hidden (view full) --- 5472 goto out; 5473 } 5474 dir_elem->ino = di_key.objectid; 5475 list_add_tail(&dir_elem->list, &dir_list); 5476 } 5477 break; 5478 } 5479 |
5480 btrfs_release_path(path); 5481 |
|
5469 if (continue_curr_inode && min_key.offset < (u64)-1) { 5470 min_key.offset++; 5471 goto again; 5472 } 5473 5474next: | 5482 if (continue_curr_inode && min_key.offset < (u64)-1) { 5483 min_key.offset++; 5484 goto again; 5485 } 5486 5487next: |
5488 btrfs_set_first_dir_index_to_log(curr_inode, next_index); 5489 |
|
5475 if (list_empty(&dir_list)) 5476 break; 5477 5478 dir_elem = list_first_entry(&dir_list, struct btrfs_dir_list, list); 5479 ino = dir_elem->ino; 5480 list_del(&dir_elem->list); 5481 kfree(dir_elem); | 5490 if (list_empty(&dir_list)) 5491 break; 5492 5493 dir_elem = list_first_entry(&dir_list, struct btrfs_dir_list, list); 5494 ino = dir_elem->ino; 5495 list_del(&dir_elem->list); 5496 kfree(dir_elem); |
5497 5498 btrfs_add_delayed_iput(curr_inode); 5499 curr_inode = NULL; 5500 5501 vfs_inode = btrfs_iget(fs_info->sb, ino, root); 5502 if (IS_ERR(vfs_inode)) { 5503 ret = PTR_ERR(vfs_inode); 5504 break; 5505 } 5506 curr_inode = BTRFS_I(vfs_inode); |
|
5482 } 5483out: 5484 btrfs_free_path(path); | 5507 } 5508out: 5509 btrfs_free_path(path); |
5510 if (curr_inode) 5511 btrfs_add_delayed_iput(curr_inode); 5512 |
|
5485 if (ret) { 5486 struct btrfs_dir_list *next; 5487 5488 list_for_each_entry_safe(dir_elem, next, &dir_list, list) 5489 kfree(dir_elem); 5490 } 5491 5492 return ret; --- 2019 unchanged lines hidden --- | 5513 if (ret) { 5514 struct btrfs_dir_list *next; 5515 5516 list_for_each_entry_safe(dir_elem, next, &dir_list, list) 5517 kfree(dir_elem); 5518 } 5519 5520 return ret; --- 2019 unchanged lines hidden --- |