diff options
Diffstat (limited to 'fs/ocfs2/file.c')
-rw-r--r-- | fs/ocfs2/file.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 4e7b0dc22450..0b055bfb8e86 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -1506,7 +1506,8 @@ static int ocfs2_zero_partial_clusters(struct inode *inode, | |||
1506 | u64 start, u64 len) | 1506 | u64 start, u64 len) |
1507 | { | 1507 | { |
1508 | int ret = 0; | 1508 | int ret = 0; |
1509 | u64 tmpend, end = start + len; | 1509 | u64 tmpend = 0; |
1510 | u64 end = start + len; | ||
1510 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 1511 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
1511 | unsigned int csize = osb->s_clustersize; | 1512 | unsigned int csize = osb->s_clustersize; |
1512 | handle_t *handle; | 1513 | handle_t *handle; |
@@ -1538,18 +1539,31 @@ static int ocfs2_zero_partial_clusters(struct inode *inode, | |||
1538 | } | 1539 | } |
1539 | 1540 | ||
1540 | /* | 1541 | /* |
1541 | * We want to get the byte offset of the end of the 1st cluster. | 1542 | * If start is on a cluster boundary and end is somewhere in another |
1543 | * cluster, we have not COWed the cluster starting at start, unless | ||
1544 | * end is also within the same cluster. So, in this case, we skip this | ||
1545 | * first call to ocfs2_zero_range_for_truncate() truncate and move on | ||
1546 | * to the next one. | ||
1542 | */ | 1547 | */ |
1543 | tmpend = (u64)osb->s_clustersize + (start & ~(osb->s_clustersize - 1)); | 1548 | if ((start & (csize - 1)) != 0) { |
1544 | if (tmpend > end) | 1549 | /* |
1545 | tmpend = end; | 1550 | * We want to get the byte offset of the end of the 1st |
1551 | * cluster. | ||
1552 | */ | ||
1553 | tmpend = (u64)osb->s_clustersize + | ||
1554 | (start & ~(osb->s_clustersize - 1)); | ||
1555 | if (tmpend > end) | ||
1556 | tmpend = end; | ||
1546 | 1557 | ||
1547 | trace_ocfs2_zero_partial_clusters_range1((unsigned long long)start, | 1558 | trace_ocfs2_zero_partial_clusters_range1( |
1548 | (unsigned long long)tmpend); | 1559 | (unsigned long long)start, |
1560 | (unsigned long long)tmpend); | ||
1549 | 1561 | ||
1550 | ret = ocfs2_zero_range_for_truncate(inode, handle, start, tmpend); | 1562 | ret = ocfs2_zero_range_for_truncate(inode, handle, start, |
1551 | if (ret) | 1563 | tmpend); |
1552 | mlog_errno(ret); | 1564 | if (ret) |
1565 | mlog_errno(ret); | ||
1566 | } | ||
1553 | 1567 | ||
1554 | if (tmpend < end) { | 1568 | if (tmpend < end) { |
1555 | /* | 1569 | /* |