From: Darrick J. Wong <djwong@xxxxxxxxxx> When iomap is in use for the pagecache, it will take care of zeroing the unaligned parts of punched out regions so we don't have to do it ourselves. Signed-off-by: "Darrick J. Wong" <djwong@xxxxxxxxxx> --- misc/fuse2fs.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c index fe6d97324c1f57..aeb2b6fbc28401 100644 --- a/misc/fuse2fs.c +++ b/misc/fuse2fs.c @@ -152,6 +152,7 @@ enum fuse2fs_iomap_state { IOMAP_DISABLED, IOMAP_UNKNOWN, IOMAP_ENABLED, + IOMAP_FILEIO, /* enabled and does all file data block IO */ }; #endif @@ -1040,6 +1041,7 @@ static errcode_t confirm_iomap(struct fuse_conn_info *conn, struct fuse2fs *ff) /* fallthrough */; case IOMAP_DISABLED: return 0; + case IOMAP_FILEIO: case IOMAP_ENABLED: break; } @@ -1059,11 +1061,17 @@ static errcode_t confirm_iomap(struct fuse_conn_info *conn, struct fuse2fs *ff) static int iomap_enabled(const struct fuse2fs *ff) { - return ff->iomap_state == IOMAP_ENABLED; + return ff->iomap_state >= IOMAP_ENABLED; +} + +static int iomap_does_fileio(const struct fuse2fs *ff) +{ + return ff->iomap_state == IOMAP_FILEIO; } #else # define confirm_iomap(...) (0) # define iomap_enabled(...) (0) +# define iomap_does_fileio(...) (0) #endif static void *op_init(struct fuse_conn_info *conn @@ -1100,6 +1108,20 @@ static void *op_init(struct fuse_conn_info *conn if (ff->iomap_state != IOMAP_DISABLED && fuse_set_feature_flag(conn, FUSE_CAP_IOMAP)) ff->iomap_state = IOMAP_ENABLED; + + /* + * If iomap is turned on and the kernel advertises support for both + * direct and pagecache IO, then that means the kernel handles all + * regular file data block IO for us. That means we can turn off all + * of libext2fs' file data block handling except for inline data. + * + * XXX: kernel doesn't support inline data iomap + */ + if (iomap_enabled(ff) && + fuse_get_feature_flag(conn, FUSE_CAP_IOMAP_DIRECTIO) && + fuse_get_feature_flag(conn, FUSE_CAP_IOMAP_PAGECACHE)) + ff->iomap_state = IOMAP_FILEIO; + /* * In iomap mode, the kernel writes file data directly to the block * device and does not flush the bdev page cache. We must open the @@ -4580,6 +4602,10 @@ static errcode_t clean_block_middle(struct fuse2fs *ff, ext2_ino_t ino, int retflags; errcode_t err; + /* the kernel does this for us in iomap mode */ + if (iomap_does_fileio(ff)) + return 0; + residue = FUSE2FS_OFF_IN_FSB(ff, offset); if (residue == 0) return 0; @@ -4617,6 +4643,10 @@ static errcode_t clean_block_edge(struct fuse2fs *ff, ext2_ino_t ino, off_t residue; errcode_t err; + /* the kernel does this for us in iomap mode */ + if (iomap_does_fileio(ff)) + return 0; + residue = FUSE2FS_OFF_IN_FSB(ff, offset); if (residue == 0) return 0;