Skip to content

Commit ac604d3

Browse files
Gang Hetorvalds
authored andcommitted
ocfs2: add ocfs2_overwrite_io()
Add ocfs2_overwrite_io function, which is used to judge if overwrite allocated blocks, otherwise, the write will bring extra block allocation overhead. [[email protected]: v3] Link: http://lkml.kernel.org/r/[email protected] [[email protected]: v2] Link: http://lkml.kernel.org/r/[email protected] Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Gang He <[email protected]> Reviewed-by: Changwei Ge <[email protected]> Cc: Mark Fasheh <[email protected]> Cc: Joel Becker <[email protected]> Cc: Junxiao Bi <[email protected]> Cc: Joseph Qi <[email protected]> Cc: Jun Piao <[email protected]> Cc: alex chen <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 06e7f13 commit ac604d3

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

fs/ocfs2/extent_map.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "inode.h"
3939
#include "super.h"
4040
#include "symlink.h"
41+
#include "aops.h"
4142
#include "ocfs2_trace.h"
4243

4344
#include "buffer_head_io.h"
@@ -832,6 +833,50 @@ int ocfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
832833
return ret;
833834
}
834835

836+
/* Is IO overwriting allocated blocks? */
837+
int ocfs2_overwrite_io(struct inode *inode, struct buffer_head *di_bh,
838+
u64 map_start, u64 map_len)
839+
{
840+
int ret = 0, is_last;
841+
u32 mapping_end, cpos;
842+
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
843+
struct ocfs2_extent_rec rec;
844+
845+
if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
846+
if (ocfs2_size_fits_inline_data(di_bh, map_start + map_len))
847+
return ret;
848+
else
849+
return -EAGAIN;
850+
}
851+
852+
cpos = map_start >> osb->s_clustersize_bits;
853+
mapping_end = ocfs2_clusters_for_bytes(inode->i_sb,
854+
map_start + map_len);
855+
is_last = 0;
856+
while (cpos < mapping_end && !is_last) {
857+
ret = ocfs2_get_clusters_nocache(inode, di_bh, cpos,
858+
NULL, &rec, &is_last);
859+
if (ret) {
860+
mlog_errno(ret);
861+
goto out;
862+
}
863+
864+
if (rec.e_blkno == 0ULL)
865+
break;
866+
867+
if (rec.e_flags & OCFS2_EXT_REFCOUNTED)
868+
break;
869+
870+
cpos = le32_to_cpu(rec.e_cpos) +
871+
le16_to_cpu(rec.e_leaf_clusters);
872+
}
873+
874+
if (cpos < mapping_end)
875+
ret = -EAGAIN;
876+
out:
877+
return ret;
878+
}
879+
835880
int ocfs2_seek_data_hole_offset(struct file *file, loff_t *offset, int whence)
836881
{
837882
struct inode *inode = file->f_mapping->host;

fs/ocfs2/extent_map.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ int ocfs2_extent_map_get_blocks(struct inode *inode, u64 v_blkno, u64 *p_blkno,
5353
int ocfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
5454
u64 map_start, u64 map_len);
5555

56+
int ocfs2_overwrite_io(struct inode *inode, struct buffer_head *di_bh,
57+
u64 map_start, u64 map_len);
58+
5659
int ocfs2_seek_data_hole_offset(struct file *file, loff_t *offset, int origin);
5760

5861
int ocfs2_xattr_get_clusters(struct inode *inode, u32 v_cluster,

0 commit comments

Comments
 (0)