Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 144647
b: refs/heads/master
c: df3935f
h: refs/heads/master
i:
  144645: 59be028
  144643: e823098
  144639: e2c767f
v: v3
  • Loading branch information
Josef Bacik authored and Linus Torvalds committed May 6, 2009
1 parent d428aab commit ac4a91a
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 21 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 57adc4d2dbf968fdbe516359688094eef4d46581
refs/heads/master: df3935ffd6166fdd00702cf548fb5bb55737758b
75 changes: 55 additions & 20 deletions trunk/fs/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,14 +258,17 @@ int __generic_block_fiemap(struct inode *inode,
long long length = 0, map_len = 0;
u64 logical = 0, phys = 0, size = 0;
u32 flags = FIEMAP_EXTENT_MERGED;
int ret = 0;
int ret = 0, past_eof = 0, whole_file = 0;

if ((ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC)))
return ret;

start_blk = logical_to_blk(inode, start);

length = (long long)min_t(u64, len, i_size_read(inode));
if (length < len)
whole_file = 1;

map_len = length;

do {
Expand All @@ -282,27 +285,64 @@ int __generic_block_fiemap(struct inode *inode,

/* HOLE */
if (!buffer_mapped(&tmp)) {
length -= blk_to_logical(inode, 1);
start_blk++;

/*
* we want to handle the case where there is an
* allocated block at the front of the file, and then
* nothing but holes up to the end of the file properly,
* to make sure that extent at the front gets properly
* marked with FIEMAP_EXTENT_LAST
*/
if (!past_eof &&
blk_to_logical(inode, start_blk) >=
blk_to_logical(inode, 0)+i_size_read(inode))
past_eof = 1;

/*
* first hole after going past the EOF, this is our
* last extent
*/
if (length <= 0) {
if (past_eof && size) {
flags = FIEMAP_EXTENT_MERGED|FIEMAP_EXTENT_LAST;
ret = fiemap_fill_next_extent(fieinfo, logical,
phys, size,
flags);
break;
}

length -= blk_to_logical(inode, 1);

/* if we have holes up to/past EOF then we're done */
if (length <= 0)
if (length <= 0 || past_eof)
break;

start_blk++;
} else {
if (length <= 0 && size) {
/*
* we have gone over the length of what we wanted to
* map, and it wasn't the entire file, so add the extent
* we got last time and exit.
*
* This is for the case where say we want to map all the
* way up to the second to the last block in a file, but
* the last block is a hole, making the second to last
* block FIEMAP_EXTENT_LAST. In this case we want to
* see if there is a hole after the second to last block
* so we can mark it properly. If we found data after
* we exceeded the length we were requesting, then we
* are good to go, just add the extent to the fieinfo
* and break
*/
if (length <= 0 && !whole_file) {
ret = fiemap_fill_next_extent(fieinfo, logical,
phys, size,
flags);
break;
}

/*
* 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);
Expand All @@ -319,19 +359,14 @@ int __generic_block_fiemap(struct inode *inode,
start_blk += logical_to_blk(inode, size);

/*
* if we are past the EOF we need to loop again to see
* if there is a hole so we can mark this extent as the
* last one, and if not keep mapping things until we
* find a hole, or we run out of slots in the extent
* array
* 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 (length <= 0)
continue;

ret = fiemap_fill_next_extent(fieinfo, logical, phys,
size, flags);
if (ret)
break;
if (!past_eof &&
logical+size >=
blk_to_logical(inode, 0)+i_size_read(inode))
past_eof = 1;
}
cond_resched();
} while (1);
Expand Down

0 comments on commit ac4a91a

Please sign in to comment.