[Linux-cluster] Updates to libgfs2

Robert S Peterson rpeterso at redhat.com
Thu Jun 8 21:16:59 UTC 2006


Hi,

I just wanted to let you know: I made some bug fixes to libgfs2 for
problems with fsck.  The following is a patch with the code changes:
Also, there were some parts that got missed from the original commit
that are there now.

Regards,

Bob Peterson
Red Hat Cluster Suite

Index: buf.c
===================================================================
RCS file: /cvs/cluster/cluster/gfs2/libgfs2/buf.c,v
retrieving revision 1.2
diff -w -u -p -u -p -r1.2 buf.c
--- buf.c	6 Jun 2006 14:20:41 -0000	1.2
+++ buf.c	8 Jun 2006 20:58:48 -0000
@@ -188,15 +188,17 @@ void bsync(struct gfs2_sbd *sdp)
 /* commit buffers to disk but do not discard */
 void bcommit(struct gfs2_sbd *sdp)
 {
-	osi_list_t *tmp;
+	osi_list_t *tmp, *x;
 	struct gfs2_buffer_head *bh;
 
-	osi_list_foreach(tmp, &sdp->buf_list) {
+	osi_list_foreach_safe(tmp, &sdp->buf_list, x) {
 		bh = osi_list_entry(tmp, struct gfs2_buffer_head, b_list);
-		if (bh->b_changed) {
+		if (!bh->b_count)             /* if not reserved for later */
+			write_buffer(sdp, bh);    /* write the data, free the memory */
+		else if (bh->b_changed) {     /* if buffer has changed */
 			do_lseek(sdp, bh->b_blocknr * sdp->bsize);
-			do_write(sdp, bh->b_data, sdp->bsize);
-			bh->b_changed = FALSE;
+			do_write(sdp, bh->b_data, sdp->bsize); /* write it out */
+			bh->b_changed = FALSE;    /* no longer changed */
 		}
 	}
 }
Index: fs_ops.c
===================================================================
RCS file: /cvs/cluster/cluster/gfs2/libgfs2/fs_ops.c,v
retrieving revision 1.2
diff -w -u -p -u -p -r1.2 fs_ops.c
--- fs_ops.c	6 Jun 2006 14:20:41 -0000	1.2
+++ fs_ops.c	8 Jun 2006 20:58:49 -0000
@@ -502,14 +502,12 @@ int gfs2_readi(struct gfs2_inode *ip, vo
 	return copied;
 }
 
-static void
-copy_from_mem(struct gfs2_buffer_head *bh, void **buf,
+static void copy_from_mem(struct gfs2_buffer_head *bh, void **buf,
 	      unsigned int offset, unsigned int size)
 {
 	char **p = (char **)buf;
 
 	memcpy(bh->b_data + offset, *p, size);
-
 	*p += size;
 }
 
@@ -526,7 +524,6 @@ int gfs2_writei(struct gfs2_inode *ip, v
 	int isdir = !!(S_ISDIR(ip->i_di.di_flags));
 	const uint64_t start = offset;
 	int copied = 0;
-	enum update_flags f;
 
 	if (!size)
 		return 0;
@@ -558,7 +555,6 @@ int gfs2_writei(struct gfs2_inode *ip, v
 			block_map(ip, lblock, &new, &dblock, &extlen);
 		}
 
-		f = not_updated;
 		if (new) {
 			bh = bget(sdp, dblock);
 			if (isdir) {
@@ -567,12 +563,11 @@ int gfs2_writei(struct gfs2_inode *ip, v
 				mh.mh_type = GFS2_METATYPE_JD;
 				mh.mh_format = GFS2_FORMAT_JD;
 				gfs2_meta_header_out(&mh, bh->b_data);
-				f = updated;
 			}
 		} else
 			bh = bread(sdp, dblock);
 		copy_from_mem(bh, &buf, o, amount);
-		brelse(bh, f);
+		brelse(bh, updated);
 
 		copied += amount;
 		lblock++;
@@ -1084,8 +1079,7 @@ dir_make_exhash(struct gfs2_inode *dip)
 	dip->i_di.di_depth = y;
 }
 
-static void
-dir_l_add(struct gfs2_inode *dip, char *filename, int len,
+static void dir_l_add(struct gfs2_inode *dip, char *filename, int len,
 		  struct gfs2_inum *inum, unsigned int type)
 {
 	struct gfs2_dirent *dent;
@@ -1564,11 +1558,10 @@ int gfs2_freedi(struct gfs2_sbd *sdp, ui
 	struct gfs2_inode *ip;
 	struct gfs2_buffer_head *bh;
 	int x;
-	uint64_t p, freed_blocks;
+	uint64_t p;
 	unsigned char *buf;
 	struct rgrp_list *rgd;
 	
-	freed_blocks = 0;
 	bh = bread(sdp, block);
 	ip = inode_get(sdp, bh);
 	if (ip->i_di.di_height > 0) {
@@ -1578,14 +1571,19 @@ int gfs2_freedi(struct gfs2_sbd *sdp, ui
 			 x += sizeof(uint64_t)) {
 			p = be64_to_cpu(*(uint64_t *)(buf + x));
 			if (p) {
-				freed_blocks++;
 				gfs2_set_bitmap(sdp, p, GFS2_BLKST_FREE);
+				/* We need to adjust the free space count for the freed */
+                /* indirect block. */
+				rgd = gfs2_blk2rgrpd(sdp, p); /* find the rg for indir block */
+				bh = bget(sdp, rgd->ri.ri_addr); /* get the buffer its rg */
+				rgd->rg.rg_free++; /* adjust the free count */
+				gfs2_rgrp_out(&rgd->rg, bh->b_data); /* back to the buffer */
+				brelse(bh, updated); /* release the buffer */
 			}
 		}
 	}
 	/* Set the bitmap type for inode to free space: */
 	gfs2_set_bitmap(sdp, ip->i_di.di_num.no_addr, GFS2_BLKST_FREE);
-	freed_blocks++; /* one for the inode itself */
 	inode_put(ip, updated);
 	/* Now we have to adjust the rg freespace count and inode count: */
 	rgd = gfs2_blk2rgrpd(sdp, block);
@@ -1593,7 +1591,7 @@ int gfs2_freedi(struct gfs2_sbd *sdp, ui
 	/* buffer in memory for the rg on disk because we used it to fix the */
 	/* bitmaps, some of which are on the same block on disk.             */
 	bh = bread(sdp, rgd->ri.ri_addr); /* get the buffer */
-	rgd->rg.rg_free += freed_blocks;
+	rgd->rg.rg_free++;
 	rgd->rg.rg_dinodes--; /* one less inode in use */
 	gfs2_rgrp_out(&rgd->rg, bh->b_data);
 	brelse(bh, updated); /* release the buffer */






More information about the Linux-cluster mailing list