mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Mauricio Faria de Oliveira <mfo@igalia.com>
To: Andreas Gruenbacher <agruenba@redhat.com>
Cc: kernel-dev@igalia.com, gfs2@lists.linux.dev,
	 linux-kernel@vger.kernel.org,
	Mauricio Faria de Oliveira <mfo@igalia.com>
Subject: [PATCH 3/5] gfs2: handle NULL return value in callers of gfs2_meta_new()
Date: Tue, 08 Sep 2026 18:16:14 -0300	[thread overview]
Message-ID: <20260908-gfs2_getbuf-error-checks-v1-3-7c59698f178f@igalia.com> (raw)
In-Reply-To: <20260908-gfs2_getbuf-error-checks-v1-0-7c59698f178f@igalia.com>

Now that gfs2_meta_new() can return NULL (instead of hit a kernel oops),
update its callers to handle it (and not hit another kernel oops).

If gfs2_meta_new() returns NULL:

- new_leaf()

  It currently checks for NULL and returns -EIO.

- gfs2_indirect_init()

  Return -EIO. The only caller is __gfs2_iomap_alloc() (same file), twice.
  Fail as currently done in other cases.

- gfs2_dir_get_new_buffer()

  Return -EIO. The only two callers already check for errors.

- gfs2_init_xattr()
- init_dinode()

  Return -EIO. The only caller is gfs2_create_inode() (same file).
  Fail as currently done in the preceding error case.

- buf_lo_scan_elements()
- data_buf_lo_scan_elements()

  Return -EIO after releasing the just acquired bh_log buffer.

- ea_alloc_blk()
- ea_write()
- ea_set_block()

  Return -EIO. The function can currently return errors.

Signed-off-by: Mauricio Faria de Oliveira <mfo@igalia.com>
---
 fs/gfs2/bmap.c  | 25 +++++++++++++++++--------
 fs/gfs2/dir.c   |  2 ++
 fs/gfs2/inode.c | 20 +++++++++++++++-----
 fs/gfs2/lops.c  |  8 ++++++++
 fs/gfs2/xattr.c |  6 ++++++
 5 files changed, 48 insertions(+), 13 deletions(-)

diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index a766b5816634d360a4bbae89f8bcdd284071864a..1c14313acea084584ae5de69a1107b45e470606a 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -608,9 +608,9 @@ static int gfs2_hole_size(struct inode *inode, sector_t lblock, u64 len,
 	return ret;
 }
 
