From: Bob Peterson <rpete...@redhat.com> This patch moves a number of gfs1-specific structures from gfs2_edit to libgfs2 so other utils can reference them. It also changes function rindex_read so it can operate on gfs1 or gfs2 rindex files.
rhbz#675723 --- gfs2/edit/extended.c | 11 +++-- gfs2/edit/hexedit.c | 13 +++-- gfs2/edit/hexedit.h | 126 ------------------------------------------------ gfs2/libgfs2/libgfs2.h | 94 +++++++++++++++++++++++++++++++++++ gfs2/libgfs2/super.c | 41 ++++++++++----- 5 files changed, 136 insertions(+), 149 deletions(-) diff --git a/gfs2/edit/extended.c b/gfs2/edit/extended.c index 059f18b..366dfc6 100644 --- a/gfs2/edit/extended.c +++ b/gfs2/edit/extended.c @@ -504,7 +504,8 @@ static int parse_rindex(struct gfs2_inode *dip, int print_rindex) start_line = line; error = 0; - print_gfs2("RG index entries found: %d.", dip->i_di.di_size / risize()); + print_gfs2("RG index entries found: %d.", dip->i_di.di_size / + sizeof(struct gfs2_rindex)); eol(0); lines_per_row[dmode] = 6; memset(highlighted_addr, 0, sizeof(highlighted_addr)); @@ -512,12 +513,14 @@ static int parse_rindex(struct gfs2_inode *dip, int print_rindex) for (print_entry_ndx=0; ; print_entry_ndx++) { uint64_t roff; - roff = print_entry_ndx * risize(); + roff = print_entry_ndx * sizeof(struct gfs2_rindex); if (sbd.gfs1) - error = gfs1_readi(dip, (void *)&rbuf, roff, risize()); + error = gfs1_readi(dip, (void *)&rbuf, roff, + sizeof(struct gfs2_rindex)); else - error = gfs2_readi(dip, (void *)&rbuf, roff, risize()); + error = gfs2_readi(dip, (void *)&rbuf, roff, + sizeof(struct gfs2_rindex)); if (!error) /* end of file */ break; gfs2_rindex_in(&ri, rbuf); diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c index 79a297e..903f169 100644 --- a/gfs2/edit/hexedit.c +++ b/gfs2/edit/hexedit.c @@ -1464,7 +1464,8 @@ uint64_t masterblock(const char *fn) static void rgcount(void) { printf("%lld RGs in this file system.\n", - (unsigned long long)sbd.md.riinode->i_di.di_size / risize()); + (unsigned long long)sbd.md.riinode->i_di.di_size / + sizeof(struct gfs2_rindex)); inode_put(&sbd.md.riinode); gfs2_rgrp_free(&sbd.rglist); exit(EXIT_SUCCESS); @@ -1479,7 +1480,7 @@ static uint64_t find_rgrp_block(struct gfs2_inode *dif, int rg) struct gfs2_rindex fbuf, ri; uint64_t foffset, gfs1_adj = 0; - foffset = rg * risize(); + foffset = rg * sizeof(struct gfs2_rindex); if (sbd.gfs1) { uint64_t sd_jbsize = (sbd.bsize - sizeof(struct gfs2_meta_header)); @@ -1488,7 +1489,8 @@ static uint64_t find_rgrp_block(struct gfs2_inode *dif, int rg) sizeof(struct gfs2_meta_header); gfs1_adj += sizeof(struct gfs2_meta_header); } - amt = gfs2_readi(dif, (void *)&fbuf, foffset + gfs1_adj, risize()); + amt = gfs2_readi(dif, (void *)&fbuf, foffset + gfs1_adj, + sizeof(struct gfs2_rindex)); if (!amt) /* end of file */ return 0; gfs2_rindex_in(&ri, (void *)&fbuf); @@ -1557,11 +1559,12 @@ static uint64_t get_rg_addr(int rgnum) else gblock = masterblock("rindex"); riinode = inode_read(&sbd, gblock); - if (rgnum < riinode->i_di.di_size / risize()) + if (rgnum < riinode->i_di.di_size / sizeof(struct gfs2_rindex)) rgblk = find_rgrp_block(riinode, rgnum); else fprintf(stderr, "Error: File system only has %lld RGs.\n", - (unsigned long long)riinode->i_di.di_size / risize()); + (unsigned long long)riinode->i_di.di_size / + sizeof(struct gfs2_rindex)); inode_put(&riinode); return rgblk; } diff --git a/gfs2/edit/hexedit.h b/gfs2/edit/hexedit.h index 8a3c615..f7b539e 100644 --- a/gfs2/edit/hexedit.h +++ b/gfs2/edit/hexedit.h @@ -21,27 +21,6 @@ enum dsp_mode { HEX_MODE = 0, GFS2_MODE = 1, EXTENDED_MODE = 2, INIT_MODE = 3 }; #define BLOCK_STACK_SIZE 256 -#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 */ - #define pv(struct, member, fmt, fmt2) do { \ print_it(" "#member, fmt, fmt2, struct->member); \ } while (FALSE); @@ -89,71 +68,6 @@ extern int dsplines; extern int dsp_lines[DMODES]; extern int combined_display; -struct gfs_jindex { - uint64_t ji_addr; /* starting block of the journal */ - uint32_t ji_nsegment; /* number (quantity) of segments in journal */ - uint32_t ji_pad; - - char ji_reserved[64]; -}; - -struct gfs_log_descriptor { - struct gfs2_meta_header ld_header; - - uint32_t ld_type; /* GFS_LOG_DESC_... Type of this log chunk */ - uint32_t ld_length; /* Number of buffers in this chunk */ - uint32_t ld_data1; /* descriptor-specific field */ - uint32_t ld_data2; /* descriptor-specific field */ - char ld_reserved[64]; -}; - -struct gfs_log_header { - struct gfs2_meta_header lh_header; - - uint32_t lh_flags; /* GFS_LOG_HEAD_... */ - uint32_t lh_pad; - - uint64_t lh_first; /* Block number of first header in this trans */ - uint64_t lh_sequence; /* Sequence number of this transaction */ - - uint64_t lh_tail; /* Block number of log tail */ - uint64_t lh_last_dump; /* Block number of last dump */ - - char lh_reserved[64]; -}; - -struct gfs_rindex { - uint64_t ri_addr; /* block # of 1st block (header) in rgrp */ - uint32_t ri_length; /* # fs blocks containing rgrp header & bitmap */ - uint32_t ri_pad; - - uint64_t ri_data1; /* block # of first data/meta block in rgrp */ - uint32_t ri_data; /* number (qty) of data/meta blocks in rgrp */ - - uint32_t ri_bitbytes; /* total # bytes used by block alloc bitmap */ - - char ri_reserved[64]; -}; - -struct gfs_rgrp { - struct gfs2_meta_header rg_header; - - uint32_t rg_flags; /* ?? */ - - uint32_t rg_free; /* Number (qty) of free data blocks */ - - /* Dinodes are USEDMETA, but are handled separately from other METAs */ - uint32_t rg_useddi; /* Number (qty) of dinodes (used or free) */ - uint32_t rg_freedi; /* Number (qty) of unused (free) dinodes */ - struct gfs2_inum rg_freedi_list; /* 1st block in chain of free dinodes */ - - /* These META statistics do not include dinodes (used or free) */ - uint32_t rg_usedmeta; /* Number (qty) of used metadata blocks */ - uint32_t rg_freemeta; /* Number (qty) of unused metadata blocks */ - - char rg_reserved[64]; -}; - struct gfs2_dirents { uint64_t block; struct gfs2_dirent dirent; @@ -189,35 +103,6 @@ struct blkstack_info { struct metapath mp; }; -struct gfs_sb { - /* Order is important; need to be able to read old superblocks - in order to support on-disk version upgrades */ - struct gfs2_meta_header sb_header; - - uint32_t sb_fs_format; /* GFS_FORMAT_FS (on-disk version) */ - uint32_t sb_multihost_format; /* GFS_FORMAT_MULTI */ - uint32_t sb_flags; /* ?? */ - - uint32_t sb_bsize; /* fundamental FS block size in bytes */ - uint32_t sb_bsize_shift; /* log2(sb_bsize) */ - uint32_t sb_seg_size; /* Journal segment size in FS blocks */ - - /* These special inodes do not appear in any on-disk directory. */ - struct gfs2_inum sb_jindex_di; /* journal index inode */ - struct gfs2_inum sb_rindex_di; /* resource group index inode */ - struct gfs2_inum sb_root_di; /* root directory inode */ - - /* Default inter-node locking protocol (lock module) and namespace */ - char sb_lockproto[GFS2_LOCKNAME_LEN]; /* lock protocol name */ - char sb_locktable[GFS2_LOCKNAME_LEN]; /* unique name for this FS */ - - /* More special inodes */ - struct gfs2_inum sb_quota_di; /* quota inode */ - struct gfs2_inum sb_license_di; /* license inode */ - - char sb_reserved[96]; -}; - extern struct blkstack_info blockstack[BLOCK_STACK_SIZE]; extern struct iinfo *indirect; /* more than the most indirect pointers possible for any given 4K block */ @@ -226,17 +111,6 @@ extern int indirect_blocks; /* count of indirect blocks */ extern enum dsp_mode dmode; /* ------------------------------------------------------------------------ */ -/* risize - size of one rindex entry, whether gfs1 or gfs2 */ -/* ------------------------------------------------------------------------ */ -static inline int risize(void) -{ - if (sbd.gfs1) - return sizeof(struct gfs_rindex); - else - return sizeof(struct gfs2_rindex); -} - -/* ------------------------------------------------------------------------ */ /* block_is_rglist - there's no such block as the rglist. This is a */ /* special case meant to parse the rindex and follow the */ /* blocks to the real rgs. */ diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h index 6db9d6c..c7d5977 100644 --- a/gfs2/libgfs2/libgfs2.h +++ b/gfs2/libgfs2/libgfs2.h @@ -564,6 +564,100 @@ struct gfs_dinode { char di_reserved[56]; }; +struct gfs_sb { + /* Order is important; need to be able to read old superblocks + in order to support on-disk version upgrades */ + struct gfs2_meta_header sb_header; + + uint32_t sb_fs_format; /* GFS_FORMAT_FS (on-disk version) */ + uint32_t sb_multihost_format; /* GFS_FORMAT_MULTI */ + uint32_t sb_flags; /* ?? */ + + uint32_t sb_bsize; /* fundamental FS block size in bytes */ + uint32_t sb_bsize_shift; /* log2(sb_bsize) */ + uint32_t sb_seg_size; /* Journal segment size in FS blocks */ + + /* These special inodes do not appear in any on-disk directory. */ + struct gfs2_inum sb_jindex_di; /* journal index inode */ + struct gfs2_inum sb_rindex_di; /* resource group index inode */ + struct gfs2_inum sb_root_di; /* root directory inode */ + + /* Default inter-node locking protocol (lock module) and namespace */ + char sb_lockproto[GFS2_LOCKNAME_LEN]; /* lock protocol name */ + char sb_locktable[GFS2_LOCKNAME_LEN]; /* unique name for this FS */ + + /* More special inodes */ + struct gfs2_inum sb_quota_di; /* quota inode */ + struct gfs2_inum sb_license_di; /* license inode */ + + char sb_reserved[96]; +}; + +struct gfs_rgrp { + struct gfs2_meta_header rg_header; + + uint32_t rg_flags; /* ?? */ + + uint32_t rg_free; /* Number (qty) of free data blocks */ + + /* Dinodes are USEDMETA, but are handled separately from other METAs */ + uint32_t rg_useddi; /* Number (qty) of dinodes (used or free) */ + uint32_t rg_freedi; /* Number (qty) of unused (free) dinodes */ + struct gfs2_inum rg_freedi_list; /* 1st block in chain of free dinodes */ + + /* These META statistics do not include dinodes (used or free) */ + uint32_t rg_usedmeta; /* Number (qty) of used metadata blocks */ + uint32_t rg_freemeta; /* Number (qty) of unused metadata blocks */ + + char rg_reserved[64]; +}; + +struct gfs_log_header { + struct gfs2_meta_header lh_header; + + uint32_t lh_flags; /* GFS_LOG_HEAD_... */ + uint32_t lh_pad; + + uint64_t lh_first; /* Block number of first header in this trans */ + uint64_t lh_sequence; /* Sequence number of this transaction */ + + uint64_t lh_tail; /* Block number of log tail */ + uint64_t lh_last_dump; /* Block number of last dump */ + + char lh_reserved[64]; +}; + +struct gfs_rindex { + uint64_t ri_addr; /* block # of 1st block (header) in rgrp */ + uint32_t ri_length; /* # fs blocks containing rgrp header & bitmap */ + uint32_t ri_pad; + + uint64_t ri_data1; /* block # of first data/meta block in rgrp */ + uint32_t ri_data; /* number (qty) of data/meta blocks in rgrp */ + + uint32_t ri_bitbytes; /* total # bytes used by block alloc bitmap */ + + char ri_reserved[64]; +}; + +struct gfs_jindex { + uint64_t ji_addr; /* starting block of the journal */ + uint32_t ji_nsegment; /* number (quantity) of segments in journal */ + uint32_t ji_pad; + + char ji_reserved[64]; +}; + +struct gfs_log_descriptor { + struct gfs2_meta_header ld_header; + + uint32_t ld_type; /* GFS_LOG_DESC_... Type of this log chunk */ + uint32_t ld_length; /* Number of buffers in this chunk */ + uint32_t ld_data1; /* descriptor-specific field */ + uint32_t ld_data2; /* descriptor-specific field */ + char ld_reserved[64]; +}; + extern void gfs1_lookup_block(struct gfs2_inode *ip, struct gfs2_buffer_head *bh, unsigned int height, struct metapath *mp, diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c index 7c9f395..d902ba2 100644 --- a/gfs2/libgfs2/super.c +++ b/gfs2/libgfs2/super.c @@ -143,7 +143,10 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane) { unsigned int rg; int error; - struct gfs2_rindex buf; + union { + struct gfs_rindex bufgfs1; + struct gfs2_rindex bufgfs2; + } buf; struct rgrp_list *rgd, *prev_rgd; uint64_t prev_length = 0; @@ -155,8 +158,14 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane) for (rg = 0; ; rg++) { if (fd > 0) error = read(fd, &buf, sizeof(struct gfs2_rindex)); + else if (sdp->gfs1) + error = gfs1_readi(sdp->md.riinode, + (char *)&buf.bufgfs1, + rg * sizeof(struct gfs2_rindex), + sizeof(struct gfs2_rindex)); else - error = gfs2_readi(sdp->md.riinode, (char *)&buf, + error = gfs2_readi(sdp->md.riinode, + (char *)&buf.bufgfs2, rg * sizeof(struct gfs2_rindex), sizeof(struct gfs2_rindex)); if (!error) @@ -172,23 +181,27 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane) memset(rgd, 0, sizeof(struct rgrp_list)); osi_list_add_prev(&rgd->list, &sdp->rglist); - gfs2_rindex_in(&rgd->ri, (char *)&buf); + gfs2_rindex_in(&rgd->ri, (char *)&buf.bufgfs2); rgd->start = rgd->ri.ri_addr; if (prev_rgd) { /* If rg addresses go backwards, it's not sane (or it's converted from gfs1). */ - if (prev_rgd->start >= rgd->start) - *sane = 0; - /* If rg lengths are not consistent, it's not sane - (or it's converted from gfs1). The first RG will - be a different length due to space allocated for - the superblock, so we can't detect this until - we check rgrp 3, when we can compare the distance - between rgrp 1 and rgrp 2. */ - if (rg > 2 && prev_length && - prev_length != rgd->start - prev_rgd->start) - *sane = 0; + if (!sdp->gfs1) { + if (prev_rgd->start >= rgd->start) + *sane = 0; + /* If rg lengths are not consistent, it's not + sane (or it's converted from gfs1). The + first RG will be a different length due to + space allocated for the superblock, so we + can't detect this until we check rgrp 3, + when we can compare the distance between + rgrp 1 and rgrp 2. */ + if (rg > 2 && prev_length && + prev_length != rgd->start - + prev_rgd->start) + *sane = 0; + } prev_length = rgd->start - prev_rgd->start; prev_rgd->length = prev_length; } -- 1.7.7.5