|
21 | 21 | #include <linux/cleancache.h>
|
22 | 22 | #include <linux/sched/signal.h>
|
23 | 23 | #include <linux/fiemap.h>
|
| 24 | +#include <linux/iomap.h> |
24 | 25 |
|
25 | 26 | #include "f2fs.h"
|
26 | 27 | #include "node.h"
|
@@ -4237,3 +4238,58 @@ void f2fs_destroy_bio_entry_cache(void)
|
4237 | 4238 | {
|
4238 | 4239 | kmem_cache_destroy(bio_entry_slab);
|
4239 | 4240 | }
|
| 4241 | + |
| 4242 | +static int f2fs_iomap_begin(struct inode *inode, loff_t offset, loff_t length, |
| 4243 | + unsigned int flags, struct iomap *iomap, |
| 4244 | + struct iomap *srcmap) |
| 4245 | +{ |
| 4246 | + struct f2fs_map_blocks map = {}; |
| 4247 | + pgoff_t next_pgofs = 0; |
| 4248 | + int err; |
| 4249 | + |
| 4250 | + map.m_lblk = bytes_to_blks(inode, offset); |
| 4251 | + map.m_len = bytes_to_blks(inode, offset + length - 1) - map.m_lblk + 1; |
| 4252 | + map.m_next_pgofs = &next_pgofs; |
| 4253 | + map.m_seg_type = f2fs_rw_hint_to_seg_type(inode->i_write_hint); |
| 4254 | + if (flags & IOMAP_WRITE) |
| 4255 | + map.m_may_create = true; |
| 4256 | + |
| 4257 | + err = f2fs_map_blocks(inode, &map, flags & IOMAP_WRITE, |
| 4258 | + F2FS_GET_BLOCK_DIO); |
| 4259 | + if (err) |
| 4260 | + return err; |
| 4261 | + |
| 4262 | + iomap->offset = blks_to_bytes(inode, map.m_lblk); |
| 4263 | + |
| 4264 | + if (map.m_flags & (F2FS_MAP_MAPPED | F2FS_MAP_UNWRITTEN)) { |
| 4265 | + iomap->length = blks_to_bytes(inode, map.m_len); |
| 4266 | + if (map.m_flags & F2FS_MAP_MAPPED) { |
| 4267 | + iomap->type = IOMAP_MAPPED; |
| 4268 | + iomap->flags |= IOMAP_F_MERGED; |
| 4269 | + } else { |
| 4270 | + iomap->type = IOMAP_UNWRITTEN; |
| 4271 | + } |
| 4272 | + if (WARN_ON_ONCE(!__is_valid_data_blkaddr(map.m_pblk))) |
| 4273 | + return -EINVAL; |
| 4274 | + |
| 4275 | + iomap->bdev = map.m_bdev; |
| 4276 | + iomap->addr = blks_to_bytes(inode, map.m_pblk); |
| 4277 | + } else { |
| 4278 | + iomap->length = blks_to_bytes(inode, next_pgofs) - |
| 4279 | + iomap->offset; |
| 4280 | + iomap->type = IOMAP_HOLE; |
| 4281 | + iomap->addr = IOMAP_NULL_ADDR; |
| 4282 | + } |
| 4283 | + |
| 4284 | + if (map.m_flags & F2FS_MAP_NEW) |
| 4285 | + iomap->flags |= IOMAP_F_NEW; |
| 4286 | + if ((inode->i_state & I_DIRTY_DATASYNC) || |
| 4287 | + offset + length > i_size_read(inode)) |
| 4288 | + iomap->flags |= IOMAP_F_DIRTY; |
| 4289 | + |
| 4290 | + return 0; |
| 4291 | +} |
| 4292 | + |
| 4293 | +const struct iomap_ops f2fs_iomap_ops = { |
| 4294 | + .iomap_begin = f2fs_iomap_begin, |
| 4295 | +}; |
0 commit comments