diff mbox series

[04/22] udf: Factor out block mapping into udf_map_block()

Message ID 20230124121814.25951-4-jack@suse.cz (mailing list archive)
State New, archived
Headers show
Series udf: Fix couple of preallocation related bugs | expand

Commit Message

Jan Kara Jan. 24, 2023, 12:17 p.m. UTC
Create new block mapping function udf_map_block() that takes new
udf_map_rq structure describing mapping request. We will convert other
places to use this function for block mapping.

Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/udf/inode.c   | 70 +++++++++++++++++++++++++++++++++---------------
 fs/udf/udfdecl.h |  1 +
 2 files changed, 49 insertions(+), 22 deletions(-)
diff mbox series

Patch

diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index ff414fff354a..53d2d8fef158 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -52,6 +52,8 @@ 
 #define FE_DELETE_PERMS	(FE_PERM_U_DELETE | FE_PERM_G_DELETE | \
 			 FE_PERM_O_DELETE)
 
+struct udf_map_rq;
+
 static umode_t udf_convert_permissions(struct fileEntry *);
 static int udf_update_inode(struct inode *, int);
 static int udf_sync_inode(struct inode *inode);
@@ -320,43 +322,67 @@  int udf_expand_file_adinicb(struct inode *inode)
 	return err;
 }
 
-static int udf_get_block(struct inode *inode, sector_t block,
-			 struct buffer_head *bh_result, int create)
+#define UDF_MAP_CREATE	0x01	/* Mapping can allocate new blocks */
+
+#define UDF_BLK_MAPPED	0x01	/* Block was successfully mapped */
+#define UDF_BLK_NEW	0x02	/* Block was freshly allocated */
+
+struct udf_map_rq {
+	sector_t lblk;
+	udf_pblk_t pblk;
+	int iflags;		/* UDF_MAP_ flags determining behavior */
+	int oflags;		/* UDF_BLK_ flags reporting results */
+};
+
+static int udf_map_block(struct inode *inode, struct udf_map_rq *map)
 {
 	int err, new;
-	sector_t phys = 0;
-	struct udf_inode_info *iinfo;
+	struct udf_inode_info *iinfo = UDF_I(inode);
 
-	if (!create) {
-		phys = udf_block_map(inode, block);
-		if (phys)
-			map_bh(bh_result, inode->i_sb, phys);
+	map->oflags = 0;
+	if (!(map->iflags & UDF_MAP_CREATE)) {
+		map->pblk = udf_block_map(inode, map->lblk);
+		if (map->pblk != 0)
+			map->oflags |= UDF_BLK_MAPPED;
 		return 0;
 	}
 
-	err = -EIO;
-	new = 0;
-	iinfo = UDF_I(inode);
-
 	down_write(&iinfo->i_data_sem);
 	/*
 	 * Block beyond EOF and prealloc extents? Just discard preallocation
 	 * as it is not useful and complicates things.
 	 */
-	if (((loff_t)block) << inode->i_blkbits > iinfo->i_lenExtents)
+	if (((loff_t)map->lblk) << inode->i_blkbits > iinfo->i_lenExtents)
 		udf_discard_prealloc(inode);
 	udf_clear_extent_cache(inode);
-	phys = inode_getblk(inode, block, &err, &new);
-	if (!phys)
-		goto abort;
-
+	map->pblk = inode_getblk(inode, map->lblk, &err, &new);
+	up_write(&iinfo->i_data_sem);
+	if (err)
+		return err;
+	map->oflags |= UDF_BLK_MAPPED;
 	if (new)
-		set_buffer_new(bh_result);
-	map_bh(bh_result, inode->i_sb, phys);
+		map->oflags |= UDF_BLK_NEW;
+	return 0;
+}
 
-abort:
-	up_write(&iinfo->i_data_sem);
-	return err;
+static int udf_get_block(struct inode *inode, sector_t block,
+			 struct buffer_head *bh_result, int create)
+{
+	int err;
+	struct udf_map_rq map = {
+		.lblk = block,
+		.iflags = create ? UDF_MAP_CREATE : 0,
+	};
+
+	err = udf_map_block(inode, &map);
+	if (err < 0)
+		return err;
+	if (map.oflags & UDF_BLK_MAPPED) {
+		map_bh(bh_result, inode->i_sb, map.pblk);
+		if (map.oflags & UDF_BLK_NEW)
+			set_buffer_new(bh_result);
+	}
+	return 0;
 }
 
 static struct buffer_head *udf_getblk(struct inode *inode, udf_pblk_t block,
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index 88667a80795d..d791458fe52a 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -138,6 +138,7 @@  static inline unsigned int udf_dir_entry_len(struct fileIdentDesc *cfi)
 
 /* file.c */
 extern long udf_ioctl(struct file *, unsigned int, unsigned long);
+
 /* inode.c */
 extern struct inode *__udf_iget(struct super_block *, struct kernel_lb_addr *,
 				bool hidden_inode);