Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fiemap add physical length #10

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 20 additions & 9 deletions Documentation/filesystems/fiemap.rst
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,24 @@ Each extent is described by a single fiemap_extent structure as
returned in fm_extents::

struct fiemap_extent {
__u64 fe_logical; /* logical offset in bytes for the start of
* the extent */
__u64 fe_physical; /* physical offset in bytes for the start
* of the extent */
__u64 fe_length; /* length in bytes for the extent */
__u64 fe_reserved64[2];
__u32 fe_flags; /* FIEMAP_EXTENT_* flags for this extent */
__u32 fe_reserved[3];
/*
* logical offset in bytes for the start of
* the extent from the beginning of the file
*/
__u64 fe_logical;
/*
* physical offset in bytes for the start
* of the extent from the beginning of the disk
*/
__u64 fe_physical;
/* length in bytes for this extent */
__u64 fe_length;
/* physical length in bytes for this extent */
__u64 fe_physical_length;
__u64 fe_reserved64[1];
/* FIEMAP_EXTENT_* flags for this extent */
__u32 fe_flags;
__u32 fe_reserved[3];
};

All offsets and lengths are in bytes and mirror those on disk. It is valid
Expand Down Expand Up @@ -224,7 +234,8 @@ For each extent in the request range, the file system should call
the helper function, fiemap_fill_next_extent()::

int fiemap_fill_next_extent(struct fiemap_extent_info *info, u64 logical,
u64 phys, u64 len, u32 flags, u32 dev);
u64 phys, u64 log_len, u64 phys_len, u32 flags,
u32 dev);

fiemap_fill_next_extent() will use the passed values to populate the
next free extent in the fm_extents array. 'General' extent flags will
Expand Down
6 changes: 5 additions & 1 deletion fs/bcachefs/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -859,7 +859,9 @@ static int bch2_fill_extent(struct bch_fs *c,
ret = fiemap_fill_next_extent(info,
bkey_start_offset(k.k) << 9,
offset << 9,
k.k->size << 9, flags|flags2);
k.k->size << 9,
k.k->size << 9,
flags|flags2);
if (ret)
return ret;
}
Expand All @@ -869,12 +871,14 @@ static int bch2_fill_extent(struct bch_fs *c,
return fiemap_fill_next_extent(info,
bkey_start_offset(k.k) << 9,
0, k.k->size << 9,
k.k->size << 9,
flags|
FIEMAP_EXTENT_DATA_INLINE);
} else if (k.k->type == KEY_TYPE_reservation) {
return fiemap_fill_next_extent(info,
bkey_start_offset(k.k) << 9,
0, k.k->size << 9,
k.k->size << 9,
flags|
FIEMAP_EXTENT_DELALLOC|
FIEMAP_EXTENT_UNWRITTEN);
Expand Down
66 changes: 41 additions & 25 deletions fs/btrfs/extent_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -2507,7 +2507,8 @@ int try_release_extent_mapping(struct page *page, gfp_t mask)
struct btrfs_fiemap_entry {
u64 offset;
u64 phys;
u64 len;
u64 log_len;
u64 phys_len;
u32 flags;
};

Expand Down Expand Up @@ -2565,7 +2566,8 @@ struct fiemap_cache {
/* Fields for the cached extent (unsubmitted, not ready, extent). */
u64 offset;
u64 phys;
u64 len;
u64 log_len;
u64 phys_len;
u32 flags;
bool cached;
};
Expand All @@ -2578,8 +2580,8 @@ static int flush_fiemap_cache(struct fiemap_extent_info *fieinfo,
int ret;

ret = fiemap_fill_next_extent(fieinfo, entry->offset,
entry->phys, entry->len,
entry->flags);
entry->phys, entry->log_len,
entry->phys_len, entry->flags);
/*
* Ignore 1 (reached max entries) because we keep track of that
* ourselves in emit_fiemap_extent().
Expand All @@ -2604,7 +2606,8 @@ static int flush_fiemap_cache(struct fiemap_extent_info *fieinfo,
*/
static int emit_fiemap_extent(struct fiemap_extent_info *fieinfo,
struct fiemap_cache *cache,
u64 offset, u64 phys, u64 len, u32 flags)
u64 offset, u64 phys, u64 log_len,
u64 phys_len, u32 flags)
{
struct btrfs_fiemap_entry *entry;
u64 cache_end;
Expand Down Expand Up @@ -2647,7 +2650,7 @@ static int emit_fiemap_extent(struct fiemap_extent_info *fieinfo,
* or equals to what we have in cache->offset. We deal with this as
* described below.
*/
cache_end = cache->offset + cache->len;
cache_end = cache->offset + cache->log_len;
if (cache_end > offset) {
if (offset == cache->offset) {
/*
Expand All @@ -2671,10 +2674,10 @@ static int emit_fiemap_extent(struct fiemap_extent_info *fieinfo,
* where a previously found file extent item was split
* due to an ordered extent completing.
*/
cache->len = offset - cache->offset;
cache->log_len = offset - cache->offset;
goto emit;
} else {
const u64 range_end = offset + len;
const u64 range_end = offset + log_len;

/*
* The offset of the file extent item we have just found
Expand Down Expand Up @@ -2711,7 +2714,7 @@ static int emit_fiemap_extent(struct fiemap_extent_info *fieinfo,
phys += cache_end - offset;

offset = cache_end;
len = range_end - cache_end;
log_len = range_end - cache_end;
goto emit;
}
}
Expand All @@ -2721,15 +2724,17 @@ static int emit_fiemap_extent(struct fiemap_extent_info *fieinfo,
* 1) Their logical addresses are continuous
*
* 2) Their physical addresses are continuous
* So truly compressed (physical size smaller than logical size)
* extents won't get merged with each other
*
* 3) Share same flags
*
* 4) Not compressed
*/
if (cache->offset + cache->len == offset &&
cache->phys + cache->len == phys &&
cache->flags == flags) {
cache->len += len;
if (cache->offset + cache->log_len == offset &&
cache->phys + cache->log_len == phys &&
cache->flags == flags &&
!(flags & FIEMAP_EXTENT_ENCODED)) {
cache->log_len += log_len;
cache->phys_len += phys_len;
return 0;
}

Expand All @@ -2746,7 +2751,7 @@ static int emit_fiemap_extent(struct fiemap_extent_info *fieinfo,
* to miss it.
*/
entry = &cache->entries[cache->entries_size - 1];
cache->next_search_offset = entry->offset + entry->len;
cache->next_search_offset = entry->offset + entry->log_len;
cache->cached = false;

return BTRFS_FIEMAP_FLUSH_CACHE;
Expand All @@ -2755,7 +2760,8 @@ static int emit_fiemap_extent(struct fiemap_extent_info *fieinfo,
entry = &cache->entries[cache->entries_pos];
entry->offset = cache->offset;
entry->phys = cache->phys;
entry->len = cache->len;
entry->log_len = cache->log_len;
entry->phys_len = cache->phys_len;
entry->flags = cache->flags;
cache->entries_pos++;
cache->extents_mapped++;
Expand All @@ -2768,7 +2774,8 @@ static int emit_fiemap_extent(struct fiemap_extent_info *fieinfo,
cache->cached = true;
cache->offset = offset;
cache->phys = phys;
cache->len = len;
cache->log_len = log_len;
cache->phys_len = phys_len;
cache->flags = flags;

return 0;
Expand All @@ -2794,7 +2801,8 @@ static int emit_last_fiemap_cache(struct fiemap_extent_info *fieinfo,
return 0;

ret = fiemap_fill_next_extent(fieinfo, cache->offset, cache->phys,
cache->len, cache->flags);
cache->log_len, cache->phys_len,
cache->flags);
cache->cached = false;
if (ret > 0)
ret = 0;
Expand Down Expand Up @@ -2988,13 +2996,15 @@ static int fiemap_process_hole(struct btrfs_inode *inode,
}
ret = emit_fiemap_extent(fieinfo, cache, prealloc_start,
disk_bytenr + extent_offset,
prealloc_len, prealloc_flags);
prealloc_len, prealloc_len,
prealloc_flags);
if (ret)
return ret;
extent_offset += prealloc_len;
}

ret = emit_fiemap_extent(fieinfo, cache, delalloc_start, 0,
delalloc_end + 1 - delalloc_start,
delalloc_end + 1 - delalloc_start,
FIEMAP_EXTENT_DELALLOC |
FIEMAP_EXTENT_UNKNOWN);
Expand Down Expand Up @@ -3035,7 +3045,8 @@ static int fiemap_process_hole(struct btrfs_inode *inode,
}
ret = emit_fiemap_extent(fieinfo, cache, prealloc_start,
disk_bytenr + extent_offset,
prealloc_len, prealloc_flags);
prealloc_len, prealloc_len,
prealloc_flags);
if (ret)
return ret;
}
Expand Down Expand Up @@ -3181,6 +3192,7 @@ int extent_fiemap(struct btrfs_inode *inode, struct fiemap_extent_info *fieinfo,
u64 extent_offset = 0;
u64 extent_gen;
u64 disk_bytenr = 0;
u64 disk_size = 0;
u64 flags = 0;
int extent_type;
u8 compression;
Expand Down Expand Up @@ -3232,8 +3244,9 @@ int extent_fiemap(struct btrfs_inode *inode, struct fiemap_extent_info *fieinfo,

if (extent_type != BTRFS_FILE_EXTENT_INLINE) {
disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, ei);
if (compression == BTRFS_COMPRESS_NONE)
if (compression == BTRFS_COMPRESS_NONE) {
extent_offset = btrfs_file_extent_offset(leaf, ei);
}
}

if (compression != BTRFS_COMPRESS_NONE)
Expand All @@ -3243,7 +3256,7 @@ int extent_fiemap(struct btrfs_inode *inode, struct fiemap_extent_info *fieinfo,
flags |= FIEMAP_EXTENT_DATA_INLINE;
flags |= FIEMAP_EXTENT_NOT_ALIGNED;
ret = emit_fiemap_extent(fieinfo, &cache, key.offset, 0,
extent_len, flags);
extent_len, extent_len, flags);
} else if (extent_type == BTRFS_FILE_EXTENT_PREALLOC) {
ret = fiemap_process_hole(inode, fieinfo, &cache,
&delalloc_cached_state,
Expand All @@ -3258,6 +3271,7 @@ int extent_fiemap(struct btrfs_inode *inode, struct fiemap_extent_info *fieinfo,
backref_ctx, 0, 0, 0,
key.offset, extent_end - 1);
} else {
disk_size = btrfs_file_extent_disk_num_bytes(leaf, ei);
/* We have a regular extent. */
if (fieinfo->fi_extents_max) {
ret = btrfs_is_data_extent_shared(inode,
Expand All @@ -3272,7 +3286,9 @@ int extent_fiemap(struct btrfs_inode *inode, struct fiemap_extent_info *fieinfo,

ret = emit_fiemap_extent(fieinfo, &cache, key.offset,
disk_bytenr + extent_offset,
extent_len, flags);
extent_len,
disk_size - extent_offset,
flags);
}

if (ret < 0) {
Expand Down Expand Up @@ -3310,7 +3326,7 @@ int extent_fiemap(struct btrfs_inode *inode, struct fiemap_extent_info *fieinfo,
prev_extent_end = range_end;
}

if (cache.cached && cache.offset + cache.len >= last_extent_end) {
if (cache.cached && cache.offset + cache.log_len >= last_extent_end) {
const u64 i_size = i_size_read(&inode->vfs_inode);

if (prev_extent_end < i_size) {
Expand Down
1 change: 1 addition & 0 deletions fs/ext4/extents.c
Original file line number Diff line number Diff line change
Expand Up @@ -2215,6 +2215,7 @@ static int ext4_fill_es_cache_info(struct inode *inode,
(__u64)es.es_lblk << blksize_bits,
(__u64)es.es_pblk << blksize_bits,
(__u64)es.es_len << blksize_bits,
(__u64)es.es_len << blksize_bits,
flags);
if (next == 0)
break;
Expand Down
8 changes: 5 additions & 3 deletions fs/f2fs/data.c
Original file line number Diff line number Diff line change
Expand Up @@ -1906,7 +1906,8 @@ static int f2fs_xattr_fiemap(struct inode *inode,
if (!xnid)
flags |= FIEMAP_EXTENT_LAST;

err = fiemap_fill_next_extent(fieinfo, 0, phys, len, flags);
err = fiemap_fill_next_extent(
fieinfo, 0, phys, len, len, flags);
trace_f2fs_fiemap(inode, 0, phys, len, flags, err);
if (err)
return err;
Expand All @@ -1932,7 +1933,8 @@ static int f2fs_xattr_fiemap(struct inode *inode,
}

if (phys) {
err = fiemap_fill_next_extent(fieinfo, 0, phys, len, flags);
err = fiemap_fill_next_extent(
fieinfo, 0, phys, len, len, flags);
trace_f2fs_fiemap(inode, 0, phys, len, flags, err);
}

Expand Down Expand Up @@ -2051,7 +2053,7 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
flags |= FIEMAP_EXTENT_DATA_ENCRYPTED;

ret = fiemap_fill_next_extent(fieinfo, logical,
phys, size, flags);
phys, size, size, flags);
trace_f2fs_fiemap(inode, logical, phys, size, flags, ret);
if (ret)
goto out;
Expand Down
3 changes: 2 additions & 1 deletion fs/f2fs/inline.c
Original file line number Diff line number Diff line change
Expand Up @@ -806,7 +806,8 @@ int f2fs_inline_data_fiemap(struct inode *inode,
byteaddr = (__u64)ni.blk_addr << inode->i_sb->s_blocksize_bits;
byteaddr += (char *)inline_data_addr(inode, ipage) -
(char *)F2FS_INODE(ipage);
err = fiemap_fill_next_extent(fieinfo, start, byteaddr, ilen, flags);
err = fiemap_fill_next_extent(
fieinfo, start, byteaddr, ilen, ilen, flags);
trace_f2fs_fiemap(inode, start, byteaddr, ilen, flags, err);
out:
f2fs_put_page(ipage, 1);
Expand Down
8 changes: 5 additions & 3 deletions fs/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ static int ioctl_fibmap(struct file *filp, int __user *p)
* @fieinfo: Fiemap context passed into ->fiemap
* @logical: Extent logical start offset, in bytes
* @phys: Extent physical start offset, in bytes
* @len: Extent length, in bytes
* @log_len: Extent logical length, in bytes
* @phys_len: Extent physical length, in bytes
* @flags: FIEMAP_EXTENT flags that describe this extent
*
* Called from file system ->fiemap callback. Will populate extent
Expand All @@ -110,7 +111,7 @@ static int ioctl_fibmap(struct file *filp, int __user *p)
* extent that will fit in user array.
*/
int fiemap_fill_next_extent(struct fiemap_extent_info *fieinfo, u64 logical,
u64 phys, u64 len, u32 flags)
u64 phys, u64 log_len, u64 phys_len, u32 flags)
{
struct fiemap_extent extent;
struct fiemap_extent __user *dest = fieinfo->fi_extents_start;
Expand Down Expand Up @@ -138,7 +139,8 @@ int fiemap_fill_next_extent(struct fiemap_extent_info *fieinfo, u64 logical,
memset(&extent, 0, sizeof(extent));
extent.fe_logical = logical;
extent.fe_physical = phys;
extent.fe_length = len;
extent.fe_length = log_len;
extent.fe_physical_length = phys_len;
extent.fe_flags = flags;

dest += fieinfo->fi_extents_mapped;
Expand Down
2 changes: 1 addition & 1 deletion fs/iomap/fiemap.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ static int iomap_to_fiemap(struct fiemap_extent_info *fi,

return fiemap_fill_next_extent(fi, iomap->offset,
iomap->addr != IOMAP_NULL_ADDR ? iomap->addr : 0,
iomap->length, flags);
iomap->length, iomap->length, flags);
}

static loff_t iomap_fiemap_iter(const struct iomap_iter *iter,
Expand Down
Loading