[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Cluster-devel] cluster/gfs2/fsck pass1.c pass1c.c



CVSROOT:	/cvs/cluster
Module name:	cluster
Changes by:	rpeterso sourceware org	2006-06-20 18:30:56

Modified files:
	gfs2/fsck      : pass1.c pass1c.c 

Log message:
	Fixed bugs regarding acls and eattrs.  Also crosswrote some fixes
	from gfs1 regarding eattrs.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/fsck/pass1.c.diff?cvsroot=cluster&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/fsck/pass1c.c.diff?cvsroot=cluster&r1=1.3&r2=1.4

--- cluster/gfs2/fsck/pass1.c	2006/06/12 20:41:43	1.3
+++ cluster/gfs2/fsck/pass1.c	2006/06/20 18:30:55	1.4
@@ -184,9 +184,9 @@
 
 	/* This inode contains an eattr - it may be invalid, but the
 	 * eattr attributes points to a non-zero block */
-	log_debug("Setting %" PRIu64 " (0x%" PRIx64 ") to eattr block\n", block,
-			  block);
-	gfs2_block_set(bl, ip->i_di.di_num.no_addr, gfs2_eattr_block);
+	log_debug("Setting %" PRIu64 " (0x%" PRIx64 ") to eattr block\n",
+			  indirect, indirect);
+	gfs2_block_set(bl, indirect, gfs2_eattr_block);
 
 	if(gfs2_check_range(sdp, indirect)) {
 		/*log_warn("EA indirect block #%"PRIu64" is out of range.\n",
@@ -287,7 +287,8 @@
 }
 
 static 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)
 {
 	struct gfs2_sbd *sdp = ip->i_sbd;
 	struct gfs2_buffer_head *leaf_bh;
@@ -297,10 +298,11 @@
 
 	/* This inode contains an eattr - it may be invalid, but the
 	 * eattr attributes points to a non-zero block */
-	log_debug("Setting %" PRIu64 " (0x%" PRIx64 ") to eattr block\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_eattr_block);
-
+	if (parent != ip->i_di.di_num.no_addr) { /* if parent isn't the inode */
+		log_debug("Setting %" PRIu64 " (0x%" PRIx64 ") to eattr block\n",
+				  parent, parent);
+		gfs2_block_set(bl, parent, gfs2_eattr_block);
+	}
 	if(gfs2_check_range(sdp, block)){
 		log_warn("EA leaf block #%" PRIu64 " (0x%" PRIx64 ") in inode %" PRIu64
 				 " (0x%" PRIx64 ") is out of range.\n",
@@ -323,14 +325,14 @@
 		leaf_bh = bread(sdp, block);
 		if(gfs2_check_meta(leaf_bh, GFS2_METATYPE_EA)) {
 			log_warn("EA leaf block has incorrect type.\n");
-			gfs2_block_set(bl, (uint64_t)*leaf_bh->b_data, gfs2_meta_inval);
+			gfs2_block_set(bl, block, gfs2_meta_inval);
 			brelse(leaf_bh, not_updated);
 			ret = 1;
 		}
 		else {
-			log_debug("Setting %" PRIu64 " (0x%" PRIx64 ") to eattr block\n",
-					  (uint64_t)*leaf_bh->b_data, (uint64_t)*leaf_bh->b_data);
-			gfs2_block_set(bl, (uint64_t)*leaf_bh->b_data, gfs2_meta_eattr);
+			log_debug("Setting block %" PRIu64 " (0x%" PRIx64
+					  ") to eattr block\n", block, block);
+			gfs2_block_set(bl, block, gfs2_meta_eattr);
 			bc->ea_count++;
 		}
 		brelse(leaf_bh, not_updated);
--- cluster/gfs2/fsck/pass1c.c	2006/06/12 20:41:43	1.3
+++ cluster/gfs2/fsck/pass1c.c	2006/06/20 18:30:55	1.4
@@ -30,10 +30,13 @@
 			 leaf_bh->b_blocknr, leaf_bh->b_blocknr);
 	if(!prev)
 		curr->ea_type = GFS2_EATYPE_UNUSED;
-	else
+	else {
 		prev->ea_rec_len =
 			cpu_to_be32(be32_to_cpu(curr->ea_rec_len) +
 						be32_to_cpu(prev->ea_rec_len));
+		if (curr->ea_flags & GFS2_EAFLAG_LAST)
+			prev->ea_flags |= GFS2_EAFLAG_LAST;	
+	}
 	return 0;
 }
 
@@ -107,9 +110,42 @@
 {
 	struct gfs2_sbd *sdp = ip->i_sbd;
 	char ea_name[256];
+	uint32_t offset = (uint32_t)(((unsigned long)ea_hdr) -
+			                  ((unsigned long)leaf_bh->b_data));
+	uint32_t max_size = sdp->sd_sb.sb_bsize;
 
 	if(!ea_hdr->ea_name_len){
 		log_err("EA has name length == 0\n");
+		ea_hdr->ea_flags |= GFS2_EAFLAG_LAST;
+		ea_hdr->ea_rec_len = cpu_to_be32(max_size - offset);
+		if(remove_eattr_entry(sdp, leaf_bh, ea_hdr, ea_hdr_prev)){
+			stack;
+			return -1;
+		}
+		return 1;
+	}
+	if(offset + be32_to_cpu(ea_hdr->ea_rec_len) > max_size){
+		log_err("EA rec length too long\n");
+		ea_hdr->ea_flags |= GFS2_EAFLAG_LAST;
+		ea_hdr->ea_rec_len = cpu_to_be32(max_size - offset);
+		if(remove_eattr_entry(sdp, leaf_bh, ea_hdr, ea_hdr_prev)){
+			stack;
+			return -1;
+		}
+		return 1;
+	}
+	if(offset + be32_to_cpu(ea_hdr->ea_rec_len) == max_size &&
+	   (ea_hdr->ea_flags & GFS2_EAFLAG_LAST) == 0){
+		log_err("last EA has no last entry flag\n");
+		ea_hdr->ea_flags |= GFS2_EAFLAG_LAST;
+		if(remove_eattr_entry(sdp, leaf_bh, ea_hdr, ea_hdr_prev)){
+			stack;
+			return -1;
+		}
+		return 1;
+	}
+	if(!ea_hdr->ea_name_len){
+		log_err("EA has name length == 0\n");
 		if(remove_eattr_entry(sdp, leaf_bh, ea_hdr, ea_hdr_prev)){
 			stack;
 			return -1;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]