[Cluster-devel] cluster/gfs2 fsck/metawalk.c fsck/metawalk.h f ...

rpeterso at sourceware.org rpeterso at sourceware.org
Tue May 15 18:11:13 UTC 2007


CVSROOT:	/cvs/cluster
Module name:	cluster
Changes by:	rpeterso at sourceware.org	2007-05-15 18:11:10

Modified files:
	gfs2/fsck      : metawalk.c metawalk.h pass1.c pass2.c 
	gfs2/libgfs2   : fs_ops.c libgfs2.h structures.c 

Log message:
	Resolves: Bugzilla Bug 239023: gfs2_fsck not good at fixing corrupt
	directory entries.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/fsck/metawalk.c.diff?cvsroot=cluster&r1=1.8&r2=1.9
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/fsck/metawalk.h.diff?cvsroot=cluster&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/fsck/pass1.c.diff?cvsroot=cluster&r1=1.7&r2=1.8
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/fsck/pass2.c.diff?cvsroot=cluster&r1=1.6&r2=1.7
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/libgfs2/fs_ops.c.diff?cvsroot=cluster&r1=1.7&r2=1.8
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/libgfs2/libgfs2.h.diff?cvsroot=cluster&r1=1.12&r2=1.13
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/libgfs2/structures.c.diff?cvsroot=cluster&r1=1.7&r2=1.8

--- cluster/gfs2/fsck/metawalk.c	2007/02/26 19:19:06	1.8
+++ cluster/gfs2/fsck/metawalk.c	2007/05/15 18:11:10	1.9
@@ -1,7 +1,7 @@
 /*****************************************************************************
 *******************************************************************************
 **
-**  Copyright (C) 2005 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2005-2007 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -24,6 +24,44 @@
 #include "metawalk.h"
 #include "hash.h"
 
+int dirent_repair(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
+		  struct gfs2_dirent *de, struct gfs2_dirent *dent,
+		  int type, int first)
+{
+	char *bh_end, *p;
+	int calc_de_name_len = 0;
+	
+	/* If this is a sentinel, just fix the length and move on */
+	if (first && !de->de_inum.no_formal_ino) { /* Is it a sentinel? */
+		if (type == DIR_LINEAR)
+			de->de_rec_len = bh->b_size -
+				sizeof(struct gfs2_dinode);
+		else
+			de->de_rec_len = bh->b_size - sizeof(struct gfs2_leaf);
+	}
+	else {
+		bh_end = bh->b_data + bh->b_size;
+		/* first, figure out a probable name length */
+		p = (char *)dent + sizeof(struct gfs2_dirent);
+		while (*p &&         /* while there's a non-zero char and */
+		       p < bh_end) { /* not past end of buffer */
+			calc_de_name_len++;
+			p++;
+		}
+		if (!calc_de_name_len)
+			return 1;
+		/* There can often be noise at the end, so only          */
+		/* Trust the shorter of the two in case we have too much */
+		/* Or rather, only trust ours if it's shorter.           */
+		if (!de->de_name_len || de->de_name_len > NAME_MAX ||
+		    calc_de_name_len < de->de_name_len) /* if dent is hosed */
+			de->de_name_len = calc_de_name_len; /* use ours */
+		de->de_rec_len = GFS2_DIRENT_SIZE(de->de_name_len);
+	}
+	gfs2_dirent_out(de, (char *)dent);
+	return 0;
+}
+
 int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
 				  int index, int type, int *update, uint16_t *count,
 				  struct metawalk_fxns *pass)
@@ -61,6 +99,28 @@
 		gfs2_dirent_in(&de, (char *)dent);
 		filename = (char *)dent + sizeof(struct gfs2_dirent);
 
