mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
nilfs2: add iomap operations for direct I/O
The patch adds iomap.h with declaration of iomaps operations and iomap.c with implementation of nilfs_iomap_begin(). This method is based on calling the nilfs_bmap_lookup_contig() method. It resolves the file's block-mapping to find the sequence of physically-contiguous blocks starting at starting block. Offsets at or beyond i_size are reported as a hole. For offsets within i_size, the requested length is first clamped to the block-aligned end of the file. Both the hole and mapped cases then report iomap->offset aligned to the containing block (blkoff << i_blkbits) rather than the raw request offset. Co-developed-by: Linmao Li <lilinmao@kylinos.cn> Signed-off-by: Linmao Li <lilinmao@kylinos.cn> cc: Christoph Hellwig <hch@lst.de> cc: Ryusuke Konishi <konishi.ryusuke@gmail.com> cc: linux-nilfs@vger.kernel.org cc: linux-fsdevel@vger.kernel.org Acked-by: Ryusuke Konishi <konishi.ryusuke@gmail.com> Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
This commit is contained in:
parent
8393ce53a5
commit
89eebc9b5f
|
|
@ -3,4 +3,4 @@ obj-$(CONFIG_NILFS2_FS) += nilfs2.o
|
|||
nilfs2-y := inode.o file.o dir.o super.o namei.o page.o mdt.o \
|
||||
btnode.o bmap.o btree.o direct.o dat.o recovery.o \
|
||||
the_nilfs.o segbuf.o segment.o cpfile.o sufile.o \
|
||||
ifile.o alloc.o gcinode.o ioctl.o sysfs.o
|
||||
ifile.o alloc.o gcinode.o ioctl.o sysfs.o iomap.o
|
||||
|
|
|
|||
72
fs/nilfs2/iomap.c
Normal file
72
fs/nilfs2/iomap.c
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* NILFS iomap support implementation.
|
||||
*
|
||||
* Written by Viacheslav Dubeyko.
|
||||
*/
|
||||
|
||||
#include <linux/iomap.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include "nilfs.h"
|
||||
#include "mdt.h"
|
||||
#include "iomap.h"
|
||||
|
||||
static int nilfs_iomap_begin(struct inode *inode, loff_t offset,
|
||||
loff_t length, unsigned int flags,
|
||||
struct iomap *iomap, struct iomap *srcmap)
|
||||
{
|
||||
struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
|
||||
struct nilfs_inode_info *ii = NILFS_I(inode);
|
||||
sector_t blkoff = offset >> inode->i_blkbits;
|
||||
loff_t iomap_offset = (loff_t)blkoff << inode->i_blkbits;
|
||||
unsigned int maxblocks;
|
||||
__u64 blknum = 0;
|
||||
int ret;
|
||||
|
||||
/* Completely beyond EOF. Treat as hole */
|
||||
if (i_size_read(inode) <= offset) {
|
||||
iomap->type = IOMAP_HOLE;
|
||||
iomap->addr = IOMAP_NULL_ADDR;
|
||||
iomap->offset = offset;
|
||||
iomap->length = length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Clamp length if the requested range goes beyond i_size */
|
||||
if (offset + length > i_size_read(inode)) {
|
||||
loff_t i_size = i_size_read(inode);
|
||||
unsigned int blocksize = i_blocksize(inode);
|
||||
|
||||
length = round_up(i_size, blocksize) - offset;
|
||||
}
|
||||
|
||||
maxblocks = min_t(loff_t, length >> inode->i_blkbits, INT_MAX);
|
||||
if (maxblocks == 0)
|
||||
maxblocks = 1;
|
||||
|
||||
down_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem);
|
||||
ret = nilfs_bmap_lookup_contig(ii->i_bmap, blkoff, &blknum, maxblocks);
|
||||
up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem);
|
||||
|
||||
if (ret == -ENOENT) {
|
||||
iomap->type = IOMAP_HOLE;
|
||||
iomap->addr = IOMAP_NULL_ADDR;
|
||||
iomap->offset = iomap_offset;
|
||||
iomap->length = i_blocksize(inode);
|
||||
return 0;
|
||||
} else if (ret < 0)
|
||||
return ret;
|
||||
|
||||
iomap->bdev = inode->i_sb->s_bdev;
|
||||
iomap->offset = iomap_offset;
|
||||
iomap->length = (loff_t)ret << inode->i_blkbits;
|
||||
iomap->addr = (loff_t)blknum << inode->i_blkbits;
|
||||
iomap->type = IOMAP_MAPPED;
|
||||
iomap->flags = IOMAP_F_MERGED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct iomap_ops nilfs_iomap_ops = {
|
||||
.iomap_begin = nilfs_iomap_begin,
|
||||
};
|
||||
13
fs/nilfs2/iomap.h
Normal file
13
fs/nilfs2/iomap.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* NILFS iomap support declarations.
|
||||
*
|
||||
* Written by Viacheslav Dubeyko.
|
||||
*/
|
||||
|
||||
#ifndef _NILFS_IOMAP_H
|
||||
#define _NILFS_IOMAP_H
|
||||
|
||||
extern const struct iomap_ops nilfs_iomap_ops;
|
||||
|
||||
#endif /* _NILFS_IOMAP_H */
|
||||
Loading…
Reference in New Issue
Block a user