[Cluster-devel] [PATCH 4/5] libgfs2: Use the new list.h

Andrew Price anprice at redhat.com
Wed Aug 14 17:01:04 UTC 2019


Requires updates in the utils where they use osi_list_t exposed through
libgfs2 interfaces.

The new list.h's pointer poisoning found a double-release in savemeta
which is fixed.

Signed-off-by: Andrew Price <anprice at redhat.com>
---
 gfs2/edit/savemeta.c      | 25 ++++++++++---------------
 gfs2/fsck/metawalk.c      | 38 +++++++++++++++++---------------------
 gfs2/fsck/pass1.c         |  2 +-
 gfs2/fsck/pass1b.c        |  2 +-
 gfs2/fsck/pass4.c         |  4 ++--
 gfs2/fsck/rgrepair.c      |  2 +-
 gfs2/fsck/util.h          |  2 +-
 gfs2/libgfs2/block_list.c | 17 ++++++++---------
 gfs2/libgfs2/buf.c        |  4 ++--
 gfs2/libgfs2/fs_ops.c     | 13 ++++++-------
 gfs2/libgfs2/gfs1.c       |  1 -
 gfs2/libgfs2/lang.h       |  1 +
 gfs2/libgfs2/libgfs2.h    |  6 +++---
 gfs2/libgfs2/super.c      |  1 -
 gfs2/mkfs/gfs2_mkfs.h     |  1 -
 15 files changed, 53 insertions(+), 66 deletions(-)

diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index 18432b7c..2e1aef36 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -22,7 +22,6 @@
 #include <time.h>
 
 #include <logging.h>
-#include "osi_list.h"
 #include "gfs2hex.h"
 #include "hexedit.h"
 #include "libgfs2.h"
