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 v5 1/4] ocfs2: Add new ocfs2_map_blocks() to introduce iomap feature
Date: Thu, 5 Nov 2026 15:19:25 +0800 [thread overview]
Message-ID: <20261105071930.16399-2-heming.zhao@suse.com> (raw)
In-Reply-To: <20261105071930.16399-1-heming.zhao@suse.com>
As part of migrating OCFS2 DIO read/write code paths towards the modern
and performant iomap framework, here introduces ocfs2_map_blocks() to
replace the legacy, high-overhead buffer_head based block mapping
routines.
In addition, OCFS2_MAP_* flags are defined to gridge OCFS2 internal block
mapping flags with the iomap API requirements.
Subsequent iomap integration patches will build on this core block mapping
routine. The implementation draws inspiration from ext4_map_blocks().
Signed-off-by: Heming Zhao <heming.zhao@suse.com>
---
fs/ocfs2/aops.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++
fs/ocfs2/aops.h | 2 ++
fs/ocfs2/ocfs2.h | 25 ++++++++++++++++-
3 files changed, 98 insertions(+), 1 deletion(-)
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 4acdbb70882c..0f7502de9b8d 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -126,6 +126,78 @@ static int ocfs2_lock_get_block(struct inode *inode, sector_t iblock,
return ret;
}
+/* ocfs2 never allocates in this function */
+int ocfs2_map_blocks(struct inode *inode, struct ocfs2_map_block *map,
+ int flags)
+{
+ int err = 0;
+ unsigned int ext_flags;
+ u64 max_blocks = map->len;
+ u64 p_blkno, count, past_eof;
+ struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+ int create = flags & OCFS2_GET_BLOCKS_CREATE;
+
+ if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_SYSTEM_FILE)
+ mlog(ML_NOTICE, "map_block on system inode 0x%p (%llu)\n",
+ inode, inode->i_ino);
+
+ err = ocfs2_extent_map_get_blocks(inode, map->lblk, &p_blkno, &count,
+ &ext_flags);
+ if (err) {
+ mlog(ML_ERROR, "get_blocks() failed, inode: 0x%p, "
+ "block: %llu\n", inode, map->lblk);
+ goto bail;
+ }
+
+ if (max_blocks < count)
+ count = max_blocks;
+
+ map->pblk = p_blkno;
+ map->len = count;
+
+ /*
+ * If we see this on a sparse file system, then a truncate has
+ * raced us and removed the cluster. We treat this as a hole
+ * and skip setting the iomap flags. The caller will set
+ * iomap->type to IOMAP_HOLE.
+ */
+ if (create && map->pblk == 0 && ocfs2_sparse_alloc(osb))
+ goto bail;
+
+ if (p_blkno) {
+ if (ext_flags & OCFS2_EXT_UNWRITTEN) {
+ map->flags |= OCFS2_MAP_UNWRITTEN;
+ } else {
+ /* Treat the unwritten extent as a hole for zeroing purposes. */
+ map->flags |= OCFS2_MAP_MAPPED;
+ }
+ }
+
+ if (!ocfs2_sparse_alloc(osb)) {
+ if (map->pblk == 0) {
+ err = -EIO;
+ mlog(ML_ERROR,
+ "iblock = %llu p_blkno = %llu blkno=(%llu)\n",
+ (unsigned long long)map->lblk,
+ (unsigned long long)map->pblk,
+ (unsigned long long)OCFS2_I(inode)->ip_blkno);
+ mlog(ML_ERROR, "Size %llu, clusters %u\n",
+ (unsigned long long)i_size_read(inode),
+ OCFS2_I(inode)->ip_clusters);
+ dump_stack();
+ goto bail;
+ }
+ }
+
+ past_eof = ocfs2_blocks_for_bytes(inode->i_sb, i_size_read(inode));
+
+ if (create && (map->lblk >= past_eof))
+ map->flags |= OCFS2_MAP_NEW;
+
+bail:
+ return err;
+}
+
int ocfs2_get_block(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create)
{
diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h
index 114efc9111e4..8dd6edd7c1a1 100644
--- a/fs/ocfs2/aops.h
+++ b/fs/ocfs2/aops.h
@@ -42,6 +42,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_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)
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
index e3bb3cc0b25a..b4583b3170e2 100644
--- a/fs/ocfs2/ocfs2.h
+++ b/fs/ocfs2/ocfs2.h
@@ -514,7 +514,30 @@ struct ocfs2_super
struct ocfs2_filecheck_sysfs_entry osb_fc_ent;
};
-#define OCFS2_SB(sb) ((struct ocfs2_super *)(sb)->s_fs_info)
+/*
+ * Logical to physical block mapping, used by ocfs2_map_blocks()
+ *
+ * This structure is used to pass requests into ocfs2_map_blocks()
+ * as well as to store the information returned by ocfs2_map_blocks().
+ * It takes less room on the stack than a struct buffer_head.
+ */
+#define OCFS2_MAP_NEW BIT(BH_New)
+#define OCFS2_MAP_MAPPED BIT(BH_Mapped)
+#define OCFS2_MAP_UNWRITTEN BIT(BH_Unwritten)
+#define OCFS2_MAP_FLAGS (OCFS2_MAP_NEW | OCFS2_MAP_MAPPED |\
+ OCFS2_MAP_UNWRITTEN)
+
+struct ocfs2_map_block {
+ u64 pblk; /* physical block# */
+ u64 lblk; /* logical block# */
+ u64 len; /* number of block */
+ unsigned int flags;
+};
+
+/* Flags used by ocfs2_map_blocks() */
+#define OCFS2_GET_BLOCKS_CREATE (0x0001)
+
+#define OCFS2_SB(sb) ((struct ocfs2_super *)(sb)->s_fs_info)
/* Useful typedef for passing around journal access functions */
typedef int (*ocfs2_journal_access_func)(handle_t *handle,
--
2.55.0
next prev parent reply other threads:[~2026-11-05 7:19 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-05 7:19 [RFC PATCH v5 0/4] migrates ocfs2 DIO from buffer_head to iomap Heming Zhao
2026-11-05 7:19 ` Heming Zhao [this message]
2026-11-05 7:19 ` [RFC PATCH v5 2/4] ocfs2: switch DIO read path " Heming Zhao
2026-11-05 7:19 ` [RFC PATCH v5 3/4] ocfs2: switch dio write " Heming Zhao
2026-11-05 7:19 ` [RFC PATCH v5 4/4] ocfs2: remove legacy blockdev direct-IO path APIs Heming Zhao
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=20261105071930.16399-2-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®