1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2016-2021 Christoph Hellwig.
5 #include <linux/module.h>
6 #include <linux/compiler.h>
8 #include <linux/iomap.h>
9 #include <linux/fiemap.h>
10 #include <linux/pagemap.h>
12 static int iomap_to_fiemap(struct fiemap_extent_info
*fi
,
13 const struct iomap
*iomap
, u32 flags
)
15 switch (iomap
->type
) {
20 flags
|= FIEMAP_EXTENT_DELALLOC
| FIEMAP_EXTENT_UNKNOWN
;
25 flags
|= FIEMAP_EXTENT_UNWRITTEN
;
28 flags
|= FIEMAP_EXTENT_DATA_INLINE
;
32 if (iomap
->flags
& IOMAP_F_MERGED
)
33 flags
|= FIEMAP_EXTENT_MERGED
;
34 if (iomap
->flags
& IOMAP_F_SHARED
)
35 flags
|= FIEMAP_EXTENT_SHARED
;
37 return fiemap_fill_next_extent(fi
, iomap
->offset
,
38 iomap
->addr
!= IOMAP_NULL_ADDR
? iomap
->addr
: 0,
39 iomap
->length
, flags
);
42 static loff_t
iomap_fiemap_iter(const struct iomap_iter
*iter
,
43 struct fiemap_extent_info
*fi
, struct iomap
*prev
)
47 if (iter
->iomap
.type
== IOMAP_HOLE
)
48 return iomap_length(iter
);
50 ret
= iomap_to_fiemap(fi
, prev
, 0);
54 return iomap_length(iter
);
55 case 1: /* extent array full */
62 int iomap_fiemap(struct inode
*inode
, struct fiemap_extent_info
*fi
,
63 u64 start
, u64 len
, const struct iomap_ops
*ops
)
65 struct iomap_iter iter
= {
69 .flags
= IOMAP_REPORT
,
76 ret
= fiemap_prep(inode
, fi
, start
, &iter
.len
, 0);
80 while ((ret
= iomap_iter(&iter
, ops
)) > 0)
81 iter
.processed
= iomap_fiemap_iter(&iter
, fi
, &prev
);
83 if (prev
.type
!= IOMAP_HOLE
) {
84 ret
= iomap_to_fiemap(fi
, &prev
, FIEMAP_EXTENT_LAST
);
89 /* inode with no (attribute) mapping will give ENOENT */
90 if (ret
< 0 && ret
!= -ENOENT
)
94 EXPORT_SYMBOL_GPL(iomap_fiemap
);
96 /* legacy ->bmap interface. 0 is the error return (!) */
98 iomap_bmap(struct address_space
*mapping
, sector_t bno
,
99 const struct iomap_ops
*ops
)
101 struct iomap_iter iter
= {
102 .inode
= mapping
->host
,
103 .pos
= (loff_t
)bno
<< mapping
->host
->i_blkbits
,
104 .len
= i_blocksize(mapping
->host
),
105 .flags
= IOMAP_REPORT
,
107 const unsigned int blkshift
= mapping
->host
->i_blkbits
- SECTOR_SHIFT
;
110 if (filemap_write_and_wait(mapping
))
114 while ((ret
= iomap_iter(&iter
, ops
)) > 0) {
115 if (iter
.iomap
.type
== IOMAP_MAPPED
)
116 bno
= iomap_sector(&iter
.iomap
, iter
.pos
) >> blkshift
;
117 /* leave iter.processed unset to abort loop */
124 EXPORT_SYMBOL_GPL(iomap_bmap
);