-static inline void gfs2_indirect_init(struct metapath *mp,
-				      struct gfs2_glock *gl, unsigned int i,
-				      unsigned offset, u64 bn)
+static inline int gfs2_indirect_init(struct metapath *mp,
+				     struct gfs2_glock *gl, unsigned int i,
+				     unsigned int offset, u64 bn)
 {
 	__be64 *ptr = (__be64 *)(mp->mp_bh[i - 1]->b_data +
 		       ((i > 1) ? sizeof(struct gfs2_meta_header) :
@@ -618,11 +618,14 @@ static inline void gfs2_indirect_init(struct metapath *mp,
 	BUG_ON(i < 1);
 	BUG_ON(mp->mp_bh[i] != NULL);
 	mp->mp_bh[i] = gfs2_meta_new(gl, bn);
+	if (!mp->mp_bh[i])
+		return -EIO;
 	gfs2_trans_add_meta(gl, mp->mp_bh[i]);
 	gfs2_metatype_set(mp->mp_bh[i], GFS2_METATYPE_IN, GFS2_FORMAT_IN);
 	gfs2_buffer_clear_tail(mp->mp_bh[i], sizeof(struct gfs2_meta_header));
 	ptr += offset;
 	*ptr = cpu_to_be64(bn);
+	return 0;
 }
 
 enum alloc_state {
@@ -723,8 +726,11 @@ static int __gfs2_iomap_alloc(struct inode *inode, struct iomap *iomap,
 				zero_bn = *ptr;
 			}
 			for (; i - 1 < mp->mp_fheight - ip->i_height && n > 0;
-			     i++, n--)
-				gfs2_indirect_init(mp, ip->i_gl, i, 0, bn++);
+			     i++, n--) {
+				ret = gfs2_indirect_init(mp, ip->i_gl, i, 0, bn++);
+				if (ret)
+					goto out;
+			}
 			if (i - 1 == mp->mp_fheight - ip->i_height) {
 				i--;
 				gfs2_buffer_copy_tail(mp->mp_bh[i],
@@ -751,9 +757,12 @@ static int __gfs2_iomap_alloc(struct inode *inode, struct iomap *iomap,
 		case ALLOC_GROW_DEPTH:
 			if (i > 1 && i < mp->mp_fheight)
 				gfs2_trans_add_meta(ip->i_gl, mp->mp_bh[i-1]);
-			for (; i < mp->mp_fheight && n > 0; i++, n--)
-				gfs2_indirect_init(mp, ip->i_gl, i,
-						   mp->mp_list[i-1], bn++);
+			for (; i < mp->mp_fheight && n > 0; i++, n--) {
+				ret = gfs2_indirect_init(mp, ip->i_gl, i,
+							 mp->mp_list[i-1], bn++);
+				if (ret)
+					goto out;
+			}
 			if (i == mp->mp_fheight)
 				state = ALLOC_DATA;
 			if (n == 0)
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index 0d92f6c33dcb85dfa2a4b07f9f09575834e75e01..d1dc1e94b6c432d2ede504b04cb71959285a945d 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -93,6 +93,8 @@ int gfs2_dir_get_new_buffer(struct gfs2_inode *ip, u64 block,
 	struct buffer_head *bh;
 
 	bh = gfs2_meta_new(ip->i_gl, block);
+	if (!bh)
+		return -EIO;
 	gfs2_trans_add_meta(ip->i_gl, bh);
 	gfs2_metatype_set(bh, GFS2_METATYPE_JD, GFS2_FORMAT_JD);
 	gfs2_buffer_clear_tail(bh, sizeof(struct gfs2_meta_header));
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index f361876c5583353a1196ed35be1c95af33a90c02..dda51390fee49b56279161fdd755b3c2b6e7eac6 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -544,13 +544,15 @@ static void gfs2_init_dir(struct buffer_head *dibh,
  * take any ACLs, LSM xattrs, etc.
  */
 
-static void gfs2_init_xattr(struct gfs2_inode *ip)
+static int gfs2_init_xattr(struct gfs2_inode *ip)
 {
 	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct buffer_head *bh;
 	struct gfs2_ea_header *ea;
 
 	bh = gfs2_meta_new(ip->i_gl, ip->i_eattr);
+	if (!bh)
+		return -EIO;
 	gfs2_trans_add_meta(ip->i_gl, bh);
 	gfs2_metatype_set(bh, GFS2_METATYPE_EA, GFS2_FORMAT_EA);
 	gfs2_buffer_clear_tail(bh, sizeof(struct gfs2_meta_header));
@@ -561,6 +563,7 @@ static void gfs2_init_xattr(struct gfs2_inode *ip)
 	ea->ea_flags = GFS2_EAFLAG_LAST;
 
 	brelse(bh);
+	return 0;
 }
 
 /**
@@ -571,13 +574,15 @@ static void gfs2_init_xattr(struct gfs2_inode *ip)
  *
  */
 
-static void init_dinode(struct gfs2_inode *dip, struct gfs2_inode *ip,
-			const char *symname)
+static int init_dinode(struct gfs2_inode *dip, struct gfs2_inode *ip,
+		       const char *symname)
 {
 	struct gfs2_dinode *di;
 	struct buffer_head *dibh;
 
 	dibh = gfs2_meta_new(ip->i_gl, ip->i_no_addr);
+	if (!dibh)
+		return -EIO;
 	gfs2_trans_add_meta(ip->i_gl, dibh);
 	di = (struct gfs2_dinode *)dibh->b_data;
 	gfs2_dinode_out(ip, di);
@@ -602,6 +607,7 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_inode *ip,
 
 	set_buffer_uptodate(dibh);
 	brelse(dibh);
+	return 0;
 }
 
 /**
@@ -864,10 +870,14 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
 		goto fail_gunlock3;
 
 	if (blocks > 1) {
-		gfs2_init_xattr(ip);
+		error = gfs2_init_xattr(ip);
+		if (error)
+			goto fail_gunlock3;
 		xattr_initialized = true;
 	}
-	init_dinode(dip, ip, symname);
+	error = init_dinode(dip, ip, symname);
+	if (error)
+		goto fail_gunlock3;
 	gfs2_trans_end(sdp);
 
 	glock_set_object(ip->i_gl, ip);
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index 6dabe73ad790d9cbf6f2725dd3e5e1c40c3781b8..192e71e630dce062361cc754f2ba878fa23c0a7f 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -801,6 +801,10 @@ static int buf_lo_scan_elements(struct gfs2_jdesc *jd, u32 start,
 			return error;
 
 		bh_ip = gfs2_meta_new(gl, blkno);
+		if (!bh_ip) {
+			brelse(bh_log);
+			return -EIO;
+		}
 		memcpy(bh_ip->b_data, bh_log->b_data, bh_log->b_size);
 
 		if (gfs2_meta_check(sdp, bh_ip))
@@ -1026,6 +1030,10 @@ static int databuf_lo_scan_elements(struct gfs2_jdesc *jd, u32 start,
 			return error;
 
 		bh_ip = gfs2_meta_new(gl, blkno);
+		if (!bh_ip) {
+			brelse(bh_log);
+			return -EIO;
+		}
 		memcpy(bh_ip->b_data, bh_log->b_data, bh_log->b_size);
 
 		/* Unescape */
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c
index b9f48d6f10a97a36365a2fe636ceb1cd476e4318..5aec4d0f240dc5beef18bc5619faf6b375152c03 100644
--- a/fs/gfs2/xattr.c
+++ b/fs/gfs2/xattr.c
@@ -648,6 +648,8 @@ static int ea_alloc_blk(struct gfs2_inode *ip, struct buffer_head **bhp)
 		return error;
 	gfs2_trans_remove_revoke(sdp, block, 1);
 	*bhp = gfs2_meta_new(ip->i_gl, block);
+	if (!*bhp)
+		return -EIO;
 	gfs2_trans_add_meta(ip->i_gl, *bhp);
 	gfs2_metatype_set(*bhp, GFS2_METATYPE_EA, GFS2_FORMAT_EA);
 	gfs2_buffer_clear_tail(*bhp, sizeof(struct gfs2_meta_header));
@@ -710,6 +712,8 @@ static int ea_write(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
 				return error;
 			gfs2_trans_remove_revoke(sdp, block, 1);
 			bh = gfs2_meta_new(ip->i_gl, block);
+			if (!bh)
+				return -EIO;
 			gfs2_trans_add_meta(ip->i_gl, bh);
 			gfs2_metatype_set(bh, GFS2_METATYPE_ED, GFS2_FORMAT_ED);
 
@@ -1011,6 +1015,8 @@ static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er,
 			return error;
 		gfs2_trans_remove_revoke(sdp, blk, 1);
 		indbh = gfs2_meta_new(ip->i_gl, blk);
+		if (!indbh)
+			return -EIO;
 		gfs2_trans_add_meta(ip->i_gl, indbh);
 		gfs2_metatype_set(indbh, GFS2_METATYPE_IN, GFS2_FORMAT_IN);
 		gfs2_buffer_clear_tail(indbh, mh_size);

-- 
2.47.3


  parent reply	other threads:[~2026-09-08 21:15 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-08 21:16 [PATCH 0/5] gfs2: handle errors from __filemap_get_folio() with FGP_CREAT in gfs2_getbuf() and its caller chain Mauricio Faria de Oliveira
2026-09-08 21:16 ` [PATCH 1/5] gfs2: handle errors from __filemap_get_folio() with FGP_CREAT in gfs2_getbuf() Mauricio Faria de Oliveira
2026-09-08 21:16 ` [PATCH 2/5] gfs2: handle NULL return value in callers of gfs2_getbuf() with CREATE Mauricio Faria de Oliveira
2026-09-08 21:16 ` Mauricio Faria de Oliveira [this message]
2026-09-08 21:16 ` [PATCH 4/5] gfs2: handle NULL return value in callers of gfs2_meta_ra() Mauricio Faria de Oliveira
2026-09-08 21:16 ` [PATCH 5/5] gfs2: check for errors from filemap_get_folio() in gfs2_jhead_process_page() Mauricio Faria de Oliveira

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=20260908-gfs2_getbuf-error-checks-v1-3-7c59698f178f@igalia.com \
    --to=mfo@igalia.com \
    --cc=agruenba@redhat.com \
    --cc=gfs2@lists.linux.dev \
    --cc=kernel-dev@igalia.com \
    --cc=linux-kernel@vger.kernel.org \
    /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®