Hi,

The return values are a bit confusing, could we have 1 for gfs1, 2 for
gfs2, and negative for error? Also lets call these functions
libgfs2_check_sb etc, to try and keep the interface clean,

Steve.

On Thu, 2011-08-11 at 16:54 -0400, Bob Peterson wrote:
> >From e85543c0c03fcaeb4ada7ee7b4ecbef361b16ffc Mon Sep 17 00:00:00 2001
> From: Bob Peterson <rpete...@redhat.com>
> Date: Mon, 8 Aug 2011 10:48:35 -0500
> Subject: [PATCH 04/44] libgfs2: Make check_sb and read_sb operate on gfs1
>  file systems
> 
> This patch adds "allow_gfs1" parameters to the read_sb and check_sb functions.
> This will allow gfs2-utils to read and operate on gfs1 file systems in
> follow-up patches.
> 
> rhbz#675723
> ---
>  gfs2/edit/savemeta.c   |   27 ++++++----------------
>  gfs2/fsck/initialize.c |    4 +-
>  gfs2/libgfs2/libgfs2.h |   28 +++++++++++++++++++++--
>  gfs2/libgfs2/super.c   |   57 ++++++++++++++++++++++++++++-------------------
>  gfs2/mkfs/main_grow.c  |    2 +-
>  5 files changed, 69 insertions(+), 49 deletions(-)
> 
> diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
> index e8bcf8f..1587438 100644
> --- a/gfs2/edit/savemeta.c
> +++ b/gfs2/edit/savemeta.c
> @@ -668,26 +668,13 @@ void savemeta(char *out_fn, int saveoption, int 
> gziplevel)
>                       fprintf(stderr, "Bad constants (1)\n");
>                       exit(-1);
>               }
> -             if(sbd.gfs1) {
> -                     sbd.bsize = sbd.sd_sb.sb_bsize;
> -                     sbd.sd_inptrs = (sbd.bsize -
> -                                      sizeof(struct gfs_indirect)) /
> -                             sizeof(uint64_t);
> -                     sbd.sd_diptrs = (sbd.bsize -
> -                                       sizeof(struct gfs_dinode)) /
> -                             sizeof(uint64_t);
> -             } else {
> -                     if (read_sb(&sbd) < 0)
> -                             slow = TRUE;
> -                     else {
> -                             sbd.sd_inptrs = (sbd.bsize -
> -                                      sizeof(struct gfs2_meta_header)) /
> -                                     sizeof(uint64_t);
> -                             sbd.sd_diptrs = (sbd.bsize -
> -                                       sizeof(struct gfs2_dinode)) /
> -                                     sizeof(uint64_t);
> -                     }
> +             sbd.gfs1 = read_sb(&sbd, 1);
> +             if (sbd.gfs1 < 0) {
> +                     slow = TRUE;
> +                     sbd.gfs1 = 0;
>               }
> +             if (sbd.gfs1)
> +                     sbd.bsize = sbd.sd_sb.sb_bsize;
>       }
>       last_fs_block = lseek(sbd.device_fd, 0, SEEK_END) / sbd.bsize;
>       printf("There are %llu blocks of %u bytes in the destination "
> @@ -923,7 +910,7 @@ static int restore_data(int fd, gzFile *gzin_fd, int 
> printblocksonly,
>                           sbd1->sb_header.mh_format == GFS_FORMAT_SB &&
>                           sbd1->sb_multihost_format == GFS_FORMAT_MULTI) {
>                               sbd.gfs1 = TRUE;
> -                     } else if (check_sb(&sbd.sd_sb)) {
> +                     } else if (check_sb(&sbd.sd_sb, 0)) {
>                               fprintf(stderr,"Error: Invalid superblock 
> data.\n");
>                               return -1;
>                       }
> diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
> index 2506108..18d13cc 100644
> --- a/gfs2/fsck/initialize.c
> +++ b/gfs2/fsck/initialize.c
> @@ -1160,7 +1160,7 @@ static int fill_super_block(struct gfs2_sbd *sdp)
>               log_crit(_("Bad constants (1)\n"));
>               exit(-1);
>       }
> -     if (read_sb(sdp) < 0) {
> +     if (read_sb(sdp, 0) < 0) {
>               /* First, check for a gfs1 (not gfs2) file system */
>               if (sdp->sd_sb.sb_header.mh_magic == GFS2_MAGIC &&
>                   sdp->sd_sb.sb_header.mh_type == GFS2_METATYPE_SB)
> @@ -1169,7 +1169,7 @@ static int fill_super_block(struct gfs2_sbd *sdp)
>               if (sb_repair(sdp) != 0)
>                       return -1; /* unrepairable, so exit */
>               /* Now that we've tried to repair it, re-read it. */
> -             if (read_sb(sdp) < 0)
> +             if (read_sb(sdp, 0) < 0)
>                       return -1;
>       }
>  
> diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
> index 5f66312..82c39f1 100644
> --- a/gfs2/libgfs2/libgfs2.h
> +++ b/gfs2/libgfs2/libgfs2.h
> @@ -493,7 +493,29 @@ extern int write_journal(struct gfs2_sbd *sdp, unsigned 
> int j,
>  
>  extern int device_size(int fd, uint64_t *bytes);
>  
> -/* gfs1.c - GFS1 backward compatibility functions */
> +/* gfs1.c - GFS1 backward compatibility structures and functions */
> +
> +#define GFS_FORMAT_SB           (100)  /* Super-Block */
> +#define GFS_METATYPE_SB         (1)    /* Super-Block */
> +#define GFS_FORMAT_FS           (1309) /* Filesystem (all-encompassing) */
> +#define GFS_FORMAT_MULTI        (1401) /* Multi-Host */
> +/* GFS1 Dinode types  */
> +#define GFS_FILE_NON            (0)
> +#define GFS_FILE_REG            (1)    /* regular file */
> +#define GFS_FILE_DIR            (2)    /* directory */
> +#define GFS_FILE_LNK            (5)    /* link */
> +#define GFS_FILE_BLK            (7)    /* block device node */
> +#define GFS_FILE_CHR            (8)    /* character device node */
> +#define GFS_FILE_FIFO           (101)  /* fifo/pipe */
> +#define GFS_FILE_SOCK           (102)  /* socket */
> +
> +/* GFS 1 journal block types: */
> +#define GFS_LOG_DESC_METADATA   (300)    /* metadata */
> +#define GFS_LOG_DESC_IUL        (400)    /* unlinked inode */
> +#define GFS_LOG_DESC_IDA        (401)    /* de-allocated inode */
> +#define GFS_LOG_DESC_Q          (402)    /* quota */
> +#define GFS_LOG_DESC_LAST       (500)    /* final in a logged transaction */
> +
>  struct gfs_indirect {
>       struct gfs2_meta_header in_header;
>  
> @@ -672,8 +694,8 @@ extern int gfs2_next_rg_meta(struct rgrp_list *rgd, 
> uint64_t *block,
>  extern int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
>                                uint64_t *block, uint32_t type, int first);
>  /* super.c */
> -extern int check_sb(struct gfs2_sb *sb);
> -extern int read_sb(struct gfs2_sbd *sdp);
> +extern int check_sb(struct gfs2_sb *sb, int allow_gfs);
> +extern int read_sb(struct gfs2_sbd *sdp, int allow_gfs);
>  extern int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane);
>  extern int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int *sane);
>  extern int write_sb(struct gfs2_sbd *sdp);
> diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c
> index 995e503..7d82d2d 100644
> --- a/gfs2/libgfs2/super.c
> +++ b/gfs2/libgfs2/super.c
> @@ -20,9 +20,9 @@
>   * read and that the sizes of the various on-disk structures have not
>   * changed.
>   *
> - * Returns: 0 on success, -1 on failure
> + * Returns: 0 on success, -1 on failure, 1 if this is gfs (gfs1)
>   */
> -int check_sb(struct gfs2_sb *sb)
> +int check_sb(struct gfs2_sb *sb, int allow_gfs)
>  {
>       if (sb->sb_header.mh_magic != GFS2_MAGIC ||
>           sb->sb_header.mh_type != GFS2_METATYPE_SB) {
> @@ -33,9 +33,12 @@ int check_sb(struct gfs2_sb *sb)
>                                 sb->sb_header.mh_type);
>               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) {
> +     if (sb->sb_fs_format == GFS_FORMAT_FS &&
> +         sb->sb_header.mh_format == GFS_FORMAT_SB &&
> +         sb->sb_multihost_format == GFS_FORMAT_MULTI) {
> +             if (allow_gfs)
> +                     return 1;
> +
>               log_crit("Old gfs1 file system detected.\n");
>               return -EINVAL;
>       }
> @@ -51,31 +54,42 @@ int check_sb(struct gfs2_sb *sb)
>   * initializes various constants maintained in the super
>   * block
>   *
> - * Returns: 0 on success, -1 on failure.
> + * allow_gfs - passed in as 1 if we're allowed to accept gfs1 file systems
> + *
> + * Returns: 0 on success, -1 on failure, 1 if this is gfs (gfs1)
>   */
> -int read_sb(struct gfs2_sbd *sdp)
> +int read_sb(struct gfs2_sbd *sdp, int allow_gfs)
>  {
>       struct gfs2_buffer_head *bh;
>       uint64_t space = 0;
>       unsigned int x;
> -     int error;
> +     int gfs1;
>  
>       bh = bread(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift);
>       gfs2_sb_in(&sdp->sd_sb, bh);
>       brelse(bh);
>  
> -     error = check_sb(&sdp->sd_sb);
> -     if (error)
> -             goto out;
> +     gfs1 = check_sb(&sdp->sd_sb, allow_gfs);
> +     if (gfs1 < 0)
> +             return gfs1;
>  
>       sdp->sd_fsb2bb_shift = sdp->sd_sb.sb_bsize_shift - 
> GFS2_BASIC_BLOCK_SHIFT;
>       sdp->bsize = sdp->sd_sb.sb_bsize;
> -     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);
> +     if (gfs1) {
> +             sdp->sd_diptrs = (sdp->sd_sb.sb_bsize -
> +                               sizeof(struct gfs_dinode)) /
> +                     sizeof(uint64_t);
> +             sdp->sd_inptrs = (sdp->sd_sb.sb_bsize -
> +                               sizeof(struct gfs_indirect)) /
> +                     sizeof(uint64_t);
> +     } else {
> +             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_hash_bsize = sdp->bsize / 2;
>       sdp->sd_hash_bsize_shift = sdp->sd_sb.sb_bsize_shift - 1;
> @@ -92,8 +106,7 @@ int read_sb(struct gfs2_sbd *sdp)
>       }
>       if (x > GFS2_MAX_META_HEIGHT){
>               log_err("Bad max metadata height.\n");
> -             error = -1;
> -             goto out;
> +             return -1;
>       }
>  
>       sdp->sd_jheightsize[0] = sdp->sd_sb.sb_bsize - sizeof(struct 
> gfs2_dinode);
> @@ -108,14 +121,12 @@ int read_sb(struct gfs2_sbd *sdp)
>       sdp->sd_max_jheight = x;
>       if(sdp->sd_max_jheight > GFS2_MAX_META_HEIGHT) {
>               log_err("Bad max jheight.\n");
> -             error = -1;
> +             return -1;
>       }
>       sdp->fssize = lseek(sdp->device_fd, 0, SEEK_END) / sdp->sd_sb.sb_bsize;
>       sdp->sb_addr = GFS2_SB_ADDR * GFS2_BASIC_BLOCK / sdp->bsize;
>  
> - out:
> -
> -     return error;
> +     return gfs1;
>  }
>  
>  /**
> diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c
> index 0eca396..8cf9fbc 100644
> --- a/gfs2/mkfs/main_grow.c
> +++ b/gfs2/mkfs/main_grow.c
> @@ -354,7 +354,7 @@ main_grow(int argc, char *argv[])
>                       log_crit(_("Bad constants (1)\n"));
>                       exit(-1);
>               }
> -             if(read_sb(sdp) < 0)
> +             if(read_sb(sdp, 0) < 0)
>                       die( _("gfs: Error reading superblock.\n"));
>  
>               if (fix_device_geometry(sdp)) {


Reply via email to