[PATCH 31/40] iomap: add a new ->iomap_iter operation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This new operation combines ->iomap_beging, ->iomap_end and the actual
advancing of the iter into a new operation.  Matthew Wilcox originally
proposed this kind of interface to eventually allow inlining most of
the iteration and avoid an indirect call.  But it also allows for more
control in the file system to e.g. keep a little more state over
multiple iterations, which is something we'll need to improve the
btrfs direct I/O code.

Signed-off-by: Christoph Hellwig <hch@xxxxxx>
---
 fs/iomap/iter.c       | 13 +++++++++----
 include/linux/iomap.h | 17 +++++++++++++++++
 2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/fs/iomap/iter.c b/fs/iomap/iter.c
index a1c7592d2aded..0bb22f2586e77 100644
--- a/fs/iomap/iter.c
+++ b/fs/iomap/iter.c
@@ -7,7 +7,7 @@
 #include <linux/iomap.h>
 #include "trace.h"
 
-static inline int iomap_iter_advance(struct iomap_iter *iter)
+int iomap_iter_advance(struct iomap_iter *iter)
 {
 	/* handle the previous iteration (if any) */
 	if (iter->iomap.length) {
@@ -27,8 +27,9 @@ static inline int iomap_iter_advance(struct iomap_iter *iter)
 	memset(&iter->srcmap, 0, sizeof(iter->srcmap));
 	return 1;
 }
+EXPORT_SYMBOL_GPL(iomap_iter_advance);
 
-static inline void iomap_iter_done(struct iomap_iter *iter)
+void iomap_iter_done(struct iomap_iter *iter)
 {
 	WARN_ON_ONCE(iter->iomap.offset > iter->pos);
 	WARN_ON_ONCE(iter->iomap.length == 0);
@@ -38,6 +39,7 @@ static inline void iomap_iter_done(struct iomap_iter *iter)
 	if (iter->srcmap.type != IOMAP_HOLE)
 		trace_iomap_iter_srcmap(iter->inode, &iter->srcmap);
 }
+EXPORT_SYMBOL_GPL(iomap_iter_done);
 
 /**
  * iomap_iter - iterate over a ranges in a file
@@ -58,10 +60,13 @@ int iomap_iter(struct iomap_iter *iter, const struct iomap_ops *ops)
 {
 	int ret;
 
+	if (ops->iomap_iter)
+		return ops->iomap_iter(iter);
+
 	if (iter->iomap.length && ops->iomap_end) {
 		ret = ops->iomap_end(iter->inode, iter->pos, iomap_length(iter),
-				iter->processed > 0 ? iter->processed : 0,
-				iter->flags, &iter->iomap);
+				iomap_processed(iter), iter->flags,
+				&iter->iomap);
 		if (ret < 0 && !iter->processed)
 			return ret;
 	}
diff --git a/include/linux/iomap.h b/include/linux/iomap.h
index 3cc5ee01066d0..494f530aa8bf8 100644
--- a/include/linux/iomap.h
+++ b/include/linux/iomap.h
@@ -14,6 +14,7 @@ struct address_space;
 struct fiemap_extent_info;
 struct inode;
 struct iomap_dio;
+struct iomap_iter;
 struct iomap_writepage_ctx;
 struct iov_iter;
 struct kiocb;
@@ -148,6 +149,8 @@ struct iomap_page_ops {
 #endif /* CONFIG_FS_DAX */
 
 struct iomap_ops {
+	int (*iomap_iter)(struct iomap_iter *iter);
+
 	/*
 	 * Return the existing mapping at pos, or reserve space starting at
 	 * pos for up to length, as long as we can do it as a single mapping.
@@ -208,6 +211,17 @@ static inline u64 iomap_length(const struct iomap_iter *iter)
 	return min(iter->len, end - iter->pos);
 }
 
+/**
+ * iomap_length - amount of data processed by the previous iomap iteration
+ * @iter: iteration structure
+ */
+static inline u64 iomap_processed(const struct iomap_iter *iter)
+{
+	if (iter->processed <= 0)
+		return 0;
+	return iter->processed;
+}
+
 /**
  * iomap_iter_srcmap - return the source map for the current iomap iteration
  * @i: iteration structure
@@ -224,6 +238,9 @@ static inline const struct iomap *iomap_iter_srcmap(const struct iomap_iter *i)
 	return &i->iomap;
 }
 
+int iomap_iter_advance(struct iomap_iter *iter);
+void iomap_iter_done(struct iomap_iter *iter);
+
 ssize_t iomap_file_buffered_write(struct kiocb *iocb, struct iov_iter *from,
 		const struct iomap_ops *ops);
 int iomap_readpage(struct page *page, const struct iomap_ops *ops);
-- 
2.30.2




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux