From mboxrd@z Thu Jan 1 00:00:00 1970 From: rpeterso@sourceware.org Date: 12 Jun 2006 20:38:29 -0000 Subject: [Cluster-devel] cluster/gfs2/libgfs2 Makefile fs_ops.c libgfs2 ... Message-ID: <20060612203829.17872.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-12 20:38:27 Modified files: gfs2/libgfs2 : Makefile fs_ops.c libgfs2.h ondisk.c structures.c Added files: gfs2/libgfs2 : gfs2_log.c super.c Log message: Moved functions from fsck to libgfs2, added functions to make gfs2_convert not use libgfs. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/libgfs2/gfs2_log.c.diff?cvsroot=cluster&r1=NONE&r2=1.1 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/libgfs2/super.c.diff?cvsroot=cluster&r1=NONE&r2=1.1 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/libgfs2/Makefile.diff?cvsroot=cluster&r1=1.2&r2=1.3 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/libgfs2/fs_ops.c.diff?cvsroot=cluster&r1=1.3&r2=1.4 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/libgfs2/libgfs2.h.diff?cvsroot=cluster&r1=1.3&r2=1.4 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/libgfs2/ondisk.c.diff?cvsroot=cluster&r1=1.3&r2=1.4 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/libgfs2/structures.c.diff?cvsroot=cluster&r1=1.3&r2=1.4 /cvs/cluster/cluster/gfs2/libgfs2/gfs2_log.c,v --> standard output revision 1.1 --- cluster/gfs2/libgfs2/gfs2_log.c +++ - 2006-06-12 20:38:28.948936000 +0000 @@ -0,0 +1,152 @@ +/***************************************************************************** +****************************************************************************** +** +** Copyright (C) 2005 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 +** of the GNU General Public License v.2. +** +****************************************************************************** +*****************************************************************************/ + +#include +#include +#include +#include + +#include +#include + +#include "libgfs2.h" + +#define _(String) gettext(String) + +struct log_state { + int print_level; +}; +static struct log_state _state = {MSG_NOTICE}; + +void increase_verbosity(void) +{ + _state.print_level++; +} + +void decrease_verbosity(void) +{ + _state.print_level--; +} + +void print_msg(int priority, char *file, int line, const char *format, + va_list args) { + + switch (priority) { + + case MSG_DEBUG: + printf("(%s:%d)\t", file, line); + vprintf(format, args); + break; + case MSG_INFO: + case MSG_NOTICE: + case MSG_WARN: + vprintf(format, args); + break; + case MSG_ERROR: + case MSG_CRITICAL: + default: + vfprintf(stderr, format, args); + break; + } + return; +} + + +void print_fsck_log(int iif, int priority, char *file, int line, + const char *format, ...) +{ + + va_list args; + const char *transform; + + va_start(args, format); + + transform = _(format); + + if((_state.print_level == priority) || + (!iif && (_state.print_level >= priority))) + print_msg(priority, file, line, transform, args); + + va_end(args); +} + + + +int query(struct gfs2_options *opts, const char *format, ...) +{ + + va_list args; + const char *transform; + char response; + fd_set rfds; + struct timeval tv; + int err = 0; + int ret = 0; + + va_start(args, format); + + transform = _(format); + + if(opts->yes) + return 1; + if(opts->no) + return 0; + + /* Watch stdin (fd 0) to see when it has input. */ + FD_ZERO(&rfds); + FD_SET(STDIN_FILENO, &rfds); + + tv.tv_sec = 0; + tv.tv_usec = 0; + /* Make sure there isn't extraneous input before asking the + * user the question */ + while((err = select(STDIN_FILENO + 1, &rfds, NULL, NULL, &tv))) { + if(err < 0) { + log_debug("Error in select() on stdin\n"); + break; + } + read(STDIN_FILENO, &response, sizeof(char)); + + } + query: + vprintf(transform, args); + + /* Make sure query is printed out */ + fflush(NULL); + + rescan: + read(STDIN_FILENO, &response, sizeof(char)); + + if(tolower(response) == 'y') { + ret = 1; + } else if (tolower(response) == 'n') { + ret = 0; + } else if ((response == ' ') || (response == '\t')) { + goto rescan; + } else { + while(response != '\n') + read(STDIN_FILENO, &response, sizeof(char)); + printf("Bad response, please type 'y' or 'n'.\n"); + goto query; + } + + /* Clip the input */ + while((err = select(STDIN_FILENO + 1, &rfds, NULL, NULL, &tv))) { + if(err < 0) { + log_debug("Error in select() on stdin\n"); + break; + } + read(STDIN_FILENO, &response, sizeof(char)); + } + + return ret; +} /cvs/cluster/cluster/gfs2/libgfs2/super.c,v --> standard output revision 1.1 --- cluster/gfs2/libgfs2/super.c +++ - 2006-06-12 20:38:29.152715000 +0000 @@ -0,0 +1,239 @@ +/****************************************************************************** +******************************************************************************* +** +** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. +** Copyright (C) 2004-2005 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 +** of the GNU General Public License v.2. +** +******************************************************************************* +******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#include "libgfs2.h" +#include "osi_list.h" + +/** + * check_sb - Check superblock + * @sdp: the filesystem + * @sb: The superblock + * + * Checks the version code of the FS is one that we understand how to + * read and that the sizes of the various on-disk structures have not + * changed. + * + * Returns: 0 on success, -1 on failure + */ +static int check_sb(struct gfs2_sbd *sdp, struct gfs2_sb *sb) +{ + if (sb->sb_header.mh_magic != GFS2_MAGIC || + sb->sb_header.mh_type != GFS2_METATYPE_SB) + return -EINVAL; + + /* If format numbers match exactly, we're done. */ + if (sb->sb_fs_format != GFS2_FORMAT_FS || + sb->sb_multihost_format != GFS2_FORMAT_MULTI) + return -EINVAL; + return 0; +} + + +/* + * read_sb: read the super block from disk + * sdp: in-core super block + * + * This function reads in the super block from disk and + * initializes various constants maintained in the super + * block + * + * Returns: 0 on success, -1 on failure. + */ +int read_sb(struct gfs2_sbd *sdp) +{ + struct gfs2_buffer_head *bh; + uint64_t space = 0; + unsigned int x; + int error; + + bh = bread(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); + gfs2_sb_in(&sdp->sd_sb, bh->b_data); + brelse(bh, not_updated); + + error = check_sb(sdp, &sdp->sd_sb); + if (error) + goto out; + + sdp->sd_fsb2bb_shift = sdp->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT; + sdp->sd_diptrs = + (sdp->sd_sb.sb_bsize-sizeof(struct gfs2_dinode)) / + sizeof(uint64_t); + sdp->sd_inptrs = + (sdp->sd_sb.sb_bsize-sizeof(struct gfs2_meta_header)) / + sizeof(uint64_t); + sdp->sd_jbsize = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header); + sdp->sd_heightsize[0] = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode); + sdp->sd_heightsize[1] = sdp->sd_sb.sb_bsize * sdp->sd_diptrs; + for (x = 2; ; x++){ + space = sdp->sd_heightsize[x - 1] * sdp->sd_inptrs; + /* FIXME: Do we really need this first check?? */ + if (space / sdp->sd_inptrs != sdp->sd_heightsize[x - 1] || + space % sdp->sd_inptrs != 0) + break; + sdp->sd_heightsize[x] = space; + } + if (x > GFS2_MAX_META_HEIGHT){ + error = -1; + goto out; + } + + sdp->sd_jheightsize[0] = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode); + sdp->sd_jheightsize[1] = sdp->sd_jbsize * sdp->sd_diptrs; + for (x = 2; ; x++){ + space = sdp->sd_jheightsize[x - 1] * sdp->sd_inptrs; + if (space / sdp->sd_inptrs != sdp->sd_jheightsize[x - 1] || + space % sdp->sd_inptrs != 0) + break; + sdp->sd_jheightsize[x] = space; + } + sdp->sd_max_jheight = x; + if(sdp->sd_max_jheight > GFS2_MAX_META_HEIGHT) + error = -1; + sdp->fssize = lseek(sdp->device_fd, 0, SEEK_END) / sdp->sd_sb.sb_bsize; + + out: + + return error; +} + +#define JOURNAL_NAME_SIZE 16 + +/* + * ji_update - fill in journal info + * sdp: the incore superblock pointer + * + * Given the inode for the journal index, read in all + * the journal inodes. + * + * Returns: 0 on success, -1 on failure + */ +int ji_update(struct gfs2_sbd *sdp) +{ + struct gfs2_inode *jip, *ip = sdp->md.jiinode; + char journal_name[JOURNAL_NAME_SIZE]; + int i; + + if(!ip) + return -1; + + if(!(sdp->md.journal = calloc(ip->i_di.di_entries - 2, sizeof(struct gfs2_inode *)))) + return -1; + sdp->md.journals = 0; + memset(journal_name, 0, sizeof(*journal_name)); + for(i = 0; i < ip->i_di.di_entries - 2; i++) { + /* FIXME check snprintf return code */ + snprintf(journal_name, JOURNAL_NAME_SIZE, "journal%u", i); + gfs2_lookupi(sdp->md.jiinode, journal_name, strlen(journal_name), + &jip); + sdp->md.journal[i] = jip; + } + sdp->md.journals = ip->i_di.di_entries - 2; + return 0; + +} + +/** + * ri_update - attach rgrps to the super block + * @sdp: + * + * Given the rgrp index inode, link in all rgrps into the super block + * and be sure that they can be read. + * + * Returns: 0 on success, -1 on failure. + */ +int ri_update(struct gfs2_sbd *sdp, int *rgcount) +{ + struct rgrp_list *rgd; + osi_list_t *tmp; + struct gfs2_rindex buf; + unsigned int rg; + int error, count1 = 0, count2 = 0; + uint64_t errblock = 0; + + for (rg = 0; ; rg++) { + error = gfs2_readi(sdp->md.riinode, (char *)&buf, + rg * sizeof(struct gfs2_rindex), + sizeof(struct gfs2_rindex)); + if (!error) + break; + if (error != sizeof(struct gfs2_rindex)) + goto fail; + + rgd = (struct rgrp_list *)malloc(sizeof(struct rgrp_list)); + memset(rgd, 0, sizeof(struct rgrp_list)); + osi_list_add_prev(&rgd->list, &sdp->rglist); + + gfs2_rindex_in(&rgd->ri, (char *)&buf); + + if(gfs2_compute_bitstructs(sdp, rgd)) + goto fail; + + count1++; + } + + for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) { + int i; + uint64_t prev_err = 0; + enum update_flags f; + + f = not_updated; + rgd = osi_list_entry(tmp, struct rgrp_list, list); + /* If we have errors, we may need to repair and continue. */ + /* We have multiple bitmaps, and all of them might potentially need */ + /* repair. So we have to try to read and repair as many times as */ + /* there are bitmaps. */ + for (i = 0; i < rgd->ri.ri_length; i++) { + errblock = gfs2_rgrp_read(sdp, rgd); + if (errblock) { + if (errblock == prev_err) /* if same block is still bad */ + goto fail; + prev_err = errblock; + } + else + break; + } /* for all bitmap structures */ + gfs2_rgrp_relse(rgd, f); + count2++; + } + + *rgcount = count1; + if (count1 != count2) + goto fail; + + return 0; + + fail: + gfs2_rgrp_free(sdp, not_updated); + return -1; +} + +int write_sb(struct gfs2_sbd *sbp) +{ + int error = 0; + struct gfs2_buffer_head *bh; + + bh = bread(sbp, GFS2_SB_ADDR >> sbp->sd_fsb2bb_shift); + gfs2_sb_out(&sbp->sd_sb, bh->b_data); + brelse(bh, updated); + return error; + +} + --- cluster/gfs2/libgfs2/Makefile 2006/06/06 14:20:41 1.2 +++ cluster/gfs2/libgfs2/Makefile 2006/06/12 20:38:27 1.3 @@ -27,7 +27,7 @@ -D_GNU_SOURCE -DGFS2_RELEASE_NAME=\"2\" ${INCLUDEPATH} H=gfs2_disk_hash.h libgfs2.h linux_endian.h ondisk.h osi_list.h -C=bitmap.c block_list.c buf.c device_geometry.c fs_bits.c fs_geometry.c fs_ops.c locking.c misc.c ondisk.c size.c structures.c rgrp.c +C=bitmap.c block_list.c buf.c device_geometry.c fs_bits.c fs_geometry.c fs_ops.c locking.c gfs2_log.c misc.c ondisk.c size.c structures.c super.c rgrp.c O=$(subst .c,.o,${C}) all: ${LIBGFS2} --- cluster/gfs2/libgfs2/fs_ops.c 2006/06/08 21:02:15 1.3 +++ cluster/gfs2/libgfs2/fs_ops.c 2006/06/12 20:38:27 1.4 @@ -606,9 +606,6 @@ return bread(sdp, dbn); } -#define IS_LEAF (1) -#define IS_DINODE (2) - int gfs2_dirent_first(struct gfs2_inode *dip, struct gfs2_buffer_head *bh, struct gfs2_dirent **dent) { --- cluster/gfs2/libgfs2/libgfs2.h 2006/06/06 14:20:41 1.3 +++ cluster/gfs2/libgfs2/libgfs2.h 2006/06/12 20:38:27 1.4 @@ -377,6 +377,9 @@ void build_rgrps(struct gfs2_sbd *sdp); /* fs_ops.c */ +#define IS_LEAF (1) +#define IS_DINODE (2) + struct gfs2_inode *inode_get(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh); void inode_put(struct gfs2_inode *ip, enum update_flags updated); @@ -441,6 +444,67 @@ /* locking.c */ void test_locking(char *lockproto, char *locktable); +/* gfs2_log.c */ +struct gfs2_options { + char *device; + int yes:1; + int no:1; +}; + +#define MSG_DEBUG 7 +#define MSG_INFO 6 +#define MSG_NOTICE 5 +#define MSG_WARN 4 +#define MSG_ERROR 3 +#define MSG_CRITICAL 2 +#define MSG_NULL 1 + +#define print_log(iif, priority, format...) \ +do { print_fsck_log(iif, priority, __FILE__, __LINE__, ## format); } while(0) + +#define log_debug(format...) \ +do { print_log(0, MSG_DEBUG, format); } while(0) +#define log_info(format...) \ +do { print_log(0, MSG_INFO, format); } while(0) + +#define log_notice(format...) \ +do { print_log(0, MSG_NOTICE, format); } while(0) + +#define log_warn(format...) \ +do { print_log(0, MSG_WARN, format); } while(0) + +#define log_err(format...) \ +do { print_log(0, MSG_ERROR, format); } while(0) + +#define log_crit(format...) \ +do { print_log(0, MSG_CRITICAL, format); } while(0) + +#define stack log_debug(" - %s()\n", __func__) + +#define log_at_debug(format...) \ +do { print_log(1, MSG_DEBUG, format); } while(0) + +#define log_at_info(format...) \ +do { print_log(1, MSG_INFO, format); } while(0) + +#define log_at_notice(format...) \ +do { print_log(1, MSG_NOTICE, format); } while(0) + +#define log_at_warn(format...) \ +do { print_log(1, MSG_WARN, format); } while(0) + +#define log_at_err(format...) \ +do { print_log(1, MSG_ERROR, format); } while(0) + +#define log_at_crit(format...) \ +do { print_log(1, MSG_CRITICAL, format); } while(0) + +void increase_verbosity(void); +void decrease_verbosity(void); +void print_fsck_log(int iif, int priority, char *file, int line, + const char *format, ...); +int query(struct gfs2_options *opts, const char *format, ...); + /* misc.c */ void compute_constants(struct gfs2_sbd *sdp); @@ -469,6 +533,11 @@ int *mfree); int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd, uint64_t *block, uint32_t type, int first); +/* super.c */ +int read_sb(struct gfs2_sbd *sdp); +int ji_update(struct gfs2_sbd *sdp); +int ri_update(struct gfs2_sbd *sdp, int *rgcount); +int write_sb(struct gfs2_sbd *sdp); /* ondisk.c */ uint32_t gfs2_disk_hash(const char *data, int len); --- cluster/gfs2/libgfs2/ondisk.c 2006/06/06 14:20:41 1.3 +++ cluster/gfs2/libgfs2/ondisk.c 2006/06/12 20:38:27 1.4 @@ -183,7 +183,7 @@ CPIN_32(ri, str, ri_bitbytes); - CPIN_08(ri, str, ri_reserved, 32); + CPIN_08(ri, str, ri_reserved, 64); } void gfs2_rindex_out(struct gfs2_rindex *ri, char *buf) @@ -199,7 +199,7 @@ CPOUT_32(ri, str, ri_bitbytes); - CPOUT_08(ri, str, ri_reserved, 32); + CPOUT_08(ri, str, ri_reserved, 64); } void gfs2_rindex_print(struct gfs2_rindex *ri) --- cluster/gfs2/libgfs2/structures.c 2006/06/06 14:20:41 1.3 +++ cluster/gfs2/libgfs2/structures.c 2006/06/12 20:38:27 1.4 @@ -509,8 +509,10 @@ uint32_t blk = (first)? 0: (uint32_t)((*block+1)-rgd->ri.ri_data0); int i; - if(!first && (*block < rgd->ri.ri_data0)) + if(!first && (*block < rgd->ri.ri_data0)) { + 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++){ @@ -555,9 +557,10 @@ uint32_t iblk, ublk, fblk; int i; - if(!first && (*block < rgd->ri.ri_data0)) + if(!first && (*block < rgd->ri.ri_data0)) { + log_err("next_rg_meta_free: Start block is outside rgrp bounds.\n"); exit(1); - + } for(i=0; i < length; i++){ bits = &rgd->bits[i]; if(blk < bits->bi_len*GFS2_NBBY)