diff options
| -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 | /* |
