aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/file.c')
-rw-r--r--fs/ocfs2/file.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 4c7a4d8ed32c..3346e5b199d5 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -1422,12 +1422,14 @@ static int ocfs2_remove_inode_range(struct inode *inode,
1422 struct buffer_head *di_bh, u64 byte_start, 1422 struct buffer_head *di_bh, u64 byte_start,
1423 u64 byte_len) 1423 u64 byte_len)
1424{ 1424{
1425 int ret = 0; 1425 int ret = 0, flags = 0;
1426 u32 trunc_start, trunc_len, cpos, phys_cpos, alloc_size; 1426 u32 trunc_start, trunc_len, cpos, phys_cpos, alloc_size;
1427 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 1427 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
1428 struct ocfs2_cached_dealloc_ctxt dealloc; 1428 struct ocfs2_cached_dealloc_ctxt dealloc;
1429 struct address_space *mapping = inode->i_mapping; 1429 struct address_space *mapping = inode->i_mapping;
1430 struct ocfs2_extent_tree et; 1430 struct ocfs2_extent_tree et;
1431 struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
1432 u64 refcount_loc = le64_to_cpu(di->i_refcount_loc);
1431 1433
1432 ocfs2_init_dinode_extent_tree(&et, INODE_CACHE(inode), di_bh); 1434 ocfs2_init_dinode_extent_tree(&et, INODE_CACHE(inode), di_bh);
1433 ocfs2_init_dealloc_ctxt(&dealloc); 1435 ocfs2_init_dealloc_ctxt(&dealloc);
@@ -1453,6 +1455,27 @@ static int ocfs2_remove_inode_range(struct inode *inode,
1453 goto out; 1455 goto out;
1454 } 1456 }
1455 1457
1458 /*
1459 * For reflinks, we may need to CoW 2 clusters which might be
1460 * partially zero'd later, if hole's start and end offset were
1461 * within one cluster(means is not exactly aligned to clustersize).
1462 */
1463
1464 if (OCFS2_I(inode)->ip_dyn_features & OCFS2_HAS_REFCOUNT_FL) {
1465
1466 ret = ocfs2_cow_file_pos(inode, di_bh, byte_start);
1467 if (ret) {
1468 mlog_errno(ret);
1469 goto out;
1470 }
1471
1472 ret = ocfs2_cow_file_pos(inode, di_bh, byte_start + byte_len);
1473 if (ret) {
1474 mlog_errno(ret);
1475 goto out;
1476 }
1477 }
1478
1456 trunc_start = ocfs2_clusters_for_bytes(osb->sb, byte_start); 1479 trunc_start = ocfs2_clusters_for_bytes(osb->sb, byte_start);
1457 trunc_len = (byte_start + byte_len) >> osb->s_clustersize_bits; 1480 trunc_len = (byte_start + byte_len) >> osb->s_clustersize_bits;
1458 if (trunc_len >= trunc_start) 1481 if (trunc_len >= trunc_start)
@@ -1474,7 +1497,7 @@ static int ocfs2_remove_inode_range(struct inode *inode,
1474 cpos = trunc_start; 1497 cpos = trunc_start;
1475 while (trunc_len) { 1498 while (trunc_len) {
1476 ret = ocfs2_get_clusters(inode, cpos, &phys_cpos, 1499 ret = ocfs2_get_clusters(inode, cpos, &phys_cpos,
1477 &alloc_size, NULL); 1500 &alloc_size, &flags);
1478 if (ret) { 1501 if (ret) {
1479 mlog_errno(ret); 1502 mlog_errno(ret);
1480 goto out; 1503 goto out;
@@ -1487,7 +1510,8 @@ static int ocfs2_remove_inode_range(struct inode *inode,
1487 if (phys_cpos != 0) { 1510 if (phys_cpos != 0) {
1488 ret = ocfs2_remove_btree_range(inode, &et, cpos, 1511 ret = ocfs2_remove_btree_range(inode, &et, cpos,
1489 phys_cpos, alloc_size, 1512 phys_cpos, alloc_size,
1490 0, &dealloc, 0); 1513 flags, &dealloc,
1514 refcount_loc);
1491 if (ret) { 1515 if (ret) {
1492 mlog_errno(ret); 1516 mlog_errno(ret);
1493 goto out; 1517 goto out;