diff options
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 59 |
1 files changed, 15 insertions, 44 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 3183742d6f0d..03708ef3deef 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -709,6 +709,18 @@ retry: | |||
709 | unlock_extent(io_tree, async_extent->start, | 709 | unlock_extent(io_tree, async_extent->start, |
710 | async_extent->start + | 710 | async_extent->start + |
711 | async_extent->ram_size - 1); | 711 | async_extent->ram_size - 1); |
712 | |||
713 | /* | ||
714 | * we need to redirty the pages if we decide to | ||
715 | * fallback to uncompressed IO, otherwise we | ||
716 | * will not submit these pages down to lower | ||
717 | * layers. | ||
718 | */ | ||
719 | extent_range_redirty_for_io(inode, | ||
720 | async_extent->start, | ||
721 | async_extent->start + | ||
722 | async_extent->ram_size - 1); | ||
723 | |||
712 | goto retry; | 724 | goto retry; |
713 | } | 725 | } |
714 | goto out_free; | 726 | goto out_free; |
@@ -7939,27 +7951,6 @@ static int btrfs_truncate(struct inode *inode) | |||
7939 | BUG_ON(ret); | 7951 | BUG_ON(ret); |
7940 | 7952 | ||
7941 | /* | 7953 | /* |
7942 | * setattr is responsible for setting the ordered_data_close flag, | ||
7943 | * but that is only tested during the last file release. That | ||
7944 | * could happen well after the next commit, leaving a great big | ||
7945 | * window where new writes may get lost if someone chooses to write | ||
7946 | * to this file after truncating to zero | ||
7947 | * | ||
7948 | * The inode doesn't have any dirty data here, and so if we commit | ||
7949 | * this is a noop. If someone immediately starts writing to the inode | ||
7950 | * it is very likely we'll catch some of their writes in this | ||
7951 | * transaction, and the commit will find this file on the ordered | ||
7952 | * data list with good things to send down. | ||
7953 | * | ||
7954 | * This is a best effort solution, there is still a window where | ||
7955 | * using truncate to replace the contents of the file will | ||
7956 | * end up with a zero length file after a crash. | ||
7957 | */ | ||
7958 | if (inode->i_size == 0 && test_bit(BTRFS_INODE_ORDERED_DATA_CLOSE, | ||
7959 | &BTRFS_I(inode)->runtime_flags)) | ||
7960 | btrfs_add_ordered_operation(trans, root, inode); | ||
7961 | |||
7962 | /* | ||
7963 | * So if we truncate and then write and fsync we normally would just | 7954 | * So if we truncate and then write and fsync we normally would just |
7964 | * write the extents that changed, which is a problem if we need to | 7955 | * write the extents that changed, which is a problem if we need to |
7965 | * first truncate that entire inode. So set this flag so we write out | 7956 | * first truncate that entire inode. So set this flag so we write out |
@@ -8106,7 +8097,6 @@ struct inode *btrfs_alloc_inode(struct super_block *sb) | |||
8106 | mutex_init(&ei->delalloc_mutex); | 8097 | mutex_init(&ei->delalloc_mutex); |
8107 | btrfs_ordered_inode_tree_init(&ei->ordered_tree); | 8098 | btrfs_ordered_inode_tree_init(&ei->ordered_tree); |
8108 | INIT_LIST_HEAD(&ei->delalloc_inodes); | 8099 | INIT_LIST_HEAD(&ei->delalloc_inodes); |
8109 | INIT_LIST_HEAD(&ei->ordered_operations); | ||
8110 | RB_CLEAR_NODE(&ei->rb_node); | 8100 | RB_CLEAR_NODE(&ei->rb_node); |
8111 | 8101 | ||
8112 | return inode; | 8102 | return inode; |
@@ -8146,17 +8136,6 @@ void btrfs_destroy_inode(struct inode *inode) | |||
8146 | if (!root) | 8136 | if (!root) |
8147 | goto free; | 8137 | goto free; |
8148 | 8138 | ||
8149 | /* | ||
8150 | * Make sure we're properly removed from the ordered operation | ||
8151 | * lists. | ||
8152 | */ | ||
8153 | smp_mb(); | ||
8154 | if (!list_empty(&BTRFS_I(inode)->ordered_operations)) { | ||
8155 | spin_lock(&root->fs_info->ordered_root_lock); | ||
8156 | list_del_init(&BTRFS_I(inode)->ordered_operations); | ||
8157 | spin_unlock(&root->fs_info->ordered_root_lock); | ||
8158 | } | ||
8159 | |||
8160 | if (test_bit(BTRFS_INODE_HAS_ORPHAN_ITEM, | 8139 | if (test_bit(BTRFS_INODE_HAS_ORPHAN_ITEM, |
8161 | &BTRFS_I(inode)->runtime_flags)) { | 8140 | &BTRFS_I(inode)->runtime_flags)) { |
8162 | btrfs_info(root->fs_info, "inode %llu still on the orphan list", | 8141 | btrfs_info(root->fs_info, "inode %llu still on the orphan list", |
@@ -8338,12 +8317,10 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
8338 | ret = 0; | 8317 | ret = 0; |
8339 | 8318 | ||
8340 | /* | 8319 | /* |
8341 | * we're using rename to replace one file with another. | 8320 | * we're using rename to replace one file with another. Start IO on it |
8342 | * and the replacement file is large. Start IO on it now so | 8321 | * now so we don't add too much work to the end of the transaction |
8343 | * we don't add too much work to the end of the transaction | ||
8344 | */ | 8322 | */ |
8345 | if (new_inode && S_ISREG(old_inode->i_mode) && new_inode->i_size && | 8323 | if (new_inode && S_ISREG(old_inode->i_mode) && new_inode->i_size) |
8346 | old_inode->i_size > BTRFS_ORDERED_OPERATIONS_FLUSH_LIMIT) | ||
8347 | filemap_flush(old_inode->i_mapping); | 8324 | filemap_flush(old_inode->i_mapping); |
8348 | 8325 | ||
8349 | /* close the racy window with snapshot create/destroy ioctl */ | 8326 | /* close the racy window with snapshot create/destroy ioctl */ |
@@ -8391,12 +8368,6 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
8391 | */ | 8368 | */ |
8392 | btrfs_pin_log_trans(root); | 8369 | btrfs_pin_log_trans(root); |
8393 | } | 8370 | } |
8394 | /* | ||
8395 | * make sure the inode gets flushed if it is replacing | ||
8396 | * something. | ||
8397 | */ | ||
8398 | if (new_inode && new_inode->i_size && S_ISREG(old_inode->i_mode)) | ||
8399 | btrfs_add_ordered_operation(trans, root, old_inode); | ||
8400 | 8371 | ||
8401 | inode_inc_iversion(old_dir); | 8372 | inode_inc_iversion(old_dir); |
8402 | inode_inc_iversion(new_dir); | 8373 | inode_inc_iversion(new_dir); |