aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c73
1 files changed, 58 insertions, 15 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index f6ab6f5e635a..d8bb0dbc4941 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -830,7 +830,7 @@ static noinline int cow_file_range(struct inode *inode,
830 if (IS_ERR(trans)) { 830 if (IS_ERR(trans)) {
831 extent_clear_unlock_delalloc(inode, 831 extent_clear_unlock_delalloc(inode,
832 &BTRFS_I(inode)->io_tree, 832 &BTRFS_I(inode)->io_tree,
833 start, end, NULL, 833 start, end, locked_page,
834 EXTENT_CLEAR_UNLOCK_PAGE | 834 EXTENT_CLEAR_UNLOCK_PAGE |
835 EXTENT_CLEAR_UNLOCK | 835 EXTENT_CLEAR_UNLOCK |
836 EXTENT_CLEAR_DELALLOC | 836 EXTENT_CLEAR_DELALLOC |
@@ -963,7 +963,7 @@ out:
963out_unlock: 963out_unlock:
964 extent_clear_unlock_delalloc(inode, 964 extent_clear_unlock_delalloc(inode,
965 &BTRFS_I(inode)->io_tree, 965 &BTRFS_I(inode)->io_tree,
966 start, end, NULL, 966 start, end, locked_page,
967 EXTENT_CLEAR_UNLOCK_PAGE | 967 EXTENT_CLEAR_UNLOCK_PAGE |
968 EXTENT_CLEAR_UNLOCK | 968 EXTENT_CLEAR_UNLOCK |
969 EXTENT_CLEAR_DELALLOC | 969 EXTENT_CLEAR_DELALLOC |
@@ -986,8 +986,10 @@ static noinline void async_cow_start(struct btrfs_work *work)
986 compress_file_range(async_cow->inode, async_cow->locked_page, 986 compress_file_range(async_cow->inode, async_cow->locked_page,
987 async_cow->start, async_cow->end, async_cow, 987 async_cow->start, async_cow->end, async_cow,
988 &num_added); 988 &num_added);
989 if (num_added == 0) 989 if (num_added == 0) {
990 btrfs_add_delayed_iput(async_cow->inode);
990 async_cow->inode = NULL; 991 async_cow->inode = NULL;
992 }
991} 993}
992 994
993/* 995/*
@@ -1020,6 +1022,8 @@ static noinline void async_cow_free(struct btrfs_work *work)
1020{ 1022{
1021 struct async_cow *async_cow; 1023 struct async_cow *async_cow;
1022 async_cow = container_of(work, struct async_cow, work); 1024 async_cow = container_of(work, struct async_cow, work);
1025 if (async_cow->inode)
1026 btrfs_add_delayed_iput(async_cow->inode);
1023 kfree(async_cow); 1027 kfree(async_cow);
1024} 1028}
1025 1029
@@ -1038,7 +1042,7 @@ static int cow_file_range_async(struct inode *inode, struct page *locked_page,
1038 while (start < end) { 1042 while (start < end) {
1039 async_cow = kmalloc(sizeof(*async_cow), GFP_NOFS); 1043 async_cow = kmalloc(sizeof(*async_cow), GFP_NOFS);
1040 BUG_ON(!async_cow); /* -ENOMEM */ 1044 BUG_ON(!async_cow); /* -ENOMEM */
1041 async_cow->inode = inode; 1045 async_cow->inode = igrab(inode);
1042 async_cow->root = root; 1046 async_cow->root = root;
1043 async_cow->locked_page = locked_page; 1047 async_cow->locked_page = locked_page;
1044 async_cow->start = start; 1048 async_cow->start = start;
@@ -1136,8 +1140,18 @@ static noinline int run_delalloc_nocow(struct inode *inode,
1136 u64 ino = btrfs_ino(inode); 1140 u64 ino = btrfs_ino(inode);
1137 1141
1138 path = btrfs_alloc_path(); 1142 path = btrfs_alloc_path();
1139 if (!path) 1143 if (!path) {
1144 extent_clear_unlock_delalloc(inode,
1145 &BTRFS_I(inode)->io_tree,
1146 start, end, locked_page,
1147 EXTENT_CLEAR_UNLOCK_PAGE |
1148 EXTENT_CLEAR_UNLOCK |
1149 EXTENT_CLEAR_DELALLOC |
1150 EXTENT_CLEAR_DIRTY |
1151 EXTENT_SET_WRITEBACK |
1152 EXTENT_END_WRITEBACK);
1140 return -ENOMEM; 1153 return -ENOMEM;
1154 }
1141 1155
1142 nolock = btrfs_is_free_space_inode(root, inode); 1156 nolock = btrfs_is_free_space_inode(root, inode);
1143 1157
@@ -1147,6 +1161,15 @@ static noinline int run_delalloc_nocow(struct inode *inode,
1147 trans = btrfs_join_transaction(root); 1161 trans = btrfs_join_transaction(root);
1148 1162
1149 if (IS_ERR(trans)) { 1163 if (IS_ERR(trans)) {
1164 extent_clear_unlock_delalloc(inode,
1165 &BTRFS_I(inode)->io_tree,
1166 start, end, locked_page,
1167 EXTENT_CLEAR_UNLOCK_PAGE |
1168 EXTENT_CLEAR_UNLOCK |
1169 EXTENT_CLEAR_DELALLOC |
1170 EXTENT_CLEAR_DIRTY |
1171 EXTENT_SET_WRITEBACK |
1172 EXTENT_END_WRITEBACK);
1150 btrfs_free_path(path); 1173 btrfs_free_path(path);
1151 return PTR_ERR(trans); 1174 return PTR_ERR(trans);
1152 } 1175 }
@@ -1327,8 +1350,11 @@ out_check:
1327 } 1350 }
1328 btrfs_release_path(path); 1351 btrfs_release_path(path);
1329 1352
1330 if (cur_offset <= end && cow_start == (u64)-1) 1353 if (cur_offset <= end && cow_start == (u64)-1) {
1331 cow_start = cur_offset; 1354 cow_start = cur_offset;
1355 cur_offset = end;
1356 }
1357
1332 if (cow_start != (u64)-1) { 1358 if (cow_start != (u64)-1) {
1333 ret = cow_file_range(inode, locked_page, cow_start, end, 1359 ret = cow_file_range(inode, locked_page, cow_start, end,
1334 page_started, nr_written, 1); 1360 page_started, nr_written, 1);
@@ -1347,6 +1373,17 @@ error:
1347 if (!ret) 1373 if (!ret)
1348 ret = err; 1374 ret = err;
1349 1375
1376 if (ret && cur_offset < end)
1377 extent_clear_unlock_delalloc(inode,
1378 &BTRFS_I(inode)->io_tree,
1379 cur_offset, end, locked_page,
1380 EXTENT_CLEAR_UNLOCK_PAGE |
1381 EXTENT_CLEAR_UNLOCK |
1382 EXTENT_CLEAR_DELALLOC |
1383 EXTENT_CLEAR_DIRTY |
1384 EXTENT_SET_WRITEBACK |
1385 EXTENT_END_WRITEBACK);
1386
1350 btrfs_free_path(path); 1387 btrfs_free_path(path);
1351 return ret; 1388 return ret;
1352} 1389}
@@ -1361,20 +1398,23 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page,
1361 int ret; 1398 int ret;
1362 struct btrfs_root *root = BTRFS_I(inode)->root; 1399 struct btrfs_root *root = BTRFS_I(inode)->root;
1363 1400
1364 if (BTRFS_I(inode)->flags & BTRFS_INODE_NODATACOW) 1401 if (BTRFS_I(inode)->flags & BTRFS_INODE_NODATACOW) {
1365 ret = run_delalloc_nocow(inode, locked_page, start, end, 1402 ret = run_delalloc_nocow(inode, locked_page, start, end,
1366 page_started, 1, nr_written); 1403 page_started, 1, nr_written);
1367 else if (BTRFS_I(inode)->flags & BTRFS_INODE_PREALLOC) 1404 } else if (BTRFS_I(inode)->flags & BTRFS_INODE_PREALLOC) {
1368 ret = run_delalloc_nocow(inode, locked_page, start, end, 1405 ret = run_delalloc_nocow(inode, locked_page, start, end,
1369 page_started, 0, nr_written); 1406 page_started, 0, nr_written);
1370 else if (!btrfs_test_opt(root, COMPRESS) && 1407 } else if (!btrfs_test_opt(root, COMPRESS) &&
1371 !(BTRFS_I(inode)->force_compress) && 1408 !(BTRFS_I(inode)->force_compress) &&
1372 !(BTRFS_I(inode)->flags & BTRFS_INODE_COMPRESS)) 1409 !(BTRFS_I(inode)->flags & BTRFS_INODE_COMPRESS)) {
1373 ret = cow_file_range(inode, locked_page, start, end, 1410 ret = cow_file_range(inode, locked_page, start, end,
1374 page_started, nr_written, 1); 1411 page_started, nr_written, 1);
1375 else 1412 } else {
1413 set_bit(BTRFS_INODE_HAS_ASYNC_EXTENT,
1414 &BTRFS_I(inode)->runtime_flags);
1376 ret = cow_file_range_async(inode, locked_page, start, end, 1415 ret = cow_file_range_async(inode, locked_page, start, end,
1377 page_started, nr_written); 1416 page_started, nr_written);
1417 }
1378 return ret; 1418 return ret;
1379} 1419}
1380 1420
@@ -7054,10 +7094,13 @@ static void fixup_inode_flags(struct inode *dir, struct inode *inode)
7054 else 7094 else
7055 b_inode->flags &= ~BTRFS_INODE_NODATACOW; 7095 b_inode->flags &= ~BTRFS_INODE_NODATACOW;
7056 7096
7057 if (b_dir->flags & BTRFS_INODE_COMPRESS) 7097 if (b_dir->flags & BTRFS_INODE_COMPRESS) {
7058 b_inode->flags |= BTRFS_INODE_COMPRESS; 7098 b_inode->flags |= BTRFS_INODE_COMPRESS;
7059 else 7099 b_inode->flags &= ~BTRFS_INODE_NOCOMPRESS;
7060 b_inode->flags &= ~BTRFS_INODE_COMPRESS; 7100 } else {
7101 b_inode->flags &= ~(BTRFS_INODE_COMPRESS |
7102 BTRFS_INODE_NOCOMPRESS);
7103 }
7061} 7104}
7062 7105
7063static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, 7106static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,