|
@@ -783,7 +783,6 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
|
|
|
loff_t isize = i_size_read(inode);
|
|
|
u64 logical = 0, phys = 0, size = 0;
|
|
|
u32 flags = 0;
|
|
|
- bool past_eof = false, whole_file = false;
|
|
|
int ret = 0;
|
|
|
|
|
|
ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC);
|
|
@@ -797,17 +796,18 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
|
|
|
}
|
|
|
|
|
|
mutex_lock(&inode->i_mutex);
|
|
|
+ if (start >= isize)
|
|
|
+ goto out;
|
|
|
|
|
|
- if (len >= isize) {
|
|
|
- whole_file = true;
|
|
|
- len = isize;
|
|
|
- }
|
|
|
+ if (start + len > isize)
|
|
|
+ len = isize - start;
|
|
|
|
|
|
if (logical_to_blk(inode, len) == 0)
|
|
|
len = blk_to_logical(inode, 1);
|
|
|
|
|
|
start_blk = logical_to_blk(inode, start);
|
|
|
last_blk = logical_to_blk(inode, start + len - 1);
|
|
|
+
|
|
|
next:
|
|
|
memset(&map_bh, 0, sizeof(struct buffer_head));
|
|
|
map_bh.b_size = len;
|
|
@@ -819,59 +819,33 @@ next:
|
|
|
|
|
|
/* HOLE */
|
|
|
if (!buffer_mapped(&map_bh)) {
|
|
|
- start_blk++;
|
|
|
-
|
|
|
- if (!past_eof && blk_to_logical(inode, start_blk) >= isize)
|
|
|
- past_eof = 1;
|
|
|
-
|
|
|
- if (past_eof && size) {
|
|
|
- flags |= FIEMAP_EXTENT_LAST;
|
|
|
- ret = fiemap_fill_next_extent(fieinfo, logical,
|
|
|
- phys, size, flags);
|
|
|
- } else if (size) {
|
|
|
- ret = fiemap_fill_next_extent(fieinfo, logical,
|
|
|
- phys, size, flags);
|
|
|
- size = 0;
|
|
|
- }
|
|
|
+ /* Go through holes util pass the EOF */
|
|
|
+ if (blk_to_logical(inode, start_blk++) < isize)
|
|
|
+ goto prep_next;
|
|
|
+ /* Found a hole beyond isize means no more extents.
|
|
|
+ * Note that the premise is that filesystems don't
|
|
|
+ * punch holes beyond isize and keep size unchanged.
|
|
|
+ */
|
|
|
+ flags |= FIEMAP_EXTENT_LAST;
|
|
|
+ }
|
|
|
|
|
|
- /* if we have holes up to/past EOF then we're done */
|
|
|
- if (start_blk > last_blk || past_eof || ret)
|
|
|
- goto out;
|
|
|
- } else {
|
|
|
- if (start_blk > last_blk && !whole_file) {
|
|
|
- ret = fiemap_fill_next_extent(fieinfo, logical,
|
|
|
- phys, size, flags);
|
|
|
- goto out;
|
|
|
- }
|
|
|
+ if (size)
|
|
|
+ ret = fiemap_fill_next_extent(fieinfo, logical,
|
|
|
+ phys, size, flags);
|
|
|
|
|
|
- /*
|
|
|
- * if size != 0 then we know we already have an extent
|
|
|
- * to add, so add it.
|
|
|
- */
|
|
|
- if (size) {
|
|
|
- ret = fiemap_fill_next_extent(fieinfo, logical,
|
|
|
- phys, size, flags);
|
|
|
- if (ret)
|
|
|
- goto out;
|
|
|
- }
|
|
|
+ if (start_blk > last_blk || ret)
|
|
|
+ goto out;
|
|
|
|
|
|
- logical = blk_to_logical(inode, start_blk);
|
|
|
- phys = blk_to_logical(inode, map_bh.b_blocknr);
|
|
|
- size = map_bh.b_size;
|
|
|
- flags = 0;
|
|
|
- if (buffer_unwritten(&map_bh))
|
|
|
- flags = FIEMAP_EXTENT_UNWRITTEN;
|
|
|
+ logical = blk_to_logical(inode, start_blk);
|
|
|
+ phys = blk_to_logical(inode, map_bh.b_blocknr);
|
|
|
+ size = map_bh.b_size;
|
|
|
+ flags = 0;
|
|
|
+ if (buffer_unwritten(&map_bh))
|
|
|
+ flags = FIEMAP_EXTENT_UNWRITTEN;
|
|
|
|
|
|
- start_blk += logical_to_blk(inode, size);
|
|
|
+ start_blk += logical_to_blk(inode, size);
|
|
|
|
|
|
- /*
|
|
|
- * If we are past the EOF, then we need to make sure as
|
|
|
- * soon as we find a hole that the last extent we found
|
|
|
- * is marked with FIEMAP_EXTENT_LAST
|
|
|
- */
|
|
|
- if (!past_eof && logical + size >= isize)
|
|
|
- past_eof = true;
|
|
|
- }
|
|
|
+prep_next:
|
|
|
cond_resched();
|
|
|
if (fatal_signal_pending(current))
|
|
|
ret = -EINTR;
|