summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/tree-log.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/tree-log.c')
-rw-r--r--fs/btrfs/tree-log.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 4a04659fded7..6c8297bcfeb7 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -3323,6 +3323,30 @@ int btrfs_free_log_root_tree(struct btrfs_trans_handle *trans,
3323} 3323}
3324 3324
3325/* 3325/*
3326 * Check if an inode was logged in the current transaction. We can't always rely
3327 * on an inode's logged_trans value, because it's an in-memory only field and
3328 * therefore not persisted. This means that its value is lost if the inode gets
3329 * evicted and loaded again from disk (in which case it has a value of 0, and
3330 * certainly it is smaller then any possible transaction ID), when that happens
3331 * the full_sync flag is set in the inode's runtime flags, so on that case we
3332 * assume eviction happened and ignore the logged_trans value, assuming the
3333 * worst case, that the inode was logged before in the current transaction.
3334 */
3335static bool inode_logged(struct btrfs_trans_handle *trans,
3336 struct btrfs_inode *inode)
3337{
3338 if (inode->logged_trans == trans->transid)
3339 return true;
3340
3341 if (inode->last_trans == trans->transid &&
3342 test_bit(BTRFS_INODE_NEEDS_FULL_SYNC, &inode->runtime_flags) &&
3343 !test_bit(BTRFS_FS_LOG_RECOVERING, &trans->fs_info->flags))
3344 return true;
3345
3346 return false;
3347}
3348
3349/*
3326 * If both a file and directory are logged, and unlinks or renames are 3350 * If both a file and directory are logged, and unlinks or renames are
3327 * mixed in, we have a few interesting corners: 3351 * mixed in, we have a few interesting corners:
3328 * 3352 *
@@ -3356,7 +3380,7 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans,
3356 int bytes_del = 0; 3380 int bytes_del = 0;
3357 u64 dir_ino = btrfs_ino(dir); 3381 u64 dir_ino = btrfs_ino(dir);
3358 3382
3359 if (dir->logged_trans < trans->transid) 3383 if (!inode_logged(trans, dir))
3360 return 0; 3384 return 0;
3361 3385
3362 ret = join_running_log_trans(root); 3386 ret = join_running_log_trans(root);
@@ -3460,7 +3484,7 @@ int btrfs_del_inode_ref_in_log(struct btrfs_trans_handle *trans,
3460 u64 index; 3484 u64 index;
3461 int ret; 3485 int ret;
3462 3486
3463 if (inode->logged_trans < trans->transid) 3487 if (!inode_logged(trans, inode))
3464 return 0; 3488 return 0;
3465 3489
3466 ret = join_running_log_trans(root); 3490 ret = join_running_log_trans(root);