+		if (de.de_rec_len < sizeof(struct gfs2_dirent) +
+		    de.de_name_len || !de.de_name_len) {
+			log_err("Directory block %" PRIu64 "(0x%"
+				PRIx64 "), entry %d of directory %"
+				PRIu64 "(0x%" PRIx64 ") is corrupt.\n",
+				bh->b_blocknr, bh->b_blocknr, (*count) + 1,
+				ip->i_di.di_num.no_addr,
+				ip->i_di.di_num.no_addr);
+			if (query(&opts, "Attempt to repair it? (y/n) ")) {
+				if (dirent_repair(ip, bh, &de, dent, type,
+						  first))
+					break;
+				else
+					*update = 1;
+			}
+			else {
+				log_err("Corrupt directory entry ignored, "
+					"stopped after checking %d entries.\n",
+					*count);
+				break;
+			}
+		}
 		if (!de.de_inum.no_formal_ino){
 			if(first){
 				log_debug("First dirent is a sentinel (place holder).\n");
@@ -96,15 +156,6 @@
 			}
 		}
 
-		if (de.de_rec_len < sizeof(struct gfs2_dirent)) {
-			log_err("Entry %" PRIu64 "(0x%"
-				PRIx64 ") of directory %" PRIu64 "(0x%"
-				PRIx64 ") is corrupt, skipping.\n",
-				bh->b_blocknr, bh->b_blocknr,
-				ip->i_di.di_num.no_addr,
-				ip->i_di.di_num.no_addr);
-                        break;
-                }
 		if ((char *)dent + de.de_rec_len >= bh_end){
 			log_debug("Last entry processed.\n");
 			break;
@@ -120,12 +171,37 @@
 	return 0;
 }
 