@@ -516,7 +515,7 @@ static void save_ea_block(struct metafd *mfd, struct gfs2_buffer_head *metabh, u
 /*
  * save_indirect_blocks - save all indirect blocks for the given buffer
  */
-static void save_indirect_blocks(struct metafd *mfd, osi_list_t *cur_list,
+static void save_indirect_blocks(struct metafd *mfd, struct list_head *cur_list,
            struct gfs2_buffer_head *mybh, uint64_t owner, int height, int hgt)
 {
 	uint64_t old_block = 0, indir_block;
@@ -545,7 +544,7 @@ static void save_indirect_blocks(struct metafd *mfd, osi_list_t *cur_list,
 		if (height != hgt && /* If not at max height and */
 		    (!gfs2_check_range(&sbd, indir_block))) {
 			nbh = bread(&sbd, indir_block);
-			osi_list_add_prev(&nbh->b_altlist, cur_list);
+			list_add_tail(&nbh->b_list, cur_list);
 			/* The buffer_head needs to be queued ahead, so
 			   don't release it!
 			   brelse(nbh);*/
@@ -601,13 +600,13 @@ static void save_inode_data(struct metafd *mfd, uint64_t iblk)
 {
 	uint32_t height;
 	struct gfs2_inode *inode;
-	osi_list_t metalist[GFS2_MAX_META_HEIGHT];
-	osi_list_t *prev_list, *cur_list, *tmp;
+	struct list_head metalist[GFS2_MAX_META_HEIGHT];
+	struct list_head *prev_list, *cur_list, *tmp;
 	struct gfs2_buffer_head *metabh, *mybh;
 	int i;
 
 	for (i = 0; i < GFS2_MAX_META_HEIGHT; i++)
-		osi_list_init(&metalist[i]);
+		INIT_LIST_HEAD(&metalist[i]);
 	metabh = bread(&sbd, iblk);
 	if (sbd.gfs1) {
 		inode = lgfs2_gfs_inode_get(&sbd, metabh);
@@ -631,14 +630,13 @@ static void save_inode_data(struct metafd *mfd, uint64_t iblk)
 	else if (height && !(inode->i_di.di_flags & GFS2_DIF_SYSTEM) &&
 		 !block_is_systemfile(iblk) && !S_ISDIR(inode->i_di.di_mode))
 		height--;
-	osi_list_add(&metabh->b_altlist, &metalist[0]);
+	list_add(&metabh->b_list, &metalist[0]);
         for (i = 1; i <= height; i++){
 		prev_list = &metalist[i - 1];
 		cur_list = &metalist[i];
 
 		for (tmp = prev_list->next; tmp != prev_list; tmp = tmp->next){
-			mybh = osi_list_entry(tmp, struct gfs2_buffer_head,
-					      b_altlist);
+			mybh = list_entry(tmp, struct gfs2_buffer_head, b_list);
 			warm_fuzzy_stuff(iblk, FALSE);
 			save_indirect_blocks(mfd, cur_list, mybh, iblk,
 					     height, i);
@@ -647,12 +645,10 @@ static void save_inode_data(struct metafd *mfd, uint64_t iblk)
 	/* free metalists */
 	for (i = 0; i < GFS2_MAX_META_HEIGHT; i++) {
 		cur_list = &metalist[i];
-		while (!osi_list_empty(cur_list)) {
-			mybh = osi_list_entry(cur_list->next,
-					    struct gfs2_buffer_head,
-					    b_altlist);
+		while (!list_empty(cur_list)) {
+			mybh = list_entry(cur_list->next, struct gfs2_buffer_head, b_list);
 			if (mybh == inode->i_bh)
-				osi_list_del(&mybh->b_altlist);
+				list_del(&mybh->b_list);
 			else
 				brelse(mybh);
 		}
@@ -703,7 +699,6 @@ static void save_inode_data(struct metafd *mfd, uint64_t iblk)
 		brelse(lbh);
 	}
 	inode_put(&inode);
-	brelse(metabh);
 }
 
 static void get_journal_inode_blocks(void)
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 3b8fefab..5176828e 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -1137,20 +1137,19 @@ int check_inode_eattr(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 /**
  * free_metalist - free all metadata on a multi-level metadata list
  */
-static void free_metalist(struct gfs2_inode *ip, osi_list_t *mlp)
+static void free_metalist(struct gfs2_inode *ip, struct list_head *mlp)
 {
 	int i;
 	struct gfs2_buffer_head *nbh;
 
 	for (i = 0; i < GFS2_MAX_META_HEIGHT; i++) {
-		osi_list_t *list;
+		struct list_head *list;
 
 		list = &mlp[i];
-		while (!osi_list_empty(list)) {
-			nbh = osi_list_entry(list->next,
-					     struct gfs2_buffer_head, b_altlist);
+		while (!list_empty(list)) {
+			nbh = list_entry(list->next, struct gfs2_buffer_head, b_list);
 			if (nbh == ip->i_bh)
-				osi_list_del_init(&nbh->b_altlist);
+				list_del_init(&nbh->b_list);
 			else
 				brelse(nbh);
 		}
@@ -1221,18 +1220,18 @@ static void file_ra(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
  * @ip:
  * @mlp:
  */
-static int build_and_check_metalist(struct gfs2_inode *ip, osi_list_t *mlp,
+static int build_and_check_metalist(struct gfs2_inode *ip, struct list_head *mlp,
 				    struct metawalk_fxns *pass)
 {
 	uint32_t height = ip->i_di.di_height;
 	struct gfs2_buffer_head *bh, *nbh, *metabh = ip->i_bh;
-	osi_list_t *prev_list, *cur_list, *tmp;
+	struct list_head *prev_list, *cur_list, *tmp;
 	int h, head_size, iblk_type;
 	uint64_t *ptr, block, *undoptr;
 	int error, was_duplicate, is_valid;
 	int maxptrs;
 
-	osi_list_add(&metabh->b_altlist, &mlp[0]);
+	list_add(&metabh->b_list, &mlp[0]);
 
 	/* Directories are special.  Their 'data' is the hash table, which is
 	   basically an indirect block list. Their height is not important
@@ -1269,8 +1268,7 @@ static int build_and_check_metalist(struct gfs2_inode *ip, osi_list_t *mlp,
 		cur_list = &mlp[h];
 
 		for (tmp = prev_list->next; tmp != prev_list; tmp = tmp->next){
-			bh = osi_list_entry(tmp, struct gfs2_buffer_head,
-					    b_altlist);
+			bh = list_entry(tmp, struct gfs2_buffer_head, b_list);
 			if (gfs2_check_meta(bh->b_data, iblk_type)) {
 				if (pass->invalid_meta_is_fatal)
 					return meta_error;
@@ -1355,7 +1353,7 @@ static int build_and_check_metalist(struct gfs2_inode *ip, osi_list_t *mlp,
 				}
 				if (!nbh)
 					nbh = bread(ip->i_sbd, block);
-				osi_list_add_prev(&nbh->b_altlist, cur_list);
+				list_add_tail(&nbh->b_list, cur_list);
 			} /* for all data on the indirect block */
 		} /* for blocks at that height */
 	} /* for height */
@@ -1537,8 +1535,8 @@ static int hdr_size(struct gfs2_buffer_head *bh, int height)
  */
 int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 {
-	osi_list_t metalist[GFS2_MAX_META_HEIGHT];
-	osi_list_t *list, *tmp;
+	struct list_head metalist[GFS2_MAX_META_HEIGHT];
+	struct list_head *list, *tmp;
 	struct gfs2_buffer_head *bh;
 	uint32_t height = ip->i_di.di_height;
 	int  i, head_size;
@@ -1552,7 +1550,7 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 		return 0;
 
 	for (i = 0; i < GFS2_MAX_META_HEIGHT; i++)
-		osi_list_init(&metalist[i]);
+		INIT_LIST_HEAD(&metalist[i]);
 
 	/* create and check the metadata list for each height */
 	error = build_and_check_metalist(ip, &metalist[0], pass);
@@ -1585,7 +1583,7 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 			free_metalist(ip, &metalist[0]);
 			return 0;
 		}
-		bh = list_entry(tmp, struct gfs2_buffer_head, b_altlist);
+		bh = list_entry(tmp, struct gfs2_buffer_head, b_list);
 		head_size = hdr_size(bh, height);
 		if (!head_size)
 			continue;
@@ -1623,11 +1621,9 @@ undo_metalist:
 		return error;
 	}
 	for (i = 0; pass->undo_check_meta && i < height; i++) {
-		while (!osi_list_empty(&metalist[i])) {
+		while (!list_empty(&metalist[i])) {
 			list = &metalist[i];
-			bh = list_entry(list->next,
-					    struct gfs2_buffer_head,
-					    b_altlist);
+			bh = list_entry(list->next, struct gfs2_buffer_head, b_list);
 			log_err(_("Undoing metadata work for block %llu "
 				  "(0x%llx)\n"),
 				(unsigned long long)bh->b_blocknr,
@@ -1661,7 +1657,7 @@ undo_metalist:
 				}
 			}
 			if (bh == ip->i_bh)
-				osi_list_del(&bh->b_altlist);
+				list_del(&bh->b_list);
 			else
 				brelse(bh);
 		}
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 442734ba..357b4fd8 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -2167,7 +2167,7 @@ int pass1(struct gfs2_sbd *sdp)
 		gfs2_bmap_destroy(sdp, bl);
 		return FSCK_ERROR;
 	}
-	osi_list_init(&gfs1_rindex_blks.list);
+	INIT_LIST_HEAD(&gfs1_rindex_blks.list);
 
 	/* FIXME: In the gfs fsck, we had to mark things like the
 	 * journals and indices and such as 'other_meta' - in gfs2,
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index a6dbf887..76d577b2 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -758,7 +758,7 @@ static int handle_dup_blk(struct gfs2_sbd *sdp, struct duptree *dt)
 	/* If there's still a last remaining reference, and it's a valid
 	   reference, use it to determine the correct block type for our
 	   blockmap and bitmap. */
-	if (dh.ref_inode_count == 1 && !osi_list_empty(&dt->ref_inode_list)) {
+	if (dh.ref_inode_count == 1 && !list_empty(&dt->ref_inode_list)) {
 		resolve_last_reference(sdp, dt, acceptable_ref);
 	} else {
 		/* They may have answered no and not fixed all references. */
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index 313ff0fb..1f097972 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -205,7 +205,7 @@ static int scan_inode_list(struct gfs2_sbd *sdp)
 		log_debug( _("block %llu (0x%llx) has link count %d\n"),
 			 (unsigned long long)ii->di_num.no_addr,
 			 (unsigned long long)ii->di_num.no_addr, ii->di_nlink);
-	} /* osi_list_foreach(tmp, list) */
+	}
 
 	return adjust_lf_links(lf_addition);
 }
@@ -238,7 +238,7 @@ static int scan_dir_list(struct gfs2_sbd *sdp)
 		log_debug( _("block %llu (0x%llx) has link count %d\n"),
 			 (unsigned long long)di->dinode.no_addr,
 			 (unsigned long long)di->dinode.no_addr, di->di_nlink);
-	} /* osi_list_foreach(tmp, list) */
+	}
 
 	return adjust_lf_links(lf_addition);
 }
diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c
index 76dd0eba..17325eb4 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -56,7 +56,7 @@ static void find_journaled_rgs(struct gfs2_sbd *sdp)
 	struct gfs2_buffer_head *bh;
 	int false_count;
 
-	osi_list_init(&false_rgrps.list);
+	INIT_LIST_HEAD(&false_rgrps.list);
 	for (j = 0; j < sdp->md.journals; j++) {
 		ip = sdp->md.journal[j];
 		log_debug(_("Checking for rgrps in journal%d which starts "
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index d93b65d3..842c4202 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -12,7 +12,7 @@
 #define INODE_VALID 1
 #define INODE_INVALID 0
 
-struct di_info *search_list(osi_list_t *list, uint64_t addr);
+struct di_info *search_list(struct list_head *list, uint64_t addr);
 void big_file_comfort(struct gfs2_inode *ip, uint64_t blks_checked);
 void warm_fuzzy_stuff(uint64_t block);
 int add_duplicate_ref(struct gfs2_inode *ip, uint64_t block,
diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c
index 9d998459..780f635d 100644
--- a/gfs2/libgfs2/block_list.c
+++ b/gfs2/libgfs2/block_list.c
@@ -14,22 +14,21 @@ void gfs2_special_free(struct special_blocks *blist)
 {
 	struct special_blocks *f;
 
-	while(!osi_list_empty(&blist->list)) {
-		f = osi_list_entry(blist->list.next, struct special_blocks,
-				   list);
-		osi_list_del(&f->list);
+	while(!list_empty(&blist->list)) {
+		f = list_entry(blist->list.next, struct special_blocks, list);
+		list_del(&f->list);
 		free(f);
 	}
 }
 
 struct special_blocks *blockfind(struct special_blocks *blist, uint64_t num)
 {
-	osi_list_t *head = &blist->list;
-	osi_list_t *tmp;
+	struct list_head *head = &blist->list;
+	struct list_head *tmp;
 	struct special_blocks *b;
 
 	for (tmp = head->next; tmp != head; tmp = tmp->next) {
-		b = osi_list_entry(tmp, struct special_blocks, list);
+		b = list_entry(tmp, struct special_blocks, list);
 		if (b->block == num)
 			return b;
 	}
@@ -44,7 +43,7 @@ void gfs2_special_add(struct special_blocks *blocklist, uint64_t block)
 	if (b) {
 		memset(b, 0, sizeof(*b));
 		b->block = block;
-		osi_list_add_prev(&b->list, &blocklist->list);
+		list_add_tail(&b->list, &blocklist->list);
 	}
 }
 
@@ -61,7 +60,7 @@ void gfs2_special_clear(struct special_blocks *blocklist, uint64_t block)
 
 	b = blockfind(blocklist, block);
 	if (b) {
-		osi_list_del(&b->list);
+		list_del(&b->list);
 		free(b);
 	}
 }
diff --git a/gfs2/libgfs2/buf.c b/gfs2/libgfs2/buf.c
index 097ac33b..7c2324fe 100644
--- a/gfs2/libgfs2/buf.c
+++ b/gfs2/libgfs2/buf.c
@@ -112,8 +112,8 @@ int brelse(struct gfs2_buffer_head *bh)
 	if (bh->b_modified)
 		error = bwrite(bh);
 	bh->b_blocknr = -1;
-	if (bh->b_altlist.next && !osi_list_empty(&bh->b_altlist))
-		osi_list_del(&bh->b_altlist);
+	if (bh->b_list.next && !list_empty(&bh->b_list))
+		list_del(&bh->b_list);
 	free(bh);
 	return error;
 }
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 0acd59bf..dbddb493 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -1948,11 +1948,11 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
 	uint64_t *ptr, block;
 	struct rgrp_tree *rgd;
 	uint32_t height;
-	osi_list_t metalist[GFS2_MAX_META_HEIGHT];
-	osi_list_t *cur_list, *next_list, *tmp;
+	struct list_head metalist[GFS2_MAX_META_HEIGHT];
+	struct list_head *cur_list, *next_list, *tmp;
 
 	for (h = 0; h < GFS2_MAX_META_HEIGHT; h++)
-		osi_list_init(&metalist[h]);
+		INIT_LIST_HEAD(&metalist[h]);
 
 	bh = bread(sdp, diblock);
 	if (bh == NULL)
@@ -1961,7 +1961,7 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
 	if (ip == NULL)
 		return -1;
 	height = ip->i_di.di_height;
-	osi_list_add(&bh->b_altlist, &metalist[0]);
+	list_add(&bh->b_list, &metalist[0]);
 
 	for (h = 0; h < height; h++){
 		cur_list = &metalist[h];
@@ -1970,8 +1970,7 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
 			     sizeof(struct gfs2_dinode));
 
 		for (tmp = cur_list->next; tmp != cur_list; tmp = tmp->next){
-			bh = osi_list_entry(tmp, struct gfs2_buffer_head,
-					    b_altlist);
+			bh = list_entry(tmp, struct gfs2_buffer_head, b_list);
 
 			for (ptr = (uint64_t *)(bh->b_data + head_size);
 			     (char *)ptr < (bh->b_data + sdp->bsize); ptr++) {
@@ -1984,7 +1983,7 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
 					continue; /* don't queue it up */
 				/* Read the next metadata block in the chain */
 				nbh = bread(sdp, block);
-				osi_list_add(&nbh->b_altlist, next_list);
+				list_add(&nbh->b_list, next_list);
 				brelse(nbh);
 			}
 		}
diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c
index b91cce5e..9bcab17b 100644
--- a/gfs2/libgfs2/gfs1.c
+++ b/gfs2/libgfs2/gfs1.c
@@ -13,7 +13,6 @@
 #include <linux/types.h>
 #include <linux/gfs2_ondisk.h>
 
-#include "osi_list.h"
 #include "libgfs2.h"
 
 /* GFS1 compatibility functions - so that programs like gfs2_convert
diff --git a/gfs2/libgfs2/lang.h b/gfs2/libgfs2/lang.h
index 7d9a6e98..c8845973 100644
--- a/gfs2/libgfs2/lang.h
+++ b/gfs2/libgfs2/lang.h
@@ -1,6 +1,7 @@
 #ifndef LANG_H
 #define LANG_H
 #include <stdint.h>
+#undef LIST_HEAD
 #include "libgfs2.h"
 
 struct lgfs2_lang_state {
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index fc0afed0..1c82ebe3 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -15,7 +15,7 @@
 #include <mntent.h>
 
 #include <linux/gfs2_ondisk.h>
-#include "osi_list.h"
+#include <list.h>
 #include "osi_tree.h"
 
 __BEGIN_DECLS
@@ -217,7 +217,7 @@ extern lgfs2_rgrp_t lgfs2_rgrp_prev(lgfs2_rgrp_t rg);
 extern struct osi_node *lgfs2_rgrps_root(lgfs2_rgrps_t rgs) __attribute__((deprecated));
 
 struct gfs2_buffer_head {
-	osi_list_t b_altlist; /* alternate list */
+	struct list_head b_list;
 	uint64_t b_blocknr;
 	union {
 		char *b_data;
@@ -228,7 +228,7 @@ struct gfs2_buffer_head {
 };
 
 struct special_blocks {
-	osi_list_t list;
+	struct list_head list;
 	uint64_t block;
 };
 
diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c
index 6fe29add..97f82f07 100644
--- a/gfs2/libgfs2/super.c
+++ b/gfs2/libgfs2/super.c
@@ -10,7 +10,6 @@
 #include <fcntl.h>
 
 #include "libgfs2.h"
-#include "osi_list.h"
 
 /**
  * check_sb - Check superblock
diff --git a/gfs2/mkfs/gfs2_mkfs.h b/gfs2/mkfs/gfs2_mkfs.h
index 75f70e6a..b9ec7acd 100644
--- a/gfs2/mkfs/gfs2_mkfs.h
+++ b/gfs2/mkfs/gfs2_mkfs.h
@@ -3,7 +3,6 @@
 
 #include <stdarg.h>
 #include <linux/gfs2_ondisk.h>
-#include "osi_list.h"
 #include "copyright.cf"
 
 /* die() used to be in libgfs2.h */
-- 
2.21.0




More information about the Cluster-devel mailing list