From mboxrd@z Thu Jan 1 00:00:00 1970 From: rpeterso@sourceware.org Date: 15 May 2007 18:11:13 -0000 Subject: [Cluster-devel] cluster/gfs2 fsck/metawalk.c fsck/metawalk.h f ... Message-ID: <20070515181113.26289.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 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@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@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; }