+/* Process a bad leaf pointer and ask to repair the first time.      */
+/* The repair process involves extending the previous leaf's entries */
+/* so that they replace the bad ones.  We have to hack up the old    */
+/* leaf a bit, but it's better than deleting the whole directory,    */
+/* which is what used to happen before.                              */
+void warn_and_patch(struct gfs2_inode *ip, uint64_t *leaf_no, 
+		    uint64_t *bad_leaf, uint64_t old_leaf, int index,
+		    const char *msg)
+{
+	if (*bad_leaf != *leaf_no) {
+		log_err("Directory Inode %" PRIu64 "(0x%"
+			PRIx64 ") points to leaf %" PRIu64 "(0x%"
+			PRIx64 ") %s.\n", ip->i_di.di_num.no_addr,
+			ip->i_di.di_num.no_addr, *leaf_no, *leaf_no, msg);
+	}
+	if (*leaf_no == *bad_leaf ||
+	    query(&opts, "Attempt to patch around it? (y/n) ")) {
+		gfs2_put_leaf_nr(ip, index, old_leaf);
+	}
+	else
+		log_err("Bad leaf left in place.\n");
+	*bad_leaf = *leaf_no;
+	*leaf_no = old_leaf;
+}
+
 /* Checks exhash directory entries */
 int check_leaf(struct gfs2_inode *ip, int *update, struct metawalk_fxns *pass)
 {
 	int error;
-	struct gfs2_leaf leaf;
-	uint64_t leaf_no, old_leaf;
+	struct gfs2_leaf leaf, oldleaf;
+	uint64_t leaf_no, old_leaf, bad_leaf = -1;
 	struct gfs2_buffer_head *lbh;
 	int index;
 	struct gfs2_sbd *sbp = ip->i_sbd;
@@ -133,53 +209,94 @@
 	int ref_count = 0, exp_count = 0;
 
 	old_leaf = 0;
+	memset(&oldleaf, 0, sizeof(oldleaf));
 	for(index = 0; index < (1 << ip->i_di.di_depth); index++) {
 		gfs2_get_leaf_nr(ip, index, &leaf_no);
 
 		/* GFS has multiple indirect pointers to the same leaf
 		 * until those extra pointers are needed, so skip the
 		 * dups */
-		if(old_leaf == leaf_no) {
+		if (leaf_no == bad_leaf) {
+			gfs2_put_leaf_nr(ip, index, old_leaf); /* fill w/old
+								  leaf info */
+			ref_count++;
+			continue;
+		}
+		else if(old_leaf == leaf_no) {
 			ref_count++;
 			continue;
 		} else {
 			if(ref_count != exp_count){
-				log_err("Dir #%" PRIu64 " (0x%" PRIx64 ") has an incorrect "
-						"number of pointers to leaf #%" PRIu64 " (0x%" PRIx64
-						")\n\tFound: %u,  Expected: %u\n",
-						ip->i_di.di_num.no_addr, ip->i_di.di_num.no_addr,
-						old_leaf, old_leaf, ref_count, exp_count);
-				return 1;
+				log_err("Dir #%" PRIu64 " (0x%"
+					PRIx64 ") has an incorrect "
+					"number of pointers to leaf #%"
+					PRIu64 " (0x%" PRIx64
+					")\n\tFound: %u,  Expected: %u\n",
+					ip->i_di.di_num.no_addr,
+					ip->i_di.di_num.no_addr,
+					old_leaf, old_leaf, ref_count,
+					exp_count);
+				if (query(&opts, "Attempt to fix it? (y/n) "))
+				{
+					int factor = 0, divisor = ref_count;
+
+					lbh = bread(sbp, old_leaf);
+					while (divisor > 1) {
+						factor++;
+						divisor /= 2;
+					}
+					oldleaf.lf_depth = ip->i_di.di_depth -
+						factor;
+					gfs2_leaf_out(&oldleaf, lbh->b_data);
+					brelse(lbh, updated);
+				}
+				else
+					return 1;
 			}
 			ref_count = 1;
 		}
 
 		count = 0;
 		do {
-			/* FIXME: Do other checks (see old
-			 * pass3:dir_exhash_scan() */
-			lbh = NULL;
-			if(pass->check_leaf) {
-				error = pass->check_leaf(ip, leaf_no, &lbh, pass->private);
-				if(error < 0) {
-					stack;
-					return -1;
-				}
-				if(error > 0) {
-					lbh = NULL;
-					return 1;
-				}
+			/* Make sure the block number is in range. */
+			if(gfs2_check_range(ip->i_sbd, leaf_no)){
+				log_err("Leaf block #%" PRIu64 " (0x%"
+					PRIx64 ") is out of range for "
+					"directory #%" PRIu64 " (0x%"
+					PRIx64 ").\n", leaf_no, leaf_no,
+					ip->i_di.di_num.no_addr,
+					ip->i_di.di_num.no_addr);
+				warn_and_patch(ip, &leaf_no, &bad_leaf,
+					       old_leaf, index,
+					       "that is out of range");
+				memcpy(&leaf, &oldleaf, sizeof(oldleaf));
+				break;
 			}
 
 			*update = not_updated;
+			/* Try to read in the leaf block. */
 			lbh = bread(sbp, leaf_no);
+			/* Make sure it's really a valid leaf block. */
+			if (gfs2_check_meta(lbh, GFS2_METATYPE_LF)) {
+				warn_and_patch(ip, &leaf_no, &bad_leaf,
+					       old_leaf, index,
+					       "that is not really a leaf");
+				memcpy(&leaf, &oldleaf, sizeof(oldleaf));
+				brelse(lbh, updated);
+				break;
+			}
 			gfs2_leaf_in(&leaf, lbh->b_data);
+			if(pass->check_leaf) {
+				error = pass->check_leaf(ip, leaf_no, lbh,
+							 pass->private);
+			}
 
 			/*
-			 * Early versions of GFS2 had an endianess bug in the kernel
-			 * that set lf_dirent_format to cpu_to_be16(GFS2_FORMAT_DE).
-			 * This was fixed to use cpu_to_be32(), but we should check
-			 * for incorrect values and replace them with the correct value. */
+			 * Early versions of GFS2 had an endianess bug in the
+			 * kernel that set lf_dirent_format to
+			 * cpu_to_be16(GFS2_FORMAT_DE).  This was fixed to use
+			 * cpu_to_be32(), but we should check for incorrect 
+			 * values and replace them with the correct value. */
 
 			if (leaf.lf_dirent_format == (GFS2_FORMAT_DE << 16)) {
 				log_debug("incorrect lf_dirent_format at leaf #%" PRIu64 "\n", leaf_no);
@@ -253,6 +370,7 @@
 			}
 		} while(1);
 		old_leaf = leaf_no;
+		memcpy(&oldleaf, &leaf, sizeof(oldleaf));
 	}
 	return 0;
 }
@@ -577,7 +695,7 @@
 		}
 	}
 
