diff options
Diffstat (limited to 'fs/btrfs/tree-log.c')
-rw-r--r-- | fs/btrfs/tree-log.c | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 1650dc44a5e3..3c2ae0e4f25a 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -6025,14 +6025,25 @@ void btrfs_record_snapshot_destroy(struct btrfs_trans_handle *trans, | |||
6025 | * Call this after adding a new name for a file and it will properly | 6025 | * Call this after adding a new name for a file and it will properly |
6026 | * update the log to reflect the new name. | 6026 | * update the log to reflect the new name. |
6027 | * | 6027 | * |
6028 | * It will return zero if all goes well, and it will return 1 if a | 6028 | * @ctx can not be NULL when @sync_log is false, and should be NULL when it's |
6029 | * full transaction commit is required. | 6029 | * true (because it's not used). |
6030 | * | ||
6031 | * Return value depends on whether @sync_log is true or false. | ||
6032 | * When true: returns BTRFS_NEED_TRANS_COMMIT if the transaction needs to be | ||
6033 | * committed by the caller, and BTRFS_DONT_NEED_TRANS_COMMIT | ||
6034 | * otherwise. | ||
6035 | * When false: returns BTRFS_DONT_NEED_LOG_SYNC if the caller does not need to | ||
6036 | * to sync the log, BTRFS_NEED_LOG_SYNC if it needs to sync the log, | ||
6037 | * or BTRFS_NEED_TRANS_COMMIT if the transaction needs to be | ||
6038 | * committed (without attempting to sync the log). | ||
6030 | */ | 6039 | */ |
6031 | int btrfs_log_new_name(struct btrfs_trans_handle *trans, | 6040 | int btrfs_log_new_name(struct btrfs_trans_handle *trans, |
6032 | struct btrfs_inode *inode, struct btrfs_inode *old_dir, | 6041 | struct btrfs_inode *inode, struct btrfs_inode *old_dir, |
6033 | struct dentry *parent) | 6042 | struct dentry *parent, |
6043 | bool sync_log, struct btrfs_log_ctx *ctx) | ||
6034 | { | 6044 | { |
6035 | struct btrfs_fs_info *fs_info = trans->fs_info; | 6045 | struct btrfs_fs_info *fs_info = trans->fs_info; |
6046 | int ret; | ||
6036 | 6047 | ||
6037 | /* | 6048 | /* |
6038 | * this will force the logging code to walk the dentry chain | 6049 | * this will force the logging code to walk the dentry chain |
@@ -6047,9 +6058,34 @@ int btrfs_log_new_name(struct btrfs_trans_handle *trans, | |||
6047 | */ | 6058 | */ |
6048 | if (inode->logged_trans <= fs_info->last_trans_committed && | 6059 | if (inode->logged_trans <= fs_info->last_trans_committed && |
6049 | (!old_dir || old_dir->logged_trans <= fs_info->last_trans_committed)) | 6060 | (!old_dir || old_dir->logged_trans <= fs_info->last_trans_committed)) |
6050 | return 0; | 6061 | return sync_log ? BTRFS_DONT_NEED_TRANS_COMMIT : |
6062 | BTRFS_DONT_NEED_LOG_SYNC; | ||
6063 | |||
6064 | if (sync_log) { | ||
6065 | struct btrfs_log_ctx ctx2; | ||
6066 | |||
6067 | btrfs_init_log_ctx(&ctx2, &inode->vfs_inode); | ||
6068 | ret = btrfs_log_inode_parent(trans, inode, parent, 0, LLONG_MAX, | ||
6069 | LOG_INODE_EXISTS, &ctx2); | ||
6070 | if (ret == BTRFS_NO_LOG_SYNC) | ||
6071 | return BTRFS_DONT_NEED_TRANS_COMMIT; | ||
6072 | else if (ret) | ||
6073 | return BTRFS_NEED_TRANS_COMMIT; | ||
6074 | |||
6075 | ret = btrfs_sync_log(trans, inode->root, &ctx2); | ||
6076 | if (ret) | ||
6077 | return BTRFS_NEED_TRANS_COMMIT; | ||
6078 | return BTRFS_DONT_NEED_TRANS_COMMIT; | ||
6079 | } | ||
6080 | |||
6081 | ASSERT(ctx); | ||
6082 | ret = btrfs_log_inode_parent(trans, inode, parent, 0, LLONG_MAX, | ||
6083 | LOG_INODE_EXISTS, ctx); | ||
6084 | if (ret == BTRFS_NO_LOG_SYNC) | ||
6085 | return BTRFS_DONT_NEED_LOG_SYNC; | ||
6086 | else if (ret) | ||
6087 | return BTRFS_NEED_TRANS_COMMIT; | ||
6051 | 6088 | ||
6052 | return btrfs_log_inode_parent(trans, inode, parent, 0, LLONG_MAX, | 6089 | return BTRFS_NEED_LOG_SYNC; |
6053 | LOG_INODE_EXISTS, NULL); | ||
6054 | } | 6090 | } |
6055 | 6091 | ||