From mboxrd@z Thu Jan 1 00:00:00 1970 From: rpeterso@sourceware.org Date: 20 Jun 2006 18:30:56 -0000 Subject: [Cluster-devel] cluster/gfs2/fsck pass1.c pass1c.c Message-ID: <20060620183056.28937.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit CVSROOT: /cvs/cluster Module name: cluster Changes by: rpeterso at 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;