-	inode_put(ip, not_updated); /* does a brelse */
+	inode_put(ip, update); /* does a brelse */
 	return error;
 }
 
--- cluster/gfs2/fsck/metawalk.h	2006/06/06 14:49:31	1.2
+++ cluster/gfs2/fsck/metawalk.h	2007/05/15 18:11:10	1.3
@@ -1,7 +1,7 @@
 /*****************************************************************************
 *******************************************************************************
 **
-**  Copyright (C) 2005 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2005-2007 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -46,31 +46,33 @@
 struct metawalk_fxns {
 	void *private;
 	int (*check_leaf) (struct gfs2_inode *ip, uint64_t block,
-					   struct gfs2_buffer_head **bh, void *private);
+			   struct gfs2_buffer_head *bh, void *private);
 	int (*check_metalist) (struct gfs2_inode *ip, uint64_t block,
-						   struct gfs2_buffer_head **bh, void *private);
+			       struct gfs2_buffer_head **bh, void *private);
 	int (*check_data) (struct gfs2_inode *ip, uint64_t block,
-					   void *private);
+			   void *private);
 	int (*check_eattr_indir) (struct gfs2_inode *ip, uint64_t block,
-							  uint64_t parent, struct gfs2_buffer_head **bh,
-							  void *private);
+				  uint64_t parent,
+				  struct gfs2_buffer_head **bh, void *private);
 	int (*check_eattr_leaf) (struct gfs2_inode *ip, uint64_t block,
-							 uint64_t parent, struct gfs2_buffer_head **bh,
-							 void *private);
+				 uint64_t parent, struct gfs2_buffer_head **bh,
+				 void *private);
 	int (*check_dentry) (struct gfs2_inode *ip, struct gfs2_dirent *de,
-						 struct gfs2_dirent *prev, struct gfs2_buffer_head *bh,
-						 char *filename, int *update, uint16_t *count,
-						 void *private);
+			     struct gfs2_dirent *prev,
+			     struct gfs2_buffer_head *bh,
+			     char *filename, int *update, uint16_t *count,
+			     void *private);
 	int (*check_eattr_entry) (struct gfs2_inode *ip,
-							  struct gfs2_buffer_head *leaf_bh,
-							  struct gfs2_ea_header *ea_hdr,
-							  struct gfs2_ea_header *ea_hdr_prev,
-							  void *private);
-	int (*check_eattr_extentry) (struct gfs2_inode *ip, uint64_t *ea_data_ptr,
-								 struct gfs2_buffer_head *leaf_bh,
-								 struct gfs2_ea_header *ea_hdr,
-								 struct gfs2_ea_header *ea_hdr_prev,
-								 void *private);
+				  struct gfs2_buffer_head *leaf_bh,
+				  struct gfs2_ea_header *ea_hdr,
+				  struct gfs2_ea_header *ea_hdr_prev,
+				  void *private);
+	int (*check_eattr_extentry) (struct gfs2_inode *ip,
+				     uint64_t *ea_data_ptr,
+				     struct gfs2_buffer_head *leaf_bh,
+				     struct gfs2_ea_header *ea_hdr,
+				     struct gfs2_ea_header *ea_hdr_prev,
+				     void *private);
 };
 
 #endif /* _METAWALK_H */
--- cluster/gfs2/fsck/pass1.c	2007/05/01 16:43:38	1.7
+++ cluster/gfs2/fsck/pass1.c	2007/05/15 18:11:10	1.8
@@ -44,51 +44,14 @@
 };
 
 static int leaf(struct gfs2_inode *ip, uint64_t block,
-				struct gfs2_buffer_head **bh, void *private)
+				struct gfs2_buffer_head *bh, void *private)
 {
-	struct gfs2_sbd *sdp = ip->i_sbd;
 	struct block_count *bc = (struct block_count *) private;
-	struct gfs2_meta_header *mh;
-	uint64_t *val;
-	enum update_flags f;
 
-	f = not_updated;
-	if(gfs2_check_range(sdp, block)){
-		log_warn("Leaf block #%" PRIu64 " (0x%" PRIx64 ") is out of range for "
-				 "directory #%" PRIu64 " (0x%" PRIx64 ").\n",
-				 block, block, ip->i_di.di_num.no_addr,
-				 ip->i_di.di_num.no_addr);
-		gfs2_block_set(bl, ip->i_di.di_num.no_addr, gfs2_bad_block);
-		return 1;
-	}
-	*bh = bread(sdp, block);
-	mh = (struct gfs2_meta_header *)(*bh)->b_data;
-	val = (uint64_t *)mh;
-
-	if(gfs2_check_meta(*bh, GFS2_METATYPE_LF)){
-		log_err("Bad meta header for leaf block #%" PRIu64 "(0x%" PRIx64 
-				") in directory #%" PRIu64 ". - is %u, should be %u\n",
-				(*bh)->b_data, (*bh)->b_data, ip->i_di.di_num.no_addr,
-				ip->i_di.di_num.no_addr,
-				(struct gfs2_meta_header *)mh->mh_type,
-				GFS2_METATYPE_LF);
-		if(query(&opts, "Clear directory inode at %" PRIu64 " (0x%"
-				 PRIx64 ")? (y/n) ", ip->i_di.di_num.no_addr,
-				 ip->i_di.di_num.no_addr)) {
-			gfs2_block_set(bl, ip->i_di.di_num.no_addr, gfs2_meta_inval);
-			log_err("Directory inode marked invalid\n");
-			f = updated;
-		} else
-			log_err("Invalid block %" PRIu64 " (0x%" PRIx64 ") ignored\n",
-				ip->i_di.di_num.no_addr, ip->i_di.di_num.no_addr);
-		brelse(*bh, f);
-		return 1;
-	}
 	log_debug("\tLeaf block at %15" PRIu64 " (0x%" PRIx64 ")\n",
 			  block, block);
 	gfs2_block_set(bl, block, gfs2_leaf_blk);
 	bc->indir_count++;
-	brelse(*bh, f);
 	return 0;
 }
 
@@ -433,7 +396,7 @@
 }
 
 int clear_leaf(struct gfs2_inode *ip, uint64_t block,
-	       struct gfs2_buffer_head **bh, void *private)
+	       struct gfs2_buffer_head *bh, void *private)
 {
 	struct gfs2_block_query q = {0};
 	log_crit("Clearing leaf %" PRIu64 " (0x%" PRIx64 ")\n", block, block);
--- cluster/gfs2/fsck/pass2.c	2007/05/01 16:43:38	1.6
+++ cluster/gfs2/fsck/pass2.c	2007/05/15 18:11:10	1.7
@@ -27,54 +27,6 @@
 
 #define MAX_FILENAME 256
 
-static int check_leaf(struct gfs2_inode *ip, uint64_t block,
-					  struct gfs2_buffer_head **lbh, void *private)
-{
-	uint64_t chain_no;
-	struct gfs2_sbd *sbp = ip->i_sbd;
-	struct gfs2_leaf leaf;
-	struct gfs2_buffer_head *chain_head = NULL;
-	struct gfs2_buffer_head *bh = NULL;
-	int chain=0;
-
-	chain_no = block;
-
-	do {
-		/* FIXME: check the range of the leaf? */
-		/* check the leaf and stuff */
-
-		bh = bread(sbp, chain_no);
-
-		if(!bh){
-			stack;
-			log_crit("Error reading leaf %" PRIu64 "(0x%" PRIx64 ")",
-					 chain_no, chain_no);
-			goto fail;
-		}
-		gfs2_leaf_in(&leaf, bh->b_data);
-
-		brelse(bh, not_updated);
-		/* Check the leaf headers */
-		if(!chain){
-			chain = 1;
-			chain_head = bh;
-			chain_no = leaf.lf_next;
-		}
-		else
-			break;
-	} while(chain_no);
-
-	*lbh = chain_head;
-	return 0;
-
- fail:
-	if(chain_head)
-		brelse(chain_head, not_updated);
-	return -1;
-
-}
-
-
 /* Set children's parent inode in dir_info structure - ext2 does not set
  * dotdot inode here, but instead in pass3 - should we? */
 int set_parent_dir(struct gfs2_sbd *sbp, uint64_t childblock,
@@ -560,7 +512,7 @@
 
 struct metawalk_fxns pass2_fxns = {
 	.private = NULL,
-	.check_leaf = check_leaf,
+	.check_leaf = NULL,
 	.check_metalist = NULL,
 	.check_data = NULL,
 	.check_eattr_indir = check_eattr_indir,
--- cluster/gfs2/libgfs2/fs_ops.c	2007/05/01 16:43:39	1.7
+++ cluster/gfs2/libgfs2/fs_ops.c	2007/05/15 18:11:10	1.8
@@ -734,6 +734,18 @@
 	*leaf_out = be64_to_cpu(leaf_no);
 }
 
+void gfs2_put_leaf_nr(struct gfs2_inode *dip, uint32_t inx, uint64_t leaf_out)
+{
+	uint64_t leaf_no;
+	int count;
+
+	leaf_no = cpu_to_be64(leaf_out);
+	count = gfs2_writei(dip, (char *)&leaf_no, inx * sizeof(uint64_t),
+			    sizeof(uint64_t));
+	if (count != sizeof(uint64_t))
+		die("gfs2_put_leaf_nr:  Bad internal write.\n");
+}
+
 static void
 dir_split_leaf(struct gfs2_inode *dip, uint32_t index, uint64_t leaf_no)
 {
--- cluster/gfs2/libgfs2/libgfs2.h	2007/05/10 15:47:44	1.12
+++ cluster/gfs2/libgfs2/libgfs2.h	2007/05/15 18:11:10	1.13
@@ -315,7 +315,7 @@
 };
 
 struct gfs2_block_list *gfs2_block_list_create(uint64_t size,
-											   uint64_t *addl_mem_needed);
+					       uint64_t *addl_mem_needed);
 int gfs2_block_mark(struct gfs2_block_list *il, uint64_t block,
 					enum gfs2_mark_block mark);
 int gfs2_block_set(struct gfs2_block_list *il, uint64_t block,
@@ -325,14 +325,14 @@
 int gfs2_block_check(struct gfs2_block_list *il, uint64_t block,
 					 struct gfs2_block_query *val);
 int gfs2_block_check_for_mark(struct gfs2_block_list *il, uint64_t block,
-							  enum gfs2_mark_block mark);
+			      enum gfs2_mark_block mark);
 void *gfs2_block_list_destroy(struct gfs2_block_list *il);
 int gfs2_find_next_block_type(struct gfs2_block_list *il,
-							  enum gfs2_mark_block m, uint64_t *b);
+			      enum gfs2_mark_block m, uint64_t *b);
 
 /* buf.c */
 struct gfs2_buffer_head *bget_generic(struct gfs2_sbd *sdp, uint64_t num,
-									  int find_existing, int read_disk);
+				      int find_existing, int read_disk);
 struct gfs2_buffer_head *bget(struct gfs2_sbd *sdp, uint64_t num);
 struct gfs2_buffer_head *bread(struct gfs2_sbd *sdp, uint64_t num);
 struct gfs2_buffer_head *bget_zero(struct gfs2_sbd *sdp, uint64_t num);
@@ -354,12 +354,12 @@
 uint32_t gfs2_bitcount(unsigned char *buffer, unsigned int buflen,
                      unsigned char state);
 uint32_t gfs2_bitfit(unsigned char *buffer, unsigned int buflen,
-					 uint32_t goal, unsigned char old_state);
+		     uint32_t goal, unsigned char old_state);
 
 /* functions with blk #'s that are rgrp relative */
 uint32_t gfs2_blkalloc_internal(struct rgrp_list *rgd, uint32_t goal,
-								unsigned char old_state,
-								unsigned char new_state, int do_it);
+				unsigned char old_state,
+				unsigned char new_state, int do_it);
 int gfs2_check_range(struct gfs2_sbd *sdp, uint64_t blkno);
 
 /* functions with blk #'s that are file system relative */
@@ -380,7 +380,7 @@
 #define IS_DINODE   (2)
 
 struct gfs2_inode *inode_get(struct gfs2_sbd *sdp,
-							 struct gfs2_buffer_head *bh);
+			     struct gfs2_buffer_head *bh);
 void inode_put(struct gfs2_inode *ip, enum update_flags updated);
 uint64_t data_alloc(struct gfs2_inode *ip);
 uint64_t meta_alloc(struct gfs2_inode *ip);
@@ -390,26 +390,28 @@
 int gfs2_writei(struct gfs2_inode *ip, void *buf,
 				uint64_t offset, unsigned int size);
 struct gfs2_buffer_head *get_file_buf(struct gfs2_inode *ip, uint64_t lbn,
-									  int prealloc);
+				      int prealloc);
 struct gfs2_buffer_head *init_dinode(struct gfs2_sbd *sdp,
-									 struct gfs2_inum *inum,
-									 unsigned int mode, uint32_t flags,
-									 struct gfs2_inum *parent);
+				     struct gfs2_inum *inum,
+				     unsigned int mode, uint32_t flags,
+				     struct gfs2_inum *parent);
 struct gfs2_inode *createi(struct gfs2_inode *dip, char *filename,
-						   unsigned int mode, uint32_t flags);
+			   unsigned int mode, uint32_t flags);
 void dirent2_del(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
-				 struct gfs2_dirent *prev, struct gfs2_dirent *cur);
+		 struct gfs2_dirent *prev, struct gfs2_dirent *cur);
 struct gfs2_inode *gfs2_load_inode(struct gfs2_sbd *sbp, uint64_t block);
 int gfs2_lookupi(struct gfs2_inode *dip, const char *filename, int len,
-				 struct gfs2_inode **ipp);
+		 struct gfs2_inode **ipp);
 void dir_add(struct gfs2_inode *dip, char *filename, int len,
 			 struct gfs2_inum *inum, unsigned int type);
 int gfs2_dirent_del(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
-					const char *filename, int filename_len);
+		    const char *filename, int filename_len);
 void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
 			   uint64_t *dblock, uint32_t *extlen, int prealloc);
 void gfs2_get_leaf_nr(struct gfs2_inode *dip, uint32_t index,
 					  uint64_t *leaf_out);
+void gfs2_put_leaf_nr(struct gfs2_inode *dip, uint32_t inx, uint64_t leaf_out);
+
 int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t block);
 int gfs2_get_leaf(struct gfs2_inode *dip, uint64_t leaf_no,
 				  struct gfs2_buffer_head **bhp);
--- cluster/gfs2/libgfs2/structures.c	2007/02/12 18:55:29	1.7
+++ cluster/gfs2/libgfs2/structures.c	2007/05/15 18:11:10	1.8
@@ -2,7 +2,7 @@
 *******************************************************************************
 **
 **  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
-**  Copyright (C) 2004 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -486,8 +486,6 @@
 		log_err("next_rg_meta:  Start block is outside rgrp bounds.\n");
 		exit(1);
 	}
-	if (*block == 0x11366)
-		bits = NULL;
 	for(i=0; i < length; i++){
 		bits = &rgd->bits[i];
 		if(blk < bits->bi_len*GFS2_NBBY)
@@ -497,11 +495,11 @@
 	for(; i < length; i++){
 		bits = &rgd->bits[i];
 		blk = gfs2_bitfit((unsigned char *)rgd->bh[i]->b_data +
-						  bits->bi_offset, bits->bi_len, blk,
-						  GFS2_BLKST_DINODE);
+				  bits->bi_offset, bits->bi_len, blk,
+				  GFS2_BLKST_DINODE);
 		if(blk != BFITNOENT){
-            *block = blk + (bits->bi_start * GFS2_NBBY) + rgd->ri.ri_data0;
-            break;
+			*block = blk + (bits->bi_start * GFS2_NBBY) + rgd->ri.ri_data0;
+			break;
 		}
 		blk=0;
 	}




More information about the Cluster-devel mailing list