mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Heming Zhao <heming.zhao@suse.com>
To: joseph.qi@linux.alibaba.com, mark@fasheh.com, jlbec@evilplan.org,
	hch@lst.de
Cc: Heming Zhao <heming.zhao@suse.com>,
	ocfs2-devel@lists.linux.dev, linux-kernel@vger.kernel.org
Subject: [RFC PATCH v6 3/3] ocfs2: switch dio write path from buffer_head to iomap
Date: Sun, 15 Nov 2026 23:40:11 +0800	[thread overview]
Message-ID: <20261115154013.9379-4-heming.zhao@suse.com> (raw)
In-Reply-To: <20261115154013.9379-1-heming.zhao@suse.com>

Converts OCFS2's DIO write path from the legacy buffer_head
infrastructure to the modern iomap framework.

The buffer_head based ocfs2_dio_wr_get_block() is replaced by
ocfs2_dio_wr_map_blocks(). Instead of one cluster per call, it now
hands iomap a mapping of as many clusters as can be described by a
single struct iomap: up to 16MB, stopped at the first cluster that is
not of the same kind as the first one (hole, unwritten, written).

Implement ocfs2_dio_write_end_io() and ocfs2_iomap_dio_end_io_write()
to handle IO completion. They convert UNWRITTEN extents, updates inode
size (EOF).

In the buffer_head path, ocfs2_dio_wr_get_block() stores dwc in
bh->b_private, enabling it to detect the first call for an IO chunk and
invoke ocfs2_add_inode_to_orphan() to protect the extent allocation.
However, iomap doesn't provide a similar private field. Therefore, moves
ocfs2_add_inode_to_orphan() from ocfs2_dio_wr_map_blocks(the buffer_head
counterpart to ocfs2_dio_wr_get_block()) to ocfs2_file_write_iter().

It is also impossible t pass The dwc to iomap_dio_ops.end_io, the iomap
->end_io callback cannot effectively distinguish between I/Os initiated
by different threads concurrently. For example, when multiple DIO write
threads operate on the same inode concurrently, the end_io callback
without the dwc context may incorrectly delete an orphan inode created
by another thread, leading to a crash. The fix is to move the orphan
inode deletion from end_io into ocfs2_file_write_iter(). In
ocfs2_file_write_iter(), inode_lock() serializes the write threads,
and IOMAP_DIO_FORCE_WAIT ensures that the function only returns after
the bio completes. This guarantees that i_size has already been
updated when ocfs2_dio_del_orphan() is called.

iomap calls ->iomap_begin() once per mapping but ->end_io() once per io,
and the latter only gets the kiocb, so the kiocb is used as the identity
of the io: ocfs2_file_write_iter() passes it in iomap_iter.private,
ocfs2_iomap_next() forwards it to ocfs2_dio_wr_map_blocks(), and each
unwritten record stores it in ue_owner with the cluster range it covers.

Doesn't like ocfs2_dio_wr_get_block(), move the zero operations from
ocfs2_dio_wr_map_blocks() to ocfs2_file_write_iter(). If do the zeroing
in ocfs2_dio_wr_map_blocks() would zero blocks that earlier mappings of
this same dio have already written, as i_size is only updated at dio
completion. this will makes xfstests generic/538 failure.

Assisted-by: LLM
Co-developed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Signed-off-by: Heming Zhao <heming.zhao@suse.com>
---
 fs/ocfs2/Kconfig |    1 -
 fs/ocfs2/aops.c  | 1445 +++++++++++++++++++++++++++++++++-------------
 fs/ocfs2/aops.h  |   35 +-
 fs/ocfs2/file.c  |  160 ++++-
 fs/ocfs2/mmap.c  |    2 +-
 5 files changed, 1197 insertions(+), 446 deletions(-)

diff --git a/fs/ocfs2/Kconfig b/fs/ocfs2/Kconfig
index bf1678a5eb01..74bc2008ef0b 100644
--- a/fs/ocfs2/Kconfig
+++ b/fs/ocfs2/Kconfig
@@ -9,7 +9,6 @@ config OCFS2_FS
 	select QUOTA_TREE
 	select FS_IOMAP
 	select FS_POSIX_ACL
-	select LEGACY_DIRECT_IO
 	help
 	  OCFS2 is a general purpose extent based shared disk cluster file
 	  system with many similarities to ext3. It supports 64 bit inode
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 6158ab6515ad..164850931217 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -117,19 +117,6 @@ static int ocfs2_symlink_get_block(struct inode *inode, sector_t iblock,
 	return err;
 }
 
-static int ocfs2_lock_get_block(struct inode *inode, sector_t iblock,
-		    struct buffer_head *bh_result, int create)
-{
-	int ret = 0;
-	struct ocfs2_inode_info *oi = OCFS2_I(inode);
-
-	down_read(&oi->ip_alloc_sem);
-	ret = ocfs2_get_block(inode, iblock, bh_result, create);
-	up_read(&oi->ip_alloc_sem);
-
-	return ret;
-}
-
 static int ocfs2_lock_map_blocks(struct inode *inode,
 				 struct ocfs2_map_block *map, int flags)
 {
@@ -761,11 +748,26 @@ int ocfs2_map_folio_blocks(struct folio *folio, u64 *p_blkno,
 
 #define OCFS2_MAX_CLUSTERS_PER_PAGE	(PAGE_SIZE / OCFS2_MIN_CLUSTERSIZE)
 
+/*
+ * Describe a range of clusters whose extents are (or were just allocated as)
+ * unwritten, and which a direct write is going to convert once its io has
+ * finished (see ocfs2_dio_end_io_write()).
+ *
+ * The entry is linked on oi->ip_unwritten_list for as long as the dio is in
+ * flight, so that buffered writers see the clusters are already taken care of
+ * and do not zero them under the dio.  iomap gives ->end_io() nothing but the
+ * kiocb, so ue_owner is how the entries created by ->iomap_begin() are found
+ * again at end_io time: it is the kiocb which __iomap_dio_rw() was called with.
+ *
+ * ue_node is used to chain the entries on a private list: the wc during
+ * write_begin, a local list in end_io.
+ */
 struct ocfs2_unwritten_extent {
 	struct list_head	ue_node;
 	struct list_head	ue_ip_node;
 	u32			ue_cpos;
-	u32			ue_phys;
+	u32			ue_clusters;
+	void			*ue_owner;
 };
 
 /*
@@ -781,6 +783,13 @@ struct ocfs2_write_cluster_desc {
 	unsigned	c_new;
 	unsigned	c_clear_unwritten;
 	unsigned	c_needs_zero;
+	/*
+	 * Direct write only: this cluster is unwritten and this very dio
+	 * (ue_owner) is going to convert it, either because it zeroed it in
+	 * this write_begin or because an earlier ->iomap_begin() of the same
+	 * dio did.  The mapping has to be reported as unwritten.
+	 */
+	unsigned	c_dio_unwritten;
 };
 
 struct ocfs2_write_ctxt {
@@ -794,7 +803,13 @@ struct ocfs2_write_ctxt {
 	/* Type of caller. Must be one of buffer, mmap, direct.  */
 	ocfs2_write_type_t		w_type;
 
-	struct ocfs2_write_cluster_desc	w_desc[OCFS2_MAX_CLUSTERS_PER_PAGE];
+	/*
+	 * One descriptor per cluster of the write.  Buffered and mmap writes
+	 * never span more than a page, so the inline array is enough for them.
+	 * A direct write may span many clusters, w_desc is then allocated.
+	 */
+	struct ocfs2_write_cluster_desc	*w_desc;
+	struct ocfs2_write_cluster_desc	w_desc_inline[OCFS2_MAX_CLUSTERS_PER_PAGE];
 
 	/*
 	 * This is true if page_size > cluster_size.
@@ -817,7 +832,8 @@ struct ocfs2_write_ctxt {
 	 * zero's.
 	 */
 	unsigned int			w_num_folios;
-	struct folio			*w_folios[OCFS2_MAX_CTXT_PAGES];
+	struct folio			**w_folios;
+	struct folio			*w_folios_inline[OCFS2_MAX_CTXT_PAGES];
 	struct folio			*w_target_folio;
 
 	/*
@@ -845,6 +861,17 @@ struct ocfs2_write_ctxt {
 
 	struct list_head		w_unwritten_list;
 	unsigned int			w_unwritten_count;
+
+	/* Direct write only: the dio which owns the unwritten entries. */
+	void				*w_owner;
+
+	/*
+	 * Direct write only: clusters we reserved quota and allocator bits
+	 * for, but which could not be allocated in one go (the allocator
+	 * returned a shorter contiguous chunk).  The write was shortened, the
+	 * caller maps the remainder with its next ->iomap_begin().
+	 */
+	unsigned int			w_clusters_unused;
 };
 
 void ocfs2_unlock_and_free_folios(struct folio **folios, int num_folios)
@@ -898,19 +925,34 @@ static void ocfs2_free_unwritten_list(struct inode *inode,
 	}
 }
 
+static void ocfs2_release_write_ctxt(struct ocfs2_write_ctxt *wc)
+{
+	if (wc->w_desc != wc->w_desc_inline)
+		kvfree(wc->w_desc);
+
+	/*
+	 * The folios in w_folios array already unlocked and
+	 * put by ocfs2_unlock_folios()
+	 */
+	if (wc->w_folios != wc->w_folios_inline)
+		kfree(wc->w_folios);
+
+	kfree(wc);
+}
+
 static void ocfs2_free_write_ctxt(struct inode *inode,
 				  struct ocfs2_write_ctxt *wc)
 {
 	ocfs2_free_unwritten_list(inode, &wc->w_unwritten_list);
 	ocfs2_unlock_folios(wc);
 	brelse(wc->w_di_bh);
-	kfree(wc);
+	ocfs2_release_write_ctxt(wc);
 }
 
 static int ocfs2_alloc_write_ctxt(struct ocfs2_write_ctxt **wcp,
 				  struct ocfs2_super *osb, loff_t pos,
 				  unsigned len, ocfs2_write_type_t type,
-				  struct buffer_head *di_bh)
+				  struct buffer_head *di_bh, void *owner)
 {
 	u32 cend;
 	struct ocfs2_write_ctxt *wc;
@@ -919,10 +961,46 @@ static int ocfs2_alloc_write_ctxt(struct ocfs2_write_ctxt **wcp,
 	if (!wc)
 		return -ENOMEM;
 
+	wc->w_desc = wc->w_desc_inline;
+	wc->w_folios = wc->w_folios_inline;
+	wc->w_owner = owner;
 	wc->w_cpos = pos >> osb->s_clustersize_bits;
 	wc->w_first_new_cpos = UINT_MAX;
 	cend = (pos + len - 1) >> osb->s_clustersize_bits;
 	wc->w_clen = cend - wc->w_cpos + 1;
+
+	/*
+	 * Only a direct write can span more clusters than fit in a page.
+	 * It needs the folios of the first and of the last cluster at most,
+	 * see ocfs2_grab_folios_for_write().
+	 */
+	if (wc->w_clen > ARRAY_SIZE(wc->w_desc_inline)) {
+		if (WARN_ON_ONCE(type != OCFS2_WRITE_DIRECT)) {
+			ocfs2_release_write_ctxt(wc);
+			return -EINVAL;
+		}
+		wc->w_desc = kvcalloc(wc->w_clen, sizeof(*wc->w_desc),
+				      GFP_NOFS);
+		if (!wc->w_desc) {
+			wc->w_desc = wc->w_desc_inline;
+			ocfs2_release_write_ctxt(wc);
+			return -ENOMEM;
+		}
+	}
+
+	/* ref ocfs2_grab_folios_direct() comments for the logic "2 *" */
+	if (type == OCFS2_WRITE_DIRECT &&
+	    2 * ocfs2_pages_per_cluster(osb->sb) >
+			ARRAY_SIZE(wc->w_folios_inline)) {
+		wc->w_folios = kcalloc(2 * ocfs2_pages_per_cluster(osb->sb),
+				       sizeof(*wc->w_folios), GFP_NOFS);
+		if (!wc->w_folios) {
+			wc->w_folios = wc->w_folios_inline;
+			ocfs2_release_write_ctxt(wc);
+			return -ENOMEM;
+		}
+	}
+
 	get_bh(di_bh);
 	wc->w_di_bh = di_bh;
 	wc->w_type = type;
@@ -1089,7 +1167,85 @@ static int ocfs2_prepare_folio_for_write(struct inode *inode, u64 *p_blkno,
 }
 
 /*
- * This function will only grab one clusters worth of pages.
+ * Grab the folios a direct write has to take care of, w_folios is laid out as
+ * two windows of one cluster's worth of pages each:
+ *
+ *   [0, ppc)    the pages of the first cluster of the write
+ *   [ppc, 2ppc) the pages of the last cluster of the write
+ *
+ * A direct write goes to the disk directly, so the pages inside of the user
+ * range are not touched and stay NULL.  The clusters in the middle of the
+ * write are covered by the user range entirely and need nothing at all.  Only
+ * the head cluster before the user range and the tail cluster after it can have
+ * pages which are not going to be overwritten, those must be zeroed through the
+ * page cache if the cluster is new or unwritten (c_needs_zero).
+ *
+ * If the write is made of just one cluster, there is only the first window.
+ *
+ * Like for the buffered write, nothing past the end of the file is needed, the
+ * tail is then cut at max(user range end, i_size).
+ */
+static int ocfs2_grab_folios_direct(struct address_space *mapping,
+		struct ocfs2_write_ctxt *wc, loff_t user_pos, unsigned user_len)
+{
+	struct inode *inode = mapping->host;
+	unsigned int ppc = ocfs2_pages_per_cluster(inode->i_sb);
+	unsigned long target_index = user_pos >> PAGE_SHIFT;
+	unsigned long end_index = (user_pos + user_len - 1) >> PAGE_SHIFT;
+	loff_t last_byte = max_t(loff_t, user_pos + user_len,
+				 i_size_read(inode));
+	unsigned long last_index = ((last_byte - 1) >> PAGE_SHIFT) + 1;
+	unsigned int nr_win = wc->w_clen > 1 ? 2 : 1;
+	int ret = 0, win, i;
+
+	wc->w_num_folios = 0;
+
+	for (win = 0; win < nr_win; win++) {
+		struct ocfs2_write_cluster_desc *desc =
+			win ? &wc->w_desc[wc->w_clen - 1] : &wc->w_desc[0];
+		unsigned long start;
+
+		if (!desc->c_needs_zero)
+			continue;
+
+		start = ocfs2_align_clusters_to_page_index(inode->i_sb,
+							    desc->c_cpos);
+
+		for (i = 0; i < ppc; i++) {
+			unsigned long index = start + i;
+			struct folio *folio;
+
+			if (index >= last_index)
+				break;
+
+			/* Track the slots in use, for the unlock/commit loops. */
+			wc->w_num_folios = max_t(unsigned int, wc->w_num_folios,
+						 win * ppc + i + 1);
+
+			/* The direct io target has no page cache page here. */
+			if (index >= target_index && index <= end_index)
+				continue;
+
+			folio = __filemap_get_folio(mapping, index,
+					FGP_LOCK | FGP_ACCESSED | FGP_CREAT,
+					GFP_NOFS);
+			if (IS_ERR(folio)) {
+				ret = PTR_ERR(folio);
+				mlog_errno(ret);
+				goto out;
+			}
+			wc->w_folios[win * ppc + i] = folio;
+			folio_wait_stable(folio);
+		}
+	}
+out:
+	return ret;
+}
+
+/*
+ * This function will only grab one clusters worth of pages, except for a
+ * direct write which gets the pages around the user range of up to two
+ * clusters, see ocfs2_grab_folios_direct().
  */
 static int ocfs2_grab_folios_for_write(struct address_space *mapping,
 		struct ocfs2_write_ctxt *wc, u32 cpos, loff_t user_pos,
@@ -1100,6 +1256,10 @@ static int ocfs2_grab_folios_for_write(struct address_space *mapping,
 	struct inode *inode = mapping->host;
 	loff_t last_byte;
 
+	if (wc->w_type == OCFS2_WRITE_DIRECT)
+		return ocfs2_grab_folios_direct(mapping, wc, user_pos,
+						user_len);
+
 	target_index = user_pos >> PAGE_SHIFT;
 
 	/*
@@ -1151,11 +1311,6 @@ static int ocfs2_grab_folios_for_write(struct address_space *mapping,
 			folio_get(mmap_folio);
 			wc->w_folios[i] = mmap_folio;
 			wc->w_target_locked = true;
-		} else if (index >= target_index && index <= end_index &&
-			   wc->w_type == OCFS2_WRITE_DIRECT) {
-			/* Direct write has no mapping page. */
-			wc->w_folios[i] = NULL;
-			continue;
 		} else {
 			wc->w_folios[i] = __filemap_get_folio(mapping, index,
 					FGP_LOCK | FGP_ACCESSED | FGP_CREAT,
@@ -1178,6 +1333,61 @@ static int ocfs2_grab_folios_for_write(struct address_space *mapping,
 	return ret;
 }
 
+/*
+ * Get the physical location of a cluster and prepare the folios [fstart, fend)
+ * of w_folios, which belong to it, for the write.
+ */
+static int ocfs2_prepare_cluster_folios(struct address_space *mapping,
+					u32 *phys, unsigned int should_zero,
+					struct ocfs2_write_ctxt *wc, u32 cpos,
+					loff_t user_pos, unsigned user_len,
+					unsigned int fstart, unsigned int fend)
+{
+	int ret, i;
+	u64 p_blkno;
+	struct inode *inode = mapping->host;
+	int bpc = ocfs2_clusters_to_blocks(inode->i_sb, 1);
+
+	/*
+	 * The only reason this should fail is due to an inability to
+	 * find the extent added.
+	 */
+	ret = ocfs2_get_clusters(inode, cpos, phys, NULL, NULL);
+	if (ret < 0) {
+		mlog(ML_ERROR, "Get physical blkno failed for inode %llu, "
+			    "at logical cluster %u",
+			    (unsigned long long)OCFS2_I(inode)->ip_blkno, cpos);
+		return ret;
+	}
+
+	BUG_ON(*phys == 0);
+
+	p_blkno = ocfs2_clusters_to_blocks(inode->i_sb, *phys);
+	if (!should_zero)
+		p_blkno += (user_pos >> inode->i_sb->s_blocksize_bits) & (u64)(bpc - 1);
+
+	for (i = fstart; i < fend; i++) {
+		int tmpret;
+
+		/* This is the direct io target page. */
+		if (wc->w_folios[i] == NULL) {
+			p_blkno += (1 << (PAGE_SHIFT - inode->i_sb->s_blocksize_bits));
+			continue;
+		}
+
+		tmpret = ocfs2_prepare_folio_for_write(inode, &p_blkno, wc,
+				wc->w_folios[i], cpos, user_pos, user_len,
+				should_zero);
+		if (tmpret) {
+			mlog_errno(tmpret);
+			if (ret == 0)
+				ret = tmpret;
+		}
+	}
+
+	return ret;
+}
+
 /*
  * Prepare a single cluster for write one cluster into the file.
  */
@@ -1190,11 +1400,9 @@ static int ocfs2_write_cluster(struct address_space *mapping,
 			       struct ocfs2_write_ctxt *wc, u32 cpos,
 			       loff_t user_pos, unsigned user_len)
 {
-	int ret, i;
-	u64 p_blkno;
+	int ret;
 	struct inode *inode = mapping->host;
 	struct ocfs2_extent_tree et;
-	int bpc = ocfs2_clusters_to_blocks(inode->i_sb, 1);
 
 	if (new) {
 		u32 tmp_pos;
@@ -1236,52 +1444,176 @@ static int ocfs2_write_cluster(struct address_space *mapping,
 		}
 	}
 
+	ret = ocfs2_prepare_cluster_folios(mapping, phys, should_zero, wc, cpos,
+					   user_pos, user_len, 0,
+					   wc->w_num_folios);
+
 	/*
-	 * The only reason this should fail is due to an inability to
-	 * find the extent added.
+	 * We only have cleanup to do in case of allocating write.
 	 */
-	ret = ocfs2_get_clusters(inode, cpos, phys, NULL, NULL);
+	if (ret && new)
+		ocfs2_write_failure(inode, wc, user_pos, user_len);
+
+out:
+
+	return ret;
+}
+
+/*
+ * A direct write allocates all the clusters it needs in one go, the same way
+ * ocfs2_extend_allocation() does.  The new extent is unwritten, it is converted
+ * when the io is done, see ocfs2_dio_end_io_write().
+ *
+ * Only one call is made, which means one chunk of contiguous clusters.  The
+ * allocator may return less than we asked for.  We don't try again, that would
+ * need more credits and the chunks would not be contiguous on the disk, which
+ * the caller needs as it hands out a single mapping.  The write is just made
+ * shorter, the caller maps the rest with its next ->iomap_begin().
+ */
+static int ocfs2_dio_alloc_clusters(struct inode *inode,
+				    struct ocfs2_write_ctxt *wc,
+				    struct ocfs2_alloc_context *data_ac,
+				    struct ocfs2_alloc_context *meta_ac)
+{
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+	unsigned int ppc = ocfs2_pages_per_cluster(inode->i_sb);
+	enum ocfs2_alloc_restarted why = RESTART_NONE;
+	u32 cpos = wc->w_cpos, got;
+	int ret, i;
+
+	ret = ocfs2_add_inode_data(osb, inode, &cpos, wc->w_clen, 1,
+				   wc->w_di_bh, wc->w_handle, data_ac, meta_ac,
+				   &why);
+	got = cpos - wc->w_cpos;
+	if (ret == -EAGAIN && why == RESTART_TRANS && got)
+		ret = 0;
+	if (ret == -EAGAIN) {
+		/*
+		 * We reserved the metadata for it up front, we do not
+		 * expect to be here.
+		 */
+		mlog(ML_ERROR, "Inode %llu: EAGAIN (%d) during dio allocation\n",
+		     (unsigned long long)OCFS2_I(inode)->ip_blkno, why);
+		ret = -ENOSPC;
+	}
 	if (ret < 0) {
-		mlog(ML_ERROR, "Get physical blkno failed for inode %llu, "
-			    "at logical cluster %u",
-			    (unsigned long long)OCFS2_I(inode)->ip_blkno, cpos);
-		goto out;
+		if (ret != -ENOSPC)
+			mlog_errno(ret);
+		return ret;
 	}
 
-	BUG_ON(*phys == 0);
-
-	p_blkno = ocfs2_clusters_to_blocks(inode->i_sb, *phys);
-	if (!should_zero)
-		p_blkno += (user_pos >> inode->i_sb->s_blocksize_bits) & (u64)(bpc - 1);
+	if (got < wc->w_clen) {
+		/*
+		 * Cut the write short.  What is left of it is not for us to
+		 * zero anymore, the last cluster we have now is covered by the
+		 * user range entirely.  Drop the folios of the old last
+		 * cluster.
+		 */
+		wc->w_clusters_unused = wc->w_clen - got;
+		wc->w_clen = got;
 
-	for (i = 0; i < wc->w_num_folios; i++) {
-		int tmpret;
+		for (i = ppc; i < 2 * ppc; i++) {
+			struct folio *folio = wc->w_folios[i];
 
-		/* This is the direct io target page. */
-		if (wc->w_folios[i] == NULL) {
-			p_blkno += (1 << (PAGE_SHIFT - inode->i_sb->s_blocksize_bits));
-			continue;
+			if (!folio)
+				continue;
+			folio_unlock(folio);
+			folio_mark_accessed(folio);
+			folio_put(folio);
+			wc->w_folios[i] = NULL;
 		}
+		if (wc->w_num_folios > ppc)
+			wc->w_num_folios = ppc;
+	}
 
-		tmpret = ocfs2_prepare_folio_for_write(inode, &p_blkno, wc,
-				wc->w_folios[i], cpos, user_pos, user_len,
-				should_zero);
-		if (tmpret) {
-			mlog_errno(tmpret);
-			if (ret == 0)
-				ret = tmpret;
+	return 0;
+}
+
+/*
+ * A direct write goes to the disk, it only needs the clusters allocated, the
+ * folios around the user range zeroed and the physical location of each
+ * cluster.  The latter is what the iomap mapping is made of.
+ */
+static int ocfs2_write_clusters_direct(struct address_space *mapping,
+				       struct ocfs2_alloc_context *data_ac,
+				       struct ocfs2_alloc_context *meta_ac,
+				       struct ocfs2_write_ctxt *wc,
+				       loff_t pos, unsigned len)
+{
+	struct inode *inode = mapping->host;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+	unsigned int ppc = ocfs2_pages_per_cluster(inode->i_sb);
+	struct ocfs2_write_cluster_desc *desc;
+	loff_t end = pos + len;
+	int ret, i, win;
+	u32 phys, num;
+
+	if (wc->w_desc[0].c_new) {
+		ret = ocfs2_dio_alloc_clusters(inode, wc, data_ac, meta_ac);
+		if (ret)
+			return ret;
+		end = min_t(loff_t, end,
+			    ocfs2_clusters_to_bytes(inode->i_sb,
+						    wc->w_cpos + wc->w_clen));
+	}
+
+	/*
+	 * Fill in the physical location of the clusters, an extent covers as
+	 * many of them as it can.
+	 */
+	for (i = 0; i < wc->w_clen; ) {
+		desc = &wc->w_desc[i];
+
+		ret = ocfs2_get_clusters(inode, desc->c_cpos, &phys, &num,
+					 NULL);
+		if (ret) {
+			mlog_errno(ret);
+			return ret;
+		}
+		if (!phys) {
+			mlog(ML_ERROR, "Inode %llu: no cluster at %u after dio allocation\n",
+			     (unsigned long long)OCFS2_I(inode)->ip_blkno,
+			     desc->c_cpos);
+			return -EIO;
 		}
+		for (; num && i < wc->w_clen; i++, num--, phys++)
+			wc->w_desc[i].c_phys = phys;
 	}
 
 	/*
-	 * We only have cleanup to do in case of allocating write.
+	 * The folios are only there for the first and the last cluster,
+	 * the ones in the middle are written by the dio as a whole.
 	 */
-	if (ret && new)
-		ocfs2_write_failure(inode, wc, user_pos, user_len);
+	for (win = 0; win < (wc->w_clen > 1 ? 2 : 1); win++) {
+		unsigned int fstart = win * ppc;
+		unsigned int fend = min(wc->w_num_folios, fstart + ppc);
+		loff_t cpos_byte;
+		unsigned int local_len;
+		loff_t user_pos;
+
+		desc = win ? &wc->w_desc[wc->w_clen - 1] : &wc->w_desc[0];
+		if (!desc->c_needs_zero || fend <= fstart)
+			continue;
 
-out:
+		/* The part of the user range which is in this cluster. */
+		cpos_byte = ocfs2_clusters_to_bytes(inode->i_sb, desc->c_cpos);
+		user_pos = max_t(loff_t, pos, cpos_byte);
+		local_len = min_t(loff_t, end,
+				  cpos_byte + osb->s_clustersize) - user_pos;
 
-	return ret;
+		ret = ocfs2_prepare_cluster_folios(mapping, &desc->c_phys,
+						   desc->c_needs_zero, wc,
+						   desc->c_cpos, user_pos,
+						   local_len, fstart, fend);
+		if (ret) {
+			mlog_errno(ret);
+			if (desc->c_new)
+				ocfs2_write_failure(inode, wc, pos, len);
+			return ret;
+		}
+	}
+
+	return 0;
 }
 
 static int ocfs2_write_cluster_by_desc(struct address_space *mapping,
@@ -1296,6 +1628,10 @@ static int ocfs2_write_cluster_by_desc(struct address_space *mapping,
 	struct ocfs2_write_cluster_desc *desc;
 	struct ocfs2_super *osb = OCFS2_SB(mapping->host->i_sb);
 
+	if (wc->w_type == OCFS2_WRITE_DIRECT)
+		return ocfs2_write_clusters_direct(mapping, data_ac, meta_ac,
+						   wc, pos, len);
+
 	for (i = 0; i < wc->w_clen; i++) {
 		desc = &wc->w_desc[i];
 
@@ -1380,77 +1716,180 @@ static void ocfs2_set_target_boundaries(struct ocfs2_super *osb,
 	}
 }
 
+/*
+ * Find the entry which covers a cluster.  Must be called with ip_lock held.
+ */
+static struct ocfs2_unwritten_extent *
+ocfs2_find_unwritten(struct ocfs2_inode_info *oi, u32 cpos)
+{
+	struct ocfs2_unwritten_extent *ue;
+
+	list_for_each_entry(ue, &oi->ip_unwritten_list, ue_ip_node) {
+		if (cpos >= ue->ue_cpos && cpos - ue->ue_cpos < ue->ue_clusters)
+			return ue;
+	}
+	return NULL;
+}
+
 /*
  * Check if this extent is marked UNWRITTEN by direct io. If so, we need not to
  * do the zero work. And should not to clear UNWRITTEN since it will be cleared
  * by the direct io procedure.
- * If this is a new extent that allocated by direct io, we should mark it in
- * the ip_unwritten_list.
+ *
+ * A direct write never clears UNWRITTEN here, that is done when its io is
+ * finished. The clusters it is going to zero are not put to the
+ * ip_unwritten_list by this function, see ocfs2_dio_add_unwritten(), as the
+ * write might get shortened afterwards.
  */
-static int ocfs2_unwritten_check(struct inode *inode,
-				 struct ocfs2_write_ctxt *wc,
-				 struct ocfs2_write_cluster_desc *desc)
+static void ocfs2_unwritten_check(struct inode *inode,
+				  struct ocfs2_write_ctxt *wc,
+				  struct ocfs2_write_cluster_desc *desc)
 {
 	struct ocfs2_inode_info *oi = OCFS2_I(inode);
-	struct ocfs2_unwritten_extent *ue = NULL, *new = NULL;
-	int ret = 0;
+	struct ocfs2_unwritten_extent *ue;
 
 	if (!desc->c_needs_zero)
-		return 0;
+		return;
 
-retry:
 	spin_lock(&oi->ip_lock);
-	/* Needs not to zero no metter buffer or direct. The one who is zero
-	 * the cluster is doing zero. And he will clear unwritten after all
-	 * cluster io finished. */
-	list_for_each_entry(ue, &oi->ip_unwritten_list, ue_ip_node) {
-		if (desc->c_cpos == ue->ue_cpos) {
-			BUG_ON(desc->c_new);
-			desc->c_needs_zero = 0;
-			desc->c_clear_unwritten = 0;
-			goto unlock;
-		}
+	ue = ocfs2_find_unwritten(oi, desc->c_cpos);
+	/* A hole (c_new is 1) can not be on the list, don't trust it if it is. */
+	if (ue && !WARN_ON_ONCE(desc->c_new)) {
+		/*
+		 * Needs not to zero no matter buffer or direct. The one who is
+		 * zero the cluster is doing zero. And he will clear unwritten
+		 * after all cluster io finished.
+		 */
+		desc->c_needs_zero = 0;
+		desc->c_clear_unwritten = 0;
+		/* match its own entry */
+		if (wc->w_type == OCFS2_WRITE_DIRECT && wc->w_owner &&
+		    ue->ue_owner == wc->w_owner)
+			desc->c_dio_unwritten = 1;
+	} else if (wc->w_type == OCFS2_WRITE_DIRECT) {
+		/* This direct write will doing zero. */
+		desc->c_clear_unwritten = 0;
 	}
-
-	if (wc->w_type != OCFS2_WRITE_DIRECT)
-		goto unlock;
-
-	if (new == NULL) {
-		spin_unlock(&oi->ip_lock);
-		new = kmalloc_obj(struct ocfs2_unwritten_extent, GFP_NOFS);
-		if (new == NULL) {
-			ret = -ENOMEM;
-			goto out;
-		}
-		goto retry;
-	}
-	/* This direct write will doing zero. */
-	new->ue_cpos = desc->c_cpos;
-	new->ue_phys = desc->c_phys;
-	desc->c_clear_unwritten = 0;
-	list_add_tail(&new->ue_ip_node, &oi->ip_unwritten_list);
-	list_add_tail(&new->ue_node, &wc->w_unwritten_list);
-	wc->w_unwritten_count++;
-	new = NULL;
-unlock:
 	spin_unlock(&oi->ip_lock);
-out:
-	kfree(new);
-	return ret;
 }
 
 /*
- * Populate each single-cluster write descriptor in the write context
- * with information about the i/o to be done.
+ * Is the cluster reported as unwritten to iomap?
+ * Returns true for unwritten, false for mapped.
+ */
+static inline bool ocfs2_desc_dio_unwritten(struct ocfs2_write_cluster_desc *d)
+{
+	/*
+	 * c_needs_zero: whether this mapping needs to be zeroed
+	 * c_dio_unwritten: whether the conversion is my job
+	 *
+	 * c_needs_zero | c_dio_unwritten | source place             | reports
+	 * ----------------------------------------------------------------
+	 *     0        |      0          | overwrite extent;        | MAPPED
+	 *              |                 | ocfs2_unwritten_check    |
+	 *              |                 | found others entry       |
+	 * ------------------------------------------------------------------
+	 *     1        |      0          | buffered/mmap write;     | UNWRITTEN
+	 *              |                 | transitional state before|
+	 *              |                 | ocfs2_dio_add_unwritten  |
+	 * ------------------------------------------------------------------
+	 *     0        |      1          | ocfs2_unwritten_check    | UNWRITTEN
+	 * ------------------------------------------------------------------
+	 *     1        |      1          | ocfs2_dio_add_unwritten  | UNWRITTEN
+	 */
+	return d->c_needs_zero || d->c_dio_unwritten;
+}
+
+/*
+ * iomap takes one mapping which is of one type and contiguous on the disk.
+ * Cut the clusters of a direct write at the first one which is not like the
+ * first, they are mapped by the next ->iomap_begin().  Also, the clusters to
+ * be allocated are all new or none of them is.
  *
- * Returns the number of clusters that will have to be allocated, as
- * well as a worst case estimate of the number of extent records that
- * would have to be created during a write to an unwritten region.
+ * Returns the number of clusters to be allocated.
  */
-static int ocfs2_populate_write_desc(struct inode *inode,
-				     struct ocfs2_write_ctxt *wc,
-				     unsigned int *clusters_to_alloc,
-				     unsigned int *extents_to_split)
+static unsigned int ocfs2_dio_trim_write_ctxt(struct ocfs2_write_ctxt *wc)
+{
+	struct ocfs2_write_cluster_desc *first = &wc->w_desc[0];
+	u32 i;
+
+	for (i = 1; i < wc->w_clen; i++) {
+		struct ocfs2_write_cluster_desc *d = &wc->w_desc[i];
+
+		if (d->c_new != first->c_new ||
+		    ocfs2_desc_dio_unwritten(d) !=
+				ocfs2_desc_dio_unwritten(first))
+			break;
+		/* mapped clusters */
+		if (!d->c_new && d->c_phys != d[-1].c_phys + 1)
+			break;
+	}
+	wc->w_clen = i;
+
+	/*
+	 * c_new is 0 for mapped clusters, which means they are not
+	 * allocated by this write.
+	 */
+	return first->c_new ? wc->w_clen : 0;
+}
+
+/*
+ * Record the clusters a direct write zeroed (or is going to convert) in
+ * ip_unwritten_list, until ocfs2_dio_end_io_write() converts them.  The
+ * entries are also on wc->w_unwritten_list, so that they are freed with the
+ * write context if the write fails. Once the write has succeeded, the caller
+ * detaches them from it, see ocfs2_dio_detach_unwritten().
+ */
+static int ocfs2_dio_add_unwritten(struct inode *inode,
+				   struct ocfs2_write_ctxt *wc)
+{
+	struct ocfs2_inode_info *oi = OCFS2_I(inode);
+	struct ocfs2_unwritten_extent *ue;
+	u32 i, j;
+
+	for (i = 0; i < wc->w_clen; i = j) {
+		j = i + 1;
+		if (!wc->w_desc[i].c_needs_zero)
+			continue;
+		while (j < wc->w_clen && wc->w_desc[j].c_needs_zero)
+			j++;
+
+		ue = kmalloc_obj(struct ocfs2_unwritten_extent, GFP_NOFS);
+		if (!ue)
+			return -ENOMEM;
+		ue->ue_cpos = wc->w_desc[i].c_cpos;
+		ue->ue_clusters = j - i;
+		ue->ue_owner = wc->w_owner;
+		INIT_LIST_HEAD(&ue->ue_ip_node);
+		list_add_tail(&ue->ue_node, &wc->w_unwritten_list);
+		wc->w_unwritten_count++;
+	}
+
+	spin_lock(&oi->ip_lock);
+	list_for_each_entry(ue, &wc->w_unwritten_list, ue_node)
+		list_add_tail(&ue->ue_ip_node, &oi->ip_unwritten_list);
+	spin_unlock(&oi->ip_lock);
+
+	for (i = 0; i < wc->w_clen; i++) {
+		if (wc->w_desc[i].c_needs_zero)
+			wc->w_desc[i].c_dio_unwritten = 1;
+	}
+
+	return 0;
+}
+
+/*
+ * Populate each single-cluster write descriptor in the write context
+ * with information about the i/o to be done.
+ *
+ * Returns the number of clusters that will have to be allocated, as
+ * well as a worst case estimate of the number of extent records that
+ * would have to be created during a write to an unwritten region.
+ */
+static int ocfs2_populate_write_desc(struct inode *inode,
+				     struct ocfs2_write_ctxt *wc,
+				     unsigned int *clusters_to_alloc,
+				     unsigned int *extents_to_split)
 {
 	int ret;
 	struct ocfs2_write_cluster_desc *desc;
@@ -1523,11 +1962,7 @@ static int ocfs2_populate_write_desc(struct inode *inode,
 			desc->c_needs_zero = 1;
 		}
 
-		ret = ocfs2_unwritten_check(inode, wc, desc);
-		if (ret) {
-			mlog_errno(ret);
-			goto out;
-		}
+		ocfs2_unwritten_check(inode, wc, desc);
 
 		num_clusters--;
 	}
@@ -1712,10 +2147,57 @@ static int ocfs2_zero_tail(struct inode *inode, struct buffer_head *di_bh,
 	return ret;
 }
 
+/*
+ * Does a direct write have folios to zero around its user range?
+ * See ocfs2_grab_folios_direct(), this has to agree with it.
+ */
+static bool ocfs2_dio_need_zero_folios(struct inode *inode,
+				       struct ocfs2_write_ctxt *wc,
+				       loff_t pos, unsigned len)
+{
+	unsigned int ppc = ocfs2_pages_per_cluster(inode->i_sb);
+	unsigned long target_index = pos >> PAGE_SHIFT;
+	unsigned long end_index = (pos + len - 1) >> PAGE_SHIFT;
+	loff_t last_byte = max_t(loff_t, pos + len, i_size_read(inode));
+	unsigned long last_index = ((last_byte - 1) >> PAGE_SHIFT) + 1;
+	unsigned int nr_win = wc->w_clen > 1 ? 2 : 1;
+	int win, i;
+
+	for (win = 0; win < nr_win; win++) {
+		struct ocfs2_write_cluster_desc *desc =
+			win ? &wc->w_desc[wc->w_clen - 1] : &wc->w_desc[0];
+		unsigned long start;
+
+		if (!desc->c_needs_zero)
+			continue;
+
+		start = ocfs2_align_clusters_to_page_index(inode->i_sb,
+							    desc->c_cpos);
+		for (i = 0; i < ppc && start + i < last_index; i++) {
+			if (start + i < target_index || start + i > end_index)
+				return true;
+		}
+	}
+	return false;
+}
+
+/*
+ * A buffered write is cut by the caller into pieces of up to a page, and the
+ * clusters it touches have to fit in a page.
+ *
+ * A direct write is not, it may span many clusters, which are all of the same
+ * kind: all of them are to be allocated or none is, and either all of them are
+ * unwritten or none is.  How many of the clusters asked for are used is up to
+ * this function, see w_clen of the returned context.
+ *
+ * @owner is only used by a direct write, it is what ocfs2_dio_end_io_write()
+ * finds the unwritten clusters recorded for this write by.
+ */
 int ocfs2_write_begin_nolock(struct address_space *mapping,
 		loff_t pos, unsigned len, ocfs2_write_type_t type,
 		struct folio **foliop, void **fsdata,
-		struct buffer_head *di_bh, struct folio *mmap_folio)
+		struct buffer_head *di_bh, struct folio *mmap_folio,
+		void *owner)
 {
 	int ret, cluster_of_pages, credits = OCFS2_INODE_UPDATE_CREDITS;
 	unsigned int clusters_to_alloc, extents_to_split, clusters_need = 0;
@@ -1730,13 +2212,14 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
 	int try_free = 1, ret1;
 
 try_again:
-	ret = ocfs2_alloc_write_ctxt(&wc, osb, pos, len, type, di_bh);
+	ret = ocfs2_alloc_write_ctxt(&wc, osb, pos, len, type, di_bh, owner);
 	if (ret) {
 		mlog_errno(ret);
 		return ret;
 	}
 
-	if (ocfs2_supports_inline_data(osb)) {
+	/* A direct write is never inline, it is not even allowed to start. */
+	if (type != OCFS2_WRITE_DIRECT && ocfs2_supports_inline_data(osb)) {
 		ret = ocfs2_try_to_write_inline_data(mapping, inode, pos, len,
 						     mmap_folio, wc);
 		if (ret == 1) {
@@ -1749,7 +2232,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
 		}
 	}
 
-	/* Direct io change i_size late, should not zero tail here. */
+	/* Direct io change i_size itself, should not zero tail here. */
 	if (type != OCFS2_WRITE_DIRECT) {
 		if (ocfs2_sparse_alloc(osb))
 			ret = ocfs2_zero_tail(inode, di_bh, pos);
@@ -1782,6 +2265,18 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
 		mlog_errno(ret);
 		goto out;
 	}
+
+	if (type == OCFS2_WRITE_DIRECT) {
+		/*
+		 * Direct write never splits an extent here, they are converted
+		 * when the io is done. What it can do is to allocate.
+		 */
+		extents_to_split = 0;
+		clusters_to_alloc = ocfs2_dio_trim_write_ctxt(wc);
+		len = min_t(loff_t, len,
+			    ocfs2_clusters_to_bytes(inode->i_sb,
+						    wc->w_cpos + wc->w_clen) - pos);
+	}
 	clusters_need += clusters_to_alloc;
 
 	di = (struct ocfs2_dinode *)wc->w_di_bh->b_data;
@@ -1820,13 +2315,24 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
 
 		credits = ocfs2_calc_extend_credits(inode->i_sb,
 						    &di->id2.i_list);
-	} else if (type == OCFS2_WRITE_DIRECT)
-		/* direct write needs not to start trans if no extents alloc. */
-		goto success;
+	} else if (type == OCFS2_WRITE_DIRECT) {
+		/*
+		 * Direct write needs not to start trans if no extents alloc,
+		 * unless there are folios to zero.
+		 */
+		if (!ocfs2_dio_need_zero_folios(inode, wc, pos, len)) {
+			ret = ocfs2_dio_add_unwritten(inode, wc);
+			if (ret) {
+				mlog_errno(ret);
+				goto out;
+			}
+			goto success;
+		}
+	}
 
 	/*
 	 * We have to zero sparse allocated clusters, unwritten extent clusters,
-	 * and non-sparse clusters we just extended.  For non-sparse writes,
+	 * and non-sparse clusters we just extended. For non-sparse writes,
 	 * we know zeros will only be needed in the first and/or last cluster.
 	 */
 	if (wc->w_clen && (wc->w_desc[0].c_needs_zero ||
@@ -1886,11 +2392,26 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
 
 	ret = ocfs2_write_cluster_by_desc(mapping, data_ac, meta_ac, wc, pos,
 					  len);
+	if (wc->w_clusters_unused) {
+		/* A direct write got a shorter chunk than reserved. */
+		dquot_free_space(inode,
+			ocfs2_clusters_to_bytes(osb->sb, wc->w_clusters_unused));
+		clusters_to_alloc -= wc->w_clusters_unused;
+		wc->w_clusters_unused = 0;
+	}
 	if (ret) {
 		mlog_errno(ret);
 		goto out_quota;
 	}
 
+	if (type == OCFS2_WRITE_DIRECT) {
+		ret = ocfs2_dio_add_unwritten(inode, wc);
+		if (ret) {
+			mlog_errno(ret);
+			goto out_quota;
+		}
+	}
+
 	if (data_ac)
 		ocfs2_free_alloc_context(data_ac);
 	if (meta_ac)
@@ -1973,7 +2494,7 @@ static int ocfs2_write_begin(const struct kiocb *iocb,
 	down_write(&OCFS2_I(inode)->ip_alloc_sem);
 
 	ret = ocfs2_write_begin_nolock(mapping, pos, len, OCFS2_WRITE_BUFFER,
-				       foliop, fsdata, di_bh, NULL);
+				       foliop, fsdata, di_bh, NULL, NULL);
 	if (ret) {
 		mlog_errno(ret);
 		goto out_fail;
@@ -2135,7 +2656,7 @@ int ocfs2_write_end_nolock(struct address_space *mapping, loff_t pos,
 	ocfs2_run_deallocs(osb, &wc->w_dealloc);
 
 	brelse(wc->w_di_bh);
-	kfree(wc);
+	ocfs2_release_write_ctxt(wc);
 
 	return copied;
 }
@@ -2156,132 +2677,134 @@ static int ocfs2_write_end(const struct kiocb *iocb,
 	return ret;
 }
 
-struct ocfs2_dio_write_ctxt {
-	struct list_head	dw_zero_list;
-	unsigned		dw_zero_count;
-	int			dw_orphaned;
-	pid_t			dw_writer_pid;
-};
-
-static struct ocfs2_dio_write_ctxt *
-ocfs2_dio_alloc_write_ctx(struct buffer_head *bh, int *alloc)
+/*
+ * Prepare the area between i_size and a direct write that starts or ends
+ * beyond it.  Must be called once per dio, before any io is issued, with
+ * i_rwsem and the rw lock held.
+ */
+int ocfs2_dio_zero_eof(struct inode *inode, loff_t pos, size_t count)
 {
-	struct ocfs2_dio_write_ctxt *dwc = NULL;
-
-	if (bh->b_private)
-		return bh->b_private;
-
-	dwc = kmalloc_obj(struct ocfs2_dio_write_ctxt, GFP_NOFS);
-	if (dwc == NULL)
-		return NULL;
-	INIT_LIST_HEAD(&dwc->dw_zero_list);
-	dwc->dw_zero_count = 0;
-	dwc->dw_orphaned = 0;
-	dwc->dw_writer_pid = task_pid_nr(current);
-	bh->b_private = dwc;
-	*alloc = 1;
-
-	return dwc;
+	struct ocfs2_inode_info *oi = OCFS2_I(inode);
+	struct buffer_head *di_bh = NULL;
+	int ret;
+
+	if (pos + count <= i_size_read(inode))
+		return 0;
+
+	ret = ocfs2_inode_lock(inode, &di_bh, 1);
+	if (ret) {
+		mlog_errno(ret);
+		return ret;
+	}
+
+	down_write(&oi->ip_alloc_sem);
+	if (ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb)))
+		ret = ocfs2_zero_tail(inode, di_bh, pos);
+	else
+		ret = ocfs2_expand_nonsparse_inode(inode, di_bh, pos, count,
+						   NULL);
+	if (ret < 0)
+		mlog_errno(ret);
+	up_write(&oi->ip_alloc_sem);
+
+	ocfs2_inode_unlock(inode, 1);
+	brelse(di_bh);
+	return ret;
 }
 
-static void ocfs2_dio_free_write_ctx(struct inode *inode,
-				     struct ocfs2_dio_write_ctxt *dwc)
+/*
+ * The most a single mapping handed out for a direct write spans.
+ * It bounds the memory of the write context, one descriptor per
+ * cluster.
+ */
+#define OCFS2_DIO_MAX_MAP_BYTES	(16U << 20)
+
+/*
+ * The entries of ip_unwritten_list which belong to a direct write
+ * have been created while the write context was alive, they have to
+ * survive it: they stay until ocfs2_dio_end_io() has converted the
+ * clusters. Take them off the write context, so that it can be
+ * released.
+ */
+static void ocfs2_dio_detach_unwritten(struct ocfs2_write_ctxt *wc)
 {
-	ocfs2_free_unwritten_list(inode, &dwc->dw_zero_list);
-	kfree(dwc);
+	struct ocfs2_unwritten_extent *ue, *tmp;
+
+	list_for_each_entry_safe(ue, tmp, &wc->w_unwritten_list, ue_node)
+		list_del_init(&ue->ue_node);
+	wc->w_unwritten_count = 0;
 }
 
 /*
- * TODO: Make this into a generic get_blocks function.
+ * Map a range of a direct write, allocate the clusters if needed.
+ *
+ * Contrary to the single cluster it was before, a mapping spans as many
+ * clusters as iomap asks for, up to the first thing that makes it unfit to
+ * be handed out as one: the kind of the extent (hole, unwritten, written),
+ * a discontiguous extent, or the end of the file. The latter is the one
+ * place where the mapping is split on purpose:
+ *
+ *		   eof_blk
+ * |--------|---------|---------|---------
+ * |<-in file range-->|<-past eof range-->
  *
- * From do_direct_io in direct-io.c:
- *  "So what we do is to permit the ->get_blocks function to populate
- *   bh.b_size with the size of IO which is permitted at this offset and
- *   this i_blkbits."
+ * the part which is in the file is not NEW, it may have data which must
+ * not be zeroed. The part which is beyond it is NEW. As the file size is
+ * only changed when the io is done, both are told apart here.
  *
- * This function is called directly from get_more_blocks in direct-io.c.
+ * Whatever is unwritten and zeroed here is recorded in ip_unwritten_list
+ * for ocfs2_dio_end_io() to convert, find them there by @owner.
  *
- * called like this: dio->get_blocks(dio->inode, fs_startblk,
- * 					fs_count, map_bh, dio->rw == WRITE);
+ * @map->lblk and @map->len go in, the mapping goes out.
  */
-static int ocfs2_dio_wr_get_block(struct inode *inode, sector_t iblock,
-			       struct buffer_head *bh_result, int create)
+static int ocfs2_dio_wr_map_blocks(struct inode *inode,
+				   struct ocfs2_map_block *map,
+				   unsigned int flags, void *owner)
 {
 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 	struct ocfs2_inode_info *oi = OCFS2_I(inode);
 	struct ocfs2_write_ctxt *wc;
-	struct ocfs2_write_cluster_desc *desc = NULL;
-	struct ocfs2_dio_write_ctxt *dwc = NULL;
+	struct ocfs2_write_cluster_desc *desc;
+	struct ocfs2_map_block probe;
 	struct buffer_head *di_bh = NULL;
-	u64 p_blkno;
-	unsigned int i_blkbits = inode->i_sb->s_blocksize_bits;
-	loff_t pos = iblock << i_blkbits;
-	sector_t endblk = (i_size_read(inode) - 1) >> i_blkbits;
-	unsigned len, total_len = bh_result->b_size;
-	int ret = 0, first_get_block = 0;
-
-	len = osb->s_clustersize - (pos & (osb->s_clustersize - 1));
-	len = min(total_len, len);
-
-	/*
-	 * bh_result->b_size is count in get_more_blocks according to write
-	 * "pos" and "end", we need map twice to return different buffer state:
-	 * 1. area in file size, not set NEW;
-	 * 2. area out file size, set  NEW.
-	 *
-	 *		   iblock    endblk
-	 * |--------|---------|---------|---------
-	 * |<-------area in file------->|
-	 */
+	unsigned int blkbits = inode->i_sb->s_blocksize_bits;
+	u64 bpc = ocfs2_clusters_to_blocks(inode->i_sb, 1);
+	u64 lblk = map->lblk;
+	u64 eof_blk = ocfs2_blocks_for_bytes(inode->i_sb, i_size_read(inode));
+	loff_t pos = lblk << blkbits;
+	loff_t len, end;
+	int ret = 0, unwritten;
 
-	if ((iblock <= endblk) &&
-	    ((iblock + ((len - 1) >> i_blkbits)) > endblk))
-		len = (endblk - iblock + 1) << i_blkbits;
+	/* Do not hand out a mapping which is over the end of the file. */
+	if (lblk < eof_blk && lblk + map->len > eof_blk)
+		map->len = eof_blk - lblk;
 
-	mlog(0, "get block of %llu at %llu:%u req %u\n",
-			inode->i_ino, pos, len, total_len);
+	map->len = min_t(u64, map->len,
+			 max_t(u64, OCFS2_DIO_MAX_MAP_BYTES >> blkbits, bpc));
 
 	/*
-	 * Because we need to change file size in ocfs2_dio_end_io_write(), or
-	 * we may need to add it to orphan dir. So can not fall to fast path
-	 * while file size will be changed.
+	 * This is the fast path for re-write.  The range which is in the file
+	 * has nothing to allocate nor to convert if it is mapped already. What
+	 * changes the file size is done at the end of io, no matter what the
+	 * mappings were.
 	 */
-	if (pos + total_len <= i_size_read(inode)) {
-
-		/* This is the fast path for re-write. */
-		ret = ocfs2_lock_get_block(inode, iblock, bh_result, create);
-		if (buffer_mapped(bh_result) &&
-		    !buffer_new(bh_result) &&
-		    ret == 0)
-			goto out;
-
-		/* Clear state set by ocfs2_get_block. */
-		bh_result->b_state = 0;
-	}
-
-	dwc = ocfs2_dio_alloc_write_ctx(bh_result, &first_get_block);
-	if (unlikely(dwc == NULL)) {
-		ret = -ENOMEM;
-		mlog_errno(ret);
-		goto out;
-	}
-
-	if (ocfs2_clusters_for_bytes(inode->i_sb, pos + total_len) >
-	    ocfs2_clusters_for_bytes(inode->i_sb, i_size_read(inode)) &&
-	    !dwc->dw_orphaned) {
-		/*
-		 * when we are going to alloc extents beyond file size, add the
-		 * inode to orphan dir, so we can recall those spaces when
-		 * system crashed during write.
-		 */
-		ret = ocfs2_add_inode_to_orphan(osb, inode);
-		if (ret < 0) {
-			mlog_errno(ret);
-			goto out;
+	if (lblk < eof_blk) {
+		probe = *map;
+		probe.flags = 0;
+		ret = ocfs2_lock_map_blocks(inode, &probe,
+					    OCFS2_GET_BLOCKS_CREATE);
+		if (ret == 0 && (probe.flags & OCFS2_MAP_MAPPED) &&
+		    !(probe.flags & OCFS2_MAP_NEW)) {
+			*map = probe;
+			return 0;
 		}
-		dwc->dw_orphaned = 1;
+		ret = 0;
 	}
 
+	/* The allocation below sleeps on locks. */
+	if (flags & IOMAP_NOWAIT) //zhm: remove??
+		return -EAGAIN;
+
 	ret = ocfs2_inode_lock(inode, &di_bh, 1);
 	if (ret) {
 		mlog_errno(ret);
@@ -2290,95 +2813,149 @@ static int ocfs2_dio_wr_get_block(struct inode *inode, sector_t iblock,
 
 	down_write(&oi->ip_alloc_sem);
 
-	if (first_get_block) {
-		if (ocfs2_sparse_alloc(osb))
-			ret = ocfs2_zero_tail(inode, di_bh, pos);
-		else
-			ret = ocfs2_expand_nonsparse_inode(inode, di_bh, pos,
-							   total_len, NULL);
-		if (ret < 0) {
-			mlog_errno(ret);
-			goto unlock;
-		}
+	/*
+	 * Only take what is of the same kind as what is at the start:
+	 * all of it is a hole, or all of it is unwritten, or all of
+	 * it is written, in one extent.
+	 */
+	probe = *map;
+	probe.flags = 0;
+	ret = ocfs2_map_blocks(inode, &probe, 0);
+	if (ret) {
+		mlog_errno(ret);
+		goto unlock;
 	}
+	map->len = min_t(u64, map->len, probe.len);
+	len = map->len << blkbits;
 
+	/*
+	 * Note, Zeroing the gap between i_size and the write is done
+	 * once per dio by ocfs2_dio_zero_eof() before the io is issued.
+	 */
+again:
 	ret = ocfs2_write_begin_nolock(inode->i_mapping, pos, len,
 				       OCFS2_WRITE_DIRECT, NULL,
-				       (void **)&wc, di_bh, NULL);
+				       (void **)&wc, di_bh, NULL, owner);
+	if (ret == -ENOSPC &&
+	    ocfs2_clusters_for_bytes(inode->i_sb, pos + len) >
+	    ocfs2_clusters_for_bytes(inode->i_sb, pos) + 1) {
+		/*
+		 * There is not room for all of it, but maybe there is for
+		 * some, take the first cluster.
+		 */
+		len = min_t(loff_t, len, osb->s_clustersize -
+				(pos & (osb->s_clustersize - 1)));
+		goto again;
+	}
 	if (ret) {
-		mlog_errno(ret);
+		if (ret != -ENOSPC)
+			mlog_errno(ret);
 		goto unlock;
 	}
 
+	/*
+	 * The write context says how many of the clusters are really there.
+	 * It is within what we asked for, what is mapped is up to the end of
+	 * the last of them.
+	 */
 	desc = &wc->w_desc[0];
+	end = min_t(loff_t, pos + len,
+		    ocfs2_clusters_to_bytes(inode->i_sb,
+					    wc->w_cpos + wc->w_clen));
 
-	p_blkno = ocfs2_clusters_to_blocks(inode->i_sb, desc->c_phys);
-	BUG_ON(p_blkno == 0);
-	p_blkno += iblock & (u64)(ocfs2_clusters_to_blocks(inode->i_sb, 1) - 1);
-
-	map_bh(bh_result, inode->i_sb, p_blkno);
-	bh_result->b_size = len;
-	if (desc->c_needs_zero)
-		set_buffer_new(bh_result);
-
-	if (iblock > endblk)
-		set_buffer_new(bh_result);
-
-	/* May sleep in end_io. It should not happen in a irq context. So defer
-	 * it to dio work queue. */
-	set_buffer_defer_completion(bh_result);
+	if (desc->c_phys == 0) {
+		ret = -EIO;
+		mlog_errno(ret);
+		if (wc->w_handle)
+			ocfs2_commit_trans(osb, wc->w_handle);
+		ocfs2_free_write_ctxt(inode, wc);
+		goto unlock;
+	}
 
-	if (!list_empty(&wc->w_unwritten_list)) {
-		struct ocfs2_unwritten_extent *ue = NULL;
+	map->pblk = ocfs2_clusters_to_blocks(inode->i_sb, desc->c_phys) +
+		    (lblk & (bpc - 1));
+	map->len = (end >> blkbits) - lblk;
 
-		ue = list_first_entry(&wc->w_unwritten_list,
-				      struct ocfs2_unwritten_extent,
-				      ue_node);
-		BUG_ON(ue->ue_cpos != desc->c_cpos);
-		/* The physical address may be 0, fill it. */
-		ue->ue_phys = desc->c_phys;
+	/*
+	 * Only report the mapping as UNWRITTEN when the cluster is newly
+	 * allocated or was already unwritten and this write is the one who
+	 * is going to convert it.
+	 */
+	unwritten = ocfs2_desc_dio_unwritten(desc);
+	map->flags = unwritten ? OCFS2_MAP_UNWRITTEN : OCFS2_MAP_MAPPED;
+	if (unwritten || lblk >= eof_blk)
+		map->flags |= OCFS2_MAP_NEW;
 
-		list_splice_tail_init(&wc->w_unwritten_list, &dwc->dw_zero_list);
-		dwc->dw_zero_count += wc->w_unwritten_count;
+	ocfs2_dio_detach_unwritten(wc);
+	/* Here returns only two types: len (success), errno (failure). */
+	ret = ocfs2_write_end_nolock(inode->i_mapping, pos, end - pos,
+				     end - pos, wc);
+	if (ret < 0) {
+		mlog_errno(ret);
+		goto unlock;
 	}
-
-	ret = ocfs2_write_end_nolock(inode->i_mapping, pos, len, len, wc);
-	BUG_ON(ret != len);
+	WARN_ON_ONCE(ret != end - pos);
 	ret = 0;
+
 unlock:
 	up_write(&oi->ip_alloc_sem);
 	ocfs2_inode_unlock(inode, 1);
 	brelse(di_bh);
+
 out:
 	return ret;
 }
 
+/*
+ * Take the unwritten clusters recorded by the direct write @owner, off
+ * the inode's list, to a private list. They stay on the inode's list.
+ */
+static void ocfs2_dio_collect_unwritten(struct inode *inode, void *owner,
+					struct list_head *head)
+{
+	struct ocfs2_inode_info *oi = OCFS2_I(inode);
+	struct ocfs2_unwritten_extent *ue;
+
+	spin_lock(&oi->ip_lock);
+	list_for_each_entry(ue, &oi->ip_unwritten_list, ue_ip_node) {
+		if (ue->ue_owner == owner)
+			list_add_tail(&ue->ue_node, head);
+	}
+	spin_unlock(&oi->ip_lock);
+}
+
+/*
+ * Convert the unwritten extents of a direct write, which is finished,
+ * and change the file size if it has been extended.
+ *
+ * @head are the clusters the write has zeroed or allocated, recorded by
+ * ocfs2_dio_wr_map_blocks(). Those which are not covered by the data
+ * written, [offset, offset + bytes), are left unwritten.
+ */
 static int ocfs2_dio_end_io_write(struct inode *inode,
-				  struct ocfs2_dio_write_ctxt *dwc,
 				  loff_t offset,
-				  ssize_t bytes)
+				  ssize_t bytes,
+				  struct list_head *head)
 {
 	struct ocfs2_cached_dealloc_ctxt dealloc;
 	struct ocfs2_extent_tree et;
 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 	struct ocfs2_inode_info *oi = OCFS2_I(inode);
-	struct ocfs2_unwritten_extent *ue = NULL;
+	struct ocfs2_unwritten_extent *ue;
 	struct buffer_head *di_bh = NULL;
 	struct ocfs2_dinode *di;
 	struct ocfs2_alloc_context *data_ac = NULL;
 	struct ocfs2_alloc_context *meta_ac = NULL;
 	handle_t *handle = NULL;
 	loff_t end = offset + bytes;
-	int ret = 0, credits = 0, batch = 0;
+	int ret = 0, credits = 0, batch = 0, pass;
+	u32 first_cpos, last_cpos;
+	u32 extents_to_split = 0;
 
-	ocfs2_init_dealloc_ctxt(&dealloc);
+	first_cpos = offset >> osb->s_clustersize_bits;
+	last_cpos = ocfs2_clusters_for_bytes(inode->i_sb, end);
 
-	/* We do clear unwritten, delete orphan, change i_size here. If neither
-	 * of these happen, we can skip all this. */
-	if (list_empty(&dwc->dw_zero_list) &&
-	    end <= i_size_read(inode) &&
-	    !dwc->dw_orphaned)
-		goto out;
+	ocfs2_init_dealloc_ctxt(&dealloc);
 
 	ret = ocfs2_inode_lock(inode, &di_bh, 1);
 	if (ret < 0) {
@@ -2391,54 +2968,102 @@ static int ocfs2_dio_end_io_write(struct inode *inode,
 
 	ocfs2_init_dinode_extent_tree(&et, INODE_CACHE(inode), di_bh);
 
-	/* Attach dealloc with extent tree in case that we may reuse extents
+	/*
+	 * Attach dealloc with extent tree in case that we may reuse extents
 	 * which are already unlinked from current extent tree due to extent
 	 * rotation and merging.
 	 */
 	et.et_dealloc = &dealloc;
 
-	ret = ocfs2_lock_allocators(inode, &et, 0, dwc->dw_zero_count*2,
-				    &data_ac, &meta_ac);
-	if (ret) {
-		mlog_errno(ret);
-		goto unlock;
-	}
+	/*
+	 * Two passes over the clusters which are recorded: the first one
+	 * counts the unwritten extents, the allocators we need depend on
+	 * it. The second one converts them.
+	 */
+	for (pass = 0; pass < 2; pass++) {
+		list_for_each_entry(ue, head, ue_node) {
+			u32 cpos = max(ue->ue_cpos, first_cpos);
+			u32 cend = min(ue->ue_cpos + ue->ue_clusters, last_cpos);
+
+			while (cpos < cend) {
+				unsigned int ext_flags;
+				u32 phys, num;
+
+				ret = ocfs2_get_clusters(inode, cpos, &phys,
+							 &num, &ext_flags);
+				if (ret < 0) {
+					mlog_errno(ret);
+					goto commit;
+				}
+				num = min(num, cend - cpos);
+				if (WARN_ON_ONCE(!num)) {
+					ret = -EIO;
+					goto commit;
+				}
 
-	credits = ocfs2_calc_extend_credits(inode->i_sb, &di->id2.i_list);
+				if (!phys || !(ext_flags & OCFS2_EXT_UNWRITTEN)) {
+					cpos += num;
+					continue;
+				}
 
-	list_for_each_entry(ue, &dwc->dw_zero_list, ue_node) {
-		if (!handle) {
-			handle = ocfs2_start_trans(osb, credits);
-			if (IS_ERR(handle)) {
-				ret = PTR_ERR(handle);
-				mlog_errno(ret);
-				goto unlock;
-			}
-			ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), di_bh,
-					OCFS2_JOURNAL_ACCESS_WRITE);
-			if (ret) {
-				mlog_errno(ret);
-				goto commit;
-			}
-		}
-		ret = ocfs2_assure_trans_credits(handle, credits);
-		if (ret < 0) {
-			mlog_errno(ret);
-			goto commit;
-		}
-		ret = ocfs2_mark_extent_written(inode, &et, handle,
-						ue->ue_cpos, 1,
-						ue->ue_phys,
+				if (pass == 0) {
+					extents_to_split++;
+					cpos += num;
+					continue;
+				}
+
+				/* pass == 1 */
+				if (!handle) {
+					handle = ocfs2_start_trans(osb, credits);
+					if (IS_ERR(handle)) {
+						ret = PTR_ERR(handle);
+						handle = NULL;
+						mlog_errno(ret);
+						goto unlock;
+					}
+					ret = ocfs2_journal_access_di(handle,
+						INODE_CACHE(inode), di_bh,
+						OCFS2_JOURNAL_ACCESS_WRITE);
+					if (ret) {
+						mlog_errno(ret);
+						goto commit;
+					}
+				}
+				ret = ocfs2_assure_trans_credits(handle, credits);
+				if (ret < 0) {
+					mlog_errno(ret);
+					goto commit;
+				}
+
+				ret = ocfs2_mark_extent_written(inode, &et,
+						handle, cpos, num, phys,
 						meta_ac, &dealloc);
-		if (ret < 0) {
-			mlog_errno(ret);
-			goto commit;
+				if (ret < 0) {
+					mlog_errno(ret);
+					goto commit;
+				}
+				cpos += num;
+
+				if (++batch == OCFS2_DIO_MARK_EXTENT_BATCH) {
+					ocfs2_commit_trans(osb, handle);
+					handle = NULL;
+					batch = 0;
+				}
+			}
 		}
 
-		if (++batch == OCFS2_DIO_MARK_EXTENT_BATCH) {
-			ocfs2_commit_trans(osb, handle);
-			handle = NULL;
-			batch = 0;
+		if (pass == 0) {
+			if (extents_to_split) {
+				ret = ocfs2_lock_allocators(inode, &et, 0,
+						extents_to_split * 2,
+						&data_ac, &meta_ac);
+				if (ret) {
+					mlog_errno(ret);
+					goto unlock;
+				}
+			}
+			credits = ocfs2_calc_extend_credits(inode->i_sb,
+							    &di->id2.i_list);
 		}
 	}
 
@@ -2447,6 +3072,7 @@ static int ocfs2_dio_end_io_write(struct inode *inode,
 			handle = ocfs2_start_trans(osb, credits);
 			if (IS_ERR(handle)) {
 				ret = PTR_ERR(handle);
+				handle = NULL;
 				mlog_errno(ret);
 				goto unlock;
 			}
@@ -2459,6 +3085,7 @@ static int ocfs2_dio_end_io_write(struct inode *inode,
 commit:
 	if (handle)
 		ocfs2_commit_trans(osb, handle);
+
 unlock:
 	up_write(&oi->ip_alloc_sem);
 
@@ -2471,89 +3098,27 @@ static int ocfs2_dio_end_io_write(struct inode *inode,
 		meta_ac = NULL;
 	}
 
-	/* everything looks good, let's start the cleanup */
-	if (!ret && dwc->dw_orphaned) {
-		BUG_ON(dwc->dw_writer_pid != task_pid_nr(current));
-
-		ret = ocfs2_del_inode_from_orphan(osb, inode, di_bh, 0, 0);
-		if (ret < 0)
-			mlog_errno(ret);
-	}
+	/*
+	 * The orphan entry is removed by ocfs2_file_write_iter(), by the writer
+	 * that added it. Other dios on this inode may complete here while it
+	 * is still in flight, so they must not touch it.
+	 */
 	ocfs2_inode_unlock(inode, 1);
 	brelse(di_bh);
+
 out:
 	ocfs2_run_deallocs(osb, &dealloc);
-	ocfs2_dio_free_write_ctx(inode, dwc);
-
 	return ret;
 }
 
 /*
- * ocfs2_dio_end_io is called by the dio core when a dio is finished.  We're
- * particularly interested in the aio/dio case.  We use the rw_lock DLM lock
- * to protect io on one node from truncation on another.
+ * The mapping for a direct write needs the owner, ocfs2_iomap_next() fetches
+ * it from iomap_iter.private, which is the kiocb ocfs2_file_write_iter() has
+ * called __iomap_dio_rw() with.  ocfs2_dio_end_io() gets the same kiocb.
  */
-static int ocfs2_dio_end_io(struct kiocb *iocb,
-			    loff_t offset,
-			    ssize_t bytes,
-			    void *private)
-{
-	struct inode *inode = file_inode(iocb->ki_filp);
-	int level;
-	int ret = 0;
-
-	/* this io's submitter should not have unlocked this before we could */
-	BUG_ON(!ocfs2_iocb_is_rw_locked(iocb));
-
-	if (bytes <= 0)
-		mlog_ratelimited(ML_ERROR, "Direct IO failed, bytes = %lld",
-				 (long long)bytes);
-	if (private) {
-		if (bytes > 0)
-			ret = ocfs2_dio_end_io_write(inode, private, offset,
-						     bytes);
-		else
-			ocfs2_dio_free_write_ctx(inode, private);
-	}
-
-	ocfs2_iocb_clear_rw_locked(iocb);
-
-	level = ocfs2_iocb_rw_locked_level(iocb);
-	ocfs2_rw_unlock(inode, level);
-	return ret;
-}
-
-static ssize_t ocfs2_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
-{
-	struct file *file = iocb->ki_filp;
-	struct inode *inode = file->f_mapping->host;
-	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
-	get_block_t *get_block;
-
-	/*
-	 * Fallback to buffered I/O if we see an inode without
-	 * extents.
-	 */
-	if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL)
-		return 0;
-
-	/* Fallback to buffered I/O if we do not support append dio. */
-	if (iocb->ki_pos + iter->count > i_size_read(inode) &&
-	    !ocfs2_supports_append_dio(osb))
-		return 0;
-
-	if (iov_iter_rw(iter) == READ)
-		get_block = ocfs2_lock_get_block;
-	else
-		get_block = ocfs2_dio_wr_get_block;
-
-	return __blockdev_direct_IO(iocb, inode, inode->i_sb->s_bdev,
-				    iter, get_block,
-				    ocfs2_dio_end_io, 0);
-}
-
 static int ocfs2_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
-		unsigned int flags, struct iomap *iomap, struct iomap *srcmap)
+		unsigned int flags, struct iomap *iomap, struct iomap *srcmap,
+		void *owner)
 {
 	int ret;
 	struct ocfs2_map_block map;
@@ -2572,10 +3137,11 @@ static int ocfs2_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
 	map.flags = 0;
 
 	if (flags & IOMAP_WRITE) {
-		return -EOPNOTSUPP;
+		ret = ocfs2_dio_wr_map_blocks(inode, &map, flags, owner);
+	} else {
+		ret = ocfs2_lock_map_blocks(inode, &map, 0);
 	}
 
-	ret = ocfs2_lock_map_blocks(inode, &map, 0);
 	if (ret < 0)
 		return ret;
 
@@ -2604,10 +3170,95 @@ static int ocfs2_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
 	return 0;
 }
 
+static int ocfs2_iomap_next(const struct iomap_iter *iter, struct iomap *iomap,
+			    struct iomap *srcmap)
+{
+	int ret;
+
+	if (iomap->length) {
+		ret = iomap_iter_continue(iter, iomap, srcmap, 0);
+		if (ret <= 0)
+			return ret;
+	}
+
+	ret = ocfs2_iomap_begin(iter->inode, iter->pos, iter->len, iter->flags,
+				iomap, srcmap, iter->private);
+	return ret < 0 ? ret : 1;
+}
+
 const struct iomap_ops ocfs2_iomap_ops = {
-	.iomap_begin	= ocfs2_iomap_begin,
+	.iomap_next	= ocfs2_iomap_next,
 };
 
+/*
+ * Direct I/O completion. Like the old buffer_head path
+ * ocfs2_dio_end_io(), we use the rw_lock (DLM lock) to protect
+ * io on one node from truncation on another, and drop it here
+ * once the io has completed. iomap_dio_complete() always calls
+ * this, including on the buffered-fallback (-ENOTBLK) path,
+ * so the rw_lock taken in ocfs2_file_{read,write}_iter() is
+ * released exactly once.
+ *
+ * It also is where the unwritten clusters of the write are made
+ * written, the ones ocfs2_iomap_begin() has recorded for this kiocb.
+ * The records go whatever the outcome of the io is.
+ *
+ * Mind the context. A write which needs nothing here, a plain
+ * overwrite, is completed by iomap from the bio completion, that is
+ * in interrupt context. ip_lock, which protects ip_unwritten_list,
+ * is not safe to be taken from there. That is no problem, as there is
+ * nothing recorded for such a write, and iomap defers the completion
+ * to a process context, when there is: for the unwritten extents we
+ * have mapped (IOMAP_DIO_UNWRITTEN), or for any error.
+ */
+static int ocfs2_dio_end_io(struct kiocb *iocb, ssize_t size,
+			int error, unsigned int flags, int level)
+{
+	struct inode *inode = file_inode(iocb->ki_filp);
+	loff_t offset = iocb->ki_pos;
+	bool recorded = error || (flags & IOMAP_DIO_UNWRITTEN);
+	LIST_HEAD(unwritten);
+	int ret = 0;
+
+	if (recorded)
+		ocfs2_dio_collect_unwritten(inode, iocb, &unwritten);
+
+	if (error)
+		mlog_ratelimited(ML_ERROR, "Direct IO failed, bytes = %lld errno:%d",
+				 (long long)size, error);
+
+	/* bounced back to buffered I/O, leave the rw_lock held */
+	if (size == 0 && error == 0) {
+		ocfs2_free_unwritten_list(inode, &unwritten);
+		return 0;
+	}
+
+	if (size && error == 0 &&
+	    (!list_empty(&unwritten) ||
+	     (offset + size > i_size_read(inode)))) {
+		ret = ocfs2_dio_end_io_write(inode, offset, size, &unwritten);
+		if (ret < 0)
+			mlog_errno(ret);
+	}
+
+	ocfs2_free_unwritten_list(inode, &unwritten);
+	ocfs2_rw_unlock(inode, level);
+
+	return ret ? ret : error;
+}
+
+static int ocfs2_dio_end_io_w_pr(struct kiocb *iocb, ssize_t size,
+				     int error, unsigned int flags)
+{
+	return ocfs2_dio_end_io(iocb, size, error, flags, 0);
+}
+
+static int ocfs2_dio_end_io_w_ex(struct kiocb *iocb, ssize_t size,
+				     int error, unsigned int flags)
+{
+	return ocfs2_dio_end_io(iocb, size, error, flags, 1);
+}
+
 static int ocfs2_dio_end_io_r_pr(struct kiocb *iocb, ssize_t size,
 				int error, unsigned int flags)
 {
@@ -2622,9 +3273,18 @@ static int ocfs2_dio_end_io_r_pr(struct kiocb *iocb, ssize_t size,
 	return error;
 }
 
+const struct iomap_dio_ops ocfs2_iomap_dio_ops_w_pr = {
+	.end_io = ocfs2_dio_end_io_w_pr,
+};
+
+const struct iomap_dio_ops ocfs2_iomap_dio_ops_w_ex = {
+	.end_io = ocfs2_dio_end_io_w_ex,
+};
+
 const struct iomap_dio_ops ocfs2_iomap_dio_ops_r_pr = {
 	.end_io = ocfs2_dio_end_io_r_pr,
 };
+
 const struct address_space_operations ocfs2_aops = {
 	.dirty_folio		= block_dirty_folio,
 	.read_folio		= ocfs2_read_folio,
@@ -2633,7 +3293,6 @@ const struct address_space_operations ocfs2_aops = {
 	.write_begin		= ocfs2_write_begin,
 	.write_end		= ocfs2_write_end,
 	.bmap			= ocfs2_bmap,
-	.direct_IO		= ocfs2_direct_IO,
 	.invalidate_folio	= block_invalidate_folio,
 	.release_folio		= ocfs2_release_folio,
 	.migrate_folio		= buffer_migrate_folio,
diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h
index 2fe3b39e02f7..232e95bf16d8 100644
--- a/fs/ocfs2/aops.h
+++ b/fs/ocfs2/aops.h
@@ -11,6 +11,8 @@
 
 extern const struct iomap_ops ocfs2_iomap_ops;
 extern const struct iomap_dio_ops ocfs2_iomap_dio_ops_r_pr;
+extern const struct iomap_dio_ops ocfs2_iomap_dio_ops_w_pr;
+extern const struct iomap_dio_ops ocfs2_iomap_dio_ops_w_ex;
 
 int ocfs2_map_folio_blocks(struct folio *folio, u64 *p_blkno,
 			  struct inode *inode, unsigned int from,
@@ -38,7 +40,8 @@ typedef enum {
 int ocfs2_write_begin_nolock(struct address_space *mapping,
 		loff_t pos, unsigned len, ocfs2_write_type_t type,
 		struct folio **foliop, void **fsdata,
-		struct buffer_head *di_bh, struct folio *mmap_folio);
+		struct buffer_head *di_bh, struct folio *mmap_folio,
+		void *owner);
 
 int ocfs2_read_inline_data(struct inode *inode, struct folio *folio,
 			   struct buffer_head *di_bh);
@@ -46,36 +49,8 @@ int ocfs2_size_fits_inline_data(struct buffer_head *di_bh, u64 new_size);
 
 int ocfs2_get_block(struct inode *inode, sector_t iblock,
 		    struct buffer_head *bh_result, int create);
+int ocfs2_dio_zero_eof(struct inode *inode, loff_t pos, size_t count);
 int ocfs2_map_blocks(struct inode *inode, struct ocfs2_map_block *map,
 		    int flags);
-/* all ocfs2_dio_end_io()'s fault */
-#define ocfs2_iocb_is_rw_locked(iocb) \
-	test_bit(0, (unsigned long *)&iocb->private)
-static inline void ocfs2_iocb_set_rw_locked(struct kiocb *iocb, int level)
-{
-	set_bit(0, (unsigned long *)&iocb->private);
-	if (level)
-		set_bit(1, (unsigned long *)&iocb->private);
-	else
-		clear_bit(1, (unsigned long *)&iocb->private);
-}
-
-/*
- * Using a named enum representing lock types in terms of #N bit stored in
- * iocb->private, which is going to be used for communication between
- * ocfs2_dio_end_io() and ocfs2_file_write/read_iter().
- */
-enum ocfs2_iocb_lock_bits {
-	OCFS2_IOCB_RW_LOCK = 0,
-	OCFS2_IOCB_RW_LOCK_LEVEL,
-	OCFS2_IOCB_NUM_LOCKS
-};
-
-#define ocfs2_iocb_init_rw_locked(iocb) \
-	(iocb->private = NULL)
-#define ocfs2_iocb_clear_rw_locked(iocb) \
-	clear_bit(OCFS2_IOCB_RW_LOCK, (unsigned long *)&iocb->private)
-#define ocfs2_iocb_rw_locked_level(iocb) \
-	test_bit(OCFS2_IOCB_RW_LOCK_LEVEL, (unsigned long *)&iocb->private)
 
 #endif /* OCFS2_FILE_H */
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 39f4fa924351..b9a7133205d3 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -48,6 +48,7 @@
 #include "quota.h"
 #include "refcounttree.h"
 #include "ocfs2_trace.h"
+#include "namei.h"
 
 #include "buffer_head_io.h"
 
@@ -135,6 +136,14 @@ static int ocfs2_file_open(struct inode *inode, struct file *file)
 
 	file->f_mode |= FMODE_NOWAIT;
 
+	/*
+	 * Direct I/O is served through iomap_dio_rw() from
+	 * ocfs2_file_{read,write}_iter() rather than an a_ops->direct_IO
+	 * method, so advertise O_DIRECT capability explicitly here.
+	 */
+	file->f_mode |= FMODE_CAN_ODIRECT;
+
+
 leave:
 	return status;
 }
@@ -1195,9 +1204,9 @@ int ocfs2_setattr(const struct mnt_idmap *idmap, struct dentry *dentry,
 	size_change = S_ISREG(inode->i_mode) && attr->ia_valid & ATTR_SIZE;
 	if (size_change) {
 		/*
-		 * Here we should wait dio to finish before inode lock
-		 * to avoid a deadlock between ocfs2_setattr() and
-		 * ocfs2_dio_end_io_write()
+		 * Here we should wait for in-flight direct I/O to finish
+		 * before taking the inode lock, to avoid a deadlock between
+		 * ocfs2_setattr() and direct I/O completion.
 		 */
 		inode_dio_wait(inode);
 
@@ -2404,6 +2413,11 @@ static bool ocfs2_should_use_dio(struct kiocb *iocb, struct iov_iter *iter,
 				struct inode *inode)
 {
 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+	unsigned int dio_align = bdev_logical_block_size(inode->i_sb->s_bdev);
+
+	/* Fallback to buffered I/O if we do not alignment. */
+	if (!IS_ALIGNED(iocb->ki_pos | iov_iter_alignment(iter), dio_align))
+		return false;
 
 	/*
 	 * Fallback to buffered I/O if we see an inode without
@@ -2420,6 +2434,35 @@ static bool ocfs2_should_use_dio(struct kiocb *iocb, struct iov_iter *iter,
 	return true;
 }
 
+/*
+ * Remove the inode from the orphan dir after an appending direct write.
+ * Only the writer that added the inode (under i_rwsem) may remove it;
+ */
+static int ocfs2_dio_del_orphan(struct inode *inode)
+{
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+	struct buffer_head *di_bh = NULL;
+	struct ocfs2_dinode *di;
+	int ret;
+
+	ret = ocfs2_inode_lock(inode, &di_bh, 1);
+	if (ret < 0) {
+		mlog_errno(ret);
+		return ret;
+	}
+
+	di = (struct ocfs2_dinode *)di_bh->b_data;
+	if (di->i_flags & cpu_to_le32(OCFS2_DIO_ORPHANED_FL)) {
+		ret = ocfs2_del_inode_from_orphan(osb, inode, di_bh, 0, 0);
+		if (ret < 0)
+			mlog_errno(ret);
+	}
+
+	ocfs2_inode_unlock(inode, 1);
+	brelse(di_bh);
+	return ret;
+}
+
 static ssize_t ocfs2_file_write_iter(struct kiocb *iocb,
 				    struct iov_iter *from)
 {
@@ -2437,6 +2480,8 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb,
 			i_size_read(inode) ? 1 : 0);
 	int direct_io = iocb->ki_flags & IOCB_DIRECT ? 1 : 0;
 	int nowait = iocb->ki_flags & IOCB_NOWAIT ? 1 : 0;
+	int dio_flags = 0;
+	int orphaned = 0;
 
 	if (trace_ocfs2_file_write_iter_enabled()) {
 		struct dentry *dentry = file->f_path.dentry;
@@ -2462,8 +2507,6 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb,
 	} else
 		inode_lock(inode);
 
-	ocfs2_iocb_init_rw_locked(iocb);
-
 	/*
 	 * Concurrent O_DIRECT writes are allowed with
 	 * mount_option "coherency=buffered".
@@ -2519,6 +2562,10 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb,
 		goto out;
 	}
 
+	ret = kiocb_modified(iocb);
+	if (ret < 0)
+		goto out;
+
 	if (direct_io && !is_sync_kiocb(iocb) &&
 	    ocfs2_is_io_unaligned(inode, count, iocb->ki_pos)) {
 		/*
@@ -2527,26 +2574,90 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb,
 		saved_ki_complete = xchg(&iocb->ki_complete, NULL);
 	}
 
-	/* communicate with ocfs2_dio_end_io */
-	ocfs2_iocb_set_rw_locked(iocb, rw_level);
+	if (direct_io && ocfs2_should_use_dio(iocb, from, inode)) {
+		if (iocb->ki_pos > i_size_read(inode) &&
+		    fault_in_iov_iter_readable(from, count)) {
+			ret = -EFAULT;
+			goto out;
+		}
 
-	written = __generic_file_write_iter(iocb, from);
-	/* buffered aio wouldn't have proper lock coverage today */
-	BUG_ON(written == -EIOCBQUEUED && !direct_io);
+		if (ocfs2_clusters_for_bytes(inode->i_sb, iocb->ki_pos + count) >
+		    ocfs2_clusters_for_bytes(inode->i_sb, i_size_read(inode))) {
+			/*
+			 * when we are going to alloc extents beyond file size, add the
+			 * inode to orphan dir, so we can recall those spaces when
+			 * system crashed during write.
+			 */
+			ret = ocfs2_add_inode_to_orphan(osb, inode);
+			if (ret < 0) {
+				mlog_errno(ret);
+				goto out;
+			}
+			orphaned = 1;
+			dio_flags = IOMAP_DIO_FORCE_WAIT;
+		}
 
-	/*
-	 * deep in g_f_a_w_n()->ocfs2_direct_IO we pass in a ocfs2_dio_end_io
-	 * function pointer which is called when o_direct io completes so that
-	 * it can unlock our rw lock.
-	 * Unfortunately there are error cases which call end_io and others
-	 * that don't.  so we don't have to unlock the rw_lock if either an
-	 * async dio is going to do it in the future or an end_io after an
-	 * error has already done it.
-	 */
-	if ((written == -EIOCBQUEUED) || (!ocfs2_iocb_is_rw_locked(iocb))) {
-		rw_level = -1;
+		ret = ocfs2_dio_zero_eof(inode, iocb->ki_pos, count);
+		if (ret < 0)
+			goto out;
+
+		const struct iomap_dio_ops *dops = rw_level ?
+			&ocfs2_iomap_dio_ops_w_ex : &ocfs2_iomap_dio_ops_w_pr;
+		struct iomap_dio *dio;
+
+		/*
+		 * The kiocb is the owner of the unwritten clusters which
+		 * ->iomap_begin() records for ->end_io() to convert, see
+		 * ocfs2_iomap_next().
+		 */
+		dio = __iomap_dio_rw(iocb, from, &ocfs2_iomap_ops,
+				     dops, dio_flags, iocb, 0);
+		if (dio == NULL) {
+			/* No I/O issued; rw_lock still held. */
+			written = 0;
+		} else if (IS_ERR(dio)) {
+			written = PTR_ERR(dio);
+			/*
+			 * -EIOCBQUEUED: async I/O; end_io will drop the lock on
+			 * completion. Any other error means no I/O started and
+			 * end_io was not called, so the cleanup path below drops
+			 * the lock.
+			 */
+			if (written == -EIOCBQUEUED)
+				rw_level = -1;
+		} else {
+			/*
+			 * Synchronous completion. iomap_dio_complete() runs
+			 * end_io, which drops the lock unless the mapping
+			 * bounced us back to buffered I/O (returns 0, lock
+			 * retained).
+			 */
+			written = iomap_dio_complete(dio);
+			if (written != 0)
+				rw_level = -1;
+		}
+
+		/*
+		 * __iomap_dio_rw() returns -ENOTBLK when it could not invalidate
+		 * the page cache for the DIO range (e.g. racing buffered/mmap
+		 * I/O on the same file, as exercised by generic/095). Fall back
+		 * to a buffered write for the remaining data, the same way
+		 * ext4/xfs do, instead of leaking -ENOTBLK to userspace.
+		 */
+		if (written == -ENOTBLK)
+			written = 0;
+		if (written == 0 && iov_iter_count(from)) {
+			written = direct_write_fallback(iocb, from, ret,
+					generic_perform_write(iocb, from));
+		}
+	} else {
+		iocb->ki_flags &= ~IOCB_DIRECT;
+		written = __generic_file_write_iter(iocb, from);
 	}
 
+	/* buffered aio wouldn't have proper lock coverage today */
+	BUG_ON(written == -EIOCBQUEUED && !direct_io);
+
 	if (unlikely(written <= 0))
 		goto out;
 
@@ -2571,6 +2682,13 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb,
 	}
 
 out:
+	/*
+	 * IOMAP_DIO_FORCE_WAIT made the dio complete synchronously, so its
+	 * end_io has already updated i_size.
+	 */
+	if (orphaned)
+		ocfs2_dio_del_orphan(inode);
+
 	if (saved_ki_complete)
 		xchg(&iocb->ki_complete, saved_ki_complete);
 
diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c
index 6c570157caf1..885583302c0d 100644
--- a/fs/ocfs2/mmap.c
+++ b/fs/ocfs2/mmap.c
@@ -90,7 +90,7 @@ static vm_fault_t __ocfs2_page_mkwrite(struct file *file,
 		len = ((size - 1) & ~PAGE_MASK) + 1;
 
 	err = ocfs2_write_begin_nolock(mapping, pos, len, OCFS2_WRITE_MMAP,
-				       &locked_folio, &fsdata, di_bh, folio);
+				       &locked_folio, &fsdata, di_bh, folio, NULL);
 	if (err) {
 		if (err != -ENOSPC)
 			mlog_errno(err);
-- 
2.55.0


      parent reply	other threads:[~2026-11-15 15:40 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-15 15:40 [RFC PATCH v6 0/3] migrate ocfs2 DIO " Heming Zhao
2026-11-15 15:40 ` [RFC PATCH v6 1/3] ocfs2: Add new ocfs2_map_blocks() to introduce iomap feature Heming Zhao
2026-11-15 15:40 ` [RFC PATCH v6 2/3] ocfs2: switch DIO read path from buffer_head to iomap Heming Zhao
2026-11-15 15:40 ` Heming Zhao [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261115154013.9379-4-heming.zhao@suse.com \
    --to=heming.zhao@suse.com \
    --cc=hch@lst.de \
    --cc=jlbec@evilplan.org \
    --cc=joseph.qi@linux.alibaba.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mark@fasheh.com \
    --cc=ocfs2-devel@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®