mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-06 19:07:52 +00:00
iomap: switch iomap_fiemap to use iomap_iter
Rewrite the ->fiemap implementation based on iomap_iter. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
This commit is contained in:
parent
a6d3d49587
commit
7892386d35
1 changed files with 29 additions and 41 deletions
|
@ -1,6 +1,6 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2018 Christoph Hellwig.
|
* Copyright (c) 2016-2021 Christoph Hellwig.
|
||||||
*/
|
*/
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
|
@ -8,13 +8,8 @@
|
||||||
#include <linux/iomap.h>
|
#include <linux/iomap.h>
|
||||||
#include <linux/fiemap.h>
|
#include <linux/fiemap.h>
|
||||||
|
|
||||||
struct fiemap_ctx {
|
|
||||||
struct fiemap_extent_info *fi;
|
|
||||||
struct iomap prev;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int iomap_to_fiemap(struct fiemap_extent_info *fi,
|
static int iomap_to_fiemap(struct fiemap_extent_info *fi,
|
||||||
struct iomap *iomap, u32 flags)
|
const struct iomap *iomap, u32 flags)
|
||||||
{
|
{
|
||||||
switch (iomap->type) {
|
switch (iomap->type) {
|
||||||
case IOMAP_HOLE:
|
case IOMAP_HOLE:
|
||||||
|
@ -43,24 +38,22 @@ static int iomap_to_fiemap(struct fiemap_extent_info *fi,
|
||||||
iomap->length, flags);
|
iomap->length, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static loff_t
|
static loff_t iomap_fiemap_iter(const struct iomap_iter *iter,
|
||||||
iomap_fiemap_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
|
struct fiemap_extent_info *fi, struct iomap *prev)
|
||||||
struct iomap *iomap, struct iomap *srcmap)
|
|
||||||
{
|
{
|
||||||
struct fiemap_ctx *ctx = data;
|
int ret;
|
||||||
loff_t ret = length;
|
|
||||||
|
|
||||||
if (iomap->type == IOMAP_HOLE)
|
if (iter->iomap.type == IOMAP_HOLE)
|
||||||
return length;
|
return iomap_length(iter);
|
||||||
|
|
||||||
ret = iomap_to_fiemap(ctx->fi, &ctx->prev, 0);
|
ret = iomap_to_fiemap(fi, prev, 0);
|
||||||
ctx->prev = *iomap;
|
*prev = iter->iomap;
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
case 0: /* success */
|
case 0: /* success */
|
||||||
return length;
|
return iomap_length(iter);
|
||||||
case 1: /* extent array full */
|
case 1: /* extent array full */
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default: /* error */
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,38 +61,33 @@ iomap_fiemap_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
|
||||||
int iomap_fiemap(struct inode *inode, struct fiemap_extent_info *fi,
|
int iomap_fiemap(struct inode *inode, struct fiemap_extent_info *fi,
|
||||||
u64 start, u64 len, const struct iomap_ops *ops)
|
u64 start, u64 len, const struct iomap_ops *ops)
|
||||||
{
|
{
|
||||||
struct fiemap_ctx ctx;
|
struct iomap_iter iter = {
|
||||||
loff_t ret;
|
.inode = inode,
|
||||||
|
.pos = start,
|
||||||
|
.len = len,
|
||||||
|
.flags = IOMAP_REPORT,
|
||||||
|
};
|
||||||
|
struct iomap prev = {
|
||||||
|
.type = IOMAP_HOLE,
|
||||||
|
};
|
||||||
|
int ret;
|
||||||
|
|
||||||
memset(&ctx, 0, sizeof(ctx));
|
ret = fiemap_prep(inode, fi, start, &iter.len, 0);
|
||||||
ctx.fi = fi;
|
|
||||||
ctx.prev.type = IOMAP_HOLE;
|
|
||||||
|
|
||||||
ret = fiemap_prep(inode, fi, start, &len, 0);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
while (len > 0) {
|
while ((ret = iomap_iter(&iter, ops)) > 0)
|
||||||
ret = iomap_apply(inode, start, len, IOMAP_REPORT, ops, &ctx,
|
iter.processed = iomap_fiemap_iter(&iter, fi, &prev);
|
||||||
iomap_fiemap_actor);
|
|
||||||
|
if (prev.type != IOMAP_HOLE) {
|
||||||
|
ret = iomap_to_fiemap(fi, &prev, FIEMAP_EXTENT_LAST);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* inode with no (attribute) mapping will give ENOENT */
|
/* inode with no (attribute) mapping will give ENOENT */
|
||||||
if (ret == -ENOENT)
|
if (ret < 0 && ret != -ENOENT)
|
||||||
break;
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
return ret;
|
||||||
if (ret == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
start += ret;
|
|
||||||
len -= ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctx.prev.type != IOMAP_HOLE) {
|
|
||||||
ret = iomap_to_fiemap(fi, &ctx.prev, FIEMAP_EXTENT_LAST);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(iomap_fiemap);
|
EXPORT_SYMBOL_GPL(iomap_fiemap);
|
||||||
|
|
Loading…
Reference in a new issue