aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ocfs2/alloc.c11
-rw-r--r--fs/ocfs2/aops.c21
-rw-r--r--fs/ocfs2/dir.c2
-rw-r--r--fs/ocfs2/extent_map.c14
-rw-r--r--fs/ocfs2/extent_map.h4
-rw-r--r--fs/ocfs2/file.c6
-rw-r--r--fs/ocfs2/inode.c3
-rw-r--r--fs/ocfs2/journal.c2
-rw-r--r--fs/ocfs2/namei.c3
-rw-r--r--fs/ocfs2/slot_map.c2
10 files changed, 45 insertions, 23 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index 0eab0d328289..412a2888a3ed 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -3487,6 +3487,7 @@ static int ocfs2_grab_eof_pages(struct inode *inode, loff_t isize, struct page *
3487{ 3487{
3488 int i, numpages = 0, ret = 0; 3488 int i, numpages = 0, ret = 0;
3489 unsigned int csize = OCFS2_SB(inode->i_sb)->s_clustersize; 3489 unsigned int csize = OCFS2_SB(inode->i_sb)->s_clustersize;
3490 unsigned int ext_flags;
3490 struct super_block *sb = inode->i_sb; 3491 struct super_block *sb = inode->i_sb;
3491 struct address_space *mapping = inode->i_mapping; 3492 struct address_space *mapping = inode->i_mapping;
3492 unsigned long index; 3493 unsigned long index;
@@ -3499,7 +3500,7 @@ static int ocfs2_grab_eof_pages(struct inode *inode, loff_t isize, struct page *
3499 goto out; 3500 goto out;
3500 3501
3501 ret = ocfs2_extent_map_get_blocks(inode, isize >> sb->s_blocksize_bits, 3502 ret = ocfs2_extent_map_get_blocks(inode, isize >> sb->s_blocksize_bits,
3502 phys, NULL); 3503 phys, NULL, &ext_flags);
3503 if (ret) { 3504 if (ret) {
3504 mlog_errno(ret); 3505 mlog_errno(ret);
3505 goto out; 3506 goto out;
@@ -3509,6 +3510,11 @@ static int ocfs2_grab_eof_pages(struct inode *inode, loff_t isize, struct page *
3509 if (*phys == 0) 3510 if (*phys == 0)
3510 goto out; 3511 goto out;
3511 3512
3513 /* Tail is marked as unwritten, we can count on write to zero
3514 * in that case. */
3515 if (ext_flags & OCFS2_EXT_UNWRITTEN)
3516 goto out;
3517
3512 next_cluster_bytes = ocfs2_align_bytes_to_clusters(inode->i_sb, isize); 3518 next_cluster_bytes = ocfs2_align_bytes_to_clusters(inode->i_sb, isize);
3513 index = isize >> PAGE_CACHE_SHIFT; 3519 index = isize >> PAGE_CACHE_SHIFT;
3514 do { 3520 do {
@@ -3579,9 +3585,6 @@ int ocfs2_zero_tail_for_truncate(struct inode *inode, handle_t *handle,
3579 goto out; 3585 goto out;
3580 } 3586 }
3581 3587
3582 /*
3583 * Truncate on an i_size boundary - nothing more to do.
3584 */
3585 if (numpages == 0) 3588 if (numpages == 0)
3586 goto out; 3589 goto out;
3587 3590
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 014f4f52809c..eb67c902b002 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -137,6 +137,7 @@ static int ocfs2_get_block(struct inode *inode, sector_t iblock,
137 struct buffer_head *bh_result, int create) 137 struct buffer_head *bh_result, int create)
138{ 138{
139 int err = 0; 139 int err = 0;
140 unsigned int ext_flags;
140 u64 p_blkno, past_eof; 141 u64 p_blkno, past_eof;
141 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 142 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
142 143
@@ -153,7 +154,8 @@ static int ocfs2_get_block(struct inode *inode, sector_t iblock,
153 goto bail; 154 goto bail;
154 } 155 }
155 156
156 err = ocfs2_extent_map_get_blocks(inode, iblock, &p_blkno, NULL); 157 err = ocfs2_extent_map_get_blocks(inode, iblock, &p_blkno, NULL,
158 &ext_flags);
157 if (err) { 159 if (err) {
158 mlog(ML_ERROR, "Error %d from get_blocks(0x%p, %llu, 1, " 160 mlog(ML_ERROR, "Error %d from get_blocks(0x%p, %llu, 1, "
159 "%llu, NULL)\n", err, inode, (unsigned long long)iblock, 161 "%llu, NULL)\n", err, inode, (unsigned long long)iblock,
@@ -171,7 +173,8 @@ static int ocfs2_get_block(struct inode *inode, sector_t iblock,
171 "ino %lu, iblock %llu\n", inode->i_ino, 173 "ino %lu, iblock %llu\n", inode->i_ino,
172 (unsigned long long)iblock); 174 (unsigned long long)iblock);
173 175
174 if (p_blkno) 176 /* Treat the unwritten extent as a hole for zeroing purposes. */
177 if (p_blkno && !(ext_flags & OCFS2_EXT_UNWRITTEN))
175 map_bh(bh_result, inode->i_sb, p_blkno); 178 map_bh(bh_result, inode->i_sb, p_blkno);
176 179
177 if (!ocfs2_sparse_alloc(osb)) { 180 if (!ocfs2_sparse_alloc(osb)) {
@@ -396,7 +399,7 @@ static sector_t ocfs2_bmap(struct address_space *mapping, sector_t block)
396 down_read(&OCFS2_I(inode)->ip_alloc_sem); 399 down_read(&OCFS2_I(inode)->ip_alloc_sem);
397 } 400 }
398 401
399 err = ocfs2_extent_map_get_blocks(inode, block, &p_blkno, NULL); 402 err = ocfs2_extent_map_get_blocks(inode, block, &p_blkno, NULL, NULL);
400 403
401 if (!INODE_JOURNAL(inode)) { 404 if (!INODE_JOURNAL(inode)) {
402 up_read(&OCFS2_I(inode)->ip_alloc_sem); 405 up_read(&OCFS2_I(inode)->ip_alloc_sem);
@@ -438,6 +441,7 @@ static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock,
438 int ret; 441 int ret;
439 u64 p_blkno, inode_blocks; 442 u64 p_blkno, inode_blocks;
440 int contig_blocks; 443 int contig_blocks;
444 unsigned int ext_flags;
441 unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; 445 unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
442 unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits; 446 unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits;
443 447
@@ -458,7 +462,7 @@ static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock,
458 /* This figures out the size of the next contiguous block, and 462 /* This figures out the size of the next contiguous block, and
459 * our logical offset */ 463 * our logical offset */
460 ret = ocfs2_extent_map_get_blocks(inode, iblock, &p_blkno, 464 ret = ocfs2_extent_map_get_blocks(inode, iblock, &p_blkno,
461 &contig_blocks); 465 &contig_blocks, &ext_flags);
462 if (ret) { 466 if (ret) {
463 mlog(ML_ERROR, "get_blocks() failed iblock=%llu\n", 467 mlog(ML_ERROR, "get_blocks() failed iblock=%llu\n",
464 (unsigned long long)iblock); 468 (unsigned long long)iblock);
@@ -478,8 +482,10 @@ static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock,
478 /* 482 /*
479 * get_more_blocks() expects us to describe a hole by clearing 483 * get_more_blocks() expects us to describe a hole by clearing
480 * the mapped bit on bh_result(). 484 * the mapped bit on bh_result().
485 *
486 * Consider an unwritten extent as a hole.
481 */ 487 */
482 if (p_blkno) 488 if (p_blkno && !(ext_flags & OCFS2_EXT_UNWRITTEN))
483 map_bh(bh_result, inode->i_sb, p_blkno); 489 map_bh(bh_result, inode->i_sb, p_blkno);
484 else { 490 else {
485 /* 491 /*
@@ -1111,7 +1117,8 @@ static ssize_t ocfs2_write(struct file *file, u32 phys, handle_t *handle,
1111 } 1117 }
1112 } 1118 }
1113 1119
1114 ret = ocfs2_extent_map_get_blocks(inode, v_blkno, &p_blkno, NULL); 1120 ret = ocfs2_extent_map_get_blocks(inode, v_blkno, &p_blkno, NULL,
1121 NULL);
1115 if (ret < 0) { 1122 if (ret < 0) {
1116 1123
1117 /* 1124 /*
@@ -1215,7 +1222,7 @@ ssize_t ocfs2_buffered_write_cluster(struct file *file, loff_t pos,
1215 */ 1222 */
1216 down_write(&OCFS2_I(inode)->ip_alloc_sem); 1223 down_write(&OCFS2_I(inode)->ip_alloc_sem);
1217 1224
1218 ret = ocfs2_get_clusters(inode, wc.w_cpos, &phys, NULL); 1225 ret = ocfs2_get_clusters(inode, wc.w_cpos, &phys, NULL, NULL);
1219 if (ret) { 1226 if (ret) {
1220 mlog_errno(ret); 1227 mlog_errno(ret);
1221 goto out_meta; 1228 goto out_meta;
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index c91490670ffa..8d22e1e4a88d 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -379,7 +379,7 @@ int ocfs2_do_extend_dir(struct super_block *sb,
379 379
380 status = ocfs2_extent_map_get_blocks(dir, (dir->i_blocks >> 380 status = ocfs2_extent_map_get_blocks(dir, (dir->i_blocks >>
381 (sb->s_blocksize_bits - 9)), 381 (sb->s_blocksize_bits - 9)),
382 &p_blkno, NULL); 382 &p_blkno, NULL, NULL);
383 if (status < 0) { 383 if (status < 0) {
384 mlog_errno(status); 384 mlog_errno(status);
385 goto bail; 385 goto bail;
diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c
index ea0ce41d4193..eef6c1887708 100644
--- a/fs/ocfs2/extent_map.c
+++ b/fs/ocfs2/extent_map.c
@@ -70,9 +70,11 @@ static int ocfs2_search_extent_list(struct ocfs2_extent_list *el,
70} 70}
71 71
72int ocfs2_get_clusters(struct inode *inode, u32 v_cluster, 72int ocfs2_get_clusters(struct inode *inode, u32 v_cluster,
73 u32 *p_cluster, u32 *num_clusters) 73 u32 *p_cluster, u32 *num_clusters,
74 unsigned int *extent_flags)
74{ 75{
75 int ret, i; 76 int ret, i;
77 unsigned int flags = 0;
76 struct buffer_head *di_bh = NULL; 78 struct buffer_head *di_bh = NULL;
77 struct buffer_head *eb_bh = NULL; 79 struct buffer_head *eb_bh = NULL;
78 struct ocfs2_dinode *di; 80 struct ocfs2_dinode *di;
@@ -142,8 +144,13 @@ int ocfs2_get_clusters(struct inode *inode, u32 v_cluster,
142 144
143 if (num_clusters) 145 if (num_clusters)
144 *num_clusters = ocfs2_rec_clusters(el, rec) - coff; 146 *num_clusters = ocfs2_rec_clusters(el, rec) - coff;
147
148 flags = rec->e_flags;
145 } 149 }
146 150
151 if (extent_flags)
152 *extent_flags = flags;
153
147out: 154out:
148 brelse(di_bh); 155 brelse(di_bh);
149 brelse(eb_bh); 156 brelse(eb_bh);
@@ -155,7 +162,7 @@ out:
155 * all while the map is in the process of being updated. 162 * all while the map is in the process of being updated.
156 */ 163 */
157int ocfs2_extent_map_get_blocks(struct inode *inode, u64 v_blkno, u64 *p_blkno, 164int ocfs2_extent_map_get_blocks(struct inode *inode, u64 v_blkno, u64 *p_blkno,
158 int *ret_count) 165 int *ret_count, unsigned int *extent_flags)
159{ 166{
160 int ret; 167 int ret;
161 int bpc = ocfs2_clusters_to_blocks(inode->i_sb, 1); 168 int bpc = ocfs2_clusters_to_blocks(inode->i_sb, 1);
@@ -164,7 +171,8 @@ int ocfs2_extent_map_get_blocks(struct inode *inode, u64 v_blkno, u64 *p_blkno,
164 171
165 cpos = ocfs2_blocks_to_clusters(inode->i_sb, v_blkno); 172 cpos = ocfs2_blocks_to_clusters(inode->i_sb, v_blkno);
166 173
167 ret = ocfs2_get_clusters(inode, cpos, &p_cluster, &num_clusters); 174 ret = ocfs2_get_clusters(inode, cpos, &p_cluster, &num_clusters,
175 extent_flags);
168 if (ret) { 176 if (ret) {
169 mlog_errno(ret); 177 mlog_errno(ret);
170 goto out; 178 goto out;
diff --git a/fs/ocfs2/extent_map.h b/fs/ocfs2/extent_map.h
index 625d0ee5e04a..0031c59c347f 100644
--- a/fs/ocfs2/extent_map.h
+++ b/fs/ocfs2/extent_map.h
@@ -26,8 +26,8 @@
26#define _EXTENT_MAP_H 26#define _EXTENT_MAP_H
27 27
28int ocfs2_get_clusters(struct inode *inode, u32 v_cluster, u32 *p_cluster, 28int ocfs2_get_clusters(struct inode *inode, u32 v_cluster, u32 *p_cluster,
29 u32 *num_clusters); 29 u32 *num_clusters, unsigned int *extent_flags);
30int ocfs2_extent_map_get_blocks(struct inode *inode, u64 v_blkno, u64 *p_blkno, 30int ocfs2_extent_map_get_blocks(struct inode *inode, u64 v_blkno, u64 *p_blkno,
31 int *ret_count); 31 int *ret_count, unsigned int *extent_flags);
32 32
33#endif /* _EXTENT_MAP_H */ 33#endif /* _EXTENT_MAP_H */
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 36176018b4b4..f516619a3744 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -1127,6 +1127,7 @@ static int ocfs2_check_range_for_holes(struct inode *inode, loff_t pos,
1127 size_t count) 1127 size_t count)
1128{ 1128{
1129 int ret = 0; 1129 int ret = 0;
1130 unsigned int extent_flags;
1130 u32 cpos, clusters, extent_len, phys_cpos; 1131 u32 cpos, clusters, extent_len, phys_cpos;
1131 struct super_block *sb = inode->i_sb; 1132 struct super_block *sb = inode->i_sb;
1132 1133
@@ -1134,13 +1135,14 @@ static int ocfs2_check_range_for_holes(struct inode *inode, loff_t pos,
1134 clusters = ocfs2_clusters_for_bytes(sb, pos + count) - cpos; 1135 clusters = ocfs2_clusters_for_bytes(sb, pos + count) - cpos;
1135 1136
1136 while (clusters) { 1137 while (clusters) {
1137 ret = ocfs2_get_clusters(inode, cpos, &phys_cpos, &extent_len); 1138 ret = ocfs2_get_clusters(inode, cpos, &phys_cpos, &extent_len,
1139 &extent_flags);
1138 if (ret < 0) { 1140 if (ret < 0) {
1139 mlog_errno(ret); 1141 mlog_errno(ret);
1140 goto out; 1142 goto out;
1141 } 1143 }
1142 1144
1143 if (phys_cpos == 0) { 1145 if (phys_cpos == 0 || (extent_flags & OCFS2_EXT_UNWRITTEN)) {
1144 ret = 1; 1146 ret = 1;
1145 break; 1147 break;
1146 } 1148 }
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
index 78c99b5050df..310049bf7f6b 100644
--- a/fs/ocfs2/inode.c
+++ b/fs/ocfs2/inode.c
@@ -1105,7 +1105,8 @@ struct buffer_head *ocfs2_bread(struct inode *inode,
1105 return NULL; 1105 return NULL;
1106 } 1106 }
1107 1107
1108 tmperr = ocfs2_extent_map_get_blocks(inode, block, &p_blkno, NULL); 1108 tmperr = ocfs2_extent_map_get_blocks(inode, block, &p_blkno, NULL,
1109 NULL);
1109 if (tmperr < 0) { 1110 if (tmperr < 0) {
1110 mlog_errno(tmperr); 1111 mlog_errno(tmperr);
1111 goto fail; 1112 goto fail;
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
index 2e2e04fe9738..db77e0996bb7 100644
--- a/fs/ocfs2/journal.c
+++ b/fs/ocfs2/journal.c
@@ -670,7 +670,7 @@ static int ocfs2_force_read_journal(struct inode *inode)
670 (inode->i_blocks >> (inode->i_sb->s_blocksize_bits - 9))) { 670 (inode->i_blocks >> (inode->i_sb->s_blocksize_bits - 9))) {
671 671
672 status = ocfs2_extent_map_get_blocks(inode, v_blkno, 672 status = ocfs2_extent_map_get_blocks(inode, v_blkno,
673 &p_blkno, &p_blocks); 673 &p_blkno, &p_blocks, NULL);
674 if (status < 0) { 674 if (status < 0) {
675 mlog_errno(status); 675 mlog_errno(status);
676 goto bail; 676 goto bail;
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index 5755e0748256..395859edb51f 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -1511,7 +1511,8 @@ static int ocfs2_create_symlink_data(struct ocfs2_super *osb,
1511 goto bail; 1511 goto bail;
1512 } 1512 }
1513 1513
1514 status = ocfs2_extent_map_get_blocks(inode, 0, &p_blkno, &p_blocks); 1514 status = ocfs2_extent_map_get_blocks(inode, 0, &p_blkno, &p_blocks,
1515 NULL);
1515 if (status < 0) { 1516 if (status < 0) {
1516 mlog_errno(status); 1517 mlog_errno(status);
1517 goto bail; 1518 goto bail;
diff --git a/fs/ocfs2/slot_map.c b/fs/ocfs2/slot_map.c
index f4416e7330e1..d921a28329dc 100644
--- a/fs/ocfs2/slot_map.c
+++ b/fs/ocfs2/slot_map.c
@@ -197,7 +197,7 @@ int ocfs2_init_slot_info(struct ocfs2_super *osb)
197 goto bail; 197 goto bail;
198 } 198 }
199 199
200 status = ocfs2_extent_map_get_blocks(inode, 0ULL, &blkno, NULL); 200 status = ocfs2_extent_map_get_blocks(inode, 0ULL, &blkno, NULL, NULL);
201 if (status < 0) { 201 if (status < 0) {
202 mlog_errno(status); 202 mlog_errno(status);
203 goto bail; 203 goto bail;