1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2017 Red Hat, Inc.
4 * Copyright (c) 2018-2021 Christoph Hellwig.
6 #include <linux/module.h>
7 #include <linux/compiler.h>
9 #include <linux/iomap.h>
10 #include <linux/pagemap.h>
11 #include <linux/pagevec.h>
13 static loff_t
iomap_seek_hole_iter(const struct iomap_iter
*iter
,
16 loff_t length
= iomap_length(iter
);
18 switch (iter
->iomap
.type
) {
20 *hole_pos
= mapping_seek_hole_data(iter
->inode
->i_mapping
,
21 iter
->pos
, iter
->pos
+ length
, SEEK_HOLE
);
22 if (*hole_pos
== iter
->pos
+ length
)
26 *hole_pos
= iter
->pos
;
34 iomap_seek_hole(struct inode
*inode
, loff_t pos
, const struct iomap_ops
*ops
)
36 loff_t size
= i_size_read(inode
);
37 struct iomap_iter iter
= {
40 .flags
= IOMAP_REPORT
,
44 /* Nothing to be found before or beyond the end of the file. */
45 if (pos
< 0 || pos
>= size
)
48 iter
.len
= size
- pos
;
49 while ((ret
= iomap_iter(&iter
, ops
)) > 0)
50 iter
.processed
= iomap_seek_hole_iter(&iter
, &pos
);
53 if (iter
.len
) /* found hole before EOF */
57 EXPORT_SYMBOL_GPL(iomap_seek_hole
);
59 static loff_t
iomap_seek_data_iter(const struct iomap_iter
*iter
,
62 loff_t length
= iomap_length(iter
);
64 switch (iter
->iomap
.type
) {
68 *hole_pos
= mapping_seek_hole_data(iter
->inode
->i_mapping
,
69 iter
->pos
, iter
->pos
+ length
, SEEK_DATA
);
74 *hole_pos
= iter
->pos
;
80 iomap_seek_data(struct inode
*inode
, loff_t pos
, const struct iomap_ops
*ops
)
82 loff_t size
= i_size_read(inode
);
83 struct iomap_iter iter
= {
86 .flags
= IOMAP_REPORT
,
90 /* Nothing to be found before or beyond the end of the file. */
91 if (pos
< 0 || pos
>= size
)
94 iter
.len
= size
- pos
;
95 while ((ret
= iomap_iter(&iter
, ops
)) > 0)
96 iter
.processed
= iomap_seek_data_iter(&iter
, &pos
);
99 if (iter
.len
) /* found data before EOF */
101 /* We've reached the end of the file without finding data */
104 EXPORT_SYMBOL_GPL(iomap_seek_data
);