commit 9555c12ec4dbd75e638b859ef7e4658ba0239fa8 Author: Bob Peterson <rpeterso@redhat.com> Date: Tue Aug 9 12:48:36 2011 -0500 fsck.gfs2 pass2: Delete extended attributes with inode When pass2 decided to delete a bad/corrupt dinode from disk, it was not deleting extended attributes associated with that dinode. Oops. This patch corrects the situation and allows it to delete them. rhbz#877150 diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c index cba0094..51cbe33 100644 --- a/gfs2/fsck/pass2.c +++ b/gfs2/fsck/pass2.c @@ -171,6 +171,59 @@ static int check_file_type(uint8_t de_type, uint8_t blk_type) return 0; } +static int delete_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) +{ + struct gfs2_sbd *sdp = ip->i_sbd; + char ea_name[256]; + + if (!ea_hdr->ea_name_len){ + /* Skip this entry for now */ + return 1; + } + + memset(ea_name, 0, sizeof(ea_name)); + strncpy(ea_name, (char *)ea_hdr + sizeof(struct gfs2_ea_header), + ea_hdr->ea_name_len); + + if (!GFS2_EATYPE_VALID(ea_hdr->ea_type) && + ((ea_hdr_prev) || (!ea_hdr_prev && ea_hdr->ea_type))){ + /* Skip invalid entry */ + return 1; + } + + if (ea_hdr->ea_num_ptrs){ + uint32_t avail_size; + int max_ptrs; + + avail_size = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header); + max_ptrs = (be32_to_cpu(ea_hdr->ea_data_len) + avail_size - 1) / + avail_size; + + if (max_ptrs > ea_hdr->ea_num_ptrs) + return 1; + else { + log_debug( _(" Pointers Required: %d\n Pointers Reported: %d\n"), + max_ptrs, ea_hdr->ea_num_ptrs); + } + } + return 0; +} + +static int delete_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) +{ + uint64_t block = be64_to_cpu(*ea_data_ptr); + + return delete_metadata(ip, block, NULL, 0, private); +} + struct metawalk_fxns pass2_fxns_delete = { .private = NULL, .check_metalist = delete_metadata, @@ -178,6 +231,8 @@ struct metawalk_fxns pass2_fxns_delete = { .check_leaf = delete_leaf, .check_eattr_indir = delete_eattr_indir, .check_eattr_leaf = delete_eattr_leaf, + .check_eattr_entry = delete_eattr_entry, + .check_eattr_extentry = delete_eattr_extentry, }; /* FIXME: should maybe refactor this a bit - but need to deal with