/* * Will look for holes and unwritten extents in the range starting at * pos for count bytes (inclusive). */ static int ocfs2_check_range_for_holes(struct inode *inode, loff_t pos, size_t count) { int ret = 0; unsigned int extent_flags; u32 cpos, clusters, extent_len, phys_cpos; struct super_block *sb = inode->i_sb; cpos = pos >> OCFS2_SB(sb)->s_clustersize_bits; clusters = ocfs2_clusters_for_bytes(sb, pos + count) - cpos; while (clusters) { ret = ocfs2_get_clusters(inode, cpos, &phys_cpos, &extent_len, &extent_flags); if (ret < 0) { mlog_errno(ret); goto out; } if (phys_cpos == 0 || (extent_flags & OCFS2_EXT_UNWRITTEN)) { ret = 1; break; } if (extent_len > clusters) extent_len = clusters; clusters -= extent_len; cpos += extent_len; } out: return ret; }
errcode_t ocfs2_extent_map_get_blocks(ocfs2_cached_inode *cinode, uint64_t v_blkno, int count, uint64_t *p_blkno, uint64_t *ret_count, uint16_t *extent_flags) { errcode_t ret; int bpc; uint32_t cpos, num_clusters = -1, p_cluster = -1; uint64_t boff = 0; ocfs2_filesys *fs = cinode->ci_fs; bpc = ocfs2_clusters_to_blocks(fs, 1); cpos = ocfs2_blocks_to_clusters(fs, v_blkno); ret = ocfs2_get_clusters(cinode, cpos, &p_cluster, &num_clusters, extent_flags); if (ret) goto out; /* * p_cluster == 0 indicates a hole. */ if (p_cluster) { boff = ocfs2_clusters_to_blocks(fs, p_cluster); boff += (v_blkno & (uint64_t)(bpc - 1)); } *p_blkno = boff; if (ret_count) { *ret_count = ocfs2_clusters_to_blocks(fs, num_clusters); *ret_count -= v_blkno & (uint64_t)(bpc - 1); } out: return ret; }