diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/btrfs/btrfs_inode.h | 3 | ||||
| -rw-r--r-- | fs/btrfs/file.c | 19 | ||||
| -rw-r--r-- | fs/btrfs/inode.c | 5 | ||||
| -rw-r--r-- | fs/btrfs/tree-log.c | 8 |
4 files changed, 29 insertions, 6 deletions
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index fcc8cf27e90..0577fda2168 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h | |||
| @@ -56,6 +56,9 @@ struct btrfs_inode { | |||
| 56 | * transid that last logged this inode | 56 | * transid that last logged this inode |
| 57 | */ | 57 | */ |
| 58 | u64 logged_trans; | 58 | u64 logged_trans; |
| 59 | |||
| 60 | /* trans that last made a change that should be fully fsync'd */ | ||
| 61 | u64 log_dirty_trans; | ||
| 59 | u64 delalloc_bytes; | 62 | u64 delalloc_bytes; |
| 60 | u64 disk_i_size; | 63 | u64 disk_i_size; |
| 61 | u32 flags; | 64 | u32 flags; |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 84ecf3ab851..58b329ddb42 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
| @@ -1061,7 +1061,9 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
| 1061 | } | 1061 | } |
| 1062 | mutex_unlock(&root->fs_info->trans_mutex); | 1062 | mutex_unlock(&root->fs_info->trans_mutex); |
| 1063 | 1063 | ||
| 1064 | root->fs_info->tree_log_batch++; | ||
| 1064 | filemap_fdatawait(inode->i_mapping); | 1065 | filemap_fdatawait(inode->i_mapping); |
| 1066 | root->fs_info->tree_log_batch++; | ||
| 1065 | 1067 | ||
| 1066 | /* | 1068 | /* |
| 1067 | * ok we haven't committed the transaction yet, lets do a commit | 1069 | * ok we haven't committed the transaction yet, lets do a commit |
| @@ -1076,14 +1078,29 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
| 1076 | } | 1078 | } |
| 1077 | 1079 | ||
| 1078 | ret = btrfs_log_dentry_safe(trans, root, file->f_dentry); | 1080 | ret = btrfs_log_dentry_safe(trans, root, file->f_dentry); |
| 1079 | if (ret < 0) | 1081 | if (ret < 0) { |
| 1080 | goto out; | 1082 | goto out; |
| 1083 | } | ||
| 1084 | |||
| 1085 | /* we've logged all the items and now have a consistent | ||
| 1086 | * version of the file in the log. It is possible that | ||
| 1087 | * someone will come in and modify the file, but that's | ||
| 1088 | * fine because the log is consistent on disk, and we | ||
| 1089 | * have references to all of the file's extents | ||
| 1090 | * | ||
| 1091 | * It is possible that someone will come in and log the | ||
| 1092 | * file again, but that will end up using the synchronization | ||
| 1093 | * inside btrfs_sync_log to keep things safe. | ||
| 1094 | */ | ||
| 1095 | mutex_unlock(&file->f_dentry->d_inode->i_mutex); | ||
| 1096 | |||
| 1081 | if (ret > 0) { | 1097 | if (ret > 0) { |
| 1082 | ret = btrfs_commit_transaction(trans, root); | 1098 | ret = btrfs_commit_transaction(trans, root); |
| 1083 | } else { | 1099 | } else { |
| 1084 | btrfs_sync_log(trans, root); | 1100 | btrfs_sync_log(trans, root); |
| 1085 | ret = btrfs_end_transaction(trans, root); | 1101 | ret = btrfs_end_transaction(trans, root); |
| 1086 | } | 1102 | } |
| 1103 | mutex_lock(&file->f_dentry->d_inode->i_mutex); | ||
| 1087 | out: | 1104 | out: |
| 1088 | return ret > 0 ? EIO : ret; | 1105 | return ret > 0 ? EIO : ret; |
| 1089 | } | 1106 | } |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 24b7e97fccb..12c1c0530f3 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -1187,7 +1187,9 @@ int btrfs_unlink_inode(struct btrfs_trans_handle *trans, | |||
| 1187 | 1187 | ||
| 1188 | ret = btrfs_del_inode_ref_in_log(trans, root, name, name_len, | 1188 | ret = btrfs_del_inode_ref_in_log(trans, root, name, name_len, |
| 1189 | inode, dir->i_ino); | 1189 | inode, dir->i_ino); |
| 1190 | BUG_ON(ret); | 1190 | BUG_ON(ret != 0 && ret != -ENOENT); |
| 1191 | if (ret != -ENOENT) | ||
| 1192 | BTRFS_I(dir)->log_dirty_trans = trans->transid; | ||
| 1191 | 1193 | ||
| 1192 | ret = btrfs_del_dir_entries_in_log(trans, root, name, name_len, | 1194 | ret = btrfs_del_dir_entries_in_log(trans, root, name, name_len, |
| 1193 | dir, index); | 1195 | dir, index); |
| @@ -1790,6 +1792,7 @@ static noinline void init_btrfs_i(struct inode *inode) | |||
| 1790 | bi->disk_i_size = 0; | 1792 | bi->disk_i_size = 0; |
| 1791 | bi->flags = 0; | 1793 | bi->flags = 0; |
| 1792 | bi->index_cnt = (u64)-1; | 1794 | bi->index_cnt = (u64)-1; |
| 1795 | bi->log_dirty_trans = 0; | ||
| 1793 | extent_map_tree_init(&BTRFS_I(inode)->extent_tree, GFP_NOFS); | 1796 | extent_map_tree_init(&BTRFS_I(inode)->extent_tree, GFP_NOFS); |
| 1794 | extent_io_tree_init(&BTRFS_I(inode)->io_tree, | 1797 | extent_io_tree_init(&BTRFS_I(inode)->io_tree, |
| 1795 | inode->i_mapping, GFP_NOFS); | 1798 | inode->i_mapping, GFP_NOFS); |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 3f4b139b27e..5d49a701bdc 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
| @@ -1973,10 +1973,10 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
| 1973 | atomic_set(&log->fs_info->tree_log_commit, 1); | 1973 | atomic_set(&log->fs_info->tree_log_commit, 1); |
| 1974 | 1974 | ||
| 1975 | while(1) { | 1975 | while(1) { |
| 1976 | batch = log->fs_info->tree_log_batch; | ||
| 1976 | mutex_unlock(&log->fs_info->tree_log_mutex); | 1977 | mutex_unlock(&log->fs_info->tree_log_mutex); |
| 1977 | schedule_timeout_uninterruptible(1); | 1978 | schedule_timeout_uninterruptible(1); |
| 1978 | mutex_lock(&log->fs_info->tree_log_mutex); | 1979 | mutex_lock(&log->fs_info->tree_log_mutex); |
| 1979 | batch = log->fs_info->tree_log_batch; | ||
| 1980 | 1980 | ||
| 1981 | while(atomic_read(&log->fs_info->tree_log_writers)) { | 1981 | while(atomic_read(&log->fs_info->tree_log_writers)) { |
| 1982 | DEFINE_WAIT(wait); | 1982 | DEFINE_WAIT(wait); |
| @@ -2189,8 +2189,6 @@ int btrfs_del_inode_ref_in_log(struct btrfs_trans_handle *trans, | |||
| 2189 | mutex_unlock(&BTRFS_I(inode)->log_mutex); | 2189 | mutex_unlock(&BTRFS_I(inode)->log_mutex); |
| 2190 | end_log_trans(root); | 2190 | end_log_trans(root); |
| 2191 | 2191 | ||
| 2192 | if (ret == 0 || ret == -ENOENT) | ||
| 2193 | return 0; | ||
| 2194 | return ret; | 2192 | return ret; |
| 2195 | } | 2193 | } |
| 2196 | 2194 | ||
| @@ -2620,9 +2618,11 @@ static int __btrfs_log_inode(struct btrfs_trans_handle *trans, | |||
| 2620 | else | 2618 | else |
| 2621 | break; | 2619 | break; |
| 2622 | } | 2620 | } |
| 2623 | if (inode_only == LOG_INODE_ALL && S_ISDIR(inode->i_mode)) { | 2621 | if (inode_only == LOG_INODE_ALL && S_ISDIR(inode->i_mode) && |
| 2622 | BTRFS_I(inode)->log_dirty_trans >= trans->transid) { | ||
| 2624 | btrfs_release_path(root, path); | 2623 | btrfs_release_path(root, path); |
| 2625 | btrfs_release_path(log, dst_path); | 2624 | btrfs_release_path(log, dst_path); |
| 2625 | BTRFS_I(inode)->log_dirty_trans = 0; | ||
| 2626 | ret = log_directory_changes(trans, root, inode, path, dst_path); | 2626 | ret = log_directory_changes(trans, root, inode, path, dst_path); |
| 2627 | BUG_ON(ret); | 2627 | BUG_ON(ret); |
| 2628 | } | 2628 | } |
