[Cluster-devel] cluster/gfs2 fsck/metawalk.c fsck/metawalk.h f ...
rpeterso at sourceware.org
rpeterso at sourceware.org
Tue May 15 18:21:10 UTC 2007
CVSROOT: /cvs/cluster
Module name: cluster
Branch: RHEL5
Changes by: rpeterso at sourceware.org 2007-05-15 18:21:09
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&only_with_tag=RHEL5&r1=1.3.2.5&r2=1.3.2.6
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/fsck/metawalk.h.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.2&r2=1.2.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/fsck/pass1.c.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.4.2.3&r2=1.4.2.4
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/fsck/pass2.c.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.4.2.2&r2=1.4.2.3
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/libgfs2/fs_ops.c.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.4.2.3&r2=1.4.2.4
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/libgfs2/libgfs2.h.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.7.2.5&r2=1.7.2.6
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/libgfs2/structures.c.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.5.2.2&r2=1.5.2.3
--- cluster/gfs2/fsck/metawalk.c 2007/02/26 19:20:46 1.3.2.5
+++ cluster/gfs2/fsck/metawalk.c 2007/05/15 18:21:08 1.3.2.6
@@ -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:21:08 1.2.2.1
@@ -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 18:20:49 1.4.2.3
+++ cluster/gfs2/fsck/pass1.c 2007/05/15 18:21:08 1.4.2.4
@@ -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 18:20:49 1.4.2.2
+++ cluster/gfs2/fsck/pass2.c 2007/05/15 18:21:08 1.4.2.3
@@ -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 18:20:50 1.4.2.3
+++ cluster/gfs2/libgfs2/fs_ops.c 2007/05/15 18:21:08 1.4.2.4
@@ -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/11 16:53:32 1.7.2.5
+++ cluster/gfs2/libgfs2/libgfs2.h 2007/05/15 18:21:08 1.7.2.6
@@ -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 19:01:41 1.5.2.2
+++ cluster/gfs2/libgfs2/structures.c 2007/05/15 18:21:08 1.5.2.3
@@ -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