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 ---