iomap: switch iomap_fiemap to use iomap_iter
authorChristoph Hellwig <hch@lst.de>
Wed, 11 Aug 2021 01:33:10 +0000 (18:33 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 17 Aug 2021 04:26:33 +0000 (21:26 -0700)
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>
fs/iomap/fiemap.c

index aab070d..acad09a 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright (c) 2016-2018 Christoph Hellwig.
+ * Copyright (c) 2016-2021 Christoph Hellwig.
  */
 #include <linux/module.h>
 #include <linux/compiler.h>
@@ -8,13 +8,8 @@
 #include <linux/iomap.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,
-               struct iomap *iomap, u32 flags)
+               const struct iomap *iomap, u32 flags)
 {
        switch (iomap->type) {
        case IOMAP_HOLE:
@@ -43,24 +38,22 @@ static int iomap_to_fiemap(struct fiemap_extent_info *fi,
                        iomap->length, flags);
 }
 
-static loff_t
-iomap_fiemap_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
-               struct iomap *iomap, struct iomap *srcmap)
+static loff_t iomap_fiemap_iter(const struct iomap_iter *iter,
+               struct fiemap_extent_info *fi, struct iomap *prev)
 {
-       struct fiemap_ctx *ctx = data;
-       loff_t ret = length;
+       int ret;
 
-       if (iomap->type == IOMAP_HOLE)
-               return length;
+       if (iter->iomap.type == IOMAP_HOLE)
+               return iomap_length(iter);
 
-       ret = iomap_to_fiemap(ctx->fi, &ctx->prev, 0);
-       ctx->prev = *iomap;
+       ret = iomap_to_fiemap(fi, prev, 0);
+       *prev = iter->iomap;
        switch (ret) {
        case 0:         /* success */
-               return length;
+               return iomap_length(iter);
        case 1:         /* extent array full */
                return 0;
-       default:
+       default:        /* error */
                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,
                u64 start, u64 len, const struct iomap_ops *ops)
 {
-       struct fiemap_ctx ctx;
-       loff_t ret;
-
-       memset(&ctx, 0, sizeof(ctx));
-       ctx.fi = fi;
-       ctx.prev.type = IOMAP_HOLE;
+       struct iomap_iter iter = {
+               .inode          = inode,
+               .pos            = start,
+               .len            = len,
+               .flags          = IOMAP_REPORT,
+       };
+       struct iomap prev = {
+               .type           = IOMAP_HOLE,
+       };
+       int ret;
 
-       ret = fiemap_prep(inode, fi, start, &len, 0);
+       ret = fiemap_prep(inode, fi, start, &iter.len, 0);
        if (ret)
                return ret;
 
-       while (len > 0) {
-               ret = iomap_apply(inode, start, len, IOMAP_REPORT, ops, &ctx,
-                               iomap_fiemap_actor);
-               /* inode with no (attribute) mapping will give ENOENT */
-               if (ret == -ENOENT)
-                       break;
-               if (ret < 0)
-                       return ret;
-               if (ret == 0)
-                       break;
+       while ((ret = iomap_iter(&iter, ops)) > 0)
+               iter.processed = iomap_fiemap_iter(&iter, fi, &prev);
 
-               start += ret;
-               len -= ret;
-       }
-
-       if (ctx.prev.type != IOMAP_HOLE) {
-               ret = iomap_to_fiemap(fi, &ctx.prev, FIEMAP_EXTENT_LAST);
+       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 */
+       if (ret < 0 && ret != -ENOENT)
+               return ret;
        return 0;
 }
 EXPORT_SYMBOL_GPL(iomap_fiemap);