From 395ff156f65cd961fdf32cc895a67f677c38f0ca Mon Sep 17 00:00:00 2001 From: Packit Service Date: Dec 09 2020 13:59:47 +0000 Subject: Prepare for a new update Reverting patches so we can apply the latest update and changes can be seen in the spec file and sources. --- diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h index 877448c..d3f7635 100644 --- a/gfs2/fsck/fsck.h +++ b/gfs2/fsck/fsck.h @@ -4,8 +4,6 @@ #include "libgfs2.h" #include "osi_tree.h" -#define FSCK_MAX_FORMAT (1801) - #define FSCK_HASH_SHIFT (13) #define FSCK_HASH_SIZE (1 << FSCK_HASH_SHIFT) #define FSCK_HASH_MASK (FSCK_HASH_SIZE - 1) diff --git a/gfs2/fsck/fsck.h.bz1622050-1-fsck_gfs2_Don_t_check_fs_formats_we_don_t_recognise b/gfs2/fsck/fsck.h.bz1622050-1-fsck_gfs2_Don_t_check_fs_formats_we_don_t_recognise deleted file mode 100644 index d3f7635..0000000 --- a/gfs2/fsck/fsck.h.bz1622050-1-fsck_gfs2_Don_t_check_fs_formats_we_don_t_recognise +++ /dev/null @@ -1,200 +0,0 @@ -#ifndef _FSCK_H -#define _FSCK_H - -#include "libgfs2.h" -#include "osi_tree.h" - -#define FSCK_HASH_SHIFT (13) -#define FSCK_HASH_SIZE (1 << FSCK_HASH_SHIFT) -#define FSCK_HASH_MASK (FSCK_HASH_SIZE - 1) - -#define query(fmt, args...) fsck_query(fmt, ##args) - -/* - * Exit codes used by fsck-type programs - * Copied from e2fsck's e2fsck.h - */ -#define FSCK_OK 0 /* No errors */ -#define FSCK_NONDESTRUCT 1 /* File system errors corrected */ -#define FSCK_REBOOT 2 /* System should be rebooted */ -#define FSCK_UNCORRECTED 4 /* File system errors left uncorrected */ -#define FSCK_ERROR 8 /* Operational error */ -#define FSCK_USAGE 16 /* Usage or syntax error */ -#define FSCK_CANCELED 32 /* Aborted with a signal or ^C */ -#define FSCK_LIBRARY 128 /* Shared library error */ - -#define BAD_POINTER_TOLERANCE 10 /* How many bad pointers is too many? */ - -struct gfs2_bmap { - uint64_t size; - uint64_t mapsize; - unsigned char *map; -}; - -struct inode_info -{ - struct osi_node node; - struct gfs2_inum di_num; - uint32_t di_nlink; /* the number of links the inode - * thinks it has */ - uint32_t counted_links; /* the number of links we've found */ -}; - -struct dir_info -{ - struct osi_node node; - struct gfs2_inum dinode; - uint64_t treewalk_parent; - struct gfs2_inum dotdot_parent; - uint32_t di_nlink; - uint32_t counted_links; - uint8_t checked:1; -}; - -struct dir_status { - uint8_t dotdir:1; - uint8_t dotdotdir:1; - int q; - uint32_t entry_count; -}; - -#define DUPFLAG_REF1_FOUND 1 /* Has the original reference been found? */ -#define DUPFLAG_REF1_IS_DUPL 2 /* The original reference is also where we - determined there was a duplicate. */ - -struct duptree { - struct osi_node node; - int dup_flags; - int refs; - uint64_t block; - osi_list_t ref_inode_list; /* list of inodes referencing a dup block */ - osi_list_t ref_invinode_list; /* list of invalid inodes referencing */ -}; - -enum dup_ref_type { - ref_as_data = 0, /* dinode references this block as a data block */ - ref_as_meta = 1, /* dinode references this block as a metadata block */ - ref_as_ea = 2, /* dinode references this block as an extended attr */ - ref_is_inode= 3, /* The reference is itself a dinode. In other words, - it's a dinode, not pointed to as data or - metadata */ - ref_types = 4, -}; - -struct inode_with_dups { - osi_list_t list; - uint64_t block_no; - int dup_count; - int reftypecount[ref_types]; - uint64_t parent; - char *name; -}; - -enum rgindex_trust_level { /* how far can we trust our RG index? */ - blind_faith = 0, /* We'd like to trust the rgindex. We always used to - before bz 179069. This should cover most cases. */ - ye_of_little_faith = 1, /* The rindex seems trustworthy but there's - rg damage that need to be fixed. */ - open_minded = 2, /* At least 1 RG is corrupt. Try to calculate what it - should be, in a perfect world where our RGs are all - on even boundaries. Blue sky. Chirping birds. */ - distrust = 3, /* The world isn't perfect, our RGs are not on nice neat - boundaries. The fs must have been messed with by - gfs2_grow or something. Count the RGs by hand. */ - indignation = 4 /* Not only do we have corruption, but the rgrps - aren't on even boundaries, so this file system - must have been converted from gfs2_convert. */ -}; - -struct error_block { - uint64_t metablk; /* metadata block where error was found */ - int metaoff; /* offset in that metadata block where error found */ - uint64_t errblk; /* error block */ -}; - -extern struct gfs2_inode *fsck_load_inode(struct gfs2_sbd *sdp, uint64_t block); -extern struct gfs2_inode *fsck_inode_get(struct gfs2_sbd *sdp, - struct rgrp_tree *rgd, - struct gfs2_buffer_head *bh); -extern void fsck_inode_put(struct gfs2_inode **ip); - -extern int initialize(struct gfs2_sbd *sdp, int force_check, int preen, - int *all_clean); -extern void destroy(struct gfs2_sbd *sdp); -extern int pass1(struct gfs2_sbd *sdp); -extern int pass1b(struct gfs2_sbd *sdp); -extern int pass1c(struct gfs2_sbd *sdp); -extern int pass2(struct gfs2_sbd *sdp); -extern int pass3(struct gfs2_sbd *sdp); -extern int pass4(struct gfs2_sbd *sdp); -extern int pass5(struct gfs2_sbd *sdp, struct gfs2_bmap *bl); -extern int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, - int *sane); -extern int fsck_query(const char *format, ...) - __attribute__((format(printf,1,2))); -extern struct dir_info *dirtree_find(uint64_t block); -extern void dup_delete(struct duptree *dt); -extern void dirtree_delete(struct dir_info *b); - -/* FIXME: Hack to get this going for pass2 - this should be pulled out - * of pass1 and put somewhere else... */ -struct dir_info *dirtree_insert(struct gfs2_inum inum); - -struct gfs2_options { - char *device; - unsigned int yes:1; - unsigned int no:1; - unsigned int query:1; -}; - -extern struct gfs2_options opts; -extern struct gfs2_inode *lf_dip; /* Lost and found directory inode */ -extern int lf_was_created; -extern uint64_t last_fs_block, last_reported_block; -extern int64_t last_reported_fblock; -extern int skip_this_pass, fsck_abort; -extern int errors_found, errors_corrected; -extern uint64_t last_data_block; -extern uint64_t first_data_block; -extern struct osi_root dup_blocks; -extern struct osi_root dirtree; -extern struct osi_root inodetree; -extern int dups_found; /* How many duplicate references have we found? */ -extern int dups_found_first; /* How many duplicates have we found the original - reference for? */ -extern struct gfs_sb *sbd1; - -static inline int valid_block(struct gfs2_sbd *sdp, uint64_t blkno) -{ - return !((blkno > sdp->fssize) || (blkno <= LGFS2_SB_ADDR(sdp)) || - (lgfs2_get_bitmap(sdp, blkno, NULL) < 0)); -} - -static inline int rgrp_contains_block(struct rgrp_tree *rgd, uint64_t blk) -{ - if (blk < rgd->ri.ri_addr) - return 0; - if (blk >= rgd->ri.ri_data0 + rgd->ri.ri_data) - return 0; - return 1; -} - -static inline int valid_block_ip(struct gfs2_inode *ip, uint64_t blk) -{ - struct gfs2_sbd *sdp = ip->i_sbd; - struct rgrp_tree *rgd = ip->i_rgd; - - if (blk > sdp->fssize) - return 0; - if (blk <= LGFS2_SB_ADDR(sdp)) - return 0; - if (rgd == NULL || !rgrp_contains_block(rgd, blk)) { - rgd = gfs2_blk2rgrpd(sdp, blk); - if (rgd == NULL) - return 0; - } - - return rgrp_contains_block(rgd, blk); -} - -#endif /* _FSCK_H */ diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c index d1c620a..ebe62b9 100644 --- a/gfs2/fsck/initialize.c +++ b/gfs2/fsck/initialize.c @@ -1334,12 +1334,12 @@ static int fill_super_block(struct gfs2_sbd *sdp) if (sizeof(struct gfs2_sb) > sdp->sd_sb.sb_bsize){ log_crit( _("GFS superblock is larger than the blocksize!\n")); log_debug("sizeof(struct gfs2_sb) > sdp->sd_sb.sb_bsize\n"); - return FSCK_ERROR; + return -1; } if (compute_constants(sdp)) { log_crit("%s\n", _("Failed to compute file system constants")); - return FSCK_ERROR; + exit(FSCK_ERROR); } ret = read_sb(sdp); if (ret < 0) { @@ -1348,15 +1348,10 @@ static int fill_super_block(struct gfs2_sbd *sdp) /* Now that we've tried to repair it, re-read it. */ ret = read_sb(sdp); if (ret < 0) - return FSCK_ERROR; + return -1; } if (sdp->gfs1) sbd1 = (struct gfs_sb *)&sdp->sd_sb; - else if (sdp->sd_sb.sb_fs_format > FSCK_MAX_FORMAT) { - log_crit(_("Unsupported gfs2 format found: %"PRIu32"\n"), sdp->sd_sb.sb_fs_format); - log_crit(_("A newer fsck.gfs2 is required to check this file system.\n")); - return FSCK_USAGE; - } return 0; } @@ -1561,7 +1556,6 @@ int initialize(struct gfs2_sbd *sdp, int force_check, int preen, int *all_clean) { int clean_journals = 0, open_flag; - int err; *all_clean = 0; @@ -1607,9 +1601,8 @@ int initialize(struct gfs2_sbd *sdp, int force_check, int preen, } /* read in sb from disk */ - err = fill_super_block(sdp); - if (err != FSCK_OK) - return err; + if (fill_super_block(sdp)) + return FSCK_ERROR; /* Change lock protocol to be fsck_* instead of lock_* */ if (!opts.no && preen_is_safe(sdp, preen, force_check)) { diff --git a/gfs2/fsck/initialize.c.bz1622050-1-fsck_gfs2_Don_t_check_fs_formats_we_don_t_recognise b/gfs2/fsck/initialize.c.bz1622050-1-fsck_gfs2_Don_t_check_fs_formats_we_don_t_recognise deleted file mode 100644 index ebe62b9..0000000 --- a/gfs2/fsck/initialize.c.bz1622050-1-fsck_gfs2_Don_t_check_fs_formats_we_don_t_recognise +++ /dev/null @@ -1,1713 +0,0 @@ -#include "clusterautoconfig.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define _(String) gettext(String) - -#include -#include "libgfs2.h" -#include "fsck.h" -#include "util.h" -#include "fs_recovery.h" -#include "metawalk.h" -#include "inode_hash.h" - -#define CLEAR_POINTER(x) \ - if (x) { \ - free(x); \ - x = NULL; \ - } -#define HIGHEST_BLOCK 0xffffffffffffffff - -static int was_mounted_ro = 0; -static uint64_t possible_root = HIGHEST_BLOCK; -static struct master_dir fix_md; -static unsigned long long blks_2free = 0; -extern int sb_fixed; - -/** - * block_mounters - * - * Change the lock protocol so nobody can mount the fs - * - */ -static int block_mounters(struct gfs2_sbd *sdp, int block_em) -{ - if (block_em) { - /* verify it starts with lock_ */ - if (!strncmp(sdp->sd_sb.sb_lockproto, "lock_", 5)) { - /* Change lock_ to fsck_ */ - memcpy(sdp->sd_sb.sb_lockproto, "fsck_", 5); - } - /* FIXME: Need to do other verification in the else - * case */ - } else { - /* verify it starts with fsck_ */ - /* verify it starts with lock_ */ - if (!strncmp(sdp->sd_sb.sb_lockproto, "fsck_", 5)) { - /* Change fsck_ to lock_ */ - memcpy(sdp->sd_sb.sb_lockproto, "lock_", 5); - } - } - - if (lgfs2_sb_write(&sdp->sd_sb, sdp->device_fd, sdp->bsize)) { - stack; - return -1; - } - return 0; -} - -static void gfs2_dup_free(void) -{ - struct osi_node *n; - struct duptree *dt; - - while ((n = osi_first(&dup_blocks))) { - dt = (struct duptree *)n; - dup_delete(dt); - } -} - -static void gfs2_dirtree_free(void) -{ - struct osi_node *n; - struct dir_info *dt; - - while ((n = osi_first(&dirtree))) { - dt = (struct dir_info *)n; - dirtree_delete(dt); - } -} - -static void gfs2_inodetree_free(void) -{ - struct osi_node *n; - struct inode_info *dt; - - while ((n = osi_first(&inodetree))) { - dt = (struct inode_info *)n; - inodetree_delete(dt); - } -} - -/* - * empty_super_block - free all structures in the super block - * sdp: the in-core super block - * - * This function frees all allocated structures within the - * super block. It does not free the super block itself. - * - * Returns: Nothing - */ -static void empty_super_block(struct gfs2_sbd *sdp) -{ - log_info( _("Freeing buffers.\n")); - gfs2_rgrp_free(&sdp->rgtree); - - gfs2_inodetree_free(); - gfs2_dirtree_free(); - gfs2_dup_free(); -} - - -/** - * set_block_ranges - * @sdp: superblock - * - * Uses info in rgrps and jindex to determine boundaries of the - * file system. - * - * Returns: 0 on success, -1 on failure - */ -static int set_block_ranges(struct gfs2_sbd *sdp) -{ - struct osi_node *n, *next = NULL; - struct rgrp_tree *rgd; - struct gfs2_rindex *ri; - char buf[sdp->sd_sb.sb_bsize]; - uint64_t rmax = 0; - uint64_t rmin = 0; - int error; - - log_info( _("Setting block ranges...")); - - for (n = osi_first(&sdp->rgtree); n; n = next) { - next = osi_next(n); - rgd = (struct rgrp_tree *)n; - ri = &rgd->ri; - if (ri->ri_data0 + ri->ri_data && - ri->ri_data0 + ri->ri_data - 1 > rmax) - rmax = ri->ri_data0 + ri->ri_data - 1; - if (!rmin || ri->ri_data0 < rmin) - rmin = ri->ri_data0; - } - - last_fs_block = rmax; - if (last_fs_block > 0xffffffff && sizeof(unsigned long) <= 4) { - log_crit( _("This file system is too big for this computer to handle.\n")); - log_crit( _("Last fs block = 0x%llx, but sizeof(unsigned long) is %zu bytes.\n"), - (unsigned long long)last_fs_block, - sizeof(unsigned long)); - goto fail; - } - - last_data_block = rmax; - first_data_block = rmin; - - if (fsck_lseek(sdp->device_fd, (last_fs_block * sdp->sd_sb.sb_bsize))){ - log_crit( _("Can't seek to last block in file system: %llu" - " (0x%llx)\n"), (unsigned long long)last_fs_block, - (unsigned long long)last_fs_block); - goto fail; - } - - memset(buf, 0, sdp->sd_sb.sb_bsize); - error = read(sdp->device_fd, buf, sdp->sd_sb.sb_bsize); - if (error != sdp->sd_sb.sb_bsize){ - log_crit( _("Can't read last block in file system (error %u), " - "last_fs_block: %llu (0x%llx)\n"), error, - (unsigned long long)last_fs_block, - (unsigned long long)last_fs_block); - goto fail; - } - - log_info(_("0x%llx to 0x%llx\n"), (unsigned long long)first_data_block, - (unsigned long long)last_data_block); - return 0; - - fail: - log_info( _("Error\n")); - return -1; -} - -/** - * check_rgrp_integrity - verify a rgrp free block count against the bitmap - */ -static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_tree *rgd, - int *fixit, int *this_rg_fixed, - int *this_rg_bad, int *this_rg_cleaned) -{ - uint32_t rg_free, rg_reclaimed, rg_unlinked, rg_usedmeta, rg_useddi; - int rgb, x, y, off, bytes_to_check, total_bytes_to_check, asked = 0; - unsigned int state; - struct gfs_rgrp *gfs1rg = (struct gfs_rgrp *)&rgd->rg; - uint64_t diblock; - struct gfs2_buffer_head *bh; - - rg_free = rg_reclaimed = rg_unlinked = rg_usedmeta = rg_useddi = 0; - total_bytes_to_check = rgd->ri.ri_bitbytes; - - *this_rg_fixed = *this_rg_bad = *this_rg_cleaned = 0; - - diblock = rgd->ri.ri_data0; - for (rgb = 0; rgb < rgd->ri.ri_length; rgb++){ - /* Count up the free blocks in the bitmap */ - off = (rgb) ? sizeof(struct gfs2_meta_header) : - sizeof(struct gfs2_rgrp); - if (total_bytes_to_check <= sdp->bsize - off) - bytes_to_check = total_bytes_to_check; - else - bytes_to_check = sdp->bsize - off; - total_bytes_to_check -= bytes_to_check; - for (x = 0; x < bytes_to_check; x++) { - unsigned char *byte; - - byte = (unsigned char *)&rgd->bits[rgb].bi_bh->b_data[off + x]; - if (*byte == 0x55) { - diblock += GFS2_NBBY; - continue; - } - if (*byte == 0x00) { - diblock += GFS2_NBBY; - rg_free += GFS2_NBBY; - continue; - } - for (y = 0; y < GFS2_NBBY; y++) { - state = (*byte >> - (GFS2_BIT_SIZE * y)) & GFS2_BIT_MASK; - if (state == GFS2_BLKST_USED) { - diblock++; - continue; - } - if (state == GFS2_BLKST_DINODE) { - if (sdp->gfs1) { - bh = bread(sdp, diblock); - if (!gfs2_check_meta(bh, - GFS2_METATYPE_DI)) - rg_useddi++; - else - rg_usedmeta++; - brelse(bh); - } - diblock++; - continue; - } - if (state == GFS2_BLKST_FREE) { - diblock++; - rg_free++; - continue; - } - /* GFS2_BLKST_UNLINKED */ - if (sdp->gfs1) - log_info(_("Free metadata block 0x%llx" - " found.\n"), - (unsigned long long)diblock); - else - log_info(_("Unlinked dinode 0x%llx " - "found.\n"), - (unsigned long long)diblock); - if (!asked) { - char msg[256]; - - asked = 1; - sprintf(msg, - _("Okay to reclaim free " - "metadata in resource group " - "%lld (0x%llx)? (y/n)"), - (unsigned long long)rgd->ri.ri_addr, - (unsigned long long)rgd->ri.ri_addr); - if (query("%s", msg)) - *fixit = 1; - } - if (!(*fixit)) { - rg_unlinked++; - diblock++; - continue; - } - *byte &= ~(GFS2_BIT_MASK << - (GFS2_BIT_SIZE * y)); - bmodified(rgd->bits[rgb].bi_bh); - rg_reclaimed++; - rg_free++; - rgd->rg.rg_free++; - if (sdp->gfs1 && gfs1rg->rg_freemeta) - gfs1rg->rg_freemeta--; - log_info(_("Free metadata block %lld (0x%llx) " - "reclaimed.\n"), - (unsigned long long)diblock, - (unsigned long long)diblock); - bh = bread(sdp, diblock); - if (!gfs2_check_meta(bh, GFS2_METATYPE_DI)) { - struct gfs2_inode *ip = - fsck_inode_get(sdp, rgd, bh); - if (ip->i_di.di_blocks > 1) { - blks_2free += - ip->i_di.di_blocks - 1; - log_info(_("%lld blocks " - "(total) may need " - "to be freed in " - "pass 5.\n"), - blks_2free); - } - fsck_inode_put(&ip); - } - brelse(bh); - diblock++; - } - } - } - /* The unlinked blocks we reclaim shouldn't be considered errors, - since we're just reclaiming them as a courtesy. If we already - got permission to reclaim them, we adjust the rgrp counts - accordingly. That way, only "real" rgrp count inconsistencies - will be reported. */ - if (rg_reclaimed && *fixit) { - if (sdp->gfs1) - gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bits[0].bi_bh); - else - gfs2_rgrp_out(&rgd->rg, rgd->bits[0].bi_bh->b_data); - bmodified(rgd->bits[0].bi_bh); - *this_rg_cleaned = 1; - log_info( _("The rgrp at %lld (0x%llx) was cleaned of %d " - "free metadata blocks.\n"), - (unsigned long long)rgd->ri.ri_addr, - (unsigned long long)rgd->ri.ri_addr, - rg_reclaimed); - } - if (rgd->rg.rg_free != rg_free) { - *this_rg_bad = 1; - *this_rg_cleaned = 0; - log_err( _("Error: resource group %lld (0x%llx): " - "free space (%d) does not match bitmap (%d)\n"), - (unsigned long long)rgd->ri.ri_addr, - (unsigned long long)rgd->ri.ri_addr, - rgd->rg.rg_free, rg_free); - if (query( _("Fix the rgrp free blocks count? (y/n)"))) { - rgd->rg.rg_free = rg_free; - if (sdp->gfs1) - gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bits[0].bi_bh); - else - gfs2_rgrp_out(&rgd->rg, rgd->bits[0].bi_bh->b_data); - bmodified(rgd->bits[0].bi_bh); - *this_rg_fixed = 1; - log_err( _("The rgrp was fixed.\n")); - } else - log_err( _("The rgrp was not fixed.\n")); - } - if (!sdp->gfs1) - return; - - if (gfs1rg->rg_freemeta != rg_unlinked) { - *this_rg_bad = 1; - *this_rg_cleaned = 0; - log_err( _("Error: resource group %lld (0x%llx): " - "free meta (%d) does not match bitmap (%d)\n"), - (unsigned long long)rgd->ri.ri_addr, - (unsigned long long)rgd->ri.ri_addr, - gfs1rg->rg_freemeta, rg_unlinked); - if (query( _("Fix the rgrp free meta blocks count? (y/n)"))) { - gfs1rg->rg_freemeta = rg_unlinked; - gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bits[0].bi_bh); - *this_rg_fixed = 1; - log_err( _("The rgrp was fixed.\n")); - } else - log_err( _("The rgrp was not fixed.\n")); - } - if (gfs1rg->rg_useddi != rg_useddi) { - *this_rg_bad = 1; - *this_rg_cleaned = 0; - log_err( _("Error: resource group %lld (0x%llx): used dinode " - "count (%d) does not match bitmap (%d)\n"), - (unsigned long long)rgd->ri.ri_addr, - (unsigned long long)rgd->ri.ri_addr, - gfs1rg->rg_useddi, rg_useddi); - if (query( _("Fix the rgrp used dinode block count? (y/n)"))) { - gfs1rg->rg_useddi = rg_useddi; - gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, - rgd->bits[0].bi_bh); - *this_rg_fixed = 1; - log_err( _("The rgrp was fixed.\n")); - } else - log_err( _("The rgrp was not fixed.\n")); - } - if (gfs1rg->rg_usedmeta != rg_usedmeta) { - *this_rg_bad = 1; - *this_rg_cleaned = 0; - log_err( _("Error: resource group %lld (0x%llx): used " - "metadata (%d) does not match bitmap (%d)\n"), - (unsigned long long)rgd->ri.ri_addr, - (unsigned long long)rgd->ri.ri_addr, - gfs1rg->rg_usedmeta, rg_usedmeta); - if (query( _("Fix the rgrp used meta blocks count? (y/n)"))) { - gfs1rg->rg_usedmeta = rg_usedmeta; - gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, - rgd->bits[0].bi_bh); - *this_rg_fixed = 1; - log_err( _("The rgrp was fixed.\n")); - } else - log_err( _("The rgrp was not fixed.\n")); - } - /* - else { - log_debug( _("Resource group %lld (0x%llx) free space " - "is consistent: free: %d reclaimed: %d\n"), - (unsigned long long)rgd->ri.ri_addr, - (unsigned long long)rgd->ri.ri_addr, - rg_free, rg_reclaimed); - }*/ -} - -/** - * check_rgrps_integrity - verify rgrp consistency - * Note: We consider an rgrp "cleaned" if the unlinked meta blocks are - * cleaned, so not quite "bad" and not quite "good" but rewritten anyway. - * - * Returns: 0 on success, 1 if errors were detected - */ -static void check_rgrps_integrity(struct gfs2_sbd *sdp) -{ - struct osi_node *n, *next = NULL; - int rgs_good = 0, rgs_bad = 0, rgs_fixed = 0, rgs_cleaned = 0; - int was_bad = 0, was_fixed = 0, was_cleaned = 0; - struct rgrp_tree *rgd; - int reclaim_unlinked = 0; - - log_info( _("Checking the integrity of all resource groups.\n")); - for (n = osi_first(&sdp->rgtree); n; n = next) { - next = osi_next(n); - rgd = (struct rgrp_tree *)n; - if (fsck_abort) - return; - check_rgrp_integrity(sdp, rgd, &reclaim_unlinked, - &was_fixed, &was_bad, &was_cleaned); - if (was_fixed) - rgs_fixed++; - if (was_cleaned) - rgs_cleaned++; - else if (was_bad) - rgs_bad++; - else - rgs_good++; - } - if (rgs_bad || rgs_cleaned) { - log_err( _("RGs: Consistent: %d Cleaned: %d Inconsistent: " - "%d Fixed: %d Total: %d\n"), - rgs_good, rgs_cleaned, rgs_bad, rgs_fixed, - rgs_good + rgs_bad + rgs_cleaned); - if (rgs_cleaned && blks_2free) - log_err(_("%lld blocks may need to be freed in pass 5 " - "due to the cleaned resource groups.\n"), - blks_2free); - } -} - -/** - * rebuild_master - rebuild a destroyed master directory - */ -static int rebuild_master(struct gfs2_sbd *sdp) -{ - struct gfs2_inum inum; - struct gfs2_buffer_head *bh = NULL; - int err = 0; - - log_err(_("The system master directory seems to be destroyed.\n")); - if (!query(_("Okay to rebuild it? (y/n)"))) { - log_err(_("System master not rebuilt; aborting.\n")); - return -1; - } - log_err(_("Trying to rebuild the master directory.\n")); - inum.no_formal_ino = sdp->md.next_inum++; - inum.no_addr = sdp->sd_sb.sb_master_dir.no_addr; - err = init_dinode(sdp, &bh, &inum, S_IFDIR | 0755, GFS2_DIF_SYSTEM, &inum); - if (err != 0) - return -1; - sdp->master_dir = lgfs2_inode_get(sdp, bh); - if (sdp->master_dir == NULL) { - log_crit(_("Error reading master: %s\n"), strerror(errno)); - return -1; - } - sdp->master_dir->bh_owned = 1; - - if (fix_md.jiinode) { - inum.no_formal_ino = sdp->md.next_inum++; - inum.no_addr = fix_md.jiinode->i_di.di_num.no_addr; - err = dir_add(sdp->master_dir, "jindex", 6, &inum, - IF2DT(S_IFDIR | 0700)); - if (err) { - log_crit(_("Error %d adding jindex directory\n"), errno); - exit(FSCK_ERROR); - } - sdp->master_dir->i_di.di_nlink++; - } else { - err = build_jindex(sdp); - if (err) { - log_crit(_("Error %d building jindex\n"), err); - exit(FSCK_ERROR); - } - } - - if (fix_md.pinode) { - inum.no_formal_ino = sdp->md.next_inum++; - inum.no_addr = fix_md.pinode->i_di.di_num.no_addr; - err = dir_add(sdp->master_dir, "per_node", 8, &inum, - IF2DT(S_IFDIR | 0700)); - if (err) { - log_crit(_("Error %d adding per_node directory\n"), - errno); - exit(FSCK_ERROR); - } - sdp->master_dir->i_di.di_nlink++; - } else { - err = build_per_node(sdp); - if (err) { - log_crit(_("Error %d building per_node directory\n"), - err); - exit(FSCK_ERROR); - } - } - - if (fix_md.inum) { - inum.no_formal_ino = sdp->md.next_inum++; - inum.no_addr = fix_md.inum->i_di.di_num.no_addr; - err = dir_add(sdp->master_dir, "inum", 4, &inum, - IF2DT(S_IFREG | 0600)); - if (err) { - log_crit(_("Error %d adding inum inode\n"), errno); - exit(FSCK_ERROR); - } - } else { - err = build_inum(sdp); - if (err) { - log_crit(_("Error %d building inum inode\n"), err); - exit(FSCK_ERROR); - } - gfs2_lookupi(sdp->master_dir, "inum", 4, &sdp->md.inum); - } - - if (fix_md.statfs) { - inum.no_formal_ino = sdp->md.next_inum++; - inum.no_addr = fix_md.statfs->i_di.di_num.no_addr; - err = dir_add(sdp->master_dir, "statfs", 6, &inum, - IF2DT(S_IFREG | 0600)); - if (err) { - log_crit(_("Error %d adding statfs inode\n"), errno); - exit(FSCK_ERROR); - } - } else { - err = build_statfs(sdp); - if (err) { - log_crit(_("Error %d building statfs inode\n"), err); - exit(FSCK_ERROR); - } - gfs2_lookupi(sdp->master_dir, "statfs", 6, &sdp->md.statfs); - } - - if (fix_md.riinode) { - inum.no_formal_ino = sdp->md.next_inum++; - inum.no_addr = fix_md.riinode->i_di.di_num.no_addr; - err = dir_add(sdp->master_dir, "rindex", 6, &inum, - IF2DT(S_IFREG | 0600)); - if (err) { - log_crit(_("Error %d adding rindex inode\n"), errno); - exit(FSCK_ERROR); - } - } else { - err = build_rindex(sdp); - if (err) { - log_crit(_("Error %d building rindex inode\n"), err); - exit(FSCK_ERROR); - } - } - - if (fix_md.qinode) { - inum.no_formal_ino = sdp->md.next_inum++; - inum.no_addr = fix_md.qinode->i_di.di_num.no_addr; - err = dir_add(sdp->master_dir, "quota", 5, &inum, - IF2DT(S_IFREG | 0600)); - if (err) { - log_crit(_("Error %d adding quota inode\n"), errno); - exit(FSCK_ERROR); - } - } else { - err = build_quota(sdp); - if (err) { - log_crit(_("Error %d building quota inode\n"), err); - exit(FSCK_ERROR); - } - } - - log_err(_("Master directory rebuilt.\n")); - inode_put(&sdp->md.inum); - inode_put(&sdp->md.statfs); - inode_put(&sdp->master_dir); - return 0; -} - -/** - * lookup_per_node - Make sure the per_node directory is read in - * - * This function is used to read in the per_node directory. It is called - * twice. The first call tries to read in the dinode early on. That ensures - * that if any journals are missing, we can figure out the number of journals - * from per_node. However, we unfortunately can't rebuild per_node at that - * point in time because our resource groups aren't read in yet. - * The second time it's called is much later when we can rebuild it. - * - * allow_rebuild: 0 if rebuilds are not allowed - * 1 if rebuilds are allowed - */ -static void lookup_per_node(struct gfs2_sbd *sdp, int allow_rebuild) -{ - if (sdp->md.pinode) - return; - - gfs2_lookupi(sdp->master_dir, "per_node", 8, &sdp->md.pinode); - if (sdp->md.pinode) - return; - if (!allow_rebuild) { - log_err( _("The gfs2 system per_node directory " - "inode is missing, so we might not be \nable to " - "rebuild missing journals this run.\n")); - return; - } - - if (query( _("The gfs2 system per_node directory " - "inode is missing. Okay to rebuild it? (y/n) "))) { - int err; - - err = build_per_node(sdp); - if (err) { - log_crit(_("Error %d rebuilding per_node directory\n"), - err); - exit(FSCK_ERROR); - } - } - gfs2_lookupi(sdp->master_dir, "per_node", 8, &sdp->md.pinode); - if (!sdp->md.pinode) { - log_err( _("Unable to rebuild per_node; aborting.\n")); - exit(FSCK_ERROR); - } -} - -/** - * fetch_rgrps - fetch the resource groups from disk, and check their integrity - */ -static int fetch_rgrps(struct gfs2_sbd *sdp) -{ - enum rgindex_trust_level trust_lvl; - int rgcount, sane = 1; - - const char *level_desc[] = { - _("Checking if all rgrp and rindex values are good"), - _("Checking if rindex values may be easily repaired"), - _("Calculating where the rgrps should be if evenly spaced"), - _("Trying to rebuild rindex assuming evenly spaced rgrps"), - _("Trying to rebuild rindex assuming unevenly spaced rgrps"), - }; - const char *fail_desc[] = { - _("Some damage was found; we need to take remedial measures"), - _("rindex is unevenly spaced: either gfs1-style or corrupt"), - _("rindex calculations don't match: uneven rgrp boundaries"), - _("Too many rgrp misses: rgrps must be unevenly spaced"), - _("Too much damage found: we cannot rebuild this rindex"), - }; - /******************************************************************* - ******** Validate and read in resource group information ******** - *******************************************************************/ - log_notice(_("Validating resource group index.\n")); - for (trust_lvl = blind_faith; trust_lvl <= indignation; trust_lvl++) { - int ret = 0; - - log_notice(_("Level %d resource group check: %s.\n"), trust_lvl + 1, - level_desc[trust_lvl]); - if ((rg_repair(sdp, trust_lvl, &rgcount, &sane) == 0) && - ((ret = ri_update(sdp, 0, &rgcount, &sane)) == 0)) { - log_notice(_("(level %d passed)\n"), trust_lvl + 1); - break; - } else { - if (ret == -1) - log_err( _("(level %d failed: %s)\n"), - trust_lvl + 1, fail_desc[trust_lvl]); - else - log_err( _("(level %d failed at block %lld " - "(0x%llx): %s)\n"), trust_lvl + 1, - (unsigned long long)ret, - (unsigned long long)ret, - fail_desc[trust_lvl]); - } - if (fsck_abort) - break; - } - if (trust_lvl > indignation) { - log_err( _("Resource group recovery impossible; I can't fix " - "this file system.\n")); - return -1; - } - log_info( _("%u resource groups found.\n"), rgcount); - - check_rgrps_integrity(sdp); - return 0; -} - -/** - * init_system_inodes - * - * Returns: 0 on success, -1 on failure - */ -static int init_system_inodes(struct gfs2_sbd *sdp) -{ - uint64_t inumbuf = 0; - char *buf; - struct gfs2_statfs_change sc; - int err; - - /******************************************************************* - ****************** Initialize important inodes ****************** - *******************************************************************/ - - log_info( _("Initializing special inodes...\n")); - - /* Get root dinode */ - sdp->md.rooti = lgfs2_inode_read(sdp, sdp->sd_sb.sb_root_dir.no_addr); - if (sdp->md.rooti == NULL) - return -1; - - /******************************************************************* - ***************** Initialize more system inodes ***************** - *******************************************************************/ - if (!sdp->gfs1) { - /* Look for "inum" entry in master dinode */ - gfs2_lookupi(sdp->master_dir, "inum", 4, &sdp->md.inum); - if (!sdp->md.inum) { - if (!query( _("The gfs2 system inum inode is missing. " - "Okay to rebuild it? (y/n) "))) { - log_err( _("fsck.gfs2 cannot continue without " - "a valid inum file; aborting.\n")); - goto fail; - } - err = build_inum(sdp); - if (err) { - log_crit(_("Error %d rebuilding inum inode\n"), - err); - exit(FSCK_ERROR); - } - gfs2_lookupi(sdp->master_dir, "inum", 4, - &sdp->md.inum); - if (!sdp->md.inum) { - log_crit(_("System inum inode was not rebuilt." - " Aborting.\n")); - goto fail; - } - } - /* Read inum entry into buffer */ - err = gfs2_readi(sdp->md.inum, &inumbuf, 0, - sdp->md.inum->i_di.di_size); - if (err != sdp->md.inum->i_di.di_size) { - log_crit(_("Error %d reading system inum inode. " - "Aborting.\n"), err); - goto fail; - } - /* call gfs2_inum_range_in() to retrieve range */ - sdp->md.next_inum = be64_to_cpu(inumbuf); - } - - if (sdp->gfs1) { - /* In gfs1, the license_di is always 3 blocks after the jindex_di */ - if ((sbd1->sb_license_di.no_addr != sbd1->sb_jindex_di.no_addr + 3) || - (sbd1->sb_license_di.no_formal_ino != sbd1->sb_jindex_di.no_addr + 3)) { - if (!query( _("The gfs system statfs inode pointer is incorrect. " - "Okay to correct? (y/n) "))) { - log_err( _("fsck.gfs2 cannot continue without a valid " - "statfs file; aborting.\n")); - goto fail; - } - sbd1->sb_license_di.no_addr = sbd1->sb_license_di.no_formal_ino - = sbd1->sb_jindex_di.no_addr + 3; - } - - sdp->md.statfs = lgfs2_inode_read(sdp, sbd1->sb_license_di.no_addr); - if (sdp->md.statfs == NULL) { - log_crit(_("Error reading statfs inode: %s\n"), strerror(errno)); - goto fail; - } - } else - gfs2_lookupi(sdp->master_dir, "statfs", 6, &sdp->md.statfs); - if (!sdp->gfs1 && !sdp->md.statfs) { - if (!query( _("The gfs2 system statfs inode is missing. " - "Okay to rebuild it? (y/n) "))) { - log_err( _("fsck.gfs2 cannot continue without a valid " - "statfs file; aborting.\n")); - goto fail; - } - err = build_statfs(sdp); - if (err) { - log_crit(_("Error %d rebuilding statfs inode\n"), err); - exit(FSCK_ERROR); - } - gfs2_lookupi(sdp->master_dir, "statfs", 6, &sdp->md.statfs); - if (!sdp->md.statfs) { - log_err( _("Rebuild of statfs system file failed.")); - log_err( _("fsck.gfs2 cannot continue without " - "a valid statfs file; aborting.\n")); - goto fail; - } - do_init_statfs(sdp); - } - if (sdp->md.statfs->i_di.di_size) { - buf = malloc(sdp->md.statfs->i_di.di_size); - if (buf) { - err = gfs2_readi(sdp->md.statfs, buf, 0, - sdp->md.statfs->i_di.di_size); - if (err != sdp->md.statfs->i_di.di_size) { - log_crit(_("Error %d reading statfs file. " - "Aborting.\n"), err); - free(buf); - goto fail; - } - /* call gfs2_inum_range_in() to retrieve range */ - gfs2_statfs_change_in(&sc, buf); - free(buf); - } - } - - if (sdp->gfs1) { - /* In gfs1, the quota_di is always 2 blocks after the jindex_di */ - if ((sbd1->sb_quota_di.no_addr != sbd1->sb_jindex_di.no_addr + 2) || - (sbd1->sb_quota_di.no_formal_ino != sbd1->sb_jindex_di.no_addr + 2)) { - if (!query( _("The gfs system quota inode pointer is incorrect. " - " Okay to correct? (y/n) "))) { - log_err( _("fsck.gfs2 cannot continue without a valid " - "quota file; aborting.\n")); - goto fail; - } - sbd1->sb_quota_di.no_addr = sbd1->sb_quota_di.no_formal_ino - = sbd1->sb_jindex_di.no_addr + 2; - } - - sdp->md.qinode = lgfs2_inode_read(sdp, sbd1->sb_quota_di.no_addr); - if (sdp->md.qinode == NULL) { - log_crit(_("Error reading quota inode: %s\n"), strerror(errno)); - goto fail; - } - } else - gfs2_lookupi(sdp->master_dir, "quota", 5, &sdp->md.qinode); - if (!sdp->gfs1 && !sdp->md.qinode) { - if (!query( _("The gfs2 system quota inode is missing. " - "Okay to rebuild it? (y/n) "))) { - log_crit(_("System quota inode was not " - "rebuilt. Aborting.\n")); - goto fail; - } - err = build_quota(sdp); - if (err) { - log_crit(_("Error %d rebuilding quota inode\n"), err); - exit(FSCK_ERROR); - } - gfs2_lookupi(sdp->master_dir, "quota", 5, &sdp->md.qinode); - if (!sdp->md.qinode) { - log_crit(_("Unable to rebuild system quota file " - "inode. Aborting.\n")); - goto fail; - } - } - - /* Try to lookup the per_node inode. If it was missing, it is now - safe to rebuild it. */ - if (!sdp->gfs1) - lookup_per_node(sdp, 1); - - /******************************************************************* - ******* Now, set boundary fields in the super block ************* - *******************************************************************/ - if (set_block_ranges(sdp)){ - log_err( _("Unable to determine the boundaries of the" - " file system.\n")); - goto fail; - } - - return 0; - fail: - empty_super_block(sdp); - - return -1; -} - -/** - * is_journal_copy - Is this a "real" dinode or a copy inside a journal? - * A real dinode will be located at the block number in its no_addr. - * A journal-copy will be at a different block (inside the journal). - */ -static int is_journal_copy(struct gfs2_inode *ip, struct gfs2_buffer_head *bh) -{ - if (ip->i_di.di_num.no_addr == bh->b_blocknr) - return 0; - return 1; /* journal copy */ -} - -/** - * peruse_system_dinode - process a system dinode - * - * This function looks at a system dinode and tries to figure out which - * dinode it is: statfs, inum, per_node, master, etc. Some of them we - * can deduce from the contents. For example, di_size will be a multiple - * of 96 for the rindex. di_size will be 8 for inum, 24 for statfs, etc. - * the per_node directory will have a ".." entry that will lead us to - * the master dinode if it's been destroyed. - */ -static void peruse_system_dinode(struct gfs2_sbd *sdp, struct gfs2_dinode *di, - struct gfs2_buffer_head *bh) -{ - struct gfs2_inode *ip, *child_ip; - struct gfs2_inum inum; - int error; - - if (di->di_num.no_formal_ino == 2) { - if (sdp->sd_sb.sb_master_dir.no_addr) - return; - log_warn(_("Found system master directory at: 0x%llx.\n"), - di->di_num.no_addr); - sdp->sd_sb.sb_master_dir.no_addr = di->di_num.no_addr; - return; - } - ip = lgfs2_inode_read(sdp, di->di_num.no_addr); - if (ip == NULL) { - log_crit(_("Error reading inode: %s\n"), strerror(errno)); - return; - } - if ((!sdp->gfs1 && di->di_num.no_formal_ino == 3) || - (sdp->gfs1 && (di->di_flags & GFS2_DIF_JDATA) && - (di->di_size % sizeof(struct gfs_jindex) == 0))) { - if (fix_md.jiinode || is_journal_copy(ip, bh)) - goto out_discard_ip; - log_warn(_("Found system jindex file at: 0x%llx\n"), - di->di_num.no_addr); - fix_md.jiinode = ip; - } else if (!sdp->gfs1 && is_dir(di, sdp->gfs1)) { - /* Check for a jindex dir entry. Only one system dir has a - jindex: master */ - gfs2_lookupi(ip, "jindex", 6, &child_ip); - if (child_ip) { - if (fix_md.jiinode || is_journal_copy(ip, bh)) { - inode_put(&child_ip); - goto out_discard_ip; - } - fix_md.jiinode = child_ip; - sdp->sd_sb.sb_master_dir.no_addr = di->di_num.no_addr; - log_warn(_("Found system master directory at: " - "0x%llx\n"), di->di_num.no_addr); - return; - } - - /* Check for a statfs_change0 dir entry. Only one system dir - has a statfs_change: per_node, and its .. will be master. */ - gfs2_lookupi(ip, "statfs_change0", 14, &child_ip); - if (child_ip) { - inode_put(&child_ip); - if (fix_md.pinode || is_journal_copy(ip, bh)) - goto out_discard_ip; - log_warn(_("Found system per_node directory at: " - "0x%llx\n"), ip->i_di.di_num.no_addr); - fix_md.pinode = ip; - error = dir_search(ip, "..", 2, NULL, &inum); - if (!error && inum.no_addr) { - sdp->sd_sb.sb_master_dir.no_addr = - inum.no_addr; - log_warn(_("From per_node\'s \'..\' I " - "backtracked the master directory " - "to: 0x%llx\n"), inum.no_addr); - } - return; - } - log_debug(_("Unknown system directory at block 0x%llx\n"), - di->di_num.no_addr); - goto out_discard_ip; - } else if (!sdp->gfs1 && di->di_size == 8) { - if (fix_md.inum || is_journal_copy(ip, bh)) - goto out_discard_ip; - fix_md.inum = ip; - log_warn(_("Found system inum file at: 0x%llx\n"), - di->di_num.no_addr); - } else if (di->di_size == 24) { - if (fix_md.statfs || is_journal_copy(ip, bh)) - goto out_discard_ip; - fix_md.statfs = ip; - log_warn(_("Found system statfs file at: 0x%llx\n"), - di->di_num.no_addr); - } else if ((di->di_size % 96) == 0) { - if (fix_md.riinode || is_journal_copy(ip, bh)) - goto out_discard_ip; - fix_md.riinode = ip; - log_warn(_("Found system rindex file at: 0x%llx\n"), - di->di_num.no_addr); - } else if (!fix_md.qinode && di->di_size >= 176 && - di->di_num.no_formal_ino >= 12 && - di->di_num.no_formal_ino <= 100) { - if (is_journal_copy(ip, bh)) - goto out_discard_ip; - fix_md.qinode = ip; - log_warn(_("Found system quota file at: 0x%llx\n"), - di->di_num.no_addr); - } else { -out_discard_ip: - inode_put(&ip); - } -} - -/** - * peruse_user_dinode - process a user dinode trying to find the root directory - * - */ -static void peruse_user_dinode(struct gfs2_sbd *sdp, struct gfs2_dinode *di, - struct gfs2_buffer_head *bh) -{ - struct gfs2_inode *ip, *parent_ip; - struct gfs2_inum inum; - int error; - - if (sdp->sd_sb.sb_root_dir.no_addr) /* if we know the root dinode */ - return; /* we don't need to find the root */ - if (!is_dir(di, sdp->gfs1)) /* if this isn't a directory */ - return; /* it can't lead us to the root anyway */ - - if (di->di_num.no_formal_ino == 1) { - struct gfs2_buffer_head *root_bh; - - if (di->di_num.no_addr == bh->b_blocknr) { - log_warn(_("Found the root directory at: 0x%llx.\n"), - di->di_num.no_addr); - sdp->sd_sb.sb_root_dir.no_addr = di->di_num.no_addr; - return; - } - log_warn(_("The root dinode should be at block 0x%llx but it " - "seems to be destroyed.\n"), - (unsigned long long)di->di_num.no_addr); - log_warn(_("Found a copy of the root directory in a journal " - "at block: 0x%llx.\n"), - (unsigned long long)bh->b_blocknr); - if (!query(_("Do you want to replace the root dinode from the " - "copy? (y/n)"))) { - log_err(_("Damaged root dinode not fixed.\n")); - return; - } - root_bh = bread(sdp, di->di_num.no_addr); - memcpy(root_bh->b_data, bh->b_data, sdp->bsize); - bmodified(root_bh); - brelse(root_bh); - log_warn(_("Root directory copied from the journal.\n")); - return; - } - ip = lgfs2_inode_read(sdp, di->di_num.no_addr); - if (ip == NULL) { - log_crit(_("Error reading inode: %s\n"), strerror(errno)); - return; - } - while (ip) { - gfs2_lookupi(ip, "..", 2, &parent_ip); - if (parent_ip && parent_ip->i_di.di_num.no_addr == - ip->i_di.di_num.no_addr) { - log_warn(_("Found the root directory at: 0x%llx\n"), - ip->i_di.di_num.no_addr); - sdp->sd_sb.sb_root_dir.no_addr = - ip->i_di.di_num.no_addr; - inode_put(&parent_ip); - inode_put(&ip); - return; - } - if (!parent_ip) - break; - inode_put(&ip); - ip = parent_ip; - } - error = dir_search(ip, "..", 2, NULL, &inum); - if (!error && inum.no_addr && inum.no_addr < possible_root) { - possible_root = inum.no_addr; - log_debug(_("Found a possible root at: 0x%llx\n"), - (unsigned long long)possible_root); - } - inode_put(&ip); -} - -/** - * find_rgs_for_bsize - check a range of blocks for rgrps to determine bsize. - * Assumes: device is open. - */ -static int find_rgs_for_bsize(struct gfs2_sbd *sdp, uint64_t startblock, - uint32_t *known_bsize) -{ - uint64_t blk, max_rg_size, rb_addr; - struct gfs2_buffer_head *bh, *rb_bh; - uint32_t bsize, bsize2; - uint32_t chk; - char *p; - int found_rg; - struct gfs2_meta_header mh; - - sdp->bsize = GFS2_DEFAULT_BSIZE; - max_rg_size = 524288; - /* Max RG size is 2GB. Max block size is 4K. 2G / 4K blks = 524288, - So this is traversing 2GB in 4K block increments. */ - for (blk = startblock; blk < startblock + max_rg_size; blk++) { - bh = bread(sdp, blk); - found_rg = 0; - for (bsize = 0; bsize < GFS2_DEFAULT_BSIZE; - bsize += GFS2_BASIC_BLOCK) { - p = bh->b_data + bsize; - chk = ((struct gfs2_meta_header *)p)->mh_magic; - if (be32_to_cpu(chk) != GFS2_MAGIC) - continue; - chk = ((struct gfs2_meta_header *)p)->mh_type; - if (be32_to_cpu(chk) == GFS2_METATYPE_RG) { - found_rg = 1; - break; - } - } - if (!found_rg) - continue; - /* Try all the block sizes in 512 byte multiples */ - for (bsize2 = GFS2_BASIC_BLOCK; bsize2 <= GFS2_DEFAULT_BSIZE; - bsize2 += GFS2_BASIC_BLOCK) { - rb_addr = (bh->b_blocknr * - (GFS2_DEFAULT_BSIZE / bsize2)) + - (bsize / bsize2) + 1; - sdp->bsize = bsize2; /* temporarily */ - rb_bh = bread(sdp, rb_addr); - gfs2_meta_header_in(&mh, rb_bh->b_data); - brelse(rb_bh); - if (mh.mh_magic == GFS2_MAGIC && - mh.mh_type == GFS2_METATYPE_RB) { - log_debug(_("boff:%d bsize2:%d rg:0x%llx, " - "rb:0x%llx\n"), bsize, bsize2, - (unsigned long long)blk, - (unsigned long long)rb_addr); - *known_bsize = bsize2; - break; - } - } - brelse(bh); - if (!(*known_bsize)) { - sdp->bsize = GFS2_DEFAULT_BSIZE; - continue; - } - - sdp->bsize = *known_bsize; - log_warn(_("Block size determined to be: %d\n"), *known_bsize); - return 0; - } - return 0; -} - -/** - * peruse_metadata - check a range of blocks for metadata - * Assumes: device is open. - */ -static int peruse_metadata(struct gfs2_sbd *sdp, uint64_t startblock) -{ - uint64_t blk, max_rg_size; - struct gfs2_buffer_head *bh; - struct gfs2_dinode di; - - max_rg_size = 2147483648ull / sdp->bsize; - /* Max RG size is 2GB. 2G / bsize. */ - for (blk = startblock; blk < startblock + max_rg_size; blk++) { - bh = bread(sdp, blk); - if (gfs2_check_meta(bh, GFS2_METATYPE_DI)) { - brelse(bh); - continue; - } - gfs2_dinode_in(&di, bh->b_data); - if (di.di_flags & GFS2_DIF_SYSTEM) - peruse_system_dinode(sdp, &di, bh); - else - peruse_user_dinode(sdp, &di, bh); - brelse(bh); - } - return 0; -} - -/** - * sb_repair - repair a damaged superblock - * Assumes: device is open. - * The biggest RG size is 2GB - */ -static int sb_repair(struct gfs2_sbd *sdp) -{ - uint64_t half; - uint32_t known_bsize = 0; - int error = 0; - - memset(&fix_md, 0, sizeof(fix_md)); - /* Step 1 - First we need to determine the correct block size. */ - sdp->bsize = GFS2_DEFAULT_BSIZE; - log_warn(_("Gathering information to repair the gfs2 superblock. " - "This may take some time.\n")); - error = find_rgs_for_bsize(sdp, (GFS2_SB_ADDR * GFS2_BASIC_BLOCK) / - GFS2_DEFAULT_BSIZE, &known_bsize); - if (error) - return error; - if (!known_bsize) { - log_warn(_("Block size not apparent; checking elsewhere.\n")); - /* First, figure out the device size. We need that so we can - find a suitable start point to determine what's what. */ - half = sdp->dinfo.size / 2; /* in bytes */ - half /= sdp->bsize; - /* Start looking halfway through the device for gfs2 - structures. If there aren't any at all, forget it. */ - error = find_rgs_for_bsize(sdp, half, &known_bsize); - if (error) - return error; - } - if (!known_bsize) { - log_err(_("Unable to determine the block size; this " - "does not look like a gfs2 file system.\n")); - return -1; - } - /* Step 2 - look for the sytem dinodes */ - error = peruse_metadata(sdp, (GFS2_SB_ADDR * GFS2_BASIC_BLOCK) / - GFS2_DEFAULT_BSIZE); - if (error) - return error; - if (!sdp->sd_sb.sb_master_dir.no_addr) { - log_err(_("Unable to locate the system master directory.\n")); - return -1; - } - if (!sdp->sd_sb.sb_root_dir.no_addr) { - struct gfs2_inum inum; - - log_err(_("Unable to locate the root directory.\n")); - if (possible_root == HIGHEST_BLOCK) { - /* Take advantage of the fact that mkfs.gfs2 - creates master immediately after root. */ - log_err(_("Can't find any dinodes that might " - "be the root; using master - 1.\n")); - possible_root = sdp->sd_sb.sb_master_dir.no_addr - 1; - } - log_err(_("Found a possible root at: 0x%llx\n"), - (unsigned long long)possible_root); - sdp->sd_sb.sb_root_dir.no_addr = possible_root; - sdp->md.rooti = lgfs2_inode_read(sdp, possible_root); - if (!sdp->md.rooti || - sdp->md.rooti->i_di.di_header.mh_magic != GFS2_MAGIC) { - struct gfs2_buffer_head *bh = NULL; - - log_err(_("The root dinode block is destroyed.\n")); - log_err(_("At this point I recommend " - "reinitializing it.\n" - "Hopefully everything will later " - "be put into lost+found.\n")); - if (!query(_("Okay to reinitialize the root " - "dinode? (y/n)"))) { - log_err(_("The root dinode was not " - "reinitialized; aborting.\n")); - return -1; - } - inum.no_formal_ino = 1; - inum.no_addr = possible_root; - error = init_dinode(sdp, &bh, &inum, S_IFDIR | 0755, 0, &inum); - if (error != 0) - return -1; - brelse(bh); - } - } - /* Step 3 - Rebuild the lock protocol and file system table name */ - if (query(_("Okay to fix the GFS2 superblock? (y/n)"))) { - struct gfs2_sb sb; - log_info(_("Found system master directory at: 0x%llx\n"), - sdp->sd_sb.sb_master_dir.no_addr); - sdp->master_dir = lgfs2_inode_read(sdp, - sdp->sd_sb.sb_master_dir.no_addr); - if (sdp->master_dir == NULL) { - log_crit(_("Error reading master inode: %s\n"), strerror(errno)); - return -1; - } - sdp->master_dir->i_di.di_num.no_addr = - sdp->sd_sb.sb_master_dir.no_addr; - log_info(_("Found the root directory at: 0x%llx\n"), - sdp->sd_sb.sb_root_dir.no_addr); - sdp->md.rooti = lgfs2_inode_read(sdp, - sdp->sd_sb.sb_root_dir.no_addr); - if (sdp->md.rooti == NULL) { - log_crit(_("Error reading root inode: %s\n"), strerror(errno)); - return -1; - } - lgfs2_sb_init(&sb, sdp->bsize); - strcpy(sb.sb_lockproto, GFS2_DEFAULT_LOCKPROTO); - strcpy(sb.sb_locktable, "unknown"); - sb.sb_master_dir = sdp->master_dir->i_di.di_num; - sb.sb_root_dir = sdp->md.rooti->i_di.di_num; - lgfs2_sb_write(&sb, sdp->device_fd, sdp->bsize); - inode_put(&sdp->md.rooti); - inode_put(&sdp->master_dir); - sb_fixed = 1; - } else { - log_crit(_("GFS2 superblock not fixed; fsck cannot proceed " - "without a valid superblock.\n")); - return -1; - } - return 0; -} - -/** - * fill_super_block - * @sdp: - * - * Returns: 0 on success, -1 on failure - */ -static int fill_super_block(struct gfs2_sbd *sdp) -{ - int ret; - - sync(); - - /******************************************************************** - ***************** First, initialize all lists ********************** - ********************************************************************/ - log_info( _("Initializing lists...\n")); - sdp->rgtree.osi_node = NULL; - - /******************************************************************** - ************ next, read in on-disk SB and set constants ********** - ********************************************************************/ - sdp->sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE; - sdp->bsize = sdp->sd_sb.sb_bsize; - - if (sizeof(struct gfs2_sb) > sdp->sd_sb.sb_bsize){ - log_crit( _("GFS superblock is larger than the blocksize!\n")); - log_debug("sizeof(struct gfs2_sb) > sdp->sd_sb.sb_bsize\n"); - return -1; - } - - if (compute_constants(sdp)) { - log_crit("%s\n", _("Failed to compute file system constants")); - exit(FSCK_ERROR); - } - ret = read_sb(sdp); - if (ret < 0) { - if (sb_repair(sdp) != 0) - return -1; /* unrepairable, so exit */ - /* Now that we've tried to repair it, re-read it. */ - ret = read_sb(sdp); - if (ret < 0) - return -1; - } - if (sdp->gfs1) - sbd1 = (struct gfs_sb *)&sdp->sd_sb; - return 0; -} - -static void gfs_log_header_out(struct gfs_log_header *head, char *buf) -{ - struct gfs_log_header *str = (struct gfs_log_header *) buf; - - str->lh_header.mh_magic = cpu_to_be32(head->lh_header.mh_magic); - str->lh_header.mh_type = cpu_to_be32(head->lh_header.mh_type); - str->lh_header.mh_format = cpu_to_be32(head->lh_header.mh_format); - str->lh_header.__pad0 = cpu_to_be32(head->lh_header.__pad0); - - str->lh_flags = cpu_to_be32(head->lh_flags); - str->lh_pad = cpu_to_be32(head->lh_pad); - str->lh_first = cpu_to_be64(head->lh_first); - str->lh_sequence = cpu_to_be64(head->lh_sequence); - str->lh_tail = cpu_to_be64(head->lh_tail); - str->lh_last_dump = cpu_to_be64(head->lh_last_dump); -} - -/* - * reconstruct_single_journal - write a fresh GFS1 journal - * @sdp: superblock - * @jnum: journal number - * - * This function will write a fresh journal over the top of - * the previous journal. All journal information is lost. This - * process is basically stolen from write_journals() in the mkfs code. - * - * Returns: -1 on error, 0 otherwise - */ -static int reconstruct_single_journal(struct gfs2_sbd *sdp, int jnum, - uint32_t ji_nsegment) -{ - struct gfs_log_header lh; - uint32_t seg, sequence; - struct gfs2_buffer_head *bh; - - srandom(time(NULL)); - sequence = ji_nsegment / (RAND_MAX + 1.0) * random(); - - log_info(_("Clearing journal %d\n"), jnum); - - for (seg = 0; seg < ji_nsegment; seg++){ - memset(&lh, 0, sizeof(struct gfs_log_header)); - - lh.lh_header.mh_magic = GFS2_MAGIC; - lh.lh_header.mh_type = GFS2_METATYPE_LH; - lh.lh_header.mh_format = GFS2_FORMAT_LH; - lh.lh_header.__pad0 = 0x101674; /* mh_generation */ - lh.lh_flags = GFS2_LOG_HEAD_UNMOUNT; - lh.lh_first = sdp->md.journal[jnum]->i_di.di_num.no_addr + - (seg * sbd1->sb_seg_size); - lh.lh_sequence = sequence; - - bh = bget(sdp, lh.lh_first * sdp->bsize); - memset(bh->b_data, 0, sdp->bsize); - gfs_log_header_out(&lh, bh->b_data); - gfs_log_header_out(&lh, bh->b_data + GFS2_BASIC_BLOCK - - sizeof(struct gfs_log_header)); - brelse(bh); - - if (++sequence == ji_nsegment) - sequence = 0; - } - return 0; -} - -static int reset_journal_seg_size(unsigned int jsize, unsigned int nsegs, - unsigned int bsize) -{ - unsigned int seg_size = jsize / (nsegs * bsize); - if (!seg_size) - seg_size = 16; /* The default with 128MB journal and 4K bsize */ - if (seg_size != sbd1->sb_seg_size) { - sbd1->sb_seg_size = seg_size; - if (!query(_("Computed correct journal segment size to %u." - " Reset it? (y/n) "), seg_size)) { - log_crit(_("Error: Cannot proceed without a valid journal" - " segment size value.\n")); - return -1; - } - log_err(_("Resetting journal segment size to %u\n"), sbd1->sb_seg_size); - } - return 0; -} - -static int correct_journal_seg_size(struct gfs2_sbd *sdp) -{ - int count; - struct gfs_jindex ji_0, ji_1; - char buf[sizeof(struct gfs_jindex)]; - unsigned int jsize = GFS2_DEFAULT_JSIZE * 1024 * 1024; - - count = gfs2_readi(sdp->md.jiinode, buf, 0, sizeof(struct gfs_jindex)); - if (count != sizeof(struct gfs_jindex)) { - log_crit(_("Error %d reading system journal index inode. " - "Aborting\n"), count); - return -1; - } - gfs_jindex_in(&ji_0, buf); - - if (sdp->md.journals == 1) { - if (sbd1->sb_seg_size == 0) { - if (!query(_("The gfs2 journal segment size is 0 and a" - " correct value cannot be determined in a" - " single-journal filesystem.\n" - "Continue with default? (y/n) "))) { - log_crit(_("Error: Cannot proceed without a valid" - " sb_seg_size value.\n")); - return -1; - } - goto out; - } - /* Don't mess with sb_seg_size because we don't know what - * it needs to be - */ - return 0; - } - - count = gfs2_readi(sdp->md.jiinode, buf, sizeof(struct gfs_jindex), - sizeof(struct gfs_jindex)); - if (count != sizeof(struct gfs_jindex)) { - log_crit(_("Error %d reading system journal index inode. " - "Aborting\n"), count); - return -1; - } - gfs_jindex_in(&ji_1, buf); - - jsize = (ji_1.ji_addr - ji_0.ji_addr) * sbd1->sb_bsize; -out: - return reset_journal_seg_size(jsize, ji_0.ji_nsegment, sbd1->sb_bsize); -} - -/* - * reconstruct_journals - write fresh journals for GFS1 only - * sdp: the super block - * - * Returns: 0 on success, -1 on failure - */ -static int reconstruct_journals(struct gfs2_sbd *sdp) -{ - int i, count; - struct gfs_jindex ji; - char buf[sizeof(struct gfs_jindex)]; - - /* Ensure that sb_seg_size is valid */ - if (correct_journal_seg_size(sdp)) { - log_crit(_("Failed to set correct journal segment size. Cannot continue\n")); - return -1; - } - - log_err(_("Clearing GFS journals (this may take a while)\n")); - for (i = 0; i < sdp->md.journals; i++) { - count = gfs2_readi(sdp->md.jiinode, buf, - i * sizeof(struct gfs_jindex), - sizeof(struct gfs_jindex)); - if (count != sizeof(struct gfs_jindex)) - return 0; - gfs_jindex_in(&ji, buf); - if ((i % 2) == 0) - log_err("."); - if (reconstruct_single_journal(sdp, i, ji.ji_nsegment)) - return -1; - } - log_err(_("\nJournals cleared.\n")); - return 0; -} - -/** - * init_rindex - read in the rindex file - */ -static int init_rindex(struct gfs2_sbd *sdp) -{ - int err; - - if (sdp->gfs1) - sdp->md.riinode = lgfs2_inode_read(sdp, sbd1->sb_rindex_di.no_addr); - else - gfs2_lookupi(sdp->master_dir, "rindex", 6, &sdp->md.riinode); - - if (sdp->md.riinode) - return 0; - - if (!query( _("The gfs2 system rindex inode is missing. " - "Okay to rebuild it? (y/n) "))) { - log_crit(_("Error: Cannot proceed without a valid rindex.\n")); - return -1; - } - if ((err = build_rindex(sdp))) { - log_crit(_("Error %d rebuilding rindex\n"), err); - return -1; - } - return 0; -} - -/** - * initialize - initialize superblock pointer - * - */ -int initialize(struct gfs2_sbd *sdp, int force_check, int preen, - int *all_clean) -{ - int clean_journals = 0, open_flag; - - *all_clean = 0; - - if (opts.no) - open_flag = O_RDONLY; - else - open_flag = O_RDWR | O_EXCL; - - sdp->device_fd = open(opts.device, open_flag); - if (sdp->device_fd < 0) { - struct mntent *mnt; - if (open_flag == O_RDONLY || errno != EBUSY) { - log_crit( _("Unable to open device: %s\n"), - opts.device); - return FSCK_USAGE; - } - /* We can't open it EXCL. It may be already open rw (in which - case we want to deny them access) or it may be mounted as - the root file system at boot time (in which case we need to - allow it.) - If the device is busy, but not because it's mounted, fail. - This protects against cases where the file system is LVM - and perhaps mounted on a different node. - Try opening without O_EXCL. */ - sdp->device_fd = lgfs2_open_mnt_dev(opts.device, O_RDWR, &mnt); - if (sdp->device_fd < 0) - goto mount_fail; - /* If the device is mounted, but not mounted RO, fail. This - protects them against cases where the file system is - mounted RW, but still allows us to check our own root - file system. */ - if (!hasmntopt(mnt, MNTOPT_RO)) - goto close_fail; - /* The device is mounted RO, so it's likely our own root - file system. We can only do so much to protect the users - from themselves. */ - was_mounted_ro = 1; - } - - if (lgfs2_get_dev_info(sdp->device_fd, &sdp->dinfo)) { - perror(opts.device); - return FSCK_ERROR; - } - - /* read in sb from disk */ - if (fill_super_block(sdp)) - return FSCK_ERROR; - - /* Change lock protocol to be fsck_* instead of lock_* */ - if (!opts.no && preen_is_safe(sdp, preen, force_check)) { - if (block_mounters(sdp, 1)) { - log_err( _("Unable to block other mounters\n")); - return FSCK_USAGE; - } - } - - /* Get master dinode */ - if (sdp->gfs1) - sdp->master_dir = NULL; - else - sdp->master_dir = lgfs2_inode_read(sdp, - sdp->sd_sb.sb_master_dir.no_addr); - if (!sdp->gfs1 && - (sdp->master_dir->i_di.di_header.mh_magic != GFS2_MAGIC || - sdp->master_dir->i_di.di_header.mh_type != GFS2_METATYPE_DI || - !sdp->master_dir->i_di.di_size)) { - inode_put(&sdp->master_dir); - rebuild_master(sdp); - sdp->master_dir = lgfs2_inode_read(sdp, - sdp->sd_sb.sb_master_dir.no_addr); - if (sdp->master_dir == NULL) { - log_crit(_("Error reading master directory: %s\n"), strerror(errno)); - return FSCK_ERROR; - } - } - - /* Look up the "per_node" inode. If there are journals missing, we - need to figure out what's missing from per_node. And we need all - our journals to be there before we can replay them. */ - if (!sdp->gfs1) - lookup_per_node(sdp, 0); - - /* We need rindex first in case jindex is missing and needs to read - in the rgrps before rebuilding it. However, note that if the rindex - is damaged, we need the journals to repair it. That's because the - journals likely contain rgrps and bitmaps, which we need to ignore - when we're trying to find the rgrps. */ - if (init_rindex(sdp)) - return FSCK_ERROR; - - if (fetch_rgrps(sdp)) - return FSCK_ERROR; - - /* We need to read in jindex in order to replay the journals. If - there's an error, we may proceed and let init_system_inodes - try to rebuild it. */ - if (init_jindex(sdp, 1) == 0) { - /* If GFS, rebuild the journals. If GFS2, replay them. We don't - have the smarts to replay GFS1 journals (neither did - gfs_fsck). */ - if (sdp->gfs1) { - if (reconstruct_journals(sdp)) - return FSCK_ERROR; - } else if (replay_journals(sdp, preen, force_check, - &clean_journals)) { - if (!opts.no && preen_is_safe(sdp, preen, force_check)) - block_mounters(sdp, 0); - stack; - return FSCK_ERROR; - } - if (sdp->md.journals == clean_journals) - *all_clean = 1; - else if (force_check || !preen) - log_notice( _("\nJournal recovery complete.\n")); - - if (!force_check && *all_clean && preen) - return FSCK_OK; - } - - if (init_system_inodes(sdp)) - return FSCK_ERROR; - - return FSCK_OK; - -close_fail: - close(sdp->device_fd); -mount_fail: - log_crit( _("Device %s is busy.\n"), opts.device); - return FSCK_USAGE; -} - -void destroy(struct gfs2_sbd *sdp) -{ - if (!opts.no) { - if (block_mounters(sdp, 0)) { - log_warn( _("Unable to unblock other mounters - manual intervention required\n")); - log_warn( _("Use 'gfs2_tool sb proto' to fix\n")); - } - log_info( _("Syncing the device.\n")); - fsync(sdp->device_fd); - } - empty_super_block(sdp); - close(sdp->device_fd); - if (was_mounted_ro && errors_corrected) { - sdp->device_fd = open("/proc/sys/vm/drop_caches", O_WRONLY); - if (sdp->device_fd >= 0) { - if (write(sdp->device_fd, "2", 1) == 2) { - close(sdp->device_fd); - return; - } - close(sdp->device_fd); - } - log_warn(_("fsck.gfs2: Could not flush caches (non-fatal).\n")); - } -} diff --git a/gfs2/libgfs2/meta.c b/gfs2/libgfs2/meta.c index e0ea491..a828946 100644 --- a/gfs2/libgfs2/meta.c +++ b/gfs2/libgfs2/meta.c @@ -940,7 +940,6 @@ int lgfs2_field_str(char *str, const size_t size, const char *blk, const struct int lgfs2_field_assign(char *blk, const struct lgfs2_metafield *field, const void *val) { char *fieldp = blk + field->offset; - uint64_t num = *(uint64_t *)val; if (field->flags & LGFS2_MFF_UUID) { memcpy(fieldp, val, 16); @@ -960,16 +959,16 @@ int lgfs2_field_assign(char *blk, const struct lgfs2_metafield *field, const voi switch(field->length) { case sizeof(uint8_t): - *fieldp = (uint8_t)num; + *fieldp = *(uint8_t *)val; return 0; case sizeof(uint16_t): - *(uint16_t *)fieldp = cpu_to_be16((uint16_t)num); + *(uint16_t *)fieldp = cpu_to_be16(*(uint16_t *)val); return 0; case sizeof(uint32_t): - *(uint32_t *)fieldp = cpu_to_be32((uint32_t)num); + *(uint32_t *)fieldp = cpu_to_be32(*(uint32_t *)val); return 0; case sizeof(uint64_t): - *(uint64_t *)fieldp = cpu_to_be64((uint64_t)num); + *(uint64_t *)fieldp = cpu_to_be64(*(uint64_t *)val); return 0; default: /* Will never happen */ diff --git a/gfs2/libgfs2/meta.c.bz1622050-2-libgfs2_Fix_pointer_cast_byte_order_issue b/gfs2/libgfs2/meta.c.bz1622050-2-libgfs2_Fix_pointer_cast_byte_order_issue deleted file mode 100644 index a828946..0000000 --- a/gfs2/libgfs2/meta.c.bz1622050-2-libgfs2_Fix_pointer_cast_byte_order_issue +++ /dev/null @@ -1,979 +0,0 @@ -#include -#include -#include "libgfs2.h" -#include "clusterautoconfig.h" - -#ifdef GFS2_HAS_UUID -#include -#endif - -#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) -#define SYM(x) { x, #x }, - -const struct lgfs2_symbolic lgfs2_metatypes[] = { -SYM(GFS2_METATYPE_NONE) -SYM(GFS2_METATYPE_SB) -SYM(GFS2_METATYPE_RG) -SYM(GFS2_METATYPE_RB) -SYM(GFS2_METATYPE_DI) -SYM(GFS2_METATYPE_IN) -SYM(GFS2_METATYPE_LF) -SYM(GFS2_METATYPE_JD) -SYM(GFS2_METATYPE_LH) -SYM(GFS2_METATYPE_LD) -SYM(GFS2_METATYPE_LB) -SYM(GFS2_METATYPE_EA) -SYM(GFS2_METATYPE_ED) -SYM(GFS2_METATYPE_QC) -}; - -const unsigned lgfs2_metatype_size = ARRAY_SIZE(lgfs2_metatypes); - -const struct lgfs2_symbolic lgfs2_metaformats[] = { -SYM(GFS2_FORMAT_NONE) -SYM(GFS2_FORMAT_SB) -SYM(GFS2_FORMAT_RG) -SYM(GFS2_FORMAT_RB) -SYM(GFS2_FORMAT_DI) -SYM(GFS2_FORMAT_IN) -SYM(GFS2_FORMAT_LF) -SYM(GFS2_FORMAT_JD) -SYM(GFS2_FORMAT_LH) -SYM(GFS2_FORMAT_LD) -SYM(GFS2_FORMAT_LB) -SYM(GFS2_FORMAT_EA) -SYM(GFS2_FORMAT_ED) -SYM(GFS2_FORMAT_QC) -SYM(GFS2_FORMAT_RI) -SYM(GFS2_FORMAT_DE) -SYM(GFS2_FORMAT_QU) -}; - -const unsigned lgfs2_metaformat_size = ARRAY_SIZE(lgfs2_metaformats); - -const struct lgfs2_symbolic lgfs2_di_flags[] = { -SYM(GFS2_DIF_JDATA) -SYM(GFS2_DIF_EXHASH) -SYM(GFS2_DIF_UNUSED) -SYM(GFS2_DIF_EA_INDIRECT) -SYM(GFS2_DIF_DIRECTIO) -SYM(GFS2_DIF_IMMUTABLE) -SYM(GFS2_DIF_APPENDONLY) -SYM(GFS2_DIF_NOATIME) -SYM(GFS2_DIF_SYNC) -SYM(GFS2_DIF_SYSTEM) -SYM(GFS2_DIF_TRUNC_IN_PROG) -SYM(GFS2_DIF_INHERIT_DIRECTIO) -SYM(GFS2_DIF_INHERIT_JDATA) -}; - -const unsigned lgfs2_di_flag_size = ARRAY_SIZE(lgfs2_di_flags); - -const struct lgfs2_symbolic lgfs2_lh_flags[] = { -SYM(GFS2_LOG_HEAD_UNMOUNT) -}; - -const unsigned int lgfs2_lh_flag_size = ARRAY_SIZE(lgfs2_lh_flags); - -const struct lgfs2_symbolic lgfs2_ld_types[] = { -SYM(GFS2_LOG_DESC_METADATA) -SYM(GFS2_LOG_DESC_REVOKE) -SYM(GFS2_LOG_DESC_JDATA) -}; - -const unsigned int lgfs2_ld_type_size = ARRAY_SIZE(lgfs2_ld_types); - -const struct lgfs2_symbolic lgfs2_ld1_types[] = { -SYM(GFS_LOG_DESC_METADATA) -SYM(GFS_LOG_DESC_IUL) -SYM(GFS_LOG_DESC_IDA) -SYM(GFS_LOG_DESC_Q) -SYM(GFS_LOG_DESC_LAST) -}; - -const unsigned int lgfs2_ld1_type_size = ARRAY_SIZE(lgfs2_ld1_types); - -#undef SYM - - - - -#define F(f,...) { .name = #f, \ - .offset = offsetof(struct STRUCT, f), \ - .length = sizeof(((struct STRUCT *)(0))->f), \ - __VA_ARGS__ }, -#define FP(f,...) F(f, .flags = LGFS2_MFF_POINTER, __VA_ARGS__) -#define RF(f) F(f, .flags = LGFS2_MFF_RESERVED) -#define RFP(f,...) F(f, .flags = LGFS2_MFF_POINTER|LGFS2_MFF_RESERVED, __VA_ARGS__) - - -#define MH(f) F(f.mh_magic) \ - F(f.mh_type, .flags = LGFS2_MFF_ENUM, .symtab=lgfs2_metatypes, .nsyms=ARRAY_SIZE(lgfs2_metatypes)) \ - RF(f.__pad0) \ - F(f.mh_format, .flags = LGFS2_MFF_ENUM, .symtab=lgfs2_metaformats, .nsyms=ARRAY_SIZE(lgfs2_metaformats)) \ - F(f.mh_jid) - -#define IN(f,...) F(f.no_formal_ino) \ - FP(f.no_addr, __VA_ARGS__) - -#define INR(f,...) RF(f.no_formal_ino) \ - RFP(f.no_addr, __VA_ARGS__) -#define ANY_COMMON_BLOCK (1 << LGFS2_MT_DIR_LEAF) | \ - (1 << LGFS2_MT_JRNL_DATA) | \ - (1 << LGFS2_MT_EA_ATTR) | \ - (1 << LGFS2_MT_EA_DATA) | \ - (1 << LGFS2_MT_DATA) - -#define ANY_GFS2_BLOCK (1 << LGFS2_MT_GFS2_DINODE) | \ - (1 << LGFS2_MT_GFS2_INDIRECT) | \ - (1 << LGFS2_MT_GFS2_LOG_HEADER) | \ - (1 << LGFS2_MT_GFS2_LOG_DESC) | \ - (1 << LGFS2_MT_GFS2_LOG_BLOCK) | \ - ANY_COMMON_BLOCK - -#define ANY_GFS_BLOCK (1 << LGFS2_MT_GFS_DINODE) | \ - (1 << LGFS2_MT_GFS_INDIRECT) | \ - ANY_COMMON_BLOCK - -#undef STRUCT -#define STRUCT gfs2_sb - -static const struct lgfs2_metafield gfs2_sb_fields[] = { -MH(sb_header) -F(sb_fs_format) -F(sb_multihost_format) -RF(__pad0) -F(sb_bsize, .flags = LGFS2_MFF_BYTES) -F(sb_bsize_shift, .flags = LGFS2_MFF_BYTES|LGFS2_MFF_SHIFT) -RF(__pad1) -IN(sb_master_dir, .points_to = (1 << LGFS2_MT_GFS2_DINODE)) -INR(__pad2, .points_to = (1 << LGFS2_MT_GFS2_DINODE)) -IN(sb_root_dir, .points_to = (1 << LGFS2_MT_GFS2_DINODE)) -F(sb_lockproto, .flags = LGFS2_MFF_STRING) -F(sb_locktable, .flags = LGFS2_MFF_STRING) -INR(__pad3, .points_to = (1 << LGFS2_MT_GFS2_DINODE)) -INR(__pad4, .points_to = (1 << LGFS2_MT_GFS2_DINODE)) -#ifdef GFS2_HAS_UUID -F(sb_uuid, .flags = LGFS2_MFF_UUID) -#endif -}; - -#undef STRUCT -#define STRUCT gfs_sb - -static const struct lgfs2_metafield gfs_sb_fields[] = { -MH(sb_header) -F(sb_fs_format) -F(sb_multihost_format) -F(sb_flags) -F(sb_bsize, .flags = LGFS2_MFF_BYTES) -F(sb_bsize_shift, .flags = LGFS2_MFF_BYTES|LGFS2_MFF_SHIFT) -F(sb_seg_size, .flags = LGFS2_MFF_FSBLOCKS) -IN(sb_jindex_di, .points_to = (1 << LGFS2_MT_GFS_DINODE)) -IN(sb_rindex_di, .points_to = (1 << LGFS2_MT_GFS_DINODE)) -IN(sb_root_di, .points_to = (1 << LGFS2_MT_GFS_DINODE)) -F(sb_lockproto, .flags = LGFS2_MFF_STRING) -F(sb_locktable, .flags = LGFS2_MFF_STRING) -IN(sb_quota_di, .points_to = (1 << LGFS2_MT_GFS_DINODE)) -IN(sb_license_di, .points_to = (1 << LGFS2_MT_GFS_DINODE)) -RF(sb_reserved) -}; - -#undef STRUCT -#define STRUCT gfs2_rindex - -static const struct lgfs2_metafield gfs2_rindex_fields[] = { -FP(ri_addr, .points_to = (1 << LGFS2_MT_GFS2_RGRP)) -F(ri_length, .flags = LGFS2_MFF_FSBLOCKS) -RF(__pad) -FP(ri_data0, .points_to = ANY_GFS2_BLOCK|(1 << LGFS2_MT_FREE)) -F(ri_data, .flags = LGFS2_MFF_FSBLOCKS) -F(ri_bitbytes, .flags = LGFS2_MFF_BYTES) -F(ri_reserved) -}; - -#undef STRUCT -#define STRUCT gfs2_rgrp - -static const struct lgfs2_metafield gfs2_rgrp_fields[] = { -MH(rg_header) -F(rg_flags) -F(rg_free, .flags = LGFS2_MFF_FSBLOCKS) -F(rg_dinodes, .flags = LGFS2_MFF_FSBLOCKS) -#ifdef GFS2_HAS_RG_SKIP -FP(rg_skip, .points_to = (1 << LGFS2_MT_GFS2_RGRP)) -#else -RF(__pad) -#endif -F(rg_igeneration) -#ifdef GFS2_HAS_RG_RI_FIELDS -FP(rg_data0, .points_to = ANY_GFS2_BLOCK|(1 << LGFS2_MT_FREE)) -F(rg_data, .flags = LGFS2_MFF_FSBLOCKS) -F(rg_bitbytes, .flags = LGFS2_MFF_BYTES) -F(rg_crc, .flags = LGFS2_MFF_CHECK) -#endif -RF(rg_reserved) -}; - -#undef STRUCT -#define STRUCT gfs_rgrp - -static const struct lgfs2_metafield gfs_rgrp_fields[] = { -MH(rg_header) -F(rg_flags) -F(rg_free, .flags = LGFS2_MFF_FSBLOCKS) -F(rg_useddi, .flags = LGFS2_MFF_FSBLOCKS) -F(rg_freedi, .flags = LGFS2_MFF_FSBLOCKS) -IN(rg_freedi_list, .points_to = (1 << LGFS2_MT_GFS_DINODE)) -F(rg_usedmeta, .flags = LGFS2_MFF_FSBLOCKS) -F(rg_freemeta, .flags = LGFS2_MFF_FSBLOCKS) -RF(rg_reserved) -}; - -#undef STRUCT -struct gfs2_rgrp_bitmap { struct gfs2_meta_header rb_header; }; -#define STRUCT gfs2_rgrp_bitmap - -static const struct lgfs2_metafield gfs2_rgrp_bitmap_fields[] = { -MH(rb_header) -}; - -#undef STRUCT -#define STRUCT gfs2_dinode - -static const struct lgfs2_metafield gfs2_dinode_fields[] = { -MH(di_header) -IN(di_num, .points_to = (1 << LGFS2_MT_GFS2_DINODE)) -F(di_mode, .flags = LGFS2_MFF_MODE) -F(di_uid, .flags = LGFS2_MFF_UID) -F(di_gid, .flags = LGFS2_MFF_GID) -F(di_nlink) -F(di_size, .flags = LGFS2_MFF_BYTES) -F(di_blocks, .flags = LGFS2_MFF_FSBLOCKS) -F(di_atime, .flags = LGFS2_MFF_SECS) -F(di_mtime, .flags = LGFS2_MFF_SECS) -F(di_ctime, .flags = LGFS2_MFF_SECS) -F(di_major, .flags = LGFS2_MFF_MAJOR) -F(di_minor, .flags = LGFS2_MFF_MINOR) -FP(di_goal_meta, .points_to = ANY_GFS2_BLOCK | (1 << LGFS2_MT_FREE)) -FP(di_goal_data, .points_to = ANY_GFS2_BLOCK | (1 << LGFS2_MT_FREE)) -F(di_generation) -F(di_flags, .flags = LGFS2_MFF_MASK, .symtab=lgfs2_di_flags, .nsyms=ARRAY_SIZE(lgfs2_di_flags)) -F(di_payload_format) -RF(__pad1) -F(di_height) -RF(__pad2) -RF(__pad3) -F(di_depth) -F(di_entries) -INR(__pad4, .points_to = (1 << LGFS2_MT_GFS2_DINODE)) -FP(di_eattr, .points_to = (1 << LGFS2_MT_EA_ATTR)|(1 << LGFS2_MT_GFS2_INDIRECT)) -F(di_atime_nsec, .flags = LGFS2_MFF_NSECS) -F(di_mtime_nsec, .flags = LGFS2_MFF_NSECS) -F(di_ctime_nsec, .flags = LGFS2_MFF_NSECS) -RF(di_reserved) -}; - -#undef STRUCT -#define STRUCT gfs_dinode - -static const struct lgfs2_metafield gfs_dinode_fields[] = { -MH(di_header) -IN(di_num, .points_to = (1 << LGFS2_MT_GFS_DINODE)) -F(di_mode, .flags = LGFS2_MFF_MODE) -F(di_uid, .flags = LGFS2_MFF_UID) -F(di_gid, .flags = LGFS2_MFF_GID) -F(di_nlink) -F(di_size, .flags = LGFS2_MFF_BYTES) -F(di_blocks, .flags = LGFS2_MFF_FSBLOCKS) -F(di_atime, .flags = LGFS2_MFF_SECS) -F(di_mtime, .flags = LGFS2_MFF_SECS) -F(di_ctime, .flags = LGFS2_MFF_SECS) -F(di_major, .flags = LGFS2_MFF_MAJOR) -F(di_minor, .flags = LGFS2_MFF_MINOR) -FP(di_rgrp, .points_to = LGFS2_MT_GFS_RGRP) -FP(di_goal_rgrp, .points_to = LGFS2_MT_GFS_RGRP) -F(di_goal_dblk) -F(di_goal_mblk) -F(di_flags, .flags = LGFS2_MFF_MASK, .symtab=lgfs2_di_flags, .nsyms=ARRAY_SIZE(lgfs2_di_flags)) -F(di_payload_format) -F(di_type) -F(di_height) -F(di_incarn) -F(di_pad) -F(di_depth) -F(di_entries) -INR(di_next_unused, .points_to = (1 << LGFS2_MT_GFS_DINODE)) -FP(di_eattr, .points_to = (1 << LGFS2_MT_EA_ATTR)|(1 << LGFS2_MT_GFS_INDIRECT)) -F(di_reserved) -}; - -#undef STRUCT -struct gfs2_indirect { struct gfs2_meta_header in_header; }; -#define STRUCT gfs2_indirect - -static const struct lgfs2_metafield gfs2_indirect_fields[] = { -MH(in_header) -}; - -#undef STRUCT -#define STRUCT gfs_indirect - -static const struct lgfs2_metafield gfs_indirect_fields[] = { -MH(in_header) -RF(in_reserved) -}; - -#undef STRUCT -#define STRUCT gfs2_leaf - -static const struct lgfs2_metafield gfs2_leaf_fields[] = { -MH(lf_header) -F(lf_depth) -F(lf_entries) -F(lf_dirent_format) -F(lf_next) -#ifdef GFS2_HAS_LEAF_HINTS -FP(lf_inode, .points_to = (1 << LGFS2_MT_GFS2_DINODE)) -F(lf_dist) -F(lf_nsec, .flags = LGFS2_MFF_NSECS) -F(lf_sec, .flags = LGFS2_MFF_SECS) -RF(lf_reserved2) -#else -RF(lf_reserved) -#endif -}; - -#undef STRUCT -struct gfs2_jrnl_data { struct gfs2_meta_header jd_header; }; -#define STRUCT gfs2_jrnl_data - -static const struct lgfs2_metafield gfs2_jdata_fields[] = { -MH(jd_header) -}; - -#undef STRUCT -#define STRUCT gfs2_log_header - -static const struct lgfs2_metafield gfs2_log_header_fields[] = { -MH(lh_header) -F(lh_sequence) -F(lh_flags) -F(lh_tail) -F(lh_blkno) -F(lh_hash, .flags = LGFS2_MFF_CHECK) -#ifdef GFS2_HAS_LH_V2 -F(lh_crc, .flags = LGFS2_MFF_CHECK) -F(lh_nsec, .flags = LGFS2_MFF_NSECS) -F(lh_sec, .flags = LGFS2_MFF_SECS) -FP(lh_addr, .points_to = (1 << LGFS2_MT_GFS2_LOG_BLOCK)) -FP(lh_jinode, .points_to = (1 << LGFS2_MT_GFS2_DINODE)) -FP(lh_statfs_addr, .points_to = (1 << LGFS2_MT_GFS2_DINODE)) -FP(lh_quota_addr, .points_to = (1 << LGFS2_MT_GFS2_DINODE)) -F(lh_local_total, .flags = LGFS2_MFF_FSBLOCKS) -F(lh_local_free, .flags = LGFS2_MFF_FSBLOCKS) -F(lh_local_dinodes, .flags = LGFS2_MFF_FSBLOCKS) -#endif -}; - -#undef STRUCT -#define STRUCT gfs_log_header - -static const struct lgfs2_metafield gfs_log_header_fields[] = { -MH(lh_header) -F(lh_flags, .flags = LGFS2_MFF_MASK, .symtab = lgfs2_lh_flags, .nsyms = ARRAY_SIZE(lgfs2_lh_flags)) -RF(lh_pad) -F(lh_first) -F(lh_sequence) -F(lh_tail) -F(lh_last_dump) -RF(lh_reserved) -}; - -#undef STRUCT -#define STRUCT gfs2_log_descriptor - -static const struct lgfs2_metafield gfs2_log_desc_fields[] = { -MH(ld_header) -F(ld_type, .flags = LGFS2_MFF_ENUM, .symtab = lgfs2_ld_types, .nsyms = ARRAY_SIZE(lgfs2_ld_types)) -F(ld_length, .flags = LGFS2_MFF_FSBLOCKS) -F(ld_data1) -F(ld_data2) -RF(ld_reserved) -}; - -#undef STRUCT -#define STRUCT gfs_log_descriptor - -static const struct lgfs2_metafield gfs_log_desc_fields[] = { -MH(ld_header) -F(ld_type, .flags = LGFS2_MFF_ENUM, .symtab = lgfs2_ld1_types, .nsyms = ARRAY_SIZE(lgfs2_ld1_types)) -F(ld_length, .flags = LGFS2_MFF_FSBLOCKS) -F(ld_data1) -F(ld_data2) -RF(ld_reserved) -}; - -#undef STRUCT -struct gfs2_log_block { struct gfs2_meta_header lb_header; }; -#define STRUCT gfs2_log_block - -static const struct lgfs2_metafield gfs2_log_block_fields[] = { -MH(lb_header) -}; - -#undef STRUCT -struct gfs2_ea_attr { struct gfs2_meta_header ea_header; }; -#define STRUCT gfs2_ea_attr - -static const struct lgfs2_metafield gfs2_ea_attr_fields[] = { -MH(ea_header) -}; - -#undef STRUCT -struct gfs2_ea_data { struct gfs2_meta_header ed_header; }; -#define STRUCT gfs2_ea_data - -static const struct lgfs2_metafield gfs2_ea_data_fields[] = { -MH(ed_header) -}; - -#undef STRUCT -#define STRUCT gfs2_quota_change - -static const struct lgfs2_metafield gfs2_quota_change_fields[] = { -F(qc_change, .flags = LGFS2_MFF_FSBLOCKS) -F(qc_flags) -F(qc_id) -}; - -#undef STRUCT -#define STRUCT gfs2_dirent - -static const struct lgfs2_metafield gfs2_dirent_fields[] = { -IN(de_inum, .points_to = (1 << LGFS2_MT_GFS_DINODE)|(1 << LGFS2_MT_GFS2_DINODE)) -F(de_hash, .flags = LGFS2_MFF_CHECK) -F(de_rec_len, .flags = LGFS2_MFF_BYTES) -F(de_name_len, .flags = LGFS2_MFF_BYTES) -F(de_type) -#ifdef GFS2_HAS_DE_RAHEAD -F(de_rahead) -#ifdef GFS2_HAS_DE_COOKIE -F(de_cookie) -RF(pad3) -#else -RF(pad2) -#endif /* GFS2_HAS_DE_COOKIE */ -#else -RF(__pad) -#endif /* GFS2_HAS_DE_RAHEAD */ -}; - -#undef STRUCT -#define STRUCT gfs2_ea_header - -static const struct lgfs2_metafield gfs2_ea_header_fields[] = { -F(ea_rec_len, .flags = LGFS2_MFF_BYTES) -F(ea_data_len, .flags = LGFS2_MFF_BYTES) -F(ea_name_len, .flags = LGFS2_MFF_BYTES) -F(ea_type) -F(ea_flags) -F(ea_num_ptrs) -RF(__pad) -}; - -#undef STRUCT -#define STRUCT gfs2_inum_range - -static const struct lgfs2_metafield gfs2_inum_range_fields[] = { -F(ir_start) -F(ir_length) -}; - -#undef STRUCT -#define STRUCT gfs2_statfs_change - -static const struct lgfs2_metafield gfs2_statfs_change_fields[] = { -F(sc_total, .flags = LGFS2_MFF_FSBLOCKS) -F(sc_free, .flags = LGFS2_MFF_FSBLOCKS) -F(sc_dinodes, .flags = LGFS2_MFF_FSBLOCKS) -}; - -#undef STRUCT -#define STRUCT gfs_jindex - -static const struct lgfs2_metafield gfs_jindex_fields[] = { -FP(ji_addr, .points_to = (1 << LGFS2_MT_DATA)) -F(ji_nsegment) -RF(ji_pad) -RF(ji_reserved) -}; - -#undef STRUCT -struct gfs_block_tag { - uint64_t bt_blkno; /* inplace block number */ - uint32_t bt_flags; /* ?? */ - uint32_t bt_pad; -}; -#define STRUCT gfs_block_tag - -static const struct lgfs2_metafield gfs_block_tag_fields[] = { -FP(bt_blkno, .points_to = ANY_GFS_BLOCK) -RF(bt_flags) -RF(bt_pad) -}; - -const struct lgfs2_metadata lgfs2_metadata[] = { - [LGFS2_MT_GFS2_SB] = { - .versions = LGFS2_MD_GFS2, - .header = 1, - .mh_type = GFS2_METATYPE_SB, - .mh_format = GFS2_FORMAT_SB, - .name = "gfs2_sb", - .fields = gfs2_sb_fields, - .nfields = ARRAY_SIZE(gfs2_sb_fields), - .size = sizeof(struct gfs2_sb), - }, - [LGFS2_MT_GFS_SB] = { - .versions = LGFS2_MD_GFS1, - .header = 1, - .mh_type = GFS2_METATYPE_SB, - .mh_format = GFS_FORMAT_SB, - .name = "gfs_sb", - .fields = gfs_sb_fields, - .nfields = ARRAY_SIZE(gfs_sb_fields), - .size = sizeof(struct gfs_sb), - }, - [LGFS2_MT_RINDEX] = { - .versions = LGFS2_MD_GFS1 | LGFS2_MD_GFS2, - .name = "rindex", - .fields = gfs2_rindex_fields, - .nfields = ARRAY_SIZE(gfs2_rindex_fields), - .size = sizeof(struct gfs2_rindex), - }, - [LGFS2_MT_GFS2_RGRP] = { - .versions = LGFS2_MD_GFS2, - .header = 1, - .mh_type = GFS2_METATYPE_RG, - .mh_format = GFS2_FORMAT_RG, - .name = "gfs2_rgrp", - .fields = gfs2_rgrp_fields, - .nfields = ARRAY_SIZE(gfs2_rgrp_fields), - .size = sizeof(struct gfs2_rgrp), - }, - [LGFS2_MT_GFS_RGRP] = { - .versions = LGFS2_MD_GFS1, - .header = 1, - .mh_type = GFS2_METATYPE_RG, - .mh_format = GFS2_FORMAT_RG, - .name = "gfs_rgrp", - .fields = gfs_rgrp_fields, - .nfields = ARRAY_SIZE(gfs_rgrp_fields), - .size = sizeof(struct gfs_rgrp), - }, - [LGFS2_MT_RGRP_BITMAP] = { - .versions = LGFS2_MD_GFS1 | LGFS2_MD_GFS2, - .header = 1, - .mh_type = GFS2_METATYPE_RB, - .mh_format = GFS2_FORMAT_RB, - .name = "gfs2_rgrp_bitmap", - .fields = gfs2_rgrp_bitmap_fields, - .nfields = ARRAY_SIZE(gfs2_rgrp_bitmap_fields), - .size = sizeof(struct gfs2_meta_header), - }, - [LGFS2_MT_GFS2_DINODE] = { - .versions = LGFS2_MD_GFS2, - .header = 1, - .mh_type = GFS2_METATYPE_DI, - .mh_format = GFS2_FORMAT_DI, - .name = "gfs2_dinode", - .fields = gfs2_dinode_fields, - .nfields = ARRAY_SIZE(gfs2_dinode_fields), - .size = sizeof(struct gfs2_dinode), - }, - [LGFS2_MT_GFS_DINODE] = { - .versions = LGFS2_MD_GFS1, - .header = 1, - .mh_type = GFS2_METATYPE_DI, - .mh_format = GFS2_FORMAT_DI, - .name = "gfs_dinode", - .fields = gfs_dinode_fields, - .nfields = ARRAY_SIZE(gfs_dinode_fields), - .size = sizeof(struct gfs_dinode), - }, - [LGFS2_MT_GFS2_INDIRECT] = { - .versions = LGFS2_MD_GFS2, - .header = 1, - .mh_type = GFS2_METATYPE_IN, - .mh_format = GFS2_FORMAT_IN, - .name = "gfs2_indirect", - .fields = gfs2_indirect_fields, - .nfields = ARRAY_SIZE(gfs2_indirect_fields), - .size = sizeof(struct gfs2_meta_header), - }, - [LGFS2_MT_GFS_INDIRECT] = { - .versions = LGFS2_MD_GFS1, - .header = 1, - .mh_type = GFS2_METATYPE_IN, - .mh_format = GFS2_FORMAT_IN, - .name = "gfs_indirect", - .fields = gfs_indirect_fields, - .nfields = ARRAY_SIZE(gfs_indirect_fields), - .size = sizeof(struct gfs_indirect), - }, - [LGFS2_MT_DIR_LEAF] = { - .versions = LGFS2_MD_GFS1 | LGFS2_MD_GFS2, - .header = 1, - .mh_type = GFS2_METATYPE_LF, - .mh_format = GFS2_FORMAT_LF, - .name = "gfs2_leaf", - .fields = gfs2_leaf_fields, - .nfields = ARRAY_SIZE(gfs2_leaf_fields), - .size = sizeof(struct gfs2_leaf), - }, - [LGFS2_MT_JRNL_DATA] = { - .versions = LGFS2_MD_GFS1 | LGFS2_MD_GFS2, - .header = 1, - .mh_type = GFS2_METATYPE_JD, - .mh_format = GFS2_FORMAT_JD, - .name = "gfs2_jdata", - .fields = gfs2_jdata_fields, - .nfields = ARRAY_SIZE(gfs2_jdata_fields), - .size = sizeof(struct gfs2_meta_header), - }, - [LGFS2_MT_GFS2_LOG_HEADER] = { - .versions = LGFS2_MD_GFS2, - .header = 1, - .mh_type = GFS2_METATYPE_LH, - .mh_format = GFS2_FORMAT_LH, - .name = "gfs2_log_header", - .fields = gfs2_log_header_fields, - .nfields = ARRAY_SIZE(gfs2_log_header_fields), - .size = sizeof(struct gfs2_log_header), - }, - [LGFS2_MT_GFS_LOG_HEADER] = { - .versions = LGFS2_MD_GFS1, - .header = 1, - .mh_type = GFS2_METATYPE_LH, - .mh_format = GFS2_FORMAT_LH, - .name = "gfs_log_header", - .fields = gfs_log_header_fields, - .nfields = ARRAY_SIZE(gfs_log_header_fields), - .size = sizeof(struct gfs_log_header), - }, - [LGFS2_MT_GFS2_LOG_DESC] = { - .versions = LGFS2_MD_GFS2, - .header = 1, - .mh_type = GFS2_METATYPE_LD, - .mh_format = GFS2_FORMAT_LD, - .name = "gfs2_log_desc", - .fields = gfs2_log_desc_fields, - .nfields = ARRAY_SIZE(gfs2_log_desc_fields), - .size = sizeof(struct gfs2_log_descriptor), - }, - [LGFS2_MT_GFS_LOG_DESC] = { - .versions = LGFS2_MD_GFS1, - .header = 1, - .mh_type = GFS2_METATYPE_LD, - .mh_format = GFS2_FORMAT_LD, - .name = "gfs_log_desc", - .fields = gfs_log_desc_fields, - .nfields = ARRAY_SIZE(gfs_log_desc_fields), - .size = sizeof(struct gfs_log_descriptor), - }, - [LGFS2_MT_GFS2_LOG_BLOCK] = { - .versions = LGFS2_MD_GFS2, - .header = 1, - .mh_type = GFS2_METATYPE_LB, - .mh_format = GFS2_FORMAT_LB, - .name = "gfs2_log_block", - .fields = gfs2_log_block_fields, - .nfields = ARRAY_SIZE(gfs2_log_block_fields), - .size = sizeof(struct gfs2_meta_header), - }, - [LGFS2_MT_EA_ATTR] = { - .versions = LGFS2_MD_GFS1 | LGFS2_MD_GFS2, - .header = 1, - .mh_type = GFS2_METATYPE_EA, - .mh_format = GFS2_FORMAT_EA, - .name = "gfs2_ea_attr", - .fields = gfs2_ea_attr_fields, - .nfields = ARRAY_SIZE(gfs2_ea_attr_fields), - .size = sizeof(struct gfs2_meta_header), - }, - [LGFS2_MT_EA_DATA] = { - .versions = LGFS2_MD_GFS1 | LGFS2_MD_GFS2, - .header = 1, - .mh_type = GFS2_METATYPE_ED, - .mh_format = GFS2_FORMAT_ED, - .name = "gfs2_ea_data", - .fields = gfs2_ea_data_fields, - .nfields = ARRAY_SIZE(gfs2_ea_data_fields), - .size = sizeof(struct gfs2_meta_header), - }, - [LGFS2_MT_GFS2_QUOTA_CHANGE] = { - .versions = LGFS2_MD_GFS2, - .name = "gfs2_quota_change", - .fields = gfs2_quota_change_fields, - .nfields = ARRAY_SIZE(gfs2_quota_change_fields), - .size = sizeof(struct gfs2_quota_change), - }, - [LGFS2_MT_DIRENT] = { - .versions = LGFS2_MD_GFS1 | LGFS2_MD_GFS2, - .name = "gfs2_dirent", - .fields = gfs2_dirent_fields, - .nfields = ARRAY_SIZE(gfs2_dirent_fields), - .size = sizeof(struct gfs2_dirent), - }, - [LGFS2_MT_EA_HEADER] = { - .versions = LGFS2_MD_GFS1 | LGFS2_MD_GFS2, - .name = "gfs2_ea_header", - .fields = gfs2_ea_header_fields, - .nfields = ARRAY_SIZE(gfs2_ea_header_fields), - .size = sizeof(struct gfs2_ea_header), - }, - [LGFS2_MT_GFS2_INUM_RANGE] = { - .versions = LGFS2_MD_GFS2, - .name = "gfs2_inum_range", - .fields = gfs2_inum_range_fields, - .nfields = ARRAY_SIZE(gfs2_inum_range_fields), - .size = sizeof(struct gfs2_inum_range), - }, - [LGFS2_MT_STATFS_CHANGE] = { - .versions = LGFS2_MD_GFS1 | LGFS2_MD_GFS2, - .name = "gfs2_statfs_change", - .fields = gfs2_statfs_change_fields, - .nfields = ARRAY_SIZE(gfs2_statfs_change_fields), - .size = sizeof(struct gfs2_statfs_change), - }, - [LGFS2_MT_GFS_JINDEX] = { - .versions = LGFS2_MD_GFS1, - .name = "gfs_jindex", - .fields = gfs_jindex_fields, - .nfields = ARRAY_SIZE(gfs_jindex_fields), - .size = sizeof(struct gfs_jindex), - }, - [LGFS2_MT_GFS_BLOCK_TAG] = { - .versions = LGFS2_MD_GFS1, - .name = "gfs_block_tag", - .fields = gfs_block_tag_fields, - .nfields = ARRAY_SIZE(gfs_block_tag_fields), - .size = sizeof(struct gfs_block_tag), - }, - [LGFS2_MT_DATA] = { - .versions = LGFS2_MD_GFS1 | LGFS2_MD_GFS2, - .name = "data", - }, - [LGFS2_MT_FREE] = { - .versions = LGFS2_MD_GFS1 | LGFS2_MD_GFS2, - .name = "free", - }, -}; - -const unsigned lgfs2_metadata_size = ARRAY_SIZE(lgfs2_metadata); - -const struct lgfs2_metafield *lgfs2_find_mfield_name(const char *name, const struct lgfs2_metadata *mtype) -{ - int j; - const struct lgfs2_metafield *f; - - for (j = 0; j < mtype->nfields; j++) { - f = &mtype->fields[j]; - if (strcmp(f->name, name) == 0) - return f; - } - return NULL; -} - -static int check_metadata_sizes(void) -{ - unsigned offset; - int i, j; - int ret = 0; - - for (i = 0; i < lgfs2_metadata_size; i++) { - const struct lgfs2_metadata *m = &lgfs2_metadata[i]; - offset = 0; - for (j = 0; j < m->nfields; j++) { - const struct lgfs2_metafield *f = &m->fields[j]; - if (f->offset != offset) { - fprintf(stderr, "%s: %s: offset is %u, expected %u\n", m->name, f->name, f->offset, offset); - ret = -1; - } - offset += f->length; - } - if (offset != m->size) { - fprintf(stderr, "%s: size mismatch between struct %u and fields %u\n", m->name, m->size, offset); - ret = -1; - } - } - - return ret; -} - -static int check_symtab(void) -{ - int i, j; - int ret = 0; - - for (i = 0; i < lgfs2_metadata_size; i++) { - const struct lgfs2_metadata *m = &lgfs2_metadata[i]; - for (j = 0; j < m->nfields; j++) { - const struct lgfs2_metafield *f = &m->fields[j]; - if (f->flags & (LGFS2_MFF_MASK|LGFS2_MFF_ENUM)) { - if (f->symtab == NULL) { - fprintf(stderr, "%s: Missing symtab for %s\n", m->name, f->name); - ret = -1; - } - } - if (f->symtab) { - if (!(f->flags & (LGFS2_MFF_MASK|LGFS2_MFF_ENUM))) { - fprintf(stderr, "%s: Symtab for non-enum and non-mask field %s\n", m->name, f->name); - ret = -1; - } - } - } - } - - return ret; -} - -static int check_ptrs(void) -{ - int i, j; - int ret = 0; - - for (i = 0; i < lgfs2_metadata_size; i++) { - const struct lgfs2_metadata *m = &lgfs2_metadata[i]; - for (j = 0; j < m->nfields; j++) { - const struct lgfs2_metafield *f = &m->fields[j]; - if ((f->flags & LGFS2_MFF_POINTER) && !f->points_to) { - fprintf(stderr, "%s: Pointer entry %s has no destination\n", m->name, f->name); - ret = -1; - } - } - } - - return ret; -} - -int lgfs2_selfcheck(void) -{ - int ret = 0; - - ret |= check_metadata_sizes(); - ret |= check_symtab(); - ret |= check_ptrs(); - - return ret; -} - -const struct lgfs2_metadata *lgfs2_find_mtype(uint32_t mh_type, const unsigned versions) -{ - const struct lgfs2_metadata *m = lgfs2_metadata; - unsigned n = 0; - - do { - if ((m[n].versions & versions) && m[n].mh_type == mh_type) - return &m[n]; - n++; - } while (n < lgfs2_metadata_size); - - return NULL; -} - -const struct lgfs2_metadata *lgfs2_find_mtype_name(const char *name, const unsigned versions) -{ - const struct lgfs2_metadata *m = lgfs2_metadata; - unsigned n = 0; - - do { - if ((m[n].versions & versions) && !strcmp(m[n].name, name)) - return &m[n]; - n++; - } while (n < lgfs2_metadata_size); - - return NULL; -} - -int lgfs2_field_str(char *str, const size_t size, const char *blk, const struct lgfs2_metafield *field, int hex) -{ - const char *fieldp = blk + field->offset; - - errno = EINVAL; - if (str == NULL) - return 1; - - if (field->flags & LGFS2_MFF_UUID) { -#ifdef GFS2_HAS_UUID - char readable_uuid[36+1]; - uuid_t uuid; - - memcpy(uuid, fieldp, sizeof(uuid_t)); - uuid_unparse(uuid, readable_uuid); - snprintf(str, size, "%s", readable_uuid); -#endif - } else if (field->flags & LGFS2_MFF_STRING) { - snprintf(str, size, "%s", fieldp); - } else { - switch(field->length) { - case sizeof(uint8_t): - snprintf(str, size, hex? "%"PRIx8 : "%"PRIu8, *(uint8_t *)fieldp); - break; - case sizeof(uint16_t): - snprintf(str, size, hex? "%"PRIx16 : "%"PRIu16, be16_to_cpu(*(uint16_t *)fieldp)); - break; - case sizeof(uint32_t): - snprintf(str, size, hex? "%"PRIx32 : "%"PRIu32, be32_to_cpu(*(uint32_t *)fieldp)); - break; - case sizeof(uint64_t): - snprintf(str, size, hex? "%"PRIx64 : "%"PRIu64, be64_to_cpu(*(uint64_t *)fieldp)); - break; - default: - break; - } - } - str[size - 1] = '\0'; - return 0; -} - -int lgfs2_field_assign(char *blk, const struct lgfs2_metafield *field, const void *val) -{ - char *fieldp = blk + field->offset; - - if (field->flags & LGFS2_MFF_UUID) { - memcpy(fieldp, val, 16); - return 0; - } - - errno = EINVAL; - if (field->flags & LGFS2_MFF_STRING) { - size_t len = strnlen(val, field->length); - - if (len >= field->length) - return 1; - strncpy(fieldp, val, field->length - 1); - fieldp[field->length - 1] = '\0'; - return 0; - } - - switch(field->length) { - case sizeof(uint8_t): - *fieldp = *(uint8_t *)val; - return 0; - case sizeof(uint16_t): - *(uint16_t *)fieldp = cpu_to_be16(*(uint16_t *)val); - return 0; - case sizeof(uint32_t): - *(uint32_t *)fieldp = cpu_to_be32(*(uint32_t *)val); - return 0; - case sizeof(uint64_t): - *(uint64_t *)fieldp = cpu_to_be64(*(uint64_t *)val); - return 0; - default: - /* Will never happen */ - break; - } - - return 1; -} diff --git a/gfs2/libgfs2/recovery.c b/gfs2/libgfs2/recovery.c index 06f8111..6b14bf9 100644 --- a/gfs2/libgfs2/recovery.c +++ b/gfs2/libgfs2/recovery.c @@ -241,7 +241,7 @@ int clean_journal(struct gfs2_inode *ip, struct gfs2_log_header *head) lh->lh_sequence = cpu_to_be64(head->lh_sequence + 1); lh->lh_flags = cpu_to_be32(GFS2_LOG_HEAD_UNMOUNT); lh->lh_blkno = cpu_to_be32(lblock); - hash = lgfs2_log_header_hash(bh->b_data); + hash = gfs2_disk_hash((const char *)lh, sizeof(struct gfs2_log_header)); lh->lh_hash = cpu_to_be32(hash); bmodified(bh); brelse(bh); diff --git a/gfs2/libgfs2/recovery.c.bz1659490-gfs2_utils_Wrong_hash_value_used_to_clean_journals b/gfs2/libgfs2/recovery.c.bz1659490-gfs2_utils_Wrong_hash_value_used_to_clean_journals deleted file mode 100644 index 6b14bf9..0000000 --- a/gfs2/libgfs2/recovery.c.bz1659490-gfs2_utils_Wrong_hash_value_used_to_clean_journals +++ /dev/null @@ -1,251 +0,0 @@ -#include "clusterautoconfig.h" - -/* - * NOTE: - * - * This code was pilfered from the gfs2 kernel and adapted to userland. - * If you change this part, you should evaluate whether the upstream kernel - * version of recovery.c should be changed as well. Likewise, if the - * upstream version changes, this part should be kept in sync. - * - */ - -#include -#include -#include "libgfs2.h" - -void gfs2_replay_incr_blk(struct gfs2_inode *ip, unsigned int *blk) -{ - uint32_t jd_blocks = ip->i_di.di_size / ip->i_sbd->sd_sb.sb_bsize; - - if (++*blk == jd_blocks) - *blk = 0; -} - -int gfs2_replay_read_block(struct gfs2_inode *ip, unsigned int blk, - struct gfs2_buffer_head **bh) -{ - int new = 0; - uint64_t dblock; - - block_map(ip, blk, &new, &dblock, NULL, FALSE); - if (!dblock) - return -EIO; - - *bh = bread(ip->i_sbd, dblock); - return 0; -} - -/** - * get_log_header - read the log header for a given segment - * @ip: the journal incore inode - * @blk: the block to look at - * @lh: the log header to return - * - * Read the log header for a given segement in a given journal. Do a few - * sanity checks on it. - * - * Returns: 0 on success, - * 1 if the header was invalid or incomplete, - * errno on error - */ - -int get_log_header(struct gfs2_inode *ip, unsigned int blk, - struct gfs2_log_header *head) -{ - struct gfs2_buffer_head *bh; - struct gfs2_log_header lh, *tmp; - uint32_t hash, saved_hash; - uint32_t lh_crc = 0; - uint32_t crc; - int error; - - error = gfs2_replay_read_block(ip, blk, &bh); - if (error) - return error; - - tmp = (struct gfs2_log_header *)bh->b_data; - saved_hash = tmp->lh_hash; - tmp->lh_hash = 0; - hash = lgfs2_log_header_hash(bh->b_data); - tmp->lh_hash = saved_hash; - crc = lgfs2_log_header_crc(bh->b_data, ip->i_sbd->bsize); - gfs2_log_header_in(&lh, bh->b_data); - brelse(bh); -#ifdef GFS2_HAS_LH_V2 - lh_crc = lh.lh_crc; -#endif - if (error || lh.lh_blkno != blk || lh.lh_hash != hash) - return 1; - /* Don't check the crc if it's zero, as it is in pre-v2 log headers */ - if (lh_crc != 0 && lh_crc != crc) - return 1; - - *head = lh; - - return 0; -} - -/** - * find_good_lh - find a good log header - * @ip: the journal incore inode - * @blk: the segment to start searching from - * @lh: the log header to fill in - * @forward: if true search forward in the log, else search backward - * - * Call get_log_header() to get a log header for a segment, but if the - * segment is bad, either scan forward or backward until we find a good one. - * - * Returns: errno - */ -static int find_good_lh(struct gfs2_inode *ip, unsigned int *blk, struct gfs2_log_header *head) -{ - unsigned int orig_blk = *blk; - int error; - uint32_t jd_blocks = ip->i_di.di_size / ip->i_sbd->sd_sb.sb_bsize; - - for (;;) { - error = get_log_header(ip, *blk, head); - if (error <= 0) - return error; - - if (++*blk == jd_blocks) - *blk = 0; - - if (*blk == orig_blk) - return -EIO; - } -} - -/** - * jhead_scan - make sure we've found the head of the log - * @jd: the journal - * @head: this is filled in with the log descriptor of the head - * - * At this point, seg and lh should be either the head of the log or just - * before. Scan forward until we find the head. - * - * Returns: errno - */ - -static int jhead_scan(struct gfs2_inode *ip, struct gfs2_log_header *head) -{ - unsigned int blk = head->lh_blkno; - uint32_t jd_blocks = ip->i_di.di_size / ip->i_sbd->sd_sb.sb_bsize; - struct gfs2_log_header lh; - int error; - - for (;;) { - if (++blk == jd_blocks) - blk = 0; - - error = get_log_header(ip, blk, &lh); - if (error < 0) - return error; - if (error == 1) - continue; - - if (lh.lh_sequence == head->lh_sequence) - return -EIO; - if (lh.lh_sequence < head->lh_sequence) - break; - - *head = lh; - } - - return 0; -} - -/** - * gfs2_find_jhead - find the head of a log - * @jd: the journal - * @head: the log descriptor for the head of the log is returned here - * - * Do a binary search of a journal and find the valid log entry with the - * highest sequence number. (i.e. the log head) - * - * Returns: errno - */ - -int gfs2_find_jhead(struct gfs2_inode *ip, struct gfs2_log_header *head) -{ - struct gfs2_log_header lh_1, lh_m; - uint32_t blk_1, blk_2, blk_m; - uint32_t jd_blocks = ip->i_di.di_size / ip->i_sbd->sd_sb.sb_bsize; - int error; - - blk_1 = 0; - blk_2 = jd_blocks - 1; - - for (;;) { - blk_m = (blk_1 + blk_2) / 2; - - error = find_good_lh(ip, &blk_1, &lh_1); - if (error) - return error; - - error = find_good_lh(ip, &blk_m, &lh_m); - if (error) - return error; - - if (blk_1 == blk_m || blk_m == blk_2) - break; - - if (lh_1.lh_sequence <= lh_m.lh_sequence) - blk_1 = blk_m; - else - blk_2 = blk_m; - } - - error = jhead_scan(ip, &lh_1); - if (error) - return error; - - *head = lh_1; - - return error; -} - -/** - * clean_journal - mark a dirty journal as being clean - * @sdp: the filesystem - * @jd: the journal - * @head: the head journal to start from - * - * Returns: errno - */ - -int clean_journal(struct gfs2_inode *ip, struct gfs2_log_header *head) -{ - unsigned int lblock; - struct gfs2_log_header *lh; - uint32_t hash; - struct gfs2_buffer_head *bh; - int new = 0; - uint64_t dblock; - - lblock = head->lh_blkno; - gfs2_replay_incr_blk(ip, &lblock); - block_map(ip, lblock, &new, &dblock, NULL, 0); - if (!dblock) - return -EIO; - - bh = bread(ip->i_sbd, dblock); - memset(bh->b_data, 0, ip->i_sbd->bsize); - - lh = (struct gfs2_log_header *)bh->b_data; - memset(lh, 0, sizeof(struct gfs2_log_header)); - lh->lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC); - lh->lh_header.mh_type = cpu_to_be32(GFS2_METATYPE_LH); - lh->lh_header.mh_format = cpu_to_be32(GFS2_FORMAT_LH); - lh->lh_sequence = cpu_to_be64(head->lh_sequence + 1); - lh->lh_flags = cpu_to_be32(GFS2_LOG_HEAD_UNMOUNT); - lh->lh_blkno = cpu_to_be32(lblock); - hash = gfs2_disk_hash((const char *)lh, sizeof(struct gfs2_log_header)); - lh->lh_hash = cpu_to_be32(hash); - bmodified(bh); - brelse(bh); - - return 0; -} - diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c index ad044d0..190715e 100644 --- a/gfs2/libgfs2/rgrp.c +++ b/gfs2/libgfs2/rgrp.c @@ -332,7 +332,7 @@ static uint64_t align_block(const uint64_t base, const uint64_t align) */ uint64_t lgfs2_rgrp_align_addr(const lgfs2_rgrps_t rgs, uint64_t addr) { - return align_block(addr, rgs->align_off); + return align_block(addr, rgs->align); } /** diff --git a/gfs2/libgfs2/rgrp.c.bz1698858-mkfs_gfs2_Improve_alignment_of_first_resource_group b/gfs2/libgfs2/rgrp.c.bz1698858-mkfs_gfs2_Improve_alignment_of_first_resource_group deleted file mode 100644 index 190715e..0000000 --- a/gfs2/libgfs2/rgrp.c.bz1698858-mkfs_gfs2_Improve_alignment_of_first_resource_group +++ /dev/null @@ -1,1016 +0,0 @@ -#include "clusterautoconfig.h" - -#include -#include -#include -#include -#include -#include - -#include "libgfs2.h" -#include "rgrp.h" - -#define RG_SYNC_TOLERANCE 1000 -#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S)) - -static void compute_bitmaps(lgfs2_rgrp_t rg, const unsigned bsize) -{ - int x; - - rg->bits[0].bi_offset = sizeof(struct gfs2_rgrp); - rg->bits[0].bi_start = 0; - rg->bits[0].bi_len = bsize - sizeof(struct gfs2_rgrp); - - for (x = 1; x < rg->ri.ri_length; x++) { - rg->bits[x].bi_offset = sizeof(struct gfs2_meta_header); - rg->bits[x].bi_start = rg->bits[x - 1].bi_start + rg->bits[x - 1].bi_len; - rg->bits[x].bi_len = bsize - sizeof(struct gfs2_meta_header); - } - x--; - rg->bits[x].bi_len = rg->ri.ri_bitbytes - rg->bits[x].bi_start; -} - -/** - * gfs2_compute_bitstructs - Compute the bitmap sizes - * bsize: Block size - * rgd: The resource group descriptor - * Returns: 0 on success, -1 on error - */ -int gfs2_compute_bitstructs(const uint32_t bsize, struct rgrp_tree *rgd) -{ - uint32_t length = rgd->ri.ri_length; - uint32_t bytes_left; - int ownbits = 0; - - /* Max size of an rg is 2GB. A 2GB RG with (minimum) 512-byte blocks - has 4194304 blocks. We can represent 4 blocks in one bitmap byte. - Therefore, all 4194304 blocks can be represented in 1048576 bytes. - Subtract a metadata header for each 512-byte block and we get - 488 bytes of bitmap per block. Divide 1048576 by 488 and we can - be assured we should never have more than 2149 of them. */ - errno = EINVAL; - if (length > 2149 || length == 0) - return -1; - - if(rgd->bits == NULL) { - rgd->bits = calloc(length, sizeof(struct gfs2_bitmap)); - if(rgd->bits == NULL) - return -1; - ownbits = 1; - } - - compute_bitmaps(rgd, bsize); - bytes_left = rgd->ri.ri_bitbytes - (rgd->bits[rgd->ri.ri_length - 1].bi_start + - rgd->bits[rgd->ri.ri_length - 1].bi_len); - errno = EINVAL; - if(bytes_left) - goto errbits; - - if((rgd->bits[length - 1].bi_start + - rgd->bits[length - 1].bi_len) * GFS2_NBBY != rgd->ri.ri_data) - goto errbits; - - return 0; -errbits: - if (ownbits) { - free(rgd->bits); - rgd->bits = NULL; - } - return -1; -} - - -/** - * blk2rgrpd - Find resource group for a given data block number - * @sdp: The GFS superblock - * @n: The data block number - * - * Returns: Ths resource group, or NULL if not found - */ -struct rgrp_tree *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, uint64_t blk) -{ - struct rgrp_tree *rgd = (struct rgrp_tree *)sdp->rgtree.osi_node; - while (rgd) { - if (blk < rgd->ri.ri_addr) - rgd = (struct rgrp_tree *)rgd->node.osi_left; - else if (blk >= rgd->ri.ri_data0 + rgd->ri.ri_data) - rgd = (struct rgrp_tree *)rgd->node.osi_right; - else - return rgd; - } - return NULL; -} - -/** - * Allocate a multi-block buffer for a resource group's bitmaps. This is done - * as one chunk and should be freed using lgfs2_rgrp_bitbuf_free(). - * Returns 0 on success with the bitmap buffer allocated in the resource group, - * or non-zero on failure with errno set. - */ -int lgfs2_rgrp_bitbuf_alloc(lgfs2_rgrp_t rg) -{ - struct gfs2_sbd *sdp = rg->rgrps->sdp; - struct gfs2_buffer_head *bhs; - size_t len = rg->ri.ri_length * sdp->bsize; - unsigned long io_align = sdp->bsize; - unsigned i; - char *bufs; - - if (rg->rgrps->align > 0) { - len = ROUND_UP(len, rg->rgrps->align * sdp->bsize); - io_align = rg->rgrps->align_off * sdp->bsize; - } - bhs = calloc(rg->ri.ri_length, sizeof(struct gfs2_buffer_head)); - if (bhs == NULL) - return 1; - - if (posix_memalign((void **)&bufs, io_align, len) != 0) { - errno = ENOMEM; - free(bhs); - return 1; - } - memset(bufs, 0, len); - - for (i = 0; i < rg->ri.ri_length; i++) { - rg->bits[i].bi_bh = bhs + i; - rg->bits[i].bi_bh->iov.iov_base = bufs + (i * sdp->bsize); - rg->bits[i].bi_bh->iov.iov_len = sdp->bsize; - rg->bits[i].bi_bh->b_blocknr = rg->ri.ri_addr + i; - rg->bits[i].bi_bh->sdp = sdp; - } - return 0; -} - -/** - * Free the multi-block bitmap buffer from a resource group. The buffer should - * have been allocated as a single chunk as in lgfs2_rgrp_bitbuf_alloc(). - * This does not implicitly write the bitmaps to disk. Use lgfs2_rgrp_write() - * for that. - * rg: The resource groups whose bitmap buffer should be freed. - */ -void lgfs2_rgrp_bitbuf_free(lgfs2_rgrp_t rg) -{ - unsigned i; - free(rg->bits[0].bi_bh->iov.iov_base); - free(rg->bits[0].bi_bh); - for (i = 0; i < rg->ri.ri_length; i++) - rg->bits[i].bi_bh = NULL; -} - -/** - * Check a resource group's crc - * Returns 0 on success, non-zero if crc is bad - */ -int lgfs2_rgrp_crc_check(char *buf) -{ - int ret = 0; -#ifdef GFS2_HAS_RG_RI_FIELDS - struct gfs2_rgrp *rg = (struct gfs2_rgrp *)buf; - uint32_t crc = rg->rg_crc; - - if (crc == 0) - return 0; - - rg->rg_crc = 0; - if (be32_to_cpu(crc) != gfs2_disk_hash(buf, sizeof(struct gfs2_rgrp))) - ret = 1; - rg->rg_crc = crc; -#endif - return ret; -} - -/** - * Set the crc of an on-disk resource group - */ -void lgfs2_rgrp_crc_set(char *buf) -{ -#ifdef GFS2_HAS_RG_RI_FIELDS - struct gfs2_rgrp *rg = (struct gfs2_rgrp *)buf; - uint32_t crc; - - rg->rg_crc = 0; - crc = gfs2_disk_hash(buf, sizeof(struct gfs2_rgrp)); - rg->rg_crc = cpu_to_be32(crc); -#endif -} - -/** - * gfs2_rgrp_read - read in the resource group information from disk. - * @rgd - resource group structure - * returns: 0 if no error, otherwise the block number that failed - */ -uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_tree *rgd) -{ - unsigned x, length = rgd->ri.ri_length; - struct gfs2_buffer_head **bhs; - - if (length == 0 || gfs2_check_range(sdp, rgd->ri.ri_addr)) - return -1; - - bhs = calloc(length, sizeof(struct gfs2_buffer_head *)); - if (bhs == NULL) - return -1; - - if (breadm(sdp, bhs, length, rgd->ri.ri_addr)) { - free(bhs); - return -1; - } - - for (x = 0; x < length; x++) { - struct gfs2_bitmap *bi = &rgd->bits[x]; - int mtype = (x ? GFS2_METATYPE_RB : GFS2_METATYPE_RG); - - bi->bi_bh = bhs[x]; - if (gfs2_check_meta(bi->bi_bh, mtype)) { - unsigned err = x; - do { - brelse(rgd->bits[x].bi_bh); - rgd->bits[x].bi_bh = NULL; - } while (x-- != 0); - free(bhs); - return rgd->ri.ri_addr + err; - } - } - if (sdp->gfs1) - gfs_rgrp_in((struct gfs_rgrp *)&rgd->rg, rgd->bits[0].bi_bh); - else { - if (lgfs2_rgrp_crc_check(rgd->bits[0].bi_bh->b_data)) { - free(bhs); - return rgd->ri.ri_addr; - } - gfs2_rgrp_in(&rgd->rg, rgd->bits[0].bi_bh->b_data); - } - free(bhs); - return 0; -} - -void gfs2_rgrp_relse(struct rgrp_tree *rgd) -{ - int x, length = rgd->ri.ri_length; - - if (rgd->bits == NULL) - return; - for (x = 0; x < length; x++) { - if (rgd->bits[x].bi_bh && rgd->bits[x].bi_bh->b_data) { - brelse(rgd->bits[x].bi_bh); - rgd->bits[x].bi_bh = NULL; - } - } -} - -struct rgrp_tree *rgrp_insert(struct osi_root *rgtree, uint64_t rgblock) -{ - struct osi_node **newn = &rgtree->osi_node, *parent = NULL; - struct rgrp_tree *data; - - /* Figure out where to put new node */ - while (*newn) { - struct rgrp_tree *cur = (struct rgrp_tree *)*newn; - - parent = *newn; - if (rgblock < cur->ri.ri_addr) - newn = &((*newn)->osi_left); - else if (rgblock > cur->ri.ri_addr) - newn = &((*newn)->osi_right); - else - return cur; - } - - data = calloc(1, sizeof(struct rgrp_tree)); - if (!data) - return NULL; - /* Add new node and rebalance tree. */ - data->ri.ri_addr = rgblock; - osi_link_node(&data->node, parent, newn); - osi_insert_color(&data->node, rgtree); - - return data; -} - -void gfs2_rgrp_free(struct osi_root *rgrp_tree) -{ - struct rgrp_tree *rgd; - int rgs_since_sync = 0; - struct osi_node *n; - struct gfs2_sbd *sdp = NULL; - - if (OSI_EMPTY_ROOT(rgrp_tree)) - return; - while ((n = osi_first(rgrp_tree))) { - rgd = (struct rgrp_tree *)n; - - if (rgd->bits) { - if (rgd->bits[0].bi_bh) { /* if a buffer exists */ - rgs_since_sync++; - if (rgs_since_sync >= RG_SYNC_TOLERANCE) { - if (!sdp) - sdp = rgd->bits[0].bi_bh->sdp; - fsync(sdp->device_fd); - rgs_since_sync = 0; - } - gfs2_rgrp_relse(rgd); /* free them all. */ - } - free(rgd->bits); - } - osi_erase(&rgd->node, rgrp_tree); - free(rgd); - } -} - -static uint64_t align_block(const uint64_t base, const uint64_t align) -{ - if ((align > 0) && ((base % align) > 0)) - return (base - (base % align)) + align; - return base; -} - -/** - * Calculate the aligned block address of a resource group. - * rgs: The resource groups handle - * base: The base address of the first resource group address, in blocks - * Returns the aligned address of the first resource group. - */ -uint64_t lgfs2_rgrp_align_addr(const lgfs2_rgrps_t rgs, uint64_t addr) -{ - return align_block(addr, rgs->align); -} - -/** - * Calculate the aligned relative address of the next resource group (and thus - * the aligned length of this one). - * rgs: The resource groups handle - * base: The base length of the current resource group, in blocks - * Returns the length of the resource group (the aligned relative address of - * the next one) - */ -uint32_t lgfs2_rgrp_align_len(const lgfs2_rgrps_t rgs, uint32_t len) -{ - return align_block(len, rgs->align) + rgs->align_off; -} - -/** - * Plan the sizes of resource groups for remaining free space, based on a - * target maximum size. In order to make best use of the space while keeping - * the resource groups aligned appropriately we need to either reduce the - * length of every resource group or of a subset of the resource groups, so - * we're left with either one or two resource group sizes. We keep track of - * both of these and the numbers of each size of resource group inside the - * resource groups descriptor. - * rgs: The resource groups descriptor - * space: The number of remaining blocks to be allocated - * tgtsize: The target resource group size in blocks - * Returns the number of resource groups planned to fit in the given space, or - * 0 if the smallest resource group would be smaller than GFS2_MIN_RGSIZE. - */ -uint32_t lgfs2_rgrps_plan(const lgfs2_rgrps_t rgs, uint64_t space, uint32_t tgtsize) -{ - uint32_t maxlen = (GFS2_MAX_RGSIZE << 20) / rgs->sdp->bsize; - uint32_t minlen = (GFS2_MIN_RGSIZE << 20) / rgs->sdp->bsize; - - /* Apps should already have checked that the rg size is <= - GFS2_MAX_RGSIZE but just in case alignment pushes it over we clamp - it back down while calculating the initial rgrp length. */ - do { - rgs->plan[0].len = lgfs2_rgrp_align_len(rgs, tgtsize); - tgtsize -= (rgs->align + 1); - } while (rgs->plan[0].len > maxlen); - - rgs->plan[0].num = space / rgs->plan[0].len; - - if ((space - (rgs->plan[0].num * rgs->plan[0].len)) > rgs->align) { - unsigned adj = (rgs->align > 0) ? rgs->align : 1; - - /* Spread the adjustment required to fit a new rgrp at the end - over all of the rgrps so that we don't end with a single - tiny one. */ - rgs->plan[0].num++; - while (((rgs->plan[0].len - adj) * (uint64_t)rgs->plan[0].num) >= space) - rgs->plan[0].len -= adj; - - /* We've adjusted the size of the rgrps down as far as we can - without leaving a large gap at the end of the device now, - but we still need to reduce the size of some rgrps in order - to make everything fit, so we use the second rgplan to - specify a second length for a subset of the resource groups. - If plan[0].len already divides the space with no remainder, - plan[1].num will stay 0 and it won't be used. */ - rgs->plan[1].len = rgs->plan[0].len - adj; - rgs->plan[1].num = 0; - - while (((rgs->plan[0].len * rgs->plan[0].num) + - (rgs->plan[1].len * rgs->plan[1].num)) >= space) { - /* Total number of rgrps stays constant now. We just - need to shift some weight around */ - rgs->plan[0].num--; - rgs->plan[1].num++; - } - } - - /* Once we've reached this point, - (plan[0].num * plan[0].len) + (plan[1].num * plan[1].len) - will be less than one adjustment smaller than 'space'. */ - if (rgs->plan[0].len < minlen) - return 0; - - return rgs->plan[0].num + rgs->plan[1].num; -} - -/** - * Create and initialise an empty set of resource groups - * bsize: The block size of the fs - * devlen: The length of the device, in fs blocks - * align: The required stripe alignment of the resource groups. Must be a multiple of 'offset'. - * offset: The required stripe offset of the resource groups - * Returns an initialised lgfs2_rgrps_t or NULL if unsuccessful with errno set - */ -lgfs2_rgrps_t lgfs2_rgrps_init(struct gfs2_sbd *sdp, uint64_t align, uint64_t offset) -{ - lgfs2_rgrps_t rgs; - - errno = EINVAL; - if (offset != 0 && (align % offset) != 0) - return NULL; - - rgs = calloc(1, sizeof(*rgs)); - if (rgs == NULL) - return NULL; - - rgs->sdp = sdp; - rgs->align = align; - rgs->align_off = offset; - memset(&rgs->root, 0, sizeof(rgs->root)); - - return rgs; -} - -/** - * Populate a set of resource groups from a gfs2 rindex file. - * fd: An open file descriptor for the rindex file. - * rgs: The set of resource groups. - * Returns the number of resource groups added to the set or 0 on error with - * errno set. - */ -unsigned lgfs2_rindex_read_fd(int fd, lgfs2_rgrps_t rgs) -{ - unsigned count = 0; - char buf[sizeof(struct gfs2_rindex)]; - - errno = EINVAL; - if (fd < 0 || rgs == NULL) - return 0; - - while (1) { - lgfs2_rgrp_t rg; - struct gfs2_rindex ri; - ssize_t ret = read(fd, buf, sizeof(struct gfs2_rindex)); - if (ret == 0) - break; - - if (ret != sizeof(struct gfs2_rindex)) - return 0; - - gfs2_rindex_in(&ri, buf); - rg = lgfs2_rgrps_append(rgs, &ri, 0); - if (rg == NULL) - return 0; - count++; - } - return count; -} - -/** - * Read a rindex entry into a set of resource groups - * rip: The inode of the rindex file - * rgs: The set of resource groups. - * i: The index of the entry to read from the rindex file - * Returns the new rindex entry added to the set or NULL on error with errno - * set. - */ -const struct gfs2_rindex *lgfs2_rindex_read_one(struct gfs2_inode *rip, lgfs2_rgrps_t rgs, unsigned i) -{ - uint64_t off = i * sizeof(struct gfs2_rindex); - char buf[sizeof(struct gfs2_rindex)]; - struct gfs2_rindex ri; - lgfs2_rgrp_t rg; - int ret; - - errno = EINVAL; - if (rip == NULL || rgs == NULL) - return NULL; - - ret = gfs2_readi(rip, buf, off, sizeof(struct gfs2_rindex)); - if (ret != sizeof(struct gfs2_rindex)) - return NULL; - - gfs2_rindex_in(&ri, buf); - rg = lgfs2_rgrps_append(rgs, &ri, 0); - if (rg == NULL) - return NULL; - - return &rg->ri; -} - -/** - * Free a set of resource groups created with lgfs2_rgrps_append() etc. This - * does not write any dirty buffers to disk. See lgfs2_rgrp_write(). - * rgs: A pointer to the set of resource groups to be freed. - */ -void lgfs2_rgrps_free(lgfs2_rgrps_t *rgs) -{ - lgfs2_rgrp_t rg; - struct osi_root *tree = &(*rgs)->root; - - while ((rg = (struct rgrp_tree *)osi_first(tree))) { - int i; - for (i = 0; i < rg->ri.ri_length; i++) { - if (rg->bits[i].bi_bh != NULL) { - free(rg->bits[i].bi_bh); - rg->bits[i].bi_bh = NULL; - } - } - osi_erase(&rg->node, tree); - free(rg); - } - free(*rgs); - *rgs = NULL; -} - -/** - * Calculate the fields for a new entry in the resource group index. - * ri: A pointer to the resource group index entry to be calculated. - * addr: The address at which to place this resource group - * len: The required length of the resource group, in fs blocks. - * If rglen is 0, geometry previously calculated by lgfs2_rgrps_plan() will be used. - * Returns the calculated address of the next resource group or 0 with errno set: - * EINVAL - The entry pointer is NULL - * ENOSPC - This rgrp would extend past the end of the device - */ -uint64_t lgfs2_rindex_entry_new(lgfs2_rgrps_t rgs, struct gfs2_rindex *ri, uint64_t addr, uint32_t len) -{ - int plan = -1; - errno = EINVAL; - if (!ri) - return 0; - - errno = ENOSPC; - if (rgs->plan[0].num > 0) - plan = 0; - else if (rgs->plan[1].num > 0) - plan = 1; - else if (len == 0) - return 0; - - if (plan >= 0 && (len == 0 || len == rgs->plan[plan].len)) { - len = rgs->plan[plan].len; - rgs->plan[plan].num--; - } - - if (addr + len > rgs->sdp->device.length) - return 0; - - ri->ri_addr = addr; - ri->ri_length = rgblocks2bitblocks(rgs->sdp->bsize, len, &ri->ri_data); - ri->__pad = 0; - ri->ri_data0 = ri->ri_addr + ri->ri_length; - ri->ri_bitbytes = ri->ri_data / GFS2_NBBY; - memset(&ri->ri_reserved, 0, sizeof(ri->ri_reserved)); - - return ri->ri_addr + len; -} - -/** - * Return the rindex structure relating to a resource group. - * The return type is const to advise callers that making changes to this - * structure directly isn't wise. libgfs2 functions should be used instead. - */ -const struct gfs2_rindex *lgfs2_rgrp_index(lgfs2_rgrp_t rg) -{ - return &rg->ri; -} - -/** - * Return the rgrp structure relating to a resource group. - * The return type is const to advise callers that making changes to this - * structure directly isn't wise. libgfs2 functions should be used instead. - */ -const struct gfs2_rgrp *lgfs2_rgrp_rgrp(lgfs2_rgrp_t rg) -{ - return &rg->rg; -} - -/** - * Returns the total resource group size, in blocks, required to give blksreq data blocks - */ -unsigned lgfs2_rgsize_for_data(uint64_t blksreq, unsigned bsize) -{ - const uint32_t blks_rgrp = GFS2_NBBY * (bsize - sizeof(struct gfs2_rgrp)); - const uint32_t blks_meta = GFS2_NBBY * (bsize - sizeof(struct gfs2_meta_header)); - unsigned bitblocks = 1; - blksreq = (blksreq + 3) & ~3; - if (blksreq > blks_rgrp) - bitblocks += ((blksreq - blks_rgrp) + blks_meta - 1) / blks_meta; - return bitblocks + blksreq; -} - -// Temporary function to aid in API migration -struct osi_node *lgfs2_rgrps_root(lgfs2_rgrps_t rgs) -{ - return rgs->root.osi_node; -} - -/** - * Insert a new resource group after the last resource group in a set. - * rgs: The set of resource groups - * entry: The entry to be added - * rg_skip: The value to be used for this resource group's rg_skip field - * Returns the new resource group on success or NULL on failure with errno set. - */ -lgfs2_rgrp_t lgfs2_rgrps_append(lgfs2_rgrps_t rgs, struct gfs2_rindex *entry, uint32_t rg_skip) -{ - lgfs2_rgrp_t rg; - struct osi_node **link = &rgs->root.osi_node; - struct osi_node *parent = osi_last(&rgs->root); - lgfs2_rgrp_t lastrg = (lgfs2_rgrp_t)parent; - - errno = EINVAL; - if (entry == NULL) - return NULL; - - if (lastrg != NULL) { /* Tree is not empty */ - if (entry->ri_addr <= lastrg->ri.ri_addr) - return NULL; /* Appending with a lower address doesn't make sense */ - link = &lastrg->node.osi_right; - } - - rg = calloc(1, sizeof(*rg) + (entry->ri_length * sizeof(struct gfs2_bitmap))); - if (rg == NULL) - return NULL; - - rg->bits = (struct gfs2_bitmap *)(rg + 1); - - osi_link_node(&rg->node, parent, link); - osi_insert_color(&rg->node, &rgs->root); - - memcpy(&rg->ri, entry, sizeof(struct gfs2_rindex)); - rg->rg.rg_header.mh_magic = GFS2_MAGIC; - rg->rg.rg_header.mh_type = GFS2_METATYPE_RG; - rg->rg.rg_header.mh_format = GFS2_FORMAT_RG; - rg->rg.rg_free = rg->ri.ri_data; -#ifdef GFS2_HAS_RG_SKIP - rg->rg.rg_skip = rg_skip; -#endif -#ifdef GFS2_HAS_RG_RI_FIELDS - rg->rg.rg_data0 = rg->ri.ri_data0; - rg->rg.rg_data = rg->ri.ri_data; - rg->rg.rg_bitbytes = rg->ri.ri_bitbytes; - rg->rg.rg_crc = 0; -#endif - compute_bitmaps(rg, rgs->sdp->bsize); - rg->rgrps = rgs; - return rg; -} - -/** - * Write a resource group to a file descriptor. - * Returns 0 on success or non-zero on failure with errno set - */ -int lgfs2_rgrp_write(int fd, const lgfs2_rgrp_t rg) -{ - struct gfs2_sbd *sdp = rg->rgrps->sdp; - unsigned int i; - const struct gfs2_meta_header bmh = { - .mh_magic = GFS2_MAGIC, - .mh_type = GFS2_METATYPE_RB, - .mh_format = GFS2_FORMAT_RB, - }; - int freebufs = 0; - ssize_t ret; - size_t len; - - if (rg->bits[0].bi_bh == NULL) { - freebufs = 1; - if (lgfs2_rgrp_bitbuf_alloc(rg) != 0) - return -1; - } - gfs2_rgrp_out(&rg->rg, rg->bits[0].bi_bh->b_data); - for (i = 1; i < rg->ri.ri_length; i++) - gfs2_meta_header_out(&bmh, rg->bits[i].bi_bh->b_data); - - len = sdp->bsize * rg->ri.ri_length; - if (rg->rgrps->align > 0) - len = ROUND_UP(len, rg->rgrps->align * sdp->bsize); - - ret = pwrite(sdp->device_fd, rg->bits[0].bi_bh->b_data, len, - rg->bits[0].bi_bh->b_blocknr * sdp->bsize); - - if (freebufs) - lgfs2_rgrp_bitbuf_free(rg); - - return ret == len ? 0 : -1; -} - -lgfs2_rgrp_t lgfs2_rgrp_first(lgfs2_rgrps_t rgs) -{ - return (lgfs2_rgrp_t)osi_first(&rgs->root); -} - -lgfs2_rgrp_t lgfs2_rgrp_next(lgfs2_rgrp_t rg) -{ - return (lgfs2_rgrp_t)osi_next(&rg->node); -} - -lgfs2_rgrp_t lgfs2_rgrp_prev(lgfs2_rgrp_t rg) -{ - return (lgfs2_rgrp_t)osi_prev(&rg->node); -} - -lgfs2_rgrp_t lgfs2_rgrp_last(lgfs2_rgrps_t rgs) -{ - return (lgfs2_rgrp_t)osi_last(&rgs->root); -} - -/** - * gfs2_rbm_from_block - Set the rbm based upon rgd and block number - * @rbm: The rbm with rgd already set correctly - * @block: The block number (filesystem relative) - * - * This sets the bi and offset members of an rbm based on a - * resource group and a filesystem relative block number. The - * resource group must be set in the rbm on entry, the bi and - * offset members will be set by this function. - * - * Returns: 0 on success, or non-zero with errno set - */ -int lgfs2_rbm_from_block(struct lgfs2_rbm *rbm, uint64_t block) -{ - uint64_t rblock = block - rbm->rgd->ri.ri_data0; - struct gfs2_sbd *sdp = rbm_bi(rbm)->bi_bh->sdp; - - if (rblock > UINT_MAX) { - errno = EINVAL; - return 1; - } - if (block >= rbm->rgd->ri.ri_data0 + rbm->rgd->ri.ri_data) { - errno = E2BIG; - return 1; - } - - rbm->bii = 0; - rbm->offset = (uint32_t)(rblock); - /* Check if the block is within the first block */ - if (rbm->offset < (rbm_bi(rbm)->bi_len * GFS2_NBBY)) - return 0; - - /* Adjust for the size diff between gfs2_meta_header and gfs2_rgrp */ - rbm->offset += (sizeof(struct gfs2_rgrp) - - sizeof(struct gfs2_meta_header)) * GFS2_NBBY; - rbm->bii = rbm->offset / sdp->sd_blocks_per_bitmap; - rbm->offset -= rbm->bii * sdp->sd_blocks_per_bitmap; - return 0; -} - -/** - * lgfs2_rbm_incr - increment an rbm structure - * @rbm: The rbm with rgd already set correctly - * - * This function takes an existing rbm structure and increments it to the next - * viable block offset. - * - * Returns: If incrementing the offset would cause the rbm to go past the - * end of the rgrp, true is returned, otherwise false. - * - */ -static int lgfs2_rbm_incr(struct lgfs2_rbm *rbm) -{ - if (rbm->offset + 1 < (rbm_bi(rbm)->bi_len * GFS2_NBBY)) { /* in the same bitmap */ - rbm->offset++; - return 0; - } - if (rbm->bii == rbm->rgd->ri.ri_length - 1) /* at the last bitmap */ - return 1; - - rbm->offset = 0; - rbm->bii++; - return 0; -} - -/** - * lgfs2_testbit - test a bit in the bitmaps - * @rbm: The bit to test - * - * Returns: The two bit block state of the requested bit - */ -static inline uint8_t lgfs2_testbit(const struct lgfs2_rbm *rbm) -{ - struct gfs2_bitmap *bi = rbm_bi(rbm); - const uint8_t *buffer = (uint8_t *)bi->bi_bh->b_data + bi->bi_offset; - const uint8_t *byte; - unsigned int bit; - - byte = buffer + (rbm->offset / GFS2_NBBY); - bit = (rbm->offset % GFS2_NBBY) * GFS2_BIT_SIZE; - - return (*byte >> bit) & GFS2_BIT_MASK; -} - -/** - * lgfs2_unaligned_extlen - Look for free blocks which are not byte aligned - * @rbm: Position to search (value/result) - * @n_unaligned: Number of unaligned blocks to check - * @len: Decremented for each block found (terminate on zero) - * - * Returns: true if a non-free block is encountered - */ -static int lgfs2_unaligned_extlen(struct lgfs2_rbm *rbm, uint32_t n_unaligned, uint32_t *len) -{ - uint32_t n; - uint8_t res; - - for (n = 0; n < n_unaligned; n++) { - res = lgfs2_testbit(rbm); - if (res != GFS2_BLKST_FREE) - return 1; - (*len)--; - if (*len == 0) - return 1; - if (lgfs2_rbm_incr(rbm)) - return 1; - } - - return 0; -} - -static uint8_t *check_bytes8(const uint8_t *start, uint8_t value, unsigned bytes) -{ - while (bytes) { - if (*start != value) - return (void *)start; - start++; - bytes--; - } - return NULL; -} - -/** - * lgfs2_free_extlen - Return extent length of free blocks - * @rbm: Starting position - * @len: Max length to check - * - * Starting at the block specified by the rbm, see how many free blocks - * there are, not reading more than len blocks ahead. This can be done - * using check_bytes8 when the blocks are byte aligned, but has to be done - * on a block by block basis in case of unaligned blocks. Also this - * function can cope with bitmap boundaries (although it must stop on - * a resource group boundary) - * - * Returns: Number of free blocks in the extent - */ -static uint32_t lgfs2_free_extlen(const struct lgfs2_rbm *rrbm, uint32_t len) -{ - struct lgfs2_rbm rbm = *rrbm; - uint32_t n_unaligned = rbm.offset & 3; - uint32_t size = len; - uint32_t bytes; - uint32_t chunk_size; - uint8_t *ptr, *start, *end; - uint64_t block; - struct gfs2_bitmap *bi; - - if (n_unaligned && - lgfs2_unaligned_extlen(&rbm, 4 - n_unaligned, &len)) - goto out; - - n_unaligned = len & 3; - /* Start is now byte aligned */ - while (len > 3) { - bi = rbm_bi(&rbm); - start = (uint8_t *)bi->bi_bh->b_data; - end = start + bi->bi_bh->sdp->bsize; - start += bi->bi_offset; - start += (rbm.offset / GFS2_NBBY); - bytes = (len / GFS2_NBBY) < (end - start) ? (len / GFS2_NBBY):(end - start); - ptr = check_bytes8(start, 0, bytes); - chunk_size = ((ptr == NULL) ? bytes : (ptr - start)); - chunk_size *= GFS2_NBBY; - len -= chunk_size; - block = lgfs2_rbm_to_block(&rbm); - if (lgfs2_rbm_from_block(&rbm, block + chunk_size)) { - n_unaligned = 0; - break; - } - if (ptr) { - n_unaligned = 3; - break; - } - n_unaligned = len & 3; - } - - /* Deal with any bits left over at the end */ - if (n_unaligned) - lgfs2_unaligned_extlen(&rbm, n_unaligned, &len); -out: - return size - len; -} - -/** - * gfs2_rbm_find - Look for blocks of a particular state - * @rbm: Value/result starting position and final position - * @state: The state which we want to find - * @minext: Pointer to the requested extent length (NULL for a single block) - * This is updated to be the actual reservation size. - * - * Returns: 0 on success, non-zero with errno == ENOSPC if there is no block of the requested state - */ -int lgfs2_rbm_find(struct lgfs2_rbm *rbm, uint8_t state, uint32_t *minext) -{ - int initial_bii; - uint32_t offset; - int n = 0; - int iters = rbm->rgd->ri.ri_length; - uint32_t extlen; - - /* If we are not starting at the beginning of a bitmap, then we - * need to add one to the bitmap count to ensure that we search - * the starting bitmap twice. - */ - if (rbm->offset != 0) - iters++; - - for (n = 0; n < iters; n++) { - struct gfs2_bitmap *bi = rbm_bi(rbm); - struct gfs2_buffer_head *bh = bi->bi_bh; - uint8_t *buf = (uint8_t *)bh->b_data + bi->bi_offset; - uint64_t block; - int ret; - - if ((rbm->rgd->rg.rg_free < *minext) && (state == GFS2_BLKST_FREE)) - goto next_bitmap; - - offset = gfs2_bitfit(buf, bi->bi_len, rbm->offset, state); - if (offset == BFITNOENT) - goto next_bitmap; - - rbm->offset = offset; - initial_bii = rbm->bii; - block = lgfs2_rbm_to_block(rbm); - extlen = 1; - - if (*minext != 0) - extlen = lgfs2_free_extlen(rbm, *minext); - - if (extlen >= *minext) - return 0; - - ret = lgfs2_rbm_from_block(rbm, block + extlen); - if (ret == 0) { - n += (rbm->bii - initial_bii); - continue; - } - - if (errno == E2BIG) { - rbm->bii = 0; - rbm->offset = 0; - n += (rbm->bii - initial_bii); - goto res_covered_end_of_rgrp; - } - - return ret; - -next_bitmap: /* Find next bitmap in the rgrp */ - rbm->offset = 0; - rbm->bii++; - if (rbm->bii == rbm->rgd->ri.ri_length) - rbm->bii = 0; - -res_covered_end_of_rgrp: - if (rbm->bii == 0) - break; - } - - errno = ENOSPC; - return 1; -} - -/** - * lgfs2_alloc_extent - allocate an extent from a given bitmap - * @rbm: the resource group information - * @state: The state of the first block, GFS2_BLKST_DINODE or GFS2_BLKST_USED - * @elen: The requested extent length - * Returns the length of the extent allocated. - */ -unsigned lgfs2_alloc_extent(const struct lgfs2_rbm *rbm, int state, const unsigned elen) -{ - struct lgfs2_rbm pos = { .rgd = rbm->rgd, }; - const uint64_t block = lgfs2_rbm_to_block(rbm); - unsigned len; - - gfs2_set_bitmap(rbm->rgd, block, state); - - for (len = 1; len < elen; len++) { - int ret = lgfs2_rbm_from_block(&pos, block + len); - if (ret || lgfs2_testbit(&pos) != GFS2_BLKST_FREE) - break; - gfs2_set_bitmap(pos.rgd, block + len, GFS2_BLKST_USED); - } - return len; -} diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c index 7592564..6e7d8c2 100644 --- a/gfs2/libgfs2/super.c +++ b/gfs2/libgfs2/super.c @@ -29,18 +29,11 @@ int check_sb(struct gfs2_sb *sb) errno = EIO; return -1; } - /* Check for gfs1 */ if (sb->sb_fs_format == GFS_FORMAT_FS && sb->sb_header.mh_format == GFS_FORMAT_SB && sb->sb_multihost_format == GFS_FORMAT_MULTI) { return 1; } - /* It's gfs2. Check format number is in a sensible range. */ - if (sb->sb_fs_format < GFS2_FORMAT_FS || - sb->sb_fs_format > 1899) { - errno = EINVAL; - return -1; - } return 2; } diff --git a/gfs2/libgfs2/super.c.bz1622050-1-fsck_gfs2_Don_t_check_fs_formats_we_don_t_recognise b/gfs2/libgfs2/super.c.bz1622050-1-fsck_gfs2_Don_t_check_fs_formats_we_don_t_recognise deleted file mode 100644 index 6e7d8c2..0000000 --- a/gfs2/libgfs2/super.c.bz1622050-1-fsck_gfs2_Don_t_check_fs_formats_we_don_t_recognise +++ /dev/null @@ -1,366 +0,0 @@ -#include "clusterautoconfig.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "libgfs2.h" -#include "osi_list.h" - -/** - * check_sb - Check superblock - * @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: -1 on failure, 1 if this is gfs (gfs1), 2 if this is gfs2 - */ -int check_sb(struct gfs2_sb *sb) -{ - if (sb->sb_header.mh_magic != GFS2_MAGIC || - sb->sb_header.mh_type != GFS2_METATYPE_SB) { - errno = EIO; - return -1; - } - if (sb->sb_fs_format == GFS_FORMAT_FS && - sb->sb_header.mh_format == GFS_FORMAT_SB && - sb->sb_multihost_format == GFS_FORMAT_MULTI) { - return 1; - } - return 2; -} - - -/* - * 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 - * sdp->gfs1 will be set if this is gfs (gfs1) - */ -int read_sb(struct gfs2_sbd *sdp) -{ - struct gfs2_buffer_head *bh; - uint64_t space = 0; - unsigned int x; - int ret; - - bh = bread(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); - gfs2_sb_in(&sdp->sd_sb, bh->b_data); - brelse(bh); - - ret = check_sb(&sdp->sd_sb); - if (ret < 0) - return ret; - if (ret == 1) - sdp->gfs1 = 1; - sdp->sd_fsb2bb_shift = sdp->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT; - sdp->bsize = sdp->sd_sb.sb_bsize; - if (sdp->bsize < 512 || sdp->bsize != (sdp->bsize & -sdp->bsize)) { - return -1; - } - if (sdp->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; - sdp->sd_hash_ptrs = sdp->sd_hash_bsize / sizeof(uint64_t); - 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 < GFS2_MAX_META_HEIGHT; 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){ - errno = E2BIG; - return -1; - } - - 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) { - errno = E2BIG; - return -1; - } - sdp->fssize = lseek(sdp->device_fd, 0, SEEK_END) / sdp->sd_sb.sb_bsize; - sdp->sd_blocks_per_bitmap = (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header)) - * GFS2_NBBY; - sdp->qcsize = GFS2_DEFAULT_QCSIZE; - - return 0; -} - -/* rgd_seems_sane - check some general things about the rindex entry - * - * 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 reserved 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. - * - * Returns: 1 if the rgd seems relatively sane - */ -static int rgd_seems_sane(struct gfs2_sbd *sdp, struct rgrp_tree *rgd) -{ - uint32_t most_bitmaps_possible; - - /* rg length must be at least 1 */ - if (rgd->ri.ri_length == 0) - return 0; - - /* A max rgrp, 2GB, divided into blocksize, divided by blocks/byte - represented in the bitmap, NBBY. Rough approximation only, due to - metadata headers. I'm doing the math this way to avoid overflow. */ - most_bitmaps_possible = (GFS2_MAX_RGSIZE * 1024 * 256) / sdp->bsize; - if (rgd->ri.ri_length > most_bitmaps_possible) - return 0; - - if (rgd->ri.ri_data0 != rgd->ri.ri_addr + rgd->ri.ri_length) - return 0; - - if (rgd->ri.ri_bitbytes != rgd->ri.ri_data / GFS2_NBBY) - return 0; - - return 1; -} - -/* good_on_disk - check if the rindex points to what looks like an rgrp on disk - * - * This is only called when the rindex pointers aren't spaced evenly, which - * isn't often. The rindex is pointing to an unexpected location, so we - * check if the block it is pointing to is really an rgrp. If so, we count the - * rindex entry as "sane" (after all, it did pass the previous checks above.) - * If not, we count it as not sane, and therefore, the whole rindex is not to - * be trusted by fsck.gfs2. - */ -static int good_on_disk(struct gfs2_sbd *sdp, struct rgrp_tree *rgd) -{ - struct gfs2_buffer_head *bh; - int is_rgrp; - - bh = bread(sdp, rgd->ri.ri_addr); - is_rgrp = (gfs2_check_meta(bh, GFS2_METATYPE_RG) == 0); - brelse(bh); - return is_rgrp; -} - -/** - * rindex_read - read in the rg index file - * @sdp: the incore superblock pointer - * fd: optional file handle for rindex file (if meta_fs file system is mounted) - * (if fd is <= zero, it will read from raw device) - * @count1: return count of the rgs. - * @sane: return whether rindex is consistent - * - * Returns: 0 on success, -1 on failure - */ -int rindex_read(struct gfs2_sbd *sdp, int fd, uint64_t *count1, int *sane) -{ - unsigned int rg; - int error; - union { - struct gfs2_rindex bufgfs2; - } buf; - struct gfs2_rindex ri; - struct rgrp_tree *rgd = NULL, *prev_rgd = NULL; - uint64_t prev_length = 0; - - *sane = 1; - *count1 = 0; - if (!fd && sdp->md.riinode->i_di.di_size % sizeof(struct gfs2_rindex)) - *sane = 0; /* rindex file size must be a multiple of 96 */ - for (rg = 0; ; rg++) { - if (fd > 0) - error = read(fd, &buf, sizeof(struct gfs2_rindex)); - else - error = gfs2_readi(sdp->md.riinode, - (char *)&buf.bufgfs2, - rg * sizeof(struct gfs2_rindex), - sizeof(struct gfs2_rindex)); - if (!error) - break; - if (error != sizeof(struct gfs2_rindex)) - return -1; - - gfs2_rindex_in(&ri, (char *)&buf.bufgfs2); - if (gfs2_check_range(sdp, ri.ri_addr) != 0) { - *sane = 0; - if (prev_rgd == NULL) - continue; - ri.ri_addr = prev_rgd->ri.ri_addr + prev_rgd->length; - } - rgd = rgrp_insert(&sdp->rgtree, ri.ri_addr); - memcpy(&rgd->ri, &ri, sizeof(struct gfs2_rindex)); - - 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 (!sdp->gfs1) { - if (prev_rgd->start >= rgd->start) - *sane = 0; - else if (!rgd_seems_sane(sdp, rgd)) - *sane = 0; - else if (*sane && rg > 2 && prev_length && - prev_length != rgd->start - - prev_rgd->start) - *sane = good_on_disk(sdp, rgd); - } - prev_length = rgd->start - prev_rgd->start; - prev_rgd->length = rgrp_size(prev_rgd); - } - - if(gfs2_compute_bitstructs(sdp->sd_sb.sb_bsize, rgd)) - *sane = 0; - - (*count1)++; - prev_rgd = rgd; - } - if (prev_rgd) - prev_rgd->length = rgrp_size(prev_rgd); - if (*count1 == 0) - return -1; - return 0; -} - -#define RA_WINDOW 32 - -static unsigned gfs2_rgrp_reada(struct gfs2_sbd *sdp, unsigned cur_window, - struct osi_node *n) -{ - struct rgrp_tree *rgd; - unsigned i; - off_t start, len; - - for (i = 0; i < RA_WINDOW; i++, n = osi_next(n)) { - if (n == NULL) - return i; - if (i < cur_window) - continue; - rgd = (struct rgrp_tree *)n; - start = rgd->ri.ri_addr * sdp->bsize; - len = rgd->ri.ri_length * sdp->bsize; - posix_fadvise(sdp->device_fd, start, len, POSIX_FADV_WILLNEED); - } - - return i; -} - -/** - * ri_update - attach rgrps to the super block - * @sdp: incore superblock data - * fd: optional file handle for rindex (through the meta_fs) - * @rgcount: returned count of rgs - * - * 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. - */ -static int __ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int *sane, - int quiet) -{ - struct rgrp_tree *rgd; - struct gfs2_rindex *ri; - uint64_t count1 = 0, count2 = 0; - uint64_t errblock = 0; - uint64_t rmax = 0; - struct osi_node *n, *next = NULL; - unsigned ra_window = 0; - - /* Turn off generic readhead */ - posix_fadvise(sdp->device_fd, 0, 0, POSIX_FADV_RANDOM); - - if (rindex_read(sdp, fd, &count1, sane)) - goto fail; - for (n = osi_first(&sdp->rgtree); n; n = next) { - next = osi_next(n); - rgd = (struct rgrp_tree *)n; - /* Readahead resource group headers */ - if (ra_window < RA_WINDOW/2) - ra_window = gfs2_rgrp_reada(sdp, ra_window, n); - /* Read resource group header */ - errblock = gfs2_rgrp_read(sdp, rgd); - if (errblock) - return errblock; - ra_window--; - count2++; - if (!quiet && count2 % 100 == 0) { - printf("."); - fflush(stdout); - } - ri = &rgd->ri; - if (ri->ri_data0 + ri->ri_data - 1 > rmax) - rmax = ri->ri_data0 + ri->ri_data - 1; - } - - sdp->fssize = rmax; - *rgcount = count1; - if (count1 != count2) - goto fail; - - posix_fadvise(sdp->device_fd, 0, 0, POSIX_FADV_NORMAL); - return 0; - - fail: - posix_fadvise(sdp->device_fd, 0, 0, POSIX_FADV_NORMAL); - gfs2_rgrp_free(&sdp->rgtree); - return -1; -} - -int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int *sane) -{ - return __ri_update(sdp, fd, rgcount, sane, 1); -} - -/** - * gfs1_ri_update - attach rgrps to the super block - * Stolen from libgfs2/super.c, but modified to handle gfs1. - * @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 gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int quiet) -{ - int sane; - - return __ri_update(sdp, fd, rgcount, &sane, quiet); -} diff --git a/gfs2/man/fsck.gfs2.8 b/gfs2/man/fsck.gfs2.8 index 9e9f925..b2b326f 100644 --- a/gfs2/man/fsck.gfs2.8 +++ b/gfs2/man/fsck.gfs2.8 @@ -1,11 +1,11 @@ .TH fsck.gfs2 8 .SH NAME -fsck.gfs2 - offline GFS and GFS2 file system checker +fsck.gfs2 - Offline GFS and GFS2 file system checker .SH SYNOPSIS .B fsck.gfs2 -[\fIoptions\fR] \fIdevice\fR +[\fIOPTION\fR]... \fIDEVICE\fR .SH WARNING All computers \fImust\fP have the filesystem unmounted before running @@ -13,22 +13,30 @@ fsck.gfs2. Failure to unmount from all nodes in a cluster will likely result in filesystem corruption. .SH DESCRIPTION -fsck.gfs2 will check that the GFS or GFS2 file system on a device is -structurally valid. It should not be run on a mounted file system. If file -system corruption is detected, it will attempt to repair the file system. -There is a limit to what fsck.gfs2 can do. If important file system structures -are destroyed, such that the checker cannot determine what the repairs should -be, reparations could fail. +fsck.gfs2 will check that the GFS or GFS2 file system on a device is structurally valid. +It should not be run on a mounted file system. If file system corruption is +detected, it will attempt to repair the file system. There is a limit to what +fsck.gfs2 can do. If important file system structures are destroyed, such that +the checker cannot determine what the repairs should be, reparations could +fail. -Other file system checkers will not check the file system if it is "clean" -(i.e. unmounted since the last use). With gfs2, storage may be shared among -several nodes in a cluster, and therefore problems may have been introduced on -a different computer. Therefore, fsck.gfs2 will always check the file system -unless the -p (preen) option is used, in which case it follows special rules +GFS2 is a journaled file system, and as such should be able to repair damage to +the file system on its own. However, faulty hardware has the ability to write +incomplete blocks to a file system thereby causing corruption that GFS2 cannot +fix. The first step to ensuring a healthy file system is the selection of +reliable hardware (i.e. storage systems that will write complete blocks - even +in the event of power failure). + +Note: Most file system checkers will not check the file system if it is +"clean" (i.e. unmounted since the last use). The fsck.gfs program behaves +differently because the storage may be shared among several nodes in a +cluster, and therefore problems may have been introduced on a different +computer. Therefore, fsck.gfs2 will always check the file system unless +the -p (preen) option is used, in which case it follows special rules (see below). -fsck.gfs2 will log a message to the system log on start and exit to aid -debugging and administration. +fsck.gfs2 will log to the system log on start and exit to aid debugging and +administration. .SH OPTIONS .TP \fB-a\fP @@ -78,8 +86,3 @@ Yes to all questions. By specifying this option, fsck.gfs2 will not prompt befor changes. This option may not be used with the \fB-n\fP or \fB-p\fP/\fB-a\fP options. - -.SH SEE ALSO -.BR gfs2 (5), -.BR gfs2_jadd (8), -.BR gfs2_grow (8) diff --git a/gfs2/man/fsck.gfs2.8.bz1693000-fsck_gfs2_8_Manpage_updates b/gfs2/man/fsck.gfs2.8.bz1693000-fsck_gfs2_8_Manpage_updates deleted file mode 100644 index b2b326f..0000000 --- a/gfs2/man/fsck.gfs2.8.bz1693000-fsck_gfs2_8_Manpage_updates +++ /dev/null @@ -1,88 +0,0 @@ -.TH fsck.gfs2 8 - -.SH NAME -fsck.gfs2 - Offline GFS and GFS2 file system checker - -.SH SYNOPSIS -.B fsck.gfs2 -[\fIOPTION\fR]... \fIDEVICE\fR - -.SH WARNING -All computers \fImust\fP have the filesystem unmounted before running -fsck.gfs2. Failure to unmount from all nodes in a cluster will likely result -in filesystem corruption. - -.SH DESCRIPTION -fsck.gfs2 will check that the GFS or GFS2 file system on a device is structurally valid. -It should not be run on a mounted file system. If file system corruption is -detected, it will attempt to repair the file system. There is a limit to what -fsck.gfs2 can do. If important file system structures are destroyed, such that -the checker cannot determine what the repairs should be, reparations could -fail. - -GFS2 is a journaled file system, and as such should be able to repair damage to -the file system on its own. However, faulty hardware has the ability to write -incomplete blocks to a file system thereby causing corruption that GFS2 cannot -fix. The first step to ensuring a healthy file system is the selection of -reliable hardware (i.e. storage systems that will write complete blocks - even -in the event of power failure). - -Note: Most file system checkers will not check the file system if it is -"clean" (i.e. unmounted since the last use). The fsck.gfs program behaves -differently because the storage may be shared among several nodes in a -cluster, and therefore problems may have been introduced on a different -computer. Therefore, fsck.gfs2 will always check the file system unless -the -p (preen) option is used, in which case it follows special rules -(see below). - -fsck.gfs2 will log to the system log on start and exit to aid debugging and -administration. -.SH OPTIONS -.TP -\fB-a\fP -Same as the \fB-p\fP (preen) option. -.TP -\fB-f\fP -Force checking even if the file system seems clean. -.TP -\fB-h\fP -Help. - -This prints out the proper command line usage syntax. -.TP -\fB-q\fP -Quiet. -.TP -\fB-n\fP -No to all questions. By specifying this option, fsck.gfs2 will only show the changes that -would be made, but not make any changes to the filesystem. - -This option may not be used with the \fB-y\fP or \fB-p\fP/\fB-a\fP options. -.TP -\fB-p\fP -Automatically repair ("preen") the file system if it is dirty and safe to do so, -otherwise exit. - -If the file system has locking protocol \fIlock_nolock\fR, it is considered a -non-shared storage device and it is considered safe. If the locking protocol -is lock_dlm and \fB-a\fP or \fB-p\fP was specified, the check is considered unsafe as it -cannot be determined whether the device is mounted by other nodes in the cluster. -In this case a warning is given if any damage or dirty journals are found. The -file system should then be unmounted from all nodes in the cluster and -fsck.gfs2 should be run manually without the \fB-a\fP or \fB-p\fP options. - -This option may not be used with the \fB-n\fP or \fB-y\fP options. -.TP -\fB-V\fP -Print out the program version information. -.TP -\fB-v\fP -Verbose operation. - -Print more information while running. -.TP -\fB-y\fP -Yes to all questions. By specifying this option, fsck.gfs2 will not prompt before making -changes. - -This option may not be used with the \fB-n\fP or \fB-p\fP/\fB-a\fP options. diff --git a/gfs2/man/gfs2.5 b/gfs2/man/gfs2.5 index 8f67ce2..56d1a00 100644 --- a/gfs2/man/gfs2.5 +++ b/gfs2/man/gfs2.5 @@ -21,20 +21,6 @@ mounts which are equivalent to mounting a read-only block device and as such can neither recover a journal or write to the filesystem, so do not require a journal assigned to them. -The GFS2 documentation has been split into a number of sections: - -\fBmkfs.gfs2\fP(8) Create a GFS2 filesystem -.br -\fBfsck.gfs2\fP(8) The GFS2 filesystem checker -.br -\fBgfs2_grow\fP(8) Growing a GFS2 filesystem -.br -\fBgfs2_jadd\fP(8) Adding a journal to a GFS2 filesystem -.br -\fBtunegfs2\fP(8) Tool to manipulate GFS2 superblocks -.br -\fBgfs2_edit\fP(8) A GFS2 debug tool (use with caution) - .SH MOUNT OPTIONS .TP @@ -48,7 +34,7 @@ currently these are \fIlock_nolock\fR and \fIlock_dlm\fR. The default lock protocol name is written to disk initially when creating the filesystem with \fBmkfs.gfs2\fP(8), -p option. It can be changed on-disk by -using the \fBtunegfs2\fP(8) command. +using the \fBgfs2_tool\fP(8) utility's \fBsb proto\fP command. The \fBlockproto\fP mount option should be used only under special circumstances in which you want to temporarily use a different lock protocol @@ -70,7 +56,7 @@ The format of \fILockTableName\fR is lock-module-specific. For The default cluster/filesystem name is written to disk initially when creating the filesystem with \fBmkfs.gfs2\fP(8), -t option. It can be changed on-disk -by using the \fBtunegfs2\fP(8) command. +by using the \fBgfs2_tool\fP(8) utility's \fBsb table\fP command. The \fBlocktable\fP mount option should be used only under special circumstances in which you want to mount the filesystem in a different cluster, @@ -214,55 +200,220 @@ versa. Finally, when first enabling this option on a filesystem that had been previously mounted without it, you must make sure that there are no outstanding cookies being cached by other software, such as NFS. +.SH BUGS + +GFS2 doesn't support \fBerrors=\fP\fIremount-ro\fR or \fBdata=\fP\fIjournal\fR. +It is not possible to switch support for user and group quotas on and +off independently of each other. Some of the error messages are rather +cryptic, if you encounter one of these messages check firstly that gfs_controld +is running and secondly that you have enough journals on the filesystem +for the number of nodes in use. + +.SH SEE ALSO + +\fBmount\fP(8) for general mount options, +\fBchmod\fP(1) and \fBchmod\fP(2) for access permission flags, +\fBacl\fP(5) for access control lists, +\fBlvm\fP(8) for volume management, +\fBccs\fP(7) for cluster management, +\fBumount\fP(8), +\fBinitrd\fP(4). + +The GFS2 documentation has been split into a number of sections: + +\fBgfs2_edit\fP(8) A GFS2 debug tool (use with caution) +\fBfsck.gfs2\fP(8) The GFS2 file system checker +\fBgfs2_grow\fP(8) Growing a GFS2 file system +\fBgfs2_jadd\fP(8) Adding a journal to a GFS2 file system +\fBmkfs.gfs2\fP(8) Make a GFS2 file system +\fBgfs2_quota\fP(8) Manipulate GFS2 disk quotas +\fBgfs2_tool\fP(8) Tool to manipulate a GFS2 file system (obsolete) +\fBtunegfs2\fP(8) Tool to manipulate GFS2 superblocks + .SH SETUP -GFS2 clustering is driven by the dlm, which depends on dlm_controld to provide -clustering from userspace. dlm_controld clustering is built on corosync -cluster/group membership and messaging. GFS2 also requires clustered lvm which -is provided by lvmlockd or, previously, clvmd. Refer to the documentation for -each of these components and ensure that they are configured before setting up -a GFS2 filesystem. Also refer to your distribution's documentation for any -specific support requirements. +GFS2 clustering is driven by the dlm, which depends on dlm_controld to +provide clustering from userspace. dlm_controld clustering is built on +corosync cluster/group membership and messaging. + +Follow these steps to manually configure and run gfs2/dlm/corosync. + +.B 1. create /etc/corosync/corosync.conf and copy to all nodes + +In this sample, replace cluster_name and IP addresses, and add nodes as +needed. If using only two nodes, uncomment the two_node line. +See corosync.conf(5) for more information. + +.nf +totem { + version: 2 + secauth: off + cluster_name: abc +} + +nodelist { + node { + ring0_addr: 10.10.10.1 + nodeid: 1 + } + node { + ring0_addr: 10.10.10.2 + nodeid: 2 + } + node { + ring0_addr: 10.10.10.3 + nodeid: 3 + } +} + +quorum { + provider: corosync_votequorum +# two_node: 1 +} + +logging { + to_syslog: yes +} +.fi + +.PP + +.B 2. start corosync on all nodes + +.nf +systemctl start corosync +.fi + +Run corosync-quorumtool to verify that all nodes are listed. + +.PP + +.B 3. create /etc/dlm/dlm.conf and copy to all nodes + +.B * +To use no fencing, use this line: -Ensure that gfs2-utils is installed on all nodes which mount the filesystem as -it provides scripts required for correct withdraw event response. +.nf +enable_fencing=0 +.fi -.B 1. Create the gfs2 filesystem +.B * +To use no fencing, but exercise fencing functions, use this line: + +.nf +fence_all /bin/true +.fi + +The "true" binary will be executed for all nodes and will succeed (exit 0) +immediately. + +.B * +To use manual fencing, use this line: + +.nf +fence_all /bin/false +.fi + +The "false" binary will be executed for all nodes and will fail (exit 1) +immediately. + +When a node fails, manually run: dlm_tool fence_ack + +.B * +To use stonith/pacemaker for fencing, use this line: + +.nf +fence_all /usr/sbin/dlm_stonith +.fi + +The "dlm_stonith" binary will be executed for all nodes. If +stonith/pacemaker systems are not available, dlm_stonith will fail and +this config becomes the equivalent of the previous /bin/false config. + +.B * +To use an APC power switch, use these lines: + +.nf +device apc /usr/sbin/fence_apc ipaddr=1.1.1.1 login=admin password=pw +connect apc node=1 port=1 +connect apc node=2 port=2 +connect apc node=3 port=3 +.fi + +Other network switch based agents are configured similarly. + +.B * +To use sanlock/watchdog fencing, use these lines: + +.nf +device wd /usr/sbin/fence_sanlock path=/dev/fence/leases +connect wd node=1 host_id=1 +connect wd node=2 host_id=2 +unfence wd +.fi + +See fence_sanlock(8) for more information. + +.B * +For other fencing configurations see dlm.conf(5) man page. + +.PP + +.B 4. start dlm_controld on all nodes + +.nf +systemctl start dlm +.fi + +Run "dlm_tool status" to verify that all nodes are listed. + +.PP + +.B 5. if using clvm, start clvmd on all nodes + +systemctl clvmd start + +.PP + +.B 6. make new gfs2 file systems mkfs.gfs2 -p lock_dlm -t cluster_name:fs_name -j num /path/to/storage -The cluster_name must match the name configured in corosync (and thus dlm). -The fs_name must be a unique name for the filesystem in the cluster. -The -j option is the number of journals to create; there must -be one for each node that will mount the filesystem. +The cluster_name must match the name used in step 1 above. +The fs_name must be a unique name in the cluster. +The -j option is the number of journals to create, there must +be one for each node that will mount the fs. .PP -.B 2. Mount the gfs2 filesystem -If you are using a clustered resource manager, see its documentation for -enabling a gfs2 filesystem resource. Otherwise, run: +.B 7. mount gfs2 file systems mount /path/to/storage /mountpoint Run "dlm_tool ls" to verify the nodes that have each fs mounted. .PP -.B 3. Shut down -If you are using a clustered resource manager, see its documentation for -disabling a gfs2 filesystem resource. Otherwise, run: +.B 8. shut down +.nf umount -a -t gfs2 +systemctl clvmd stop +systemctl dlm stop +systemctl corosync stop +.fi .PP -.SH SEE ALSO -\fBmount\fP(8) and \fBumount\fP(8) for general mount information, -\fBchmod\fP(1) and \fBchmod\fP(2) for access permission flags, -\fBacl\fP(5) for access control lists, -\fBlvm\fP(8) for volume management, -\fBdlm_controld\fP(8), -\fBdlm_tool\fP(8), -\fBdlm.conf\fP(5), -\fBcorosync\fP(8), -\fBcorosync.conf\fP(5), +.B More setup information: +.br +.BR dlm_controld (8), +.br +.BR dlm_tool (8), +.br +.BR dlm.conf (5), +.br +.BR corosync (8), +.br +.BR corosync.conf (5) +.br diff --git a/gfs2/man/gfs2.5.bz1757115-gfs2_5_General_updates_and_layout_improvements b/gfs2/man/gfs2.5.bz1757115-gfs2_5_General_updates_and_layout_improvements deleted file mode 100644 index 56d1a00..0000000 --- a/gfs2/man/gfs2.5.bz1757115-gfs2_5_General_updates_and_layout_improvements +++ /dev/null @@ -1,419 +0,0 @@ -.TH gfs2 5 - -.SH NAME -gfs2 \- GFS2 reference guide - -.SH SYNOPSIS -Overview of the GFS2 filesystem - -.SH DESCRIPTION - -GFS2 is a clustered filesystem, designed for sharing data between -multiple nodes -connected to a common shared storage device. It can also be used as a -local filesystem on a single node, however since the design is aimed -at clusters, that will usually result in lower performance than using -a filesystem designed specifically for single node use. - -GFS2 is a journaling filesystem and one journal is required for each node -that will mount the filesystem. The one exception to that is spectator -mounts which are equivalent to mounting a read-only block device and as -such can neither recover a journal or write to the filesystem, so do not -require a journal assigned to them. - -.SH MOUNT OPTIONS - -.TP -\fBlockproto=\fP\fILockProtoName\fR -This specifies which inter-node lock protocol is used by the GFS2 filesystem -for this mount, overriding the default lock protocol name stored in the -filesystem's on-disk superblock. - -The \fILockProtoName\fR must be one of the supported locking protocols, -currently these are \fIlock_nolock\fR and \fIlock_dlm\fR. - -The default lock protocol name is written to disk initially when creating the -filesystem with \fBmkfs.gfs2\fP(8), -p option. It can be changed on-disk by -using the \fBgfs2_tool\fP(8) utility's \fBsb proto\fP command. - -The \fBlockproto\fP mount option should be used only under special -circumstances in which you want to temporarily use a different lock protocol -without changing the on-disk default. Using the incorrect lock protocol -on a cluster filesystem mounted from more than one node will almost -certainly result in filesystem corruption. -.TP -\fBlocktable=\fP\fILockTableName\fR -This specifies the identity of the cluster and of the filesystem for this -mount, overriding the default cluster/filesystem identify stored in the -filesystem's on-disk superblock. The cluster/filesystem name is recognized -globally throughout the cluster, and establishes a unique namespace for -the inter-node locking system, enabling the mounting of multiple GFS2 -filesystems. - -The format of \fILockTableName\fR is lock-module-specific. For -\fIlock_dlm\fR, the format is \fIclustername:fsname\fR. For -\fIlock_nolock\fR, the field is ignored. - -The default cluster/filesystem name is written to disk initially when creating -the filesystem with \fBmkfs.gfs2\fP(8), -t option. It can be changed on-disk -by using the \fBgfs2_tool\fP(8) utility's \fBsb table\fP command. - -The \fBlocktable\fP mount option should be used only under special -circumstances in which you want to mount the filesystem in a different cluster, -or mount it as a different filesystem name, without changing the on-disk -default. -.TP -\fBlocalflocks\fP -This flag tells GFS2 that it is running as a local (not clustered) filesystem, -so it can allow the kernel VFS layer to do all flock and fcntl file locking. -When running in cluster mode, these file locks require inter-node locks, -and require the support of GFS2. When running locally, better performance -is achieved by letting VFS handle the whole job. - -This is turned on automatically by the lock_nolock module. -.TP -\fBerrors=\fP\fI[panic|withdraw]\fR -Setting errors=panic causes GFS2 to oops when encountering an error that -would otherwise cause the -mount to withdraw or print an assertion warning. The default setting -is errors=withdraw. This option should not be used in a production system. -It replaces the earlier \fBdebug\fP option on kernel versions 2.6.31 and -above. -.TP -\fBacl\fP -Enables POSIX Access Control List \fBacl\fP(5) support within GFS2. -.TP -\fBspectator\fP -Mount this filesystem using a special form of read-only mount. The mount -does not use one of the filesystem's journals. The node is unable to -recover journals for other nodes. -.TP -\fBnorecovery\fP -A synonym for spectator -.TP -\fBsuiddir\fP -Sets owner of any newly created file or directory to be that of parent -directory, if parent directory has S_ISUID permission attribute bit set. -Sets S_ISUID in any new directory, if its parent directory's S_ISUID is set. -Strips all execution bits on a new file, if parent directory owner is different -from owner of process creating the file. Set this option only if you know -why you are setting it. -.TP -\fBquota=\fP\fI[off/account/on]\fR -Turns quotas on or off for a filesystem. Setting the quotas to be in -the "account" state causes the per UID/GID usage statistics to be -correctly maintained by the filesystem, limit and warn values are -ignored. The default value is "off". -.TP -\fBdiscard\fP -Causes GFS2 to generate "discard" I/O requests for blocks which have -been freed. These can be used by suitable hardware to implement -thin-provisioning and similar schemes. This feature is supported -in kernel version 2.6.30 and above. -.TP -\fBbarrier\fP -This option, which defaults to on, causes GFS2 to send I/O barriers -when flushing the journal. The option is automatically turned off -if the underlying device does not support I/O barriers. We highly -recommend the use of I/O barriers with GFS2 at all times unless -the block device is designed so that it cannot lose its write cache -content (e.g. its on a UPS, or it doesn't have a write cache) -.TP -\fBcommit=\fP\fIsecs\fR -This is similar to the ext3 \fBcommit=\fP option in that it sets -the maximum number of seconds between journal commits if there is -dirty data in the journal. The default is 60 seconds. This option -is only provided in kernel versions 2.6.31 and above. -.TP -\fBdata=\fP\fI[ordered|writeback]\fR -When data=ordered is set, the user data modified by a transaction is -flushed to the disk before the transaction is committed to disk. This -should prevent the user from seeing uninitialized blocks in a file -after a crash. Data=writeback mode writes the user data to the disk -at any time after it's dirtied. This doesn't provide the same -consistency guarantee as ordered mode, but it should be slightly -faster for some workloads. The default is ordered mode. -.TP -\fBmeta\fP -This option results in selecting the meta filesystem root rather than -the normal filesystem root. This option is normally only used by -the GFS2 utility functions. Altering any file on the GFS2 meta filesystem -may render the filesystem unusable, so only experts in the GFS2 -on-disk layout should use this option. -.TP -\fBquota_quantum=\fP\fIsecs\fR -This sets the number of seconds for which a change in the quota -information may sit on one node before being written to the quota -file. This is the preferred way to set this parameter. The value -is an integer number of seconds greater than zero. The default is -60 seconds. Shorter settings result in faster updates of the lazy -quota information and less likelihood of someone exceeding their -quota. Longer settings make filesystem operations involving quotas -faster and more efficient. -.TP -\fBstatfs_quantum=\fP\fIsecs\fR -Setting statfs_quantum to 0 is the preferred way to set the slow version -of statfs. The default value is 30 secs which sets the maximum time -period before statfs changes will be syned to the master statfs file. -This can be adjusted to allow for faster, less accurate statfs values -or slower more accurate values. When set to 0, statfs will always -report the true values. -.TP -\fBstatfs_percent=\fP\fIvalue\fR -This setting provides a bound on the maximum percentage change in -the statfs information on a local basis before it is synced back -to the master statfs file, even if the time period has not -expired. If the setting of statfs_quantum is 0, then this setting -is ignored. -.TP -\fBrgrplvb\fP -This flag tells gfs2 to look for information about a resource group's free -space and unlinked inodes in its glock lock value block. This keeps gfs2 from -having to read in the resource group data from disk, speeding up allocations in -some cases. This option was added in the 3.6 Linux kernel. Prior to this -kernel, no information was saved to the resource group lvb. \fBNote:\fP To -safely turn on this option, all nodes mounting the filesystem must be running -at least a 3.6 Linux kernel. If any nodes had previously mounted the filesystem -using older kernels, the filesystem must be unmounted on all nodes before it -can be mounted with this option enabled. This option does not need to be -enabled on all nodes using a filesystem. -.TP -\fBloccookie\fP -This flag tells gfs2 to use location based readdir cookies, instead of its -usual filename hash readdir cookies. The filename hash cookies are not -guaranteed to be unique, and as the number of files in a directory increases, -so does the likelihood of a collision. NFS requires readdir cookies to be -unique, which can cause problems with very large directories (over 100,000 -files). With this flag set, gfs2 will try to give out location based cookies. -Since the cookie is 31 bits, gfs2 will eventually run out of unique cookies, -and will fail back to using hash cookies. The maximum number of files that -could have unique location cookies assuming perfectly even hashing and names of -8 or fewer characters is 1,073,741,824. An average directory should be able to -give out well over half a billion location based cookies. This option was added -in the 4.5 Linux kernel. Prior to this kernel, gfs2 did not add directory -entries in a way that allowed it to use location based readdir cookies. -\fBNote:\fP To safely turn on this option, all nodes mounting the filesystem -must be running at least a 4.5 Linux kernel. If this option is only enabled on -some of the nodes mounting a filesystem, the cookies returned by nodes using -this option will not be valid on nodes that are not using this option, and vice -versa. Finally, when first enabling this option on a filesystem that had been -previously mounted without it, you must make sure that there are no outstanding -cookies being cached by other software, such as NFS. - -.SH BUGS - -GFS2 doesn't support \fBerrors=\fP\fIremount-ro\fR or \fBdata=\fP\fIjournal\fR. -It is not possible to switch support for user and group quotas on and -off independently of each other. Some of the error messages are rather -cryptic, if you encounter one of these messages check firstly that gfs_controld -is running and secondly that you have enough journals on the filesystem -for the number of nodes in use. - -.SH SEE ALSO - -\fBmount\fP(8) for general mount options, -\fBchmod\fP(1) and \fBchmod\fP(2) for access permission flags, -\fBacl\fP(5) for access control lists, -\fBlvm\fP(8) for volume management, -\fBccs\fP(7) for cluster management, -\fBumount\fP(8), -\fBinitrd\fP(4). - -The GFS2 documentation has been split into a number of sections: - -\fBgfs2_edit\fP(8) A GFS2 debug tool (use with caution) -\fBfsck.gfs2\fP(8) The GFS2 file system checker -\fBgfs2_grow\fP(8) Growing a GFS2 file system -\fBgfs2_jadd\fP(8) Adding a journal to a GFS2 file system -\fBmkfs.gfs2\fP(8) Make a GFS2 file system -\fBgfs2_quota\fP(8) Manipulate GFS2 disk quotas -\fBgfs2_tool\fP(8) Tool to manipulate a GFS2 file system (obsolete) -\fBtunegfs2\fP(8) Tool to manipulate GFS2 superblocks - -.SH SETUP - -GFS2 clustering is driven by the dlm, which depends on dlm_controld to -provide clustering from userspace. dlm_controld clustering is built on -corosync cluster/group membership and messaging. - -Follow these steps to manually configure and run gfs2/dlm/corosync. - -.B 1. create /etc/corosync/corosync.conf and copy to all nodes - -In this sample, replace cluster_name and IP addresses, and add nodes as -needed. If using only two nodes, uncomment the two_node line. -See corosync.conf(5) for more information. - -.nf -totem { - version: 2 - secauth: off - cluster_name: abc -} - -nodelist { - node { - ring0_addr: 10.10.10.1 - nodeid: 1 - } - node { - ring0_addr: 10.10.10.2 - nodeid: 2 - } - node { - ring0_addr: 10.10.10.3 - nodeid: 3 - } -} - -quorum { - provider: corosync_votequorum -# two_node: 1 -} - -logging { - to_syslog: yes -} -.fi - -.PP - -.B 2. start corosync on all nodes - -.nf -systemctl start corosync -.fi - -Run corosync-quorumtool to verify that all nodes are listed. - -.PP - -.B 3. create /etc/dlm/dlm.conf and copy to all nodes - -.B * -To use no fencing, use this line: - -.nf -enable_fencing=0 -.fi - -.B * -To use no fencing, but exercise fencing functions, use this line: - -.nf -fence_all /bin/true -.fi - -The "true" binary will be executed for all nodes and will succeed (exit 0) -immediately. - -.B * -To use manual fencing, use this line: - -.nf -fence_all /bin/false -.fi - -The "false" binary will be executed for all nodes and will fail (exit 1) -immediately. - -When a node fails, manually run: dlm_tool fence_ack - -.B * -To use stonith/pacemaker for fencing, use this line: - -.nf -fence_all /usr/sbin/dlm_stonith -.fi - -The "dlm_stonith" binary will be executed for all nodes. If -stonith/pacemaker systems are not available, dlm_stonith will fail and -this config becomes the equivalent of the previous /bin/false config. - -.B * -To use an APC power switch, use these lines: - -.nf -device apc /usr/sbin/fence_apc ipaddr=1.1.1.1 login=admin password=pw -connect apc node=1 port=1 -connect apc node=2 port=2 -connect apc node=3 port=3 -.fi - -Other network switch based agents are configured similarly. - -.B * -To use sanlock/watchdog fencing, use these lines: - -.nf -device wd /usr/sbin/fence_sanlock path=/dev/fence/leases -connect wd node=1 host_id=1 -connect wd node=2 host_id=2 -unfence wd -.fi - -See fence_sanlock(8) for more information. - -.B * -For other fencing configurations see dlm.conf(5) man page. - -.PP - -.B 4. start dlm_controld on all nodes - -.nf -systemctl start dlm -.fi - -Run "dlm_tool status" to verify that all nodes are listed. - -.PP - -.B 5. if using clvm, start clvmd on all nodes - -systemctl clvmd start - -.PP - -.B 6. make new gfs2 file systems - -mkfs.gfs2 -p lock_dlm -t cluster_name:fs_name -j num /path/to/storage - -The cluster_name must match the name used in step 1 above. -The fs_name must be a unique name in the cluster. -The -j option is the number of journals to create, there must -be one for each node that will mount the fs. - -.PP - -.B 7. mount gfs2 file systems - -mount /path/to/storage /mountpoint - -Run "dlm_tool ls" to verify the nodes that have each fs mounted. - -.PP - -.B 8. shut down - -.nf -umount -a -t gfs2 -systemctl clvmd stop -systemctl dlm stop -systemctl corosync stop -.fi - -.PP - -.B More setup information: -.br -.BR dlm_controld (8), -.br -.BR dlm_tool (8), -.br -.BR dlm.conf (5), -.br -.BR corosync (8), -.br -.BR corosync.conf (5) -.br diff --git a/gfs2/man/gfs2.5.bz1818983-gfs2_5_Update_some_mentions_of_gfs2_tool b/gfs2/man/gfs2.5.bz1818983-gfs2_5_Update_some_mentions_of_gfs2_tool deleted file mode 100644 index 436abc0..0000000 --- a/gfs2/man/gfs2.5.bz1818983-gfs2_5_Update_some_mentions_of_gfs2_tool +++ /dev/null @@ -1,268 +0,0 @@ -.TH gfs2 5 - -.SH NAME -gfs2 \- GFS2 reference guide - -.SH SYNOPSIS -Overview of the GFS2 filesystem - -.SH DESCRIPTION - -GFS2 is a clustered filesystem, designed for sharing data between -multiple nodes -connected to a common shared storage device. It can also be used as a -local filesystem on a single node, however since the design is aimed -at clusters, that will usually result in lower performance than using -a filesystem designed specifically for single node use. - -GFS2 is a journaling filesystem and one journal is required for each node -that will mount the filesystem. The one exception to that is spectator -mounts which are equivalent to mounting a read-only block device and as -such can neither recover a journal or write to the filesystem, so do not -require a journal assigned to them. - -The GFS2 documentation has been split into a number of sections: - -\fBmkfs.gfs2\fP(8) Create a GFS2 filesystem -.br -\fBfsck.gfs2\fP(8) The GFS2 filesystem checker -.br -\fBgfs2_grow\fP(8) Growing a GFS2 filesystem -.br -\fBgfs2_jadd\fP(8) Adding a journal to a GFS2 filesystem -.br -\fBtunegfs2\fP(8) Tool to manipulate GFS2 superblocks -.br -\fBgfs2_edit\fP(8) A GFS2 debug tool (use with caution) - -.SH MOUNT OPTIONS - -.TP -\fBlockproto=\fP\fILockProtoName\fR -This specifies which inter-node lock protocol is used by the GFS2 filesystem -for this mount, overriding the default lock protocol name stored in the -filesystem's on-disk superblock. - -The \fILockProtoName\fR must be one of the supported locking protocols, -currently these are \fIlock_nolock\fR and \fIlock_dlm\fR. - -The default lock protocol name is written to disk initially when creating the -filesystem with \fBmkfs.gfs2\fP(8), -p option. It can be changed on-disk by -using the \fBgfs2_tool\fP(8) utility's \fBsb proto\fP command. - -The \fBlockproto\fP mount option should be used only under special -circumstances in which you want to temporarily use a different lock protocol -without changing the on-disk default. Using the incorrect lock protocol -on a cluster filesystem mounted from more than one node will almost -certainly result in filesystem corruption. -.TP -\fBlocktable=\fP\fILockTableName\fR -This specifies the identity of the cluster and of the filesystem for this -mount, overriding the default cluster/filesystem identify stored in the -filesystem's on-disk superblock. The cluster/filesystem name is recognized -globally throughout the cluster, and establishes a unique namespace for -the inter-node locking system, enabling the mounting of multiple GFS2 -filesystems. - -The format of \fILockTableName\fR is lock-module-specific. For -\fIlock_dlm\fR, the format is \fIclustername:fsname\fR. For -\fIlock_nolock\fR, the field is ignored. - -The default cluster/filesystem name is written to disk initially when creating -the filesystem with \fBmkfs.gfs2\fP(8), -t option. It can be changed on-disk -by using the \fBgfs2_tool\fP(8) utility's \fBsb table\fP command. - -The \fBlocktable\fP mount option should be used only under special -circumstances in which you want to mount the filesystem in a different cluster, -or mount it as a different filesystem name, without changing the on-disk -default. -.TP -\fBlocalflocks\fP -This flag tells GFS2 that it is running as a local (not clustered) filesystem, -so it can allow the kernel VFS layer to do all flock and fcntl file locking. -When running in cluster mode, these file locks require inter-node locks, -and require the support of GFS2. When running locally, better performance -is achieved by letting VFS handle the whole job. - -This is turned on automatically by the lock_nolock module. -.TP -\fBerrors=\fP\fI[panic|withdraw]\fR -Setting errors=panic causes GFS2 to oops when encountering an error that -would otherwise cause the -mount to withdraw or print an assertion warning. The default setting -is errors=withdraw. This option should not be used in a production system. -It replaces the earlier \fBdebug\fP option on kernel versions 2.6.31 and -above. -.TP -\fBacl\fP -Enables POSIX Access Control List \fBacl\fP(5) support within GFS2. -.TP -\fBspectator\fP -Mount this filesystem using a special form of read-only mount. The mount -does not use one of the filesystem's journals. The node is unable to -recover journals for other nodes. -.TP -\fBnorecovery\fP -A synonym for spectator -.TP -\fBsuiddir\fP -Sets owner of any newly created file or directory to be that of parent -directory, if parent directory has S_ISUID permission attribute bit set. -Sets S_ISUID in any new directory, if its parent directory's S_ISUID is set. -Strips all execution bits on a new file, if parent directory owner is different -from owner of process creating the file. Set this option only if you know -why you are setting it. -.TP -\fBquota=\fP\fI[off/account/on]\fR -Turns quotas on or off for a filesystem. Setting the quotas to be in -the "account" state causes the per UID/GID usage statistics to be -correctly maintained by the filesystem, limit and warn values are -ignored. The default value is "off". -.TP -\fBdiscard\fP -Causes GFS2 to generate "discard" I/O requests for blocks which have -been freed. These can be used by suitable hardware to implement -thin-provisioning and similar schemes. This feature is supported -in kernel version 2.6.30 and above. -.TP -\fBbarrier\fP -This option, which defaults to on, causes GFS2 to send I/O barriers -when flushing the journal. The option is automatically turned off -if the underlying device does not support I/O barriers. We highly -recommend the use of I/O barriers with GFS2 at all times unless -the block device is designed so that it cannot lose its write cache -content (e.g. its on a UPS, or it doesn't have a write cache) -.TP -\fBcommit=\fP\fIsecs\fR -This is similar to the ext3 \fBcommit=\fP option in that it sets -the maximum number of seconds between journal commits if there is -dirty data in the journal. The default is 60 seconds. This option -is only provided in kernel versions 2.6.31 and above. -.TP -\fBdata=\fP\fI[ordered|writeback]\fR -When data=ordered is set, the user data modified by a transaction is -flushed to the disk before the transaction is committed to disk. This -should prevent the user from seeing uninitialized blocks in a file -after a crash. Data=writeback mode writes the user data to the disk -at any time after it's dirtied. This doesn't provide the same -consistency guarantee as ordered mode, but it should be slightly -faster for some workloads. The default is ordered mode. -.TP -\fBmeta\fP -This option results in selecting the meta filesystem root rather than -the normal filesystem root. This option is normally only used by -the GFS2 utility functions. Altering any file on the GFS2 meta filesystem -may render the filesystem unusable, so only experts in the GFS2 -on-disk layout should use this option. -.TP -\fBquota_quantum=\fP\fIsecs\fR -This sets the number of seconds for which a change in the quota -information may sit on one node before being written to the quota -file. This is the preferred way to set this parameter. The value -is an integer number of seconds greater than zero. The default is -60 seconds. Shorter settings result in faster updates of the lazy -quota information and less likelihood of someone exceeding their -quota. Longer settings make filesystem operations involving quotas -faster and more efficient. -.TP -\fBstatfs_quantum=\fP\fIsecs\fR -Setting statfs_quantum to 0 is the preferred way to set the slow version -of statfs. The default value is 30 secs which sets the maximum time -period before statfs changes will be syned to the master statfs file. -This can be adjusted to allow for faster, less accurate statfs values -or slower more accurate values. When set to 0, statfs will always -report the true values. -.TP -\fBstatfs_percent=\fP\fIvalue\fR -This setting provides a bound on the maximum percentage change in -the statfs information on a local basis before it is synced back -to the master statfs file, even if the time period has not -expired. If the setting of statfs_quantum is 0, then this setting -is ignored. -.TP -\fBrgrplvb\fP -This flag tells gfs2 to look for information about a resource group's free -space and unlinked inodes in its glock lock value block. This keeps gfs2 from -having to read in the resource group data from disk, speeding up allocations in -some cases. This option was added in the 3.6 Linux kernel. Prior to this -kernel, no information was saved to the resource group lvb. \fBNote:\fP To -safely turn on this option, all nodes mounting the filesystem must be running -at least a 3.6 Linux kernel. If any nodes had previously mounted the filesystem -using older kernels, the filesystem must be unmounted on all nodes before it -can be mounted with this option enabled. This option does not need to be -enabled on all nodes using a filesystem. -.TP -\fBloccookie\fP -This flag tells gfs2 to use location based readdir cookies, instead of its -usual filename hash readdir cookies. The filename hash cookies are not -guaranteed to be unique, and as the number of files in a directory increases, -so does the likelihood of a collision. NFS requires readdir cookies to be -unique, which can cause problems with very large directories (over 100,000 -files). With this flag set, gfs2 will try to give out location based cookies. -Since the cookie is 31 bits, gfs2 will eventually run out of unique cookies, -and will fail back to using hash cookies. The maximum number of files that -could have unique location cookies assuming perfectly even hashing and names of -8 or fewer characters is 1,073,741,824. An average directory should be able to -give out well over half a billion location based cookies. This option was added -in the 4.5 Linux kernel. Prior to this kernel, gfs2 did not add directory -entries in a way that allowed it to use location based readdir cookies. -\fBNote:\fP To safely turn on this option, all nodes mounting the filesystem -must be running at least a 4.5 Linux kernel. If this option is only enabled on -some of the nodes mounting a filesystem, the cookies returned by nodes using -this option will not be valid on nodes that are not using this option, and vice -versa. Finally, when first enabling this option on a filesystem that had been -previously mounted without it, you must make sure that there are no outstanding -cookies being cached by other software, such as NFS. - -.SH SETUP - -GFS2 clustering is driven by the dlm, which depends on dlm_controld to provide -clustering from userspace. dlm_controld clustering is built on corosync -cluster/group membership and messaging. GFS2 also requires clustered lvm which -is provided by lvmlockd or, previously, clvmd. Refer to the documentation for -each of these components and ensure that they are configured before setting up -a GFS2 filesystem. Also refer to your distribution's documentation for any -specific support requirements. - -Ensure that gfs2-utils is installed on all nodes which mount the filesystem as -it provides scripts required for correct withdraw event response. - -.B 1. Create the gfs2 filesystem - -mkfs.gfs2 -p lock_dlm -t cluster_name:fs_name -j num /path/to/storage - -The cluster_name must match the name configured in corosync (and thus dlm). -The fs_name must be a unique name for the filesystem in the cluster. -The -j option is the number of journals to create; there must -be one for each node that will mount the filesystem. - -.PP -.B 2. Mount the gfs2 filesystem - -If you are using a clustered resource manager, see its documentation for -enabling a gfs2 filesystem resource. Otherwise, run: - -mount /path/to/storage /mountpoint - -Run "dlm_tool ls" to verify the nodes that have each fs mounted. - -.PP -.B 3. Shut down - -If you are using a clustered resource manager, see its documentation for -disabling a gfs2 filesystem resource. Otherwise, run: - -umount -a -t gfs2 - -.PP -.SH SEE ALSO - -\fBmount\fP(8) and \fBumount\fP(8) for general mount information, -\fBchmod\fP(1) and \fBchmod\fP(2) for access permission flags, -\fBacl\fP(5) for access control lists, -\fBlvm\fP(8) for volume management, -\fBdlm_controld\fP(8), -\fBdlm_tool\fP(8), -\fBdlm.conf\fP(5), -\fBcorosync\fP(8), -\fBcorosync.conf\fP(5), diff --git a/gfs2/mkfs/main_jadd.c b/gfs2/mkfs/main_jadd.c index ea89c96..efe91e3 100644 --- a/gfs2/mkfs/main_jadd.c +++ b/gfs2/mkfs/main_jadd.c @@ -42,13 +42,15 @@ struct jadd_opts { #define JA_FL_SET 0 #define JA_FL_CLEAR 1 -static int set_flags(int fd, int op, uint32_t flags) +static void set_flags(int fd, int op, uint32_t flags) { + int err; uint32_t val; - if (ioctl(fd, FS_IOC_GETFLAGS, &val)) { + err = ioctl(fd, FS_IOC_GETFLAGS, &val); + if (err) { perror("GETFLAGS"); - return -1; + exit(EXIT_FAILURE); } if (op == JA_FL_SET) @@ -56,11 +58,11 @@ static int set_flags(int fd, int op, uint32_t flags) else if (op == JA_FL_CLEAR) val &= ~flags; - if (ioctl(fd, FS_IOC_SETFLAGS, &val)) { + err = ioctl(fd, FS_IOC_SETFLAGS, &val); + if (err) { perror("SETFLAGS"); - return -1; + exit(EXIT_FAILURE); } - return 0; } static int rename2system(struct jadd_opts *opts, const char *new_dir, const char *new_name) @@ -241,214 +243,186 @@ static void print_results(struct jadd_opts *opts) static int create_new_inode(struct jadd_opts *opts, uint64_t *addr) { char *name = opts->new_inode; - int fd, error = 0; + int fd; + int error; for (;;) { fd = open(name, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW | O_CLOEXEC, 0600); if (fd >= 0) break; if (errno == EEXIST) { - if (unlink(name)) { + error = unlink(name); + if (error){ perror("unlink"); - return -1; + exit(EXIT_FAILURE); } - continue; + } else{ + perror("create"); + exit(EXIT_FAILURE); } - perror("create"); - return -1; } - if (addr != NULL) { struct stat st; - if ((error = fstat(fd, &st))) { - perror("fstat"); - return close(fd); - } + fstat(fd, &st); *addr = st.st_ino; } return fd; } -static int add_ir(struct jadd_opts *opts) +static void add_ir(struct jadd_opts *opts) { - int fd, error = 0; + int fd; char new_name[256]; - struct gfs2_inum_range ir; - - if ((fd = create_new_inode(opts, NULL)) < 0) - return fd; + int error; - if ((error = set_flags(fd, JA_FL_SET, FS_JOURNAL_DATA_FL))) - goto close_fd; + fd = create_new_inode(opts, NULL); - memset(&ir, 0, sizeof(struct gfs2_inum_range)); - if (write(fd, (void*)&ir, sizeof(struct gfs2_inum_range)) != - sizeof(struct gfs2_inum_range)) { - perror("add_ir write"); - error = -1; - goto close_fd; - } + { + struct gfs2_inum_range ir; - if ((error = fsync(fd))) { - perror("add_ir fsync"); - goto close_fd; + set_flags(fd, JA_FL_SET, FS_JOURNAL_DATA_FL); + memset(&ir, 0, sizeof(struct gfs2_inum_range)); + if (write(fd, (void*)&ir, sizeof(struct gfs2_inum_range)) != + sizeof(struct gfs2_inum_range)) { + perror("add_ir"); + exit(EXIT_FAILURE); + } } + close(fd); sprintf(new_name, "inum_range%u", opts->journals); error = rename2system(opts, opts->per_node, new_name); - if (error < 0 && errno != EEXIST) { + if (error < 0 && errno != EEXIST){ perror("add_ir rename2system"); - goto close_fd; + exit(EXIT_FAILURE); } -close_fd: - return close(fd) || error; } -static int add_sc(struct jadd_opts *opts) +static void add_sc(struct jadd_opts *opts) { - int fd, error = 0; + int fd; char new_name[256]; - struct gfs2_statfs_change sc; + int error; - if ((fd = create_new_inode(opts, NULL)) < 0) - return fd; + fd = create_new_inode(opts, NULL); - if ((error = set_flags(fd, JA_FL_SET, FS_JOURNAL_DATA_FL))) - goto close_fd; + { + struct gfs2_statfs_change sc; + set_flags(fd, JA_FL_SET, FS_JOURNAL_DATA_FL); - memset(&sc, 0, sizeof(struct gfs2_statfs_change)); - if (write(fd, (void*)&sc, sizeof(struct gfs2_statfs_change)) != - sizeof(struct gfs2_statfs_change)) { - perror("add_sc write"); - error = -1; - goto close_fd; + memset(&sc, 0, sizeof(struct gfs2_statfs_change)); + if (write(fd, (void*)&sc, sizeof(struct gfs2_statfs_change)) != + sizeof(struct gfs2_statfs_change)) { + perror("add_sc"); + exit(EXIT_FAILURE); + } } - if ((error = fsync(fd))) { - perror("add_sc fsync"); - goto close_fd; - } + close(fd); sprintf(new_name, "statfs_change%u", opts->journals); error = rename2system(opts, opts->per_node, new_name); if (error < 0 && errno != EEXIST){ perror("add_sc rename2system"); - goto close_fd; + exit(EXIT_FAILURE); } -close_fd: - return close(fd) || error; } -static int add_qc(struct gfs2_sbd *sdp, struct jadd_opts *opts) +static void add_qc(struct gfs2_sbd *sdp, struct jadd_opts *opts) { - int fd, error = 0; - char new_name[256], buf[sdp->bsize]; - unsigned int blocks = - sdp->qcsize << (20 - sdp->sd_sb.sb_bsize_shift); - unsigned int x; - struct gfs2_meta_header mh; - - if ((fd = create_new_inode(opts, NULL)) < 0) - return fd; - - if ((error = set_flags(fd, JA_FL_CLEAR, FS_JOURNAL_DATA_FL))) - goto close_fd; - - memset(buf, 0, sdp->bsize); - for (x=0; xbsize) != sdp->bsize) { - perror("add_qc write"); - error = -1; - goto close_fd; + int fd; + char new_name[256]; + int error; + + fd = create_new_inode(opts, NULL); + + { + char buf[sdp->bsize]; + unsigned int blocks = + sdp->qcsize << (20 - sdp->sd_sb.sb_bsize_shift); + unsigned int x; + struct gfs2_meta_header mh; + + set_flags(fd, JA_FL_CLEAR, FS_JOURNAL_DATA_FL); + memset(buf, 0, sdp->bsize); + + for (x=0; xbsize) != sdp->bsize) { + perror("add_qc"); + exit(EXIT_FAILURE); + } } - } - if ((error = lseek(fd, 0, SEEK_SET)) < 0) { - perror("add_qc lseek"); - goto close_fd; - } + lseek(fd, 0, SEEK_SET); + + memset(&mh, 0, sizeof(struct gfs2_meta_header)); + mh.mh_magic = GFS2_MAGIC; + mh.mh_type = GFS2_METATYPE_QC; + mh.mh_format = GFS2_FORMAT_QC; + gfs2_meta_header_out(&mh, buf); - memset(&mh, 0, sizeof(struct gfs2_meta_header)); - mh.mh_magic = GFS2_MAGIC; - mh.mh_type = GFS2_METATYPE_QC; - mh.mh_format = GFS2_FORMAT_QC; - gfs2_meta_header_out(&mh, buf); - - for (x=0; xbsize) != sdp->bsize) { - perror("add_qc write"); - error = 1; - goto close_fd; + for (x=0; xbsize) != sdp->bsize) { + perror("add_qc"); + exit(EXIT_FAILURE); + } } - if ((error = fsync(fd))) { + + error = fsync(fd); + if (error){ perror("add_qc fsync"); - goto close_fd; + exit(EXIT_FAILURE); } } + close(fd); + sprintf(new_name, "quota_change%u", opts->journals); error = rename2system(opts, opts->per_node, new_name); if (error < 0 && errno != EEXIST){ perror("add_qc rename2system"); - goto close_fd; + exit(EXIT_FAILURE); } -close_fd: - return close(fd) || error; } -static int gather_info(struct gfs2_sbd *sdp, struct jadd_opts *opts) +static void gather_info(struct gfs2_sbd *sdp, struct jadd_opts *opts) { struct statfs statbuf; - if (statfs(opts->path, &statbuf) < 0) { perror(opts->path); - return -1; + exit(EXIT_FAILURE); } - sdp->bsize = statbuf.f_bsize; - sdp->blks_total = statbuf.f_blocks; - sdp->blks_alloced = sdp->blks_total - statbuf.f_bfree; - - return 0; } -static int find_current_journals(struct jadd_opts *opts) +static void find_current_journals(struct jadd_opts *opts) { struct dirent *dp; DIR *dirp; unsigned existing_journals = 0; - int ret = 0; dirp = opendir(opts->jindex); if (!dirp) { perror("jindex"); - ret = -1; - goto out; + exit(EXIT_FAILURE); } while (dirp) { if ((dp = readdir(dirp)) != NULL) { if (strncmp(dp->d_name, "journal", 7) == 0) existing_journals++; } else - goto close_fd; + goto close; } -close_fd: - if ((ret = closedir(dirp))) - goto out; - +close: + closedir(dirp); if (existing_journals == 0) { - errno = EINVAL; - perror("No journals found. Did you run mkfs.gfs2 correctly?\n"); - ret = -1; - goto out; + die( _("No journals found. Did you run mkfs.gfs2 correctly?\n")); } opts->orig_journals = existing_journals; -out: - return ret; } #ifdef GFS2_HAS_LH_V2 @@ -474,118 +448,83 @@ static uint64_t find_block_address(int fd, off_t offset, unsigned bsize) } #endif -static int add_j(struct gfs2_sbd *sdp, struct jadd_opts *opts) +static void add_j(struct gfs2_sbd *sdp, struct jadd_opts *opts) { - int fd, error = 0; - char new_name[256], buf[sdp->bsize]; - unsigned int x, blocks = - sdp->jsize << (20 - sdp->sd_sb.sb_bsize_shift); - struct gfs2_log_header lh; - uint64_t seq = RANDOM(blocks), addr; - off_t off = 0; - - if ((fd = create_new_inode(opts, &addr)) < 0) - return fd; - - if ((error = set_flags(fd, JA_FL_CLEAR, FS_JOURNAL_DATA_FL))) - goto close_fd; - - memset(buf, 0, sdp->bsize); - for (x=0; xbsize) != sdp->bsize) { - perror("add_j write"); - error = -1; - goto close_fd; + int fd; + char new_name[256]; + int error; + uint64_t addr; + + fd = create_new_inode(opts, &addr); + + { + char buf[sdp->bsize]; + unsigned int blocks = + sdp->jsize << (20 - sdp->sd_sb.sb_bsize_shift); + unsigned int x; + struct gfs2_log_header lh; + uint64_t seq = RANDOM(blocks); + off_t off = 0; + + set_flags(fd, JA_FL_CLEAR, FS_JOURNAL_DATA_FL); + memset(buf, 0, sdp->bsize); + for (x=0; xbsize) != sdp->bsize) { + perror("add_j"); + exit(EXIT_FAILURE); + } } - } - if ((error = lseek(fd, 0, SEEK_SET)) < 0) { - perror("add_j lseek"); - goto close_fd; - } + lseek(fd, 0, SEEK_SET); - memset(&lh, 0, sizeof(struct gfs2_log_header)); - lh.lh_header.mh_magic = GFS2_MAGIC; - lh.lh_header.mh_type = GFS2_METATYPE_LH; - lh.lh_header.mh_format = GFS2_FORMAT_LH; - lh.lh_flags = GFS2_LOG_HEAD_UNMOUNT; -#ifdef GFS2_HAS_LH_V2 - lh.lh_flags |= GFS2_LOG_HEAD_USERSPACE; - lh.lh_jinode = addr; -#endif - for (x=0; xlh_hash = cpu_to_be32(hash); + for (x=0; xlh_hash = cpu_to_be32(hash); #ifdef GFS2_HAS_LH_V2 - if (!(blk_addr = find_block_address(fd, off, sdp->bsize))) { - error = -1; - goto close_fd; - } - ((struct gfs2_log_header *)buf)->lh_addr = cpu_to_be64(blk_addr); - hash = lgfs2_log_header_crc(buf, sdp->bsize); - ((struct gfs2_log_header *)buf)->lh_crc = cpu_to_be32(hash); + ((struct gfs2_log_header *)buf)->lh_addr = cpu_to_be64( + find_block_address(fd, off, sdp->bsize)); + hash = lgfs2_log_header_crc(buf, sdp->bsize); + ((struct gfs2_log_header *)buf)->lh_crc = cpu_to_be32(hash); #endif - if (write(fd, buf, sdp->bsize) != sdp->bsize) { - perror("add_j write"); - error = -1; - goto close_fd; - } + if (write(fd, buf, sdp->bsize) != sdp->bsize) { + perror("add_j"); + exit(EXIT_FAILURE); + } - if (++seq == blocks) - seq = 0; - off += sdp->bsize; + if (++seq == blocks) + seq = 0; + off += sdp->bsize; + } - if ((error = fsync(fd))) { + error = fsync(fd); + if (error){ perror("add_j fsync"); - goto close_fd; + exit(EXIT_FAILURE); } } + close(fd); + sprintf(new_name, "journal%u", opts->journals); error = rename2system(opts, opts->jindex, new_name); if (error < 0 && errno != EEXIST){ perror("add_j rename2system"); - goto close_fd; - } -close_fd: - return close(fd) || error; -} - -static int check_fit(struct gfs2_sbd *sdp, struct jadd_opts *opts) -{ - /* Compute how much space we'll need for the new journals - * Number of blocks needed per added journal: - * 1 block for the ir inode - * 1 block for the sc inode - * for sizes of the qc and journal inodes, use lgfs2_space_for_data() - * to calculate. - */ - uint64_t blks_per_j, total_blks; - - blks_per_j = 1 + 1 + - lgfs2_space_for_data(sdp, sdp->bsize, sdp->qcsize << 20) + - lgfs2_space_for_data(sdp, sdp->bsize, sdp->jsize << 20); - total_blks = opts->journals * blks_per_j; - - if (total_blks > (sdp->blks_total - sdp->blks_alloced)) { - printf( _("\nInsufficient space on the device to add %u %uMB " - "journals (%uMB QC size)\n\n"), - opts->journals, sdp->jsize, sdp->qcsize); - printf( _("Required space : %*lu blks (%lu blks per " - "journal)\n"), 10, total_blks, blks_per_j); - printf( _("Available space : %*lu blks\n\n"), 10, - sdp->blks_total - sdp->blks_alloced); - errno = ENOSPC; - return -1; + exit(EXIT_FAILURE); } - return 0; } int main(int argc, char *argv[]) @@ -594,7 +533,7 @@ int main(int argc, char *argv[]) struct gfs2_sbd sbd, *sdp = &sbd; struct metafs mfs = {0}; struct mntent *mnt; - unsigned int total, ret = 0; + unsigned int total; setlocale(LC_ALL, ""); textdomain("gfs2-utils"); @@ -610,74 +549,52 @@ int main(int argc, char *argv[]) sbd.path_fd = lgfs2_open_mnt_dir(opts.path, O_RDONLY|O_CLOEXEC, &mnt); if (sbd.path_fd < 0) { - fprintf(stderr, "Error looking up mount '%s': %s\n", - opts.path, strerror(errno)); - ret = -1; - goto out; + fprintf(stderr, _("Error looking up mount '%s': %s\n"), opts.path, strerror(errno)); + exit(EXIT_FAILURE); } if (mnt == NULL) { - fprintf(stderr, "%s: not a mounted gfs2 file system\n", opts.path); - ret = -1; - goto close_sb; + fprintf(stderr, _("%s: not a mounted gfs2 file system\n"), opts.path); + exit(EXIT_FAILURE); } - - if ((ret = gather_info(sdp, &opts))) - goto close_sb; - + gather_info(sdp, &opts); mfs.context = copy_context_opt(mnt); - if ((ret = mount_gfs2_meta(&mfs, mnt->mnt_dir, opts.debug))) { + if (mount_gfs2_meta(&mfs, mnt->mnt_dir, opts.debug)) { perror("GFS2 metafs"); - goto close_sb; + exit(EXIT_FAILURE); } - if ((ret = build_paths(mfs.path, &opts))) { + if (build_paths(mfs.path, &opts)) { perror(_("Failed to build paths")); - goto umount_meta; + exit(EXIT_FAILURE); } - if ((ret = compute_constants(sdp))) { + if (compute_constants(sdp)) { perror(_("Failed to compute file system constants")); - goto free_paths; - } - - if ((ret = find_current_journals(&opts))) - goto free_paths; - - if ((ret = check_fit(sdp, &opts))) { - perror(_("Failed to add journals")); - goto free_paths; + exit(EXIT_FAILURE); } + find_current_journals(&opts); total = opts.orig_journals + opts.journals; for (opts.journals = opts.orig_journals; opts.journals < total; opts.journals++) { if (metafs_interrupted) { - errno = 130; - goto free_paths; + cleanup_metafs(&mfs); + exit(130); } - if ((ret = add_ir(&opts))) - goto free_paths; - if ((ret = add_sc(&opts))) - goto free_paths; - if ((ret = add_qc(sdp, &opts))) - goto free_paths; - if ((ret = add_j(sdp, &opts))) - goto free_paths; + add_ir(&opts); + add_sc(&opts); + add_qc(sdp, &opts); + add_j(sdp, &opts); } -free_paths: free(opts.new_inode); free(opts.per_node); free(opts.jindex); -umount_meta: - sync(); - cleanup_metafs(&mfs); -close_sb: close(sdp->path_fd); -out: - if (!ret) - print_results(&opts); + cleanup_metafs(&mfs); + sync(); + print_results(&opts); - return ret; + return 0; } diff --git a/gfs2/mkfs/main_jadd.c.bz1833141-1-gfs2_jadd_Handle_out_of_space_issues b/gfs2/mkfs/main_jadd.c.bz1833141-1-gfs2_jadd_Handle_out_of_space_issues deleted file mode 100644 index efe91e3..0000000 --- a/gfs2/mkfs/main_jadd.c.bz1833141-1-gfs2_jadd_Handle_out_of_space_issues +++ /dev/null @@ -1,600 +0,0 @@ -#include "clusterautoconfig.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define _(String) gettext(String) - -#include -#include -#include -#include "libgfs2.h" -#include "gfs2_mkfs.h" -#include "metafs.h" - -#define RANDOM(values) ((values) * (random() / (RAND_MAX + 1.0))) - -struct jadd_opts { - char *path; - char *new_inode; - char *per_node; - char *jindex; - unsigned orig_journals; - unsigned journals; - unsigned quiet:1; - unsigned debug:1; -}; - -#define JA_FL_SET 0 -#define JA_FL_CLEAR 1 -static void set_flags(int fd, int op, uint32_t flags) -{ - int err; - uint32_t val; - - err = ioctl(fd, FS_IOC_GETFLAGS, &val); - if (err) { - perror("GETFLAGS"); - exit(EXIT_FAILURE); - } - - if (op == JA_FL_SET) - val |= flags; - else if (op == JA_FL_CLEAR) - val &= ~flags; - - err = ioctl(fd, FS_IOC_SETFLAGS, &val); - if (err) { - perror("SETFLAGS"); - exit(EXIT_FAILURE); - } -} - -static int rename2system(struct jadd_opts *opts, const char *new_dir, const char *new_name) -{ - char *newpath; - int ret; - - if (asprintf(&newpath, "%s/%s", new_dir, new_name) < 0) { - perror(_("Failed to allocate new path")); - return -1; - } - - ret = rename(opts->new_inode, newpath); - free(newpath); - return ret; -} - -static int build_paths(const char *metafs_path, struct jadd_opts *opts) -{ - int i = 0; - struct { - char **path; - const char *tail; - } p[] = { - { &opts->new_inode, "new_inode" }, - { &opts->per_node, "per_node" }, - { &opts->jindex, "jindex" }, - { NULL, NULL} - }; - - while (p[i].path != NULL) { - if (asprintf(p[i].path, "%s/%s", metafs_path, p[i].tail) < 0) { - while (i > 0) - free(*p[--i].path); - return 1; - } - if (opts->debug) - printf("%d: %s\n", i, *p[i].path); - i++; - } - return 0; -} - -/** - * print_usage - print out usage information - * @prog_name: The name of this program - */ - -static void print_usage(const char *prog_name) -{ - int i; - const char *option, *param, *desc; - const char *options[] = { - /* Translators: This is a usage string printed with --help. - and here are the commandline parameters, - e.g. gfs2_jadd -j /dev/sda */ - "-c", "", _("Size of quota change file, in megabytes"), - "-D", NULL, _("Enable debugging code"), - "-h", NULL, _("Display this help, then exit"), - "-J", "", _("Size of journals, in megabytes"), - "-j", "", _("Number of journals"), - "-q", NULL, _("Don't print anything"), - "-V", NULL, _("Display version information, then exit"), - NULL, NULL, NULL /* Must be kept at the end */ - }; - - printf("%s\n", _("Usage:")); - printf("%s [%s] <%s>\n\n", prog_name, _("options"), _("device")); - printf(_("Adds journals to a GFS2 file system.")); - printf("\n\n%s\n", _("Options:")); - - for (i = 0; options[i] != NULL; i += 3) { - option = options[i]; - param = options[i+1]; - desc = options[i+2]; - printf("%3s %-15s %s\n", option, param ? param : "", desc); - } -} - -/** - * decode_arguments - decode command line arguments and fill in the struct gfs2_sbd - * @argc: - * @argv: - * @sdp: the decoded command line arguments - * - */ - -static void decode_arguments(int argc, char *argv[], struct gfs2_sbd *sdp, struct jadd_opts *opts) -{ - int cont = TRUE; - int optchar; - - while (cont) { - optchar = getopt(argc, argv, "c:DhJ:j:qu:V"); - - switch (optchar) { - case 'c': - sdp->qcsize = atoi(optarg); - break; - case 'D': - opts->debug = 1; - lgfs2_set_debug(1); - break; - case 'h': - print_usage(argv[0]); - exit(0); - break; - case 'J': - sdp->jsize = atoi(optarg); - break; - case 'j': - opts->journals = atoi(optarg); - break; - case 'q': - opts->quiet = 1; - break; - case 'V': - printf("gfs2_jadd %s (built %s %s)\n", VERSION, - __DATE__, __TIME__); - printf(REDHAT_COPYRIGHT "\n"); - exit(0); - break; - case ':': - case '?': - fprintf(stderr, _("Please use '-h' for help.\n")); - exit(EXIT_FAILURE); - break; - case EOF: - cont = FALSE; - break; - default: - die( _("Invalid option: %c\n"), optchar); - break; - }; - } - - if (optind < argc) { - opts->path = argv[optind]; - optind++; - } else - die( _("no path specified (try -h for help)\n")); - - if (optind < argc) - die( _("Unrecognized argument: %s\n"), argv[optind]); - - if (opts->debug) { - printf( _("Command line arguments:\n")); - printf(" qcsize = %u\n", sdp->qcsize); - printf(" jsize = %u\n", sdp->jsize); - printf(" journals = %u\n", sdp->md.journals); - printf(" quiet = %u\n", opts->quiet); - printf(" path = %s\n", opts->path); - } -} - -static void verify_arguments(struct gfs2_sbd *sdp, struct jadd_opts *opts) -{ - if (!opts->journals) - die( _("no journals specified\n")); - if (sdp->jsize < 32 || sdp->jsize > 1024) - die( _("bad journal size\n")); - if (!sdp->qcsize || sdp->qcsize > 64) - die( _("bad quota change size\n")); -} - -static void print_results(struct jadd_opts *opts) -{ - if (opts->debug) - printf("\n"); - else if (opts->quiet) - return; - - printf( _("Filesystem: %s\n"), opts->path); - printf( _("Old journals: %u\n"), opts->orig_journals); - printf( _("New journals: %u\n"), opts->journals); -} - -static int create_new_inode(struct jadd_opts *opts, uint64_t *addr) -{ - char *name = opts->new_inode; - int fd; - int error; - - for (;;) { - fd = open(name, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW | O_CLOEXEC, 0600); - if (fd >= 0) - break; - if (errno == EEXIST) { - error = unlink(name); - if (error){ - perror("unlink"); - exit(EXIT_FAILURE); - } - } else{ - perror("create"); - exit(EXIT_FAILURE); - } - } - if (addr != NULL) { - struct stat st; - - fstat(fd, &st); - *addr = st.st_ino; - } - - return fd; -} - -static void add_ir(struct jadd_opts *opts) -{ - int fd; - char new_name[256]; - int error; - - fd = create_new_inode(opts, NULL); - - { - struct gfs2_inum_range ir; - - set_flags(fd, JA_FL_SET, FS_JOURNAL_DATA_FL); - memset(&ir, 0, sizeof(struct gfs2_inum_range)); - if (write(fd, (void*)&ir, sizeof(struct gfs2_inum_range)) != - sizeof(struct gfs2_inum_range)) { - perror("add_ir"); - exit(EXIT_FAILURE); - } - } - - close(fd); - - sprintf(new_name, "inum_range%u", opts->journals); - error = rename2system(opts, opts->per_node, new_name); - if (error < 0 && errno != EEXIST){ - perror("add_ir rename2system"); - exit(EXIT_FAILURE); - } -} - -static void add_sc(struct jadd_opts *opts) -{ - int fd; - char new_name[256]; - int error; - - fd = create_new_inode(opts, NULL); - - { - struct gfs2_statfs_change sc; - set_flags(fd, JA_FL_SET, FS_JOURNAL_DATA_FL); - - memset(&sc, 0, sizeof(struct gfs2_statfs_change)); - if (write(fd, (void*)&sc, sizeof(struct gfs2_statfs_change)) != - sizeof(struct gfs2_statfs_change)) { - perror("add_sc"); - exit(EXIT_FAILURE); - } - } - - close(fd); - - sprintf(new_name, "statfs_change%u", opts->journals); - error = rename2system(opts, opts->per_node, new_name); - if (error < 0 && errno != EEXIST){ - perror("add_sc rename2system"); - exit(EXIT_FAILURE); - } -} - -static void add_qc(struct gfs2_sbd *sdp, struct jadd_opts *opts) -{ - int fd; - char new_name[256]; - int error; - - fd = create_new_inode(opts, NULL); - - { - char buf[sdp->bsize]; - unsigned int blocks = - sdp->qcsize << (20 - sdp->sd_sb.sb_bsize_shift); - unsigned int x; - struct gfs2_meta_header mh; - - set_flags(fd, JA_FL_CLEAR, FS_JOURNAL_DATA_FL); - memset(buf, 0, sdp->bsize); - - for (x=0; xbsize) != sdp->bsize) { - perror("add_qc"); - exit(EXIT_FAILURE); - } - } - - lseek(fd, 0, SEEK_SET); - - memset(&mh, 0, sizeof(struct gfs2_meta_header)); - mh.mh_magic = GFS2_MAGIC; - mh.mh_type = GFS2_METATYPE_QC; - mh.mh_format = GFS2_FORMAT_QC; - gfs2_meta_header_out(&mh, buf); - - for (x=0; xbsize) != sdp->bsize) { - perror("add_qc"); - exit(EXIT_FAILURE); - } - } - - error = fsync(fd); - if (error){ - perror("add_qc fsync"); - exit(EXIT_FAILURE); - } - } - - close(fd); - - sprintf(new_name, "quota_change%u", opts->journals); - error = rename2system(opts, opts->per_node, new_name); - if (error < 0 && errno != EEXIST){ - perror("add_qc rename2system"); - exit(EXIT_FAILURE); - } -} - -static void gather_info(struct gfs2_sbd *sdp, struct jadd_opts *opts) -{ - struct statfs statbuf; - if (statfs(opts->path, &statbuf) < 0) { - perror(opts->path); - exit(EXIT_FAILURE); - } - sdp->bsize = statbuf.f_bsize; -} - -static void find_current_journals(struct jadd_opts *opts) -{ - struct dirent *dp; - DIR *dirp; - unsigned existing_journals = 0; - - dirp = opendir(opts->jindex); - if (!dirp) { - perror("jindex"); - exit(EXIT_FAILURE); - } - while (dirp) { - if ((dp = readdir(dirp)) != NULL) { - if (strncmp(dp->d_name, "journal", 7) == 0) - existing_journals++; - } else - goto close; - } -close: - closedir(dirp); - if (existing_journals == 0) { - die( _("No journals found. Did you run mkfs.gfs2 correctly?\n")); - } - - opts->orig_journals = existing_journals; -} - -#ifdef GFS2_HAS_LH_V2 -static uint64_t find_block_address(int fd, off_t offset, unsigned bsize) -{ - struct { - struct fiemap fm; - struct fiemap_extent fe; - } fme; - int ret; - - fme.fm.fm_start = offset; - fme.fm.fm_length = 1; - fme.fm.fm_flags = FIEMAP_FLAG_SYNC; - fme.fm.fm_extent_count = 1; - - ret = ioctl(fd, FS_IOC_FIEMAP, &fme.fm); - if (ret != 0 || fme.fm.fm_mapped_extents != 1) { - fprintf(stderr, "Failed to find log header block address\n"); - return 0; - } - return fme.fe.fe_physical / bsize; -} -#endif - -static void add_j(struct gfs2_sbd *sdp, struct jadd_opts *opts) -{ - int fd; - char new_name[256]; - int error; - uint64_t addr; - - fd = create_new_inode(opts, &addr); - - { - char buf[sdp->bsize]; - unsigned int blocks = - sdp->jsize << (20 - sdp->sd_sb.sb_bsize_shift); - unsigned int x; - struct gfs2_log_header lh; - uint64_t seq = RANDOM(blocks); - off_t off = 0; - - set_flags(fd, JA_FL_CLEAR, FS_JOURNAL_DATA_FL); - memset(buf, 0, sdp->bsize); - for (x=0; xbsize) != sdp->bsize) { - perror("add_j"); - exit(EXIT_FAILURE); - } - } - - lseek(fd, 0, SEEK_SET); - - memset(&lh, 0, sizeof(struct gfs2_log_header)); - lh.lh_header.mh_magic = GFS2_MAGIC; - lh.lh_header.mh_type = GFS2_METATYPE_LH; - lh.lh_header.mh_format = GFS2_FORMAT_LH; - lh.lh_flags = GFS2_LOG_HEAD_UNMOUNT; -#ifdef GFS2_HAS_LH_V2 - lh.lh_flags |= GFS2_LOG_HEAD_USERSPACE; - lh.lh_jinode = addr; -#endif - for (x=0; xlh_hash = cpu_to_be32(hash); -#ifdef GFS2_HAS_LH_V2 - ((struct gfs2_log_header *)buf)->lh_addr = cpu_to_be64( - find_block_address(fd, off, sdp->bsize)); - hash = lgfs2_log_header_crc(buf, sdp->bsize); - ((struct gfs2_log_header *)buf)->lh_crc = cpu_to_be32(hash); -#endif - if (write(fd, buf, sdp->bsize) != sdp->bsize) { - perror("add_j"); - exit(EXIT_FAILURE); - } - - if (++seq == blocks) - seq = 0; - off += sdp->bsize; - } - - error = fsync(fd); - if (error){ - perror("add_j fsync"); - exit(EXIT_FAILURE); - } - } - - close(fd); - - sprintf(new_name, "journal%u", opts->journals); - error = rename2system(opts, opts->jindex, new_name); - if (error < 0 && errno != EEXIST){ - perror("add_j rename2system"); - exit(EXIT_FAILURE); - } -} - -int main(int argc, char *argv[]) -{ - struct jadd_opts opts = {0}; - struct gfs2_sbd sbd, *sdp = &sbd; - struct metafs mfs = {0}; - struct mntent *mnt; - unsigned int total; - - setlocale(LC_ALL, ""); - textdomain("gfs2-utils"); - srandom(time(NULL) ^ getpid()); - - memset(sdp, 0, sizeof(struct gfs2_sbd)); - sdp->jsize = GFS2_DEFAULT_JSIZE; - sdp->qcsize = GFS2_DEFAULT_QCSIZE; - opts.journals = 1; - - decode_arguments(argc, argv, sdp, &opts); - verify_arguments(sdp, &opts); - - sbd.path_fd = lgfs2_open_mnt_dir(opts.path, O_RDONLY|O_CLOEXEC, &mnt); - if (sbd.path_fd < 0) { - fprintf(stderr, _("Error looking up mount '%s': %s\n"), opts.path, strerror(errno)); - exit(EXIT_FAILURE); - } - if (mnt == NULL) { - fprintf(stderr, _("%s: not a mounted gfs2 file system\n"), opts.path); - exit(EXIT_FAILURE); - } - gather_info(sdp, &opts); - mfs.context = copy_context_opt(mnt); - if (mount_gfs2_meta(&mfs, mnt->mnt_dir, opts.debug)) { - perror("GFS2 metafs"); - exit(EXIT_FAILURE); - } - - if (build_paths(mfs.path, &opts)) { - perror(_("Failed to build paths")); - exit(EXIT_FAILURE); - } - - if (compute_constants(sdp)) { - perror(_("Failed to compute file system constants")); - exit(EXIT_FAILURE); - } - find_current_journals(&opts); - - total = opts.orig_journals + opts.journals; - for (opts.journals = opts.orig_journals; - opts.journals < total; - opts.journals++) { - if (metafs_interrupted) { - cleanup_metafs(&mfs); - exit(130); - } - add_ir(&opts); - add_sc(&opts); - add_qc(sdp, &opts); - add_j(sdp, &opts); - } - - free(opts.new_inode); - free(opts.per_node); - free(opts.jindex); - close(sdp->path_fd); - cleanup_metafs(&mfs); - sync(); - print_results(&opts); - - return 0; -} diff --git a/gfs2/mkfs/main_jadd.c.bz1833141-2-gfs2_jadd_error_handling_overhaul b/gfs2/mkfs/main_jadd.c.bz1833141-2-gfs2_jadd_error_handling_overhaul deleted file mode 100644 index c542480..0000000 --- a/gfs2/mkfs/main_jadd.c.bz1833141-2-gfs2_jadd_error_handling_overhaul +++ /dev/null @@ -1,641 +0,0 @@ -#include "clusterautoconfig.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define _(String) gettext(String) - -#include -#include -#include -#include "libgfs2.h" -#include "gfs2_mkfs.h" -#include "metafs.h" - -#define RANDOM(values) ((values) * (random() / (RAND_MAX + 1.0))) - -struct jadd_opts { - char *path; - char *new_inode; - char *per_node; - char *jindex; - unsigned orig_journals; - unsigned journals; - unsigned quiet:1; - unsigned debug:1; -}; - -#define JA_FL_SET 0 -#define JA_FL_CLEAR 1 -static void set_flags(int fd, int op, uint32_t flags) -{ - int err; - uint32_t val; - - err = ioctl(fd, FS_IOC_GETFLAGS, &val); - if (err) { - perror("GETFLAGS"); - exit(EXIT_FAILURE); - } - - if (op == JA_FL_SET) - val |= flags; - else if (op == JA_FL_CLEAR) - val &= ~flags; - - err = ioctl(fd, FS_IOC_SETFLAGS, &val); - if (err) { - perror("SETFLAGS"); - exit(EXIT_FAILURE); - } -} - -static int rename2system(struct jadd_opts *opts, const char *new_dir, const char *new_name) -{ - char *newpath; - int ret; - - if (asprintf(&newpath, "%s/%s", new_dir, new_name) < 0) { - perror(_("Failed to allocate new path")); - return -1; - } - - ret = rename(opts->new_inode, newpath); - free(newpath); - return ret; -} - -static int build_paths(const char *metafs_path, struct jadd_opts *opts) -{ - int i = 0; - struct { - char **path; - const char *tail; - } p[] = { - { &opts->new_inode, "new_inode" }, - { &opts->per_node, "per_node" }, - { &opts->jindex, "jindex" }, - { NULL, NULL} - }; - - while (p[i].path != NULL) { - if (asprintf(p[i].path, "%s/%s", metafs_path, p[i].tail) < 0) { - while (i > 0) - free(*p[--i].path); - return 1; - } - if (opts->debug) - printf("%d: %s\n", i, *p[i].path); - i++; - } - return 0; -} - -/** - * print_usage - print out usage information - * @prog_name: The name of this program - */ - -static void print_usage(const char *prog_name) -{ - int i; - const char *option, *param, *desc; - const char *options[] = { - /* Translators: This is a usage string printed with --help. - and here are the commandline parameters, - e.g. gfs2_jadd -j /dev/sda */ - "-c", "", _("Size of quota change file, in megabytes"), - "-D", NULL, _("Enable debugging code"), - "-h", NULL, _("Display this help, then exit"), - "-J", "", _("Size of journals, in megabytes"), - "-j", "", _("Number of journals"), - "-q", NULL, _("Don't print anything"), - "-V", NULL, _("Display version information, then exit"), - NULL, NULL, NULL /* Must be kept at the end */ - }; - - printf("%s\n", _("Usage:")); - printf("%s [%s] <%s>\n\n", prog_name, _("options"), _("device")); - printf(_("Adds journals to a GFS2 file system.")); - printf("\n\n%s\n", _("Options:")); - - for (i = 0; options[i] != NULL; i += 3) { - option = options[i]; - param = options[i+1]; - desc = options[i+2]; - printf("%3s %-15s %s\n", option, param ? param : "", desc); - } -} - -/** - * decode_arguments - decode command line arguments and fill in the struct gfs2_sbd - * @argc: - * @argv: - * @sdp: the decoded command line arguments - * - */ - -static void decode_arguments(int argc, char *argv[], struct gfs2_sbd *sdp, struct jadd_opts *opts) -{ - int cont = TRUE; - int optchar; - - while (cont) { - optchar = getopt(argc, argv, "c:DhJ:j:qu:V"); - - switch (optchar) { - case 'c': - sdp->qcsize = atoi(optarg); - break; - case 'D': - opts->debug = 1; - lgfs2_set_debug(1); - break; - case 'h': - print_usage(argv[0]); - exit(0); - break; - case 'J': - sdp->jsize = atoi(optarg); - break; - case 'j': - opts->journals = atoi(optarg); - break; - case 'q': - opts->quiet = 1; - break; - case 'V': - printf("gfs2_jadd %s (built %s %s)\n", VERSION, - __DATE__, __TIME__); - printf(REDHAT_COPYRIGHT "\n"); - exit(0); - break; - case ':': - case '?': - fprintf(stderr, _("Please use '-h' for help.\n")); - exit(EXIT_FAILURE); - break; - case EOF: - cont = FALSE; - break; - default: - die( _("Invalid option: %c\n"), optchar); - break; - }; - } - - if (optind < argc) { - opts->path = argv[optind]; - optind++; - } else - die( _("no path specified (try -h for help)\n")); - - if (optind < argc) - die( _("Unrecognized argument: %s\n"), argv[optind]); - - if (opts->debug) { - printf( _("Command line arguments:\n")); - printf(" qcsize = %u\n", sdp->qcsize); - printf(" jsize = %u\n", sdp->jsize); - printf(" journals = %u\n", sdp->md.journals); - printf(" quiet = %u\n", opts->quiet); - printf(" path = %s\n", opts->path); - } -} - -static void verify_arguments(struct gfs2_sbd *sdp, struct jadd_opts *opts) -{ - if (!opts->journals) - die( _("no journals specified\n")); - if (sdp->jsize < 32 || sdp->jsize > 1024) - die( _("bad journal size\n")); - if (!sdp->qcsize || sdp->qcsize > 64) - die( _("bad quota change size\n")); -} - -static void print_results(struct jadd_opts *opts) -{ - if (opts->debug) - printf("\n"); - else if (opts->quiet) - return; - - printf( _("Filesystem: %s\n"), opts->path); - printf( _("Old journals: %u\n"), opts->orig_journals); - printf( _("New journals: %u\n"), opts->journals); -} - -static int create_new_inode(struct jadd_opts *opts, uint64_t *addr) -{ - char *name = opts->new_inode; - int fd; - int error; - - for (;;) { - fd = open(name, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW | O_CLOEXEC, 0600); - if (fd >= 0) - break; - if (errno == EEXIST) { - error = unlink(name); - if (error){ - perror("unlink"); - exit(EXIT_FAILURE); - } - } else{ - perror("create"); - exit(EXIT_FAILURE); - } - } - if (addr != NULL) { - struct stat st; - - fstat(fd, &st); - *addr = st.st_ino; - } - - return fd; -} - -static void add_ir(struct jadd_opts *opts) -{ - int fd; - char new_name[256]; - int error; - - fd = create_new_inode(opts, NULL); - - { - struct gfs2_inum_range ir; - - set_flags(fd, JA_FL_SET, FS_JOURNAL_DATA_FL); - memset(&ir, 0, sizeof(struct gfs2_inum_range)); - if (write(fd, (void*)&ir, sizeof(struct gfs2_inum_range)) != - sizeof(struct gfs2_inum_range)) { - perror("add_ir"); - exit(EXIT_FAILURE); - } - } - - close(fd); - - sprintf(new_name, "inum_range%u", opts->journals); - error = rename2system(opts, opts->per_node, new_name); - if (error < 0 && errno != EEXIST){ - perror("add_ir rename2system"); - exit(EXIT_FAILURE); - } -} - -static void add_sc(struct jadd_opts *opts) -{ - int fd; - char new_name[256]; - int error; - - fd = create_new_inode(opts, NULL); - - { - struct gfs2_statfs_change sc; - set_flags(fd, JA_FL_SET, FS_JOURNAL_DATA_FL); - - memset(&sc, 0, sizeof(struct gfs2_statfs_change)); - if (write(fd, (void*)&sc, sizeof(struct gfs2_statfs_change)) != - sizeof(struct gfs2_statfs_change)) { - perror("add_sc"); - exit(EXIT_FAILURE); - } - } - - close(fd); - - sprintf(new_name, "statfs_change%u", opts->journals); - error = rename2system(opts, opts->per_node, new_name); - if (error < 0 && errno != EEXIST){ - perror("add_sc rename2system"); - exit(EXIT_FAILURE); - } -} - -static void add_qc(struct gfs2_sbd *sdp, struct jadd_opts *opts) -{ - int fd; - char new_name[256]; - int error; - - fd = create_new_inode(opts, NULL); - - { - char buf[sdp->bsize]; - unsigned int blocks = - sdp->qcsize << (20 - sdp->sd_sb.sb_bsize_shift); - unsigned int x; - struct gfs2_meta_header mh; - - set_flags(fd, JA_FL_CLEAR, FS_JOURNAL_DATA_FL); - memset(buf, 0, sdp->bsize); - - for (x=0; xbsize) != sdp->bsize) { - perror("add_qc"); - exit(EXIT_FAILURE); - } - } - - lseek(fd, 0, SEEK_SET); - - memset(&mh, 0, sizeof(struct gfs2_meta_header)); - mh.mh_magic = GFS2_MAGIC; - mh.mh_type = GFS2_METATYPE_QC; - mh.mh_format = GFS2_FORMAT_QC; - gfs2_meta_header_out(&mh, buf); - - for (x=0; xbsize) != sdp->bsize) { - perror("add_qc"); - exit(EXIT_FAILURE); - } - } - - error = fsync(fd); - if (error){ - perror("add_qc fsync"); - exit(EXIT_FAILURE); - } - } - - close(fd); - - sprintf(new_name, "quota_change%u", opts->journals); - error = rename2system(opts, opts->per_node, new_name); - if (error < 0 && errno != EEXIST){ - perror("add_qc rename2system"); - exit(EXIT_FAILURE); - } -} - -static void gather_info(struct gfs2_sbd *sdp, struct jadd_opts *opts) -{ - struct statfs statbuf; - if (statfs(opts->path, &statbuf) < 0) { - perror(opts->path); - exit(EXIT_FAILURE); - } - sdp->bsize = statbuf.f_bsize; - sdp->blks_total = statbuf.f_blocks; - sdp->blks_alloced = sdp->blks_total - statbuf.f_bfree; -} - -static void find_current_journals(struct jadd_opts *opts) -{ - struct dirent *dp; - DIR *dirp; - unsigned existing_journals = 0; - - dirp = opendir(opts->jindex); - if (!dirp) { - perror("jindex"); - exit(EXIT_FAILURE); - } - while (dirp) { - if ((dp = readdir(dirp)) != NULL) { - if (strncmp(dp->d_name, "journal", 7) == 0) - existing_journals++; - } else - goto close; - } -close: - closedir(dirp); - if (existing_journals == 0) { - die( _("No journals found. Did you run mkfs.gfs2 correctly?\n")); - } - - opts->orig_journals = existing_journals; -} - -#ifdef GFS2_HAS_LH_V2 -static uint64_t find_block_address(int fd, off_t offset, unsigned bsize) -{ - struct { - struct fiemap fm; - struct fiemap_extent fe; - } fme; - int ret; - - fme.fm.fm_start = offset; - fme.fm.fm_length = 1; - fme.fm.fm_flags = FIEMAP_FLAG_SYNC; - fme.fm.fm_extent_count = 1; - - ret = ioctl(fd, FS_IOC_FIEMAP, &fme.fm); - if (ret != 0 || fme.fm.fm_mapped_extents != 1) { - fprintf(stderr, "Failed to find log header block address\n"); - return 0; - } - return fme.fe.fe_physical / bsize; -} -#endif - -static void add_j(struct gfs2_sbd *sdp, struct jadd_opts *opts) -{ - int fd; - char new_name[256]; - int error; - uint64_t addr; - - fd = create_new_inode(opts, &addr); - - { - char buf[sdp->bsize]; - unsigned int blocks = - sdp->jsize << (20 - sdp->sd_sb.sb_bsize_shift); - unsigned int x; - struct gfs2_log_header lh; - uint64_t seq = RANDOM(blocks); - off_t off = 0; - - set_flags(fd, JA_FL_CLEAR, FS_JOURNAL_DATA_FL); - memset(buf, 0, sdp->bsize); - for (x=0; xbsize) != sdp->bsize) { - perror("add_j"); - exit(EXIT_FAILURE); - } - } - - lseek(fd, 0, SEEK_SET); - - memset(&lh, 0, sizeof(struct gfs2_log_header)); - lh.lh_header.mh_magic = GFS2_MAGIC; - lh.lh_header.mh_type = GFS2_METATYPE_LH; - lh.lh_header.mh_format = GFS2_FORMAT_LH; - lh.lh_flags = GFS2_LOG_HEAD_UNMOUNT; -#ifdef GFS2_HAS_LH_V2 - lh.lh_flags |= GFS2_LOG_HEAD_USERSPACE; - lh.lh_jinode = addr; -#endif - for (x=0; xlh_hash = cpu_to_be32(hash); -#ifdef GFS2_HAS_LH_V2 - ((struct gfs2_log_header *)buf)->lh_addr = cpu_to_be64( - find_block_address(fd, off, sdp->bsize)); - hash = lgfs2_log_header_crc(buf, sdp->bsize); - ((struct gfs2_log_header *)buf)->lh_crc = cpu_to_be32(hash); -#endif - if (write(fd, buf, sdp->bsize) != sdp->bsize) { - perror("add_j"); - exit(EXIT_FAILURE); - } - - if (++seq == blocks) - seq = 0; - off += sdp->bsize; - } - - error = fsync(fd); - if (error){ - perror("add_j fsync"); - exit(EXIT_FAILURE); - } - } - - close(fd); - - sprintf(new_name, "journal%u", opts->journals); - error = rename2system(opts, opts->jindex, new_name); - if (error < 0 && errno != EEXIST){ - perror("add_j rename2system"); - exit(EXIT_FAILURE); - } -} - -static int check_fit(struct gfs2_sbd *sdp, struct jadd_opts *opts) -{ - /* Compute how much space we'll need for the new journals - * Number of blocks needed per added journal: - * 1 block for the ir inode - * 1 block for the sc inode - * for sizes of the qc and journal inodes, use lgfs2_space_for_data() - * to calculate. - */ - uint64_t blks_per_j, total_blks; - - blks_per_j = 1 + 1 + - lgfs2_space_for_data(sdp, sdp->bsize, sdp->qcsize << 20) + - lgfs2_space_for_data(sdp, sdp->bsize, sdp->jsize << 20); - total_blks = opts->journals * blks_per_j; - - if (total_blks > (sdp->blks_total - sdp->blks_alloced)) { - printf( _("\nInsufficient space on the device to add %u %uMB " - "journals (%uMB QC size)\n\n"), - opts->journals, sdp->jsize, sdp->qcsize); - printf( _("Required space : %*lu blks (%lu blks per " - "journal)\n"), 10, total_blks, blks_per_j); - printf( _("Available space : %*lu blks\n\n"), 10, - sdp->blks_total - sdp->blks_alloced); - errno = ENOSPC; - return 1; - } - return 0; -} - -int main(int argc, char *argv[]) -{ - struct jadd_opts opts = {0}; - struct gfs2_sbd sbd, *sdp = &sbd; - struct metafs mfs = {0}; - struct mntent *mnt; - unsigned int total, ret = 0; - - setlocale(LC_ALL, ""); - textdomain("gfs2-utils"); - srandom(time(NULL) ^ getpid()); - - memset(sdp, 0, sizeof(struct gfs2_sbd)); - sdp->jsize = GFS2_DEFAULT_JSIZE; - sdp->qcsize = GFS2_DEFAULT_QCSIZE; - opts.journals = 1; - - decode_arguments(argc, argv, sdp, &opts); - verify_arguments(sdp, &opts); - - sbd.path_fd = lgfs2_open_mnt_dir(opts.path, O_RDONLY|O_CLOEXEC, &mnt); - if (sbd.path_fd < 0) { - fprintf(stderr, _("Error looking up mount '%s': %s\n"), opts.path, strerror(errno)); - exit(EXIT_FAILURE); - } - if (mnt == NULL) { - fprintf(stderr, _("%s: not a mounted gfs2 file system\n"), opts.path); - exit(EXIT_FAILURE); - } - gather_info(sdp, &opts); - mfs.context = copy_context_opt(mnt); - if (mount_gfs2_meta(&mfs, mnt->mnt_dir, opts.debug)) { - perror("GFS2 metafs"); - exit(EXIT_FAILURE); - } - - if (build_paths(mfs.path, &opts)) { - perror(_("Failed to build paths")); - exit(EXIT_FAILURE); - } - - if (compute_constants(sdp)) { - perror(_("Failed to compute file system constants")); - exit(EXIT_FAILURE); - } - find_current_journals(&opts); - - ret = check_fit(sdp, &opts); - if (ret) { - perror(_("Failed to add journals")); - goto out; - } - - total = opts.orig_journals + opts.journals; - for (opts.journals = opts.orig_journals; - opts.journals < total; - opts.journals++) { - if (metafs_interrupted) { - cleanup_metafs(&mfs); - exit(130); - } - add_ir(&opts); - add_sc(&opts); - add_qc(sdp, &opts); - add_j(sdp, &opts); - } - -out: - free(opts.new_inode); - free(opts.per_node); - free(opts.jindex); - close(sdp->path_fd); - cleanup_metafs(&mfs); - sync(); - - if (!ret) - print_results(&opts); - - return ret; -} diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c index 412d470..846b341 100644 --- a/gfs2/mkfs/main_mkfs.c +++ b/gfs2/mkfs/main_mkfs.c @@ -505,7 +505,7 @@ static unsigned choose_blocksize(struct mkfs_opts *opts) } if (!opts->got_bsize && got_topol) { if (dev->optimal_io_size <= getpagesize() && - dev->optimal_io_size >= GFS2_DEFAULT_BSIZE) + dev->optimal_io_size >= dev->minimum_io_size) bsize = dev->optimal_io_size; else if (dev->physical_sector_size <= getpagesize() && dev->physical_sector_size >= GFS2_DEFAULT_BSIZE) diff --git a/gfs2/mkfs/main_mkfs.c.bz1839219-mkfs_gfs2_Don_t_use_i_o_limits_hints_4K_for_block_size b/gfs2/mkfs/main_mkfs.c.bz1839219-mkfs_gfs2_Don_t_use_i_o_limits_hints_4K_for_block_size deleted file mode 100644 index 846b341..0000000 --- a/gfs2/mkfs/main_mkfs.c.bz1839219-mkfs_gfs2_Don_t_use_i_o_limits_hints_4K_for_block_size +++ /dev/null @@ -1,1189 +0,0 @@ -#include "clusterautoconfig.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define _(String) gettext(String) - -#include -#include "libgfs2.h" -#include "gfs2_mkfs.h" -#include "progress.h" - -#ifdef GFS2_HAS_UUID -#include -#endif - -static void print_usage(const char *prog_name) -{ - int i; - const char *option, *param, *desc; - const char *options[] = { - /* Translators: This is a usage string printed with --help. - and here are the commandline parameters, - e.g. mkfs.gfs2 -b -j /dev/sda */ - "-b", _(""), _("File system block size, in bytes"), - "-c", _(""), _("Size of quota change file, in megabytes"), - "-D", NULL, _("Enable debugging code"), - "-h", NULL, _("Display this help, then exit"), - "-J", _(""), _("Size of journals, in megabytes"), - "-j", _(""), _("Number of journals"), - "-K", NULL, _("Don't try to discard unused blocks"), - "-O", NULL, _("Don't ask for confirmation"), - "-o", _("[=][,...]"), _("Specify extended options. See '-o help'."), - "-p", _(""), _("Name of the locking protocol"), - "-q", NULL, _("Don't print anything"), - "-r", _(""), _("Size of resource groups, in megabytes"), - "-t", _(""), _("Name of the lock table"), - "-V", NULL, _("Display program version information, then exit"), - NULL, NULL, NULL /* Must be kept at the end */ - }; - - printf("%s\n", _("Usage:")); - printf("%s [%s] <%s> [%s]\n\n", prog_name, _("options"), _("device"), _("size")); - printf(_("Create a gfs2 file system on a device. If a size, in blocks, is not " - "specified, the whole device will be used.")); - printf("\n\n%s\n", _("Options:")); - - for (i = 0; options[i] != NULL; i += 3) { - option = options[i]; - param = options[i + 1]; - desc = options[i + 2]; - printf("%3s %-22s %s\n", option, param ? param : "", desc); - } -} - -static void print_ext_opts(void) -{ - int i; - const char *options[] = { - "help", _("Display this help, then exit"), - "swidth=N", _("Specify the stripe width of the device, overriding probed values"), - "sunit=N", _("Specify the stripe unit of the device, overriding probed values"), - "align=[0|1]", _("Disable or enable alignment of resource groups"), - NULL, NULL - }; - printf(_("Extended options:\n")); - for (i = 0; options[i] != NULL; i += 2) { - printf("%15s %-22s\n", options[i], options[i + 1]); - } -} - -/** - * Values probed by libblkid: - * alignment_offset: offset, in bytes, of the start of the dev from its natural alignment - * logical_sector_size: smallest addressable unit - * minimum_io_size: device's preferred unit of I/O. RAID stripe unit. - * optimal_io_size: biggest I/O we can submit without incurring a penalty. RAID stripe width. - * physical_sector_size: the smallest unit we can write atomically - */ -struct mkfs_dev { - int fd; - const char *path; - struct stat stat; - uint64_t size; - unsigned long alignment_offset; - unsigned long logical_sector_size; - unsigned long minimum_io_size; - unsigned long optimal_io_size; - unsigned long physical_sector_size; - - unsigned int got_topol:1; -}; - -struct mkfs_opts { - unsigned bsize; - unsigned qcsize; - unsigned jsize; - unsigned rgsize; - unsigned long sunit; - unsigned long swidth; - uint64_t fssize; - uint32_t journals; - const char *lockproto; - const char *locktable; - struct mkfs_dev dev; - unsigned discard:1; - - unsigned got_bsize:1; - unsigned got_qcsize:1; - unsigned got_jsize:1; - unsigned got_rgsize:1; - unsigned got_sunit:1; - unsigned got_swidth:1; - unsigned got_fssize:1; - unsigned got_journals:1; - unsigned got_lockproto:1; - unsigned got_locktable:1; - unsigned got_device:1; - unsigned got_topol:1; - - unsigned override:1; - unsigned quiet:1; - unsigned debug:1; - unsigned confirm:1; - unsigned align:1; -}; - -static void opts_init(struct mkfs_opts *opts) -{ - memset(opts, 0, sizeof(*opts)); - opts->discard = 1; - opts->journals = 1; - opts->bsize = GFS2_DEFAULT_BSIZE; - opts->jsize = GFS2_DEFAULT_JSIZE; - opts->qcsize = GFS2_DEFAULT_QCSIZE; - opts->rgsize = GFS2_DEFAULT_RGSIZE; - opts->lockproto = "lock_dlm"; - opts->locktable = ""; - opts->confirm = 1; - opts->align = 1; -} - -struct gfs2_inum *mkfs_journals = NULL; - -#ifndef BLKDISCARD -#define BLKDISCARD _IO(0x12,119) -#endif - -static int discard_blocks(int fd, uint64_t len, int debug) -{ - __uint64_t range[2]; - - range[0] = 0; - range[1] = len; - if (debug) - /* Translators: "discard" is a request sent to a storage device to - * discard a range of blocks. */ - printf(_("Issuing discard request: range: %llu - %llu..."), - (unsigned long long)range[0], - (unsigned long long)range[1]); - if (ioctl(fd, BLKDISCARD, &range) < 0) { - if (debug) - printf("%s = %d\n", _("error"), errno); - return errno; - } - if (debug) - printf(_("Successful.\n")); - return 0; -} - -/** - * Convert a human-readable size string to a long long. - * Copied and adapted from xfs_mkfs.c. - */ -static long long cvtnum(unsigned int blocksize, unsigned int sectorsize, const char *s) -{ - long long i; - char *sp; - - i = strtoll(s, &sp, 0); - if (i == 0 && sp == s) - return -1LL; - if (*sp == '\0') - return i; - - *sp = tolower(*sp); - if (*sp == 'b' && sp[1] == '\0') { - if (blocksize) - return i * blocksize; - fprintf(stderr, _("Block size not available yet.\n")); - exit(1); - } - if (*sp == 's' && sp[1] == '\0') { - if (sectorsize) - return i * sectorsize; - return i * GFS2_BASIC_BLOCK; - } - if (*sp == 'k' && sp[1] == '\0') - return 1024LL * i; - if (*sp == 'm' && sp[1] == '\0') - return 1024LL * 1024LL * i; - if (*sp == 'g' && sp[1] == '\0') - return 1024LL * 1024LL * 1024LL * i; - if (*sp == 't' && sp[1] == '\0') - return 1024LL * 1024LL * 1024LL * 1024LL * i; - if (*sp == 'p' && sp[1] == '\0') - return 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * i; - if (*sp == 'e' && sp[1] == '\0') - return 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * i; - return -1LL; -} - -static unsigned long parse_ulong(struct mkfs_opts *opts, const char *key, const char *val) -{ - long long l; - if (val == NULL || *val == '\0') { - fprintf(stderr, _("Missing argument to '%s'\n"), key); - exit(-1); - } - l = cvtnum(opts->bsize, 0, val); - if (l > ULONG_MAX || l < 0) { - fprintf(stderr, _("Value of '%s' is invalid\n"), key); - exit(-1); - } - return (unsigned long)l; -} - -static unsigned parse_bool(struct mkfs_opts *opts, const char *key, const char *val) -{ - if (strnlen(val, 2) == 1) { - if (*val == '0') - return 0; - if (*val == '1') - return 1; - } - fprintf(stderr, _("Option '%s' must be either 1 or 0\n"), key); - exit(-1); -} - -static int parse_topology(struct mkfs_opts *opts, char *str) -{ - char *opt; - unsigned i = 0; - unsigned long *topol[5] = { - &opts->dev.alignment_offset, - &opts->dev.logical_sector_size, - &opts->dev.minimum_io_size, - &opts->dev.optimal_io_size, - &opts->dev.physical_sector_size - }; - - while ((opt = strsep(&str, ":")) != NULL) { - if (i > 4) { - fprintf(stderr, "Too many topology values.\n"); - return 1; - } - *topol[i] = parse_ulong(opts, "test_topology", opt); - i++; - } - if (i < 5) { - fprintf(stderr, "Too few topology values.\n"); - return 1; - } - return 0; -} - -static void opt_parse_extended(char *str, struct mkfs_opts *opts) -{ - char *opt; - while ((opt = strsep(&str, ",")) != NULL) { - char *key = strsep(&opt, "="); - char *val = strsep(&opt, "="); - if (key == NULL || *key == '\0') { - fprintf(stderr, _("Missing argument to '-o' option\n")); - exit(-1); - } - if (strcmp("sunit", key) == 0) { - opts->sunit = parse_ulong(opts, "sunit", val); - opts->got_sunit = 1; - } else if (strcmp("swidth", key) == 0) { - opts->swidth = parse_ulong(opts, "swidth", val); - opts->got_swidth = 1; - } else if (strcmp("align", key) == 0) { - opts->align = parse_bool(opts, "align", val); - } else if (strcmp("test_topology", key) == 0) { - if (parse_topology(opts, val) != 0) - exit(-1); - opts->got_topol = (opts->dev.logical_sector_size != 0 && - opts->dev.physical_sector_size != 0); - } else if (strcmp("help", key) == 0) { - print_ext_opts(); - exit(0); - } else { - fprintf(stderr, _("Invalid option '%s'\n"), key); - exit(-1); - } - } -} - -static void opts_get(int argc, char *argv[], struct mkfs_opts *opts) -{ - int c; - while (1) { - c = getopt(argc, argv, "-b:c:DhJ:j:KOo:p:qr:t:V"); - if (c == -1) - break; - - switch (c) { - case 'b': - opts->bsize = atoi(optarg); - opts->got_bsize = 1; - break; - case 'c': - opts->qcsize = atoi(optarg); - opts->got_qcsize = 1; - break; - case 'D': - opts->debug = 1; - lgfs2_set_debug(1); - break; - case 'h': - print_usage(argv[0]); - exit(0); - case 'J': - opts->jsize = atoi(optarg); - opts->got_jsize = 1; - break; - case 'j': - opts->journals = atoi(optarg); - opts->got_journals = 1; - break; - case 'K': - opts->discard = 0; - break; - case 'O': - opts->override = 1; - break; - case 'p': - opts->lockproto = optarg; - opts->got_lockproto = 1; - break; - case 't': - opts->locktable = optarg; - opts->got_locktable = 1; - break; - case 'q': - opts->quiet = 1; - break; - case 'r': - opts->rgsize = atoi(optarg); - opts->got_rgsize = 1; - break; - case 'o': - opt_parse_extended(optarg, opts); - break; - case 'V': - printf("mkfs.gfs2 %s (built %s %s)\n", VERSION, - __DATE__, __TIME__); - printf(REDHAT_COPYRIGHT "\n"); - exit(EXIT_SUCCESS); - break; - case ':': - case '?': - fprintf(stderr, _("Please use '-h' for help.\n")); - exit(EXIT_FAILURE); - break; - case 1: - if (strcmp(optarg, "gfs2") == 0) - continue; - if (!opts->got_device) { - opts->dev.path = optarg; - opts->got_device = 1; - } else if (!opts->got_fssize && isdigit(optarg[0])) { - opts->fssize = atol(optarg); - opts->got_fssize = 1; - } else - die( _("More than one device specified (try -h for help)\n")); - break; - default: - die( _("Invalid option: %c\n"), c); - break; - }; - } -} - -/** - * test_locking - Make sure the GFS2 is set up to use the right lock protocol - * @lockproto: the lock protocol to mount - * @locktable: the locktable name - * - */ - -static void test_locking(struct mkfs_opts *opts) -{ - const char *c; - /* Translators: A lock table is a string identifying a gfs2 file system - * in a cluster, e.g. cluster_name:fs_name */ - const char *errprefix = _("Invalid lock table:"); - int table_required = (strcmp(opts->lockproto, "lock_gulm") == 0) - || (strcmp(opts->lockproto, "lock_dlm") == 0); - - if ((strcmp(opts->lockproto, "lock_nolock") != 0) && !table_required) - die( _("Invalid lock protocol: %s\n"), opts->lockproto); - - /* When lock_*lm is given as the lock protocol, require a lock table too */ - if (!opts->got_locktable) { - if (table_required) { - fprintf(stderr, _("No lock table specified.\n")); - exit(-1); - } - return; - } - /* User gave a lock table option, validate it */ - if (*opts->locktable == '\0') { - fprintf(stderr, _("Lock table is empty.\n")); - exit(-1); - } - for (c = opts->locktable; *c; c++) { - if (!isalnum(*c) && (*c != '-') && (*c != '_') && (*c != ':')) - die("%s %s '%c'\n", errprefix, _("invalid character"), *c); - } - c = strstr(opts->locktable, ":"); - if (!c) - die("%s %s\n", errprefix, _("missing colon")); - - if (c == opts->locktable) - die("%s %s\n", errprefix, _("cluster name is missing")); - if (c - opts->locktable > 32) - die("%s %s\n", errprefix, _("cluster name is too long")); - - c++; - if (strstr(c, ":")) - die("%s %s\n", errprefix, _("contains more than one colon")); - if (!strlen(c)) - die("%s %s\n", errprefix, _("file system name is missing")); - if (strlen(c) > 30) - die("%s %s\n", errprefix, _("file system name is too long")); -} - -static void are_you_sure(void) -{ - while (1) { - char *line = NULL; - size_t len = 0; - int ret; - int res; - - /* Translators: We use rpmatch(3) to match the answers to y/n - questions in the user's own language, so the [y/n] here must also be - translated to match one of the letters in the pattern printed by - `locale -k yesexpr` and one of the letters in the pattern printed by - `locale -k noexpr` */ - printf( _("Are you sure you want to proceed? [y/n] ")); - ret = getline(&line, &len, stdin); - res = rpmatch(line); - free(line); - if (ret <= 0) - continue; - if (res == 1) /* Yes */ - return; - if (res == 0) /* No */ - exit(1); - /* Unrecognized input; go again. */ - }; -} - -static unsigned choose_blocksize(struct mkfs_opts *opts) -{ - unsigned int x; - unsigned int bsize = opts->bsize; - struct mkfs_dev *dev = &opts->dev; - int got_topol = (dev->got_topol || opts->got_topol); - - if (got_topol && opts->debug) { - printf("alignment_offset: %lu\n", dev->alignment_offset); - printf("logical_sector_size: %lu\n", dev->logical_sector_size); - printf("minimum_io_size: %lu\n", dev->minimum_io_size); - printf("optimal_io_size: %lu\n", dev->optimal_io_size); - printf("physical_sector_size: %lu\n", dev->physical_sector_size); - } - if (got_topol && dev->alignment_offset != 0) { - fprintf(stderr, - _("Warning: device is not properly aligned. This may harm performance.\n")); - dev->physical_sector_size = dev->logical_sector_size; - } - if (!opts->got_bsize && got_topol) { - if (dev->optimal_io_size <= getpagesize() && - dev->optimal_io_size >= dev->minimum_io_size) - bsize = dev->optimal_io_size; - else if (dev->physical_sector_size <= getpagesize() && - dev->physical_sector_size >= GFS2_DEFAULT_BSIZE) - bsize = dev->physical_sector_size; - } - - /* Block sizes must be a power of two from 512 to 65536 */ - for (x = 512; x; x <<= 1) - if (x == bsize) - break; - - if (!x || bsize > getpagesize()) - die( _("Block size must be a power of two between 512 and %d\n"), - getpagesize()); - - if (bsize < dev->logical_sector_size) { - die( _("Error: Block size %d is less than minimum logical " - "block size (%lu).\n"), bsize, dev->logical_sector_size); - } - - if (bsize < dev->physical_sector_size) { - printf( _("Warning: Block size %d is inefficient because it " - "is less than the physical block size (%lu).\n"), - bsize, dev->physical_sector_size); - opts->confirm = 1; - } - return bsize; -} - -static void opts_check(struct mkfs_opts *opts) -{ - if (!opts->got_device) { - fprintf(stderr, _("No device specified. Use -h for help\n")); - exit(1); - } - - test_locking(opts); - - if (GFS2_MIN_RGSIZE > opts->rgsize || opts->rgsize > GFS2_MAX_RGSIZE) - /* Translators: gfs2 file systems are split into equal sized chunks called - resource groups. We're checking that the user gave a valid size for them. */ - die( _("bad resource group size\n")); - - if (!opts->journals) - die( _("no journals specified\n")); - - if (opts->jsize < GFS2_MIN_JSIZE || opts->jsize > GFS2_MAX_JSIZE) - die( _("bad journal size\n")); - - if (!opts->qcsize || opts->qcsize > 64) - die( _("bad quota change size\n")); - - if ((opts->got_sunit && !opts->got_swidth) || (!opts->got_sunit && opts->got_swidth)) { - fprintf(stderr, _("Stripe unit and stripe width must be specified together\n")); - exit(1); - } -} - -static void print_results(struct gfs2_sb *sb, struct mkfs_opts *opts, uint64_t rgrps, uint64_t fssize) -{ - printf("%-27s%s\n", _("Device:"), opts->dev.path); - printf("%-27s%u\n", _("Block size:"), sb->sb_bsize); - printf("%-27s%.2f %s (%"PRIu64" %s)\n", _("Device size:"), - /* Translators: "GB" here means "gigabytes" */ - (opts->dev.size / ((float)(1 << 30))), _("GB"), - (opts->dev.size / sb->sb_bsize), _("blocks")); - printf("%-27s%.2f %s (%"PRIu64" %s)\n", _("Filesystem size:"), - (fssize / ((float)(1 << 30)) * sb->sb_bsize), _("GB"), fssize, _("blocks")); - printf("%-27s%u\n", _("Journals:"), opts->journals); - printf("%-27s%uMB\n", _("Journal size:"), opts->jsize); - printf("%-27s%"PRIu64"\n", _("Resource groups:"), rgrps); - printf("%-27s\"%s\"\n", _("Locking protocol:"), opts->lockproto); - printf("%-27s\"%s\"\n", _("Lock table:"), opts->locktable); -#ifdef GFS2_HAS_UUID - { - char readable_uuid[36+1]; - - uuid_unparse(sb->sb_uuid, readable_uuid); - /* Translators: "UUID" = universally unique identifier. */ - printf("%-27s%s\n", _("UUID:"), readable_uuid); - } -#endif -} - -static void warn_of_destruction(const char *path) -{ - struct stat lnkstat; - char *abspath = NULL; - - if (lstat(path, &lnkstat) == -1) { - perror(_("Failed to lstat the device")); - exit(EXIT_FAILURE); - } - if (S_ISLNK(lnkstat.st_mode)) { - abspath = canonicalize_file_name(path); - if (abspath == NULL) { - perror(_("Could not find the absolute path of the device")); - exit(EXIT_FAILURE); - } - /* Translators: Example: "/dev/vg/lv is a symbolic link to /dev/dm-2" */ - printf( _("%s is a symbolic link to %s\n"), path, abspath); - path = abspath; - } - printf(_("This will destroy any data on %s\n"), path); - free(abspath); -} - -static int zero_gap(struct gfs2_sbd *sdp, uint64_t addr, size_t blocks) -{ - struct iovec *iov; - char *zerobuf; - ssize_t wrote; - unsigned i; - - if (blocks == 0) - return 0; - iov = calloc(blocks, sizeof(*iov)); - if (iov == NULL) { - perror(_("Failed to zero blocks\n")); - return 1; - } - zerobuf = calloc(1, sdp->bsize); - if (zerobuf == NULL) { - perror(_("Failed to zero blocks\n")); - free(iov); - return 1; - } - for (i = 0; i < blocks; i++) { - iov[i].iov_base = zerobuf; - iov[i].iov_len = sdp->bsize; - } - wrote = pwritev(sdp->device_fd, iov, blocks, addr * sdp->bsize); - if (wrote != blocks * sdp->bsize) { - fprintf(stderr, _("Zeroing write failed at block %"PRIu64"\n"), addr); - free(zerobuf); - free(iov); - return 1; - } - free(zerobuf); - free(iov); - return 0; -} - -static lgfs2_rgrps_t rgs_init(struct mkfs_opts *opts, struct gfs2_sbd *sdp) -{ - lgfs2_rgrps_t rgs; - uint64_t al_base = 0; - uint64_t al_off = 0; - - if (opts->align && opts->got_sunit) { - if ((opts->sunit % sdp->bsize) != 0) { - fprintf(stderr, _("Stripe unit (%lu) must be a multiple of block size (%u)\n"), - opts->sunit, sdp->bsize); - exit(1); - } else if ((opts->swidth % opts->sunit) != 0) { - fprintf(stderr, _("Stripe width (%lu) must be a multiple of stripe unit (%lu)\n"), - opts->swidth, opts->sunit); - exit(1); - } else { - al_base = opts->swidth / sdp->bsize; - al_off = opts->sunit / sdp->bsize; - } - } else if (opts->align) { - if (opts->dev.optimal_io_size <= opts->dev.physical_sector_size || - opts->dev.minimum_io_size <= opts->dev.physical_sector_size || - (opts->dev.optimal_io_size % opts->dev.minimum_io_size) != 0) { - /* If optimal_io_size is not a multiple of minimum_io_size then - the values are not reliable swidth and sunit values, so disable - rgrp alignment */ - opts->align = 0; - } else { - al_base = opts->dev.optimal_io_size / sdp->bsize; - al_off = opts->dev.minimum_io_size / sdp->bsize; - } - } - - rgs = lgfs2_rgrps_init(sdp, al_base, al_off); - if (rgs == NULL) { - perror(_("Could not initialise resource groups")); - exit(-1); - } - - if (opts->debug) { - printf(" rgrp align = "); - if (opts->align) - printf("%"PRIu64"+%"PRIu64" blocks\n", al_base, al_off); - else - printf("(disabled)\n"); - } - - return rgs; -} - -static int place_rgrp(struct gfs2_sbd *sdp, lgfs2_rgrp_t rg, int debug) -{ - uint64_t prev_end = (GFS2_SB_ADDR * GFS2_BASIC_BLOCK / sdp->bsize) + 1; - const struct gfs2_rindex *ri = lgfs2_rgrp_index(rg); - lgfs2_rgrp_t prev = lgfs2_rgrp_prev(rg); - int err = 0; - - if (prev != NULL) { - prev_end = lgfs2_rgrp_index(prev)->ri_data0 + - lgfs2_rgrp_index(prev)->ri_data; - } - err = zero_gap(sdp, prev_end, ri->ri_addr - prev_end); - if (err != 0) - return -1; - err = lgfs2_rgrp_write(sdp->device_fd, rg); - if (err != 0) { - perror(_("Failed to write resource group")); - return -1; - } - if (debug) { - gfs2_rindex_print(ri); - printf("\n"); - } - sdp->blks_total += ri->ri_data; - sdp->fssize = ri->ri_data0 + ri->ri_data; - sdp->rgrps++; - return 0; -} - -static int add_rgrp(lgfs2_rgrps_t rgs, uint64_t *addr, uint32_t len, lgfs2_rgrp_t *rg) -{ - struct gfs2_rindex ri; - uint64_t nextaddr; - - /* When we get to the end of the device, it's only an error if we have - more structures left to write, i.e. when len is != 0. */ - nextaddr = lgfs2_rindex_entry_new(rgs, &ri, *addr, len); - if (nextaddr == 0) { - if (len != 0) { - perror(_("Failed to create resource group index entry")); - return -1; - } else { - return 1; - } - } - *rg = lgfs2_rgrps_append(rgs, &ri, nextaddr - *addr); - if (*rg == NULL) { - perror(_("Failed to create resource group")); - return -1; - } - *addr = nextaddr; - return 0; -} - -static int place_journals(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs, struct mkfs_opts *opts, uint64_t *rgaddr) -{ - struct gfs2_progress_bar progress; - uint64_t jfsize = lgfs2_space_for_data(sdp, sdp->bsize, opts->jsize << 20); - uint32_t rgsize = lgfs2_rgsize_for_data(jfsize, sdp->bsize); - unsigned j; - - gfs2_progress_init(&progress, opts->journals, _("Adding journals: "), opts->quiet); - - /* We'll build the jindex later so remember where we put the journals */ - mkfs_journals = calloc(opts->journals, sizeof(*mkfs_journals)); - if (mkfs_journals == NULL) - return 1; - *rgaddr = lgfs2_rgrp_align_addr(rgs, LGFS2_SB_ADDR(sdp) + 1); - rgsize = lgfs2_rgrp_align_len(rgs, rgsize); - - for (j = 0; j < opts->journals; j++) { - int result; - lgfs2_rgrp_t rg; - struct gfs2_inode in = {0}; - - gfs2_progress_update(&progress, (j + 1)); - - if (opts->debug) - printf(_("Placing resource group for journal%u\n"), j); - - result = add_rgrp(rgs, rgaddr, rgsize, &rg); - if (result > 0) - break; - else if (result < 0) - return result; - - result = lgfs2_rgrp_bitbuf_alloc(rg); - if (result != 0) { - perror(_("Failed to allocate space for bitmap buffer")); - return result; - } - /* Allocate at the beginning of the rgrp, bypassing extent search */ - in.i_di.di_num.no_addr = lgfs2_rgrp_index(rg)->ri_data0; - /* In order to keep writes sequential here, we have to allocate - the journal, then write the rgrp header (which is now in its - final form) and then write the journal out */ - result = lgfs2_file_alloc(rg, opts->jsize << 20, &in, GFS2_DIF_SYSTEM, S_IFREG | 0600); - if (result != 0) { - fprintf(stderr, _("Failed to allocate space for journal %u\n"), j); - return result; - } - - if (opts->debug) - gfs2_dinode_print(&in.i_di); - - result = place_rgrp(sdp, rg, opts->debug); - if (result != 0) - return result; - - lgfs2_rgrp_bitbuf_free(rg); - - result = lgfs2_write_filemeta(&in); - if (result != 0) { - fprintf(stderr, _("Failed to write journal %u\n"), j); - return result; - } - - result = lgfs2_write_journal_data(&in); - if (result != 0) { - fprintf(stderr, _("Failed to write data blocks for journal %u\n"), j); - return result; - } - mkfs_journals[j] = in.i_di.di_num; - } - gfs2_progress_close(&progress, _("Done\n")); - - return 0; -} - -static int place_rgrps(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs, uint64_t *rgaddr, struct mkfs_opts *opts) -{ - struct gfs2_progress_bar progress; - uint32_t rgblks = ((opts->rgsize << 20) / sdp->bsize); - uint32_t rgnum; - int result; - - rgnum = lgfs2_rgrps_plan(rgs, sdp->device.length - *rgaddr, rgblks); - gfs2_progress_init(&progress, (rgnum + opts->journals), _("Building resource groups: "), opts->quiet); - - while (1) { - lgfs2_rgrp_t rg; - result = add_rgrp(rgs, rgaddr, 0, &rg); - if (result > 0) - break; - else if (result < 0) - return result; - - result = place_rgrp(sdp, rg, opts->debug); - if (result != 0) { - fprintf(stderr, _("Failed to build resource groups\n")); - return result; - } - - gfs2_progress_update(&progress, (sdp->rgrps)); - } - gfs2_progress_close(&progress, _("Done\n")); - posix_fadvise(sdp->device_fd, 0, sdp->fssize * sdp->bsize, POSIX_FADV_DONTNEED); - - return 0; -} - -/* - * Find a reasonable journal file size (in blocks) given the number of blocks - * in the filesystem. For very small filesystems, it is not reasonable to - * have a journal that fills more than half of the filesystem. - * - * n.b. comments assume 4k blocks - * - * This was copied and adapted from e2fsprogs. - */ -static int default_journal_size(unsigned bsize, uint64_t num_blocks) -{ - int min_blocks = (GFS2_MIN_JSIZE << 20) / bsize; - - if (num_blocks < 2 * min_blocks) - return -1; - if (num_blocks < 131072) /* 512 MB */ - return min_blocks; /* 8 MB */ - if (num_blocks < 512*1024) /* 2 GB */ - return (4096); /* 16 MB */ - if (num_blocks < 2048*1024) /* 8 GB */ - return (8192); /* 32 MB */ - if (num_blocks < 4096*1024) /* 16 GB */ - return (16384); /* 64 MB */ - if (num_blocks < 262144*1024) /* 1 TB */ - return (32768); /* 128 MB */ - if (num_blocks < 2621440UL*1024) /* 10 TB */ - return (131072); /* 512 MB */ - return 262144; /* 1 GB */ -} - -static void sbd_init(struct gfs2_sbd *sdp, struct mkfs_opts *opts, unsigned bsize) -{ - memset(sdp, 0, sizeof(struct gfs2_sbd)); - sdp->time = time(NULL); - sdp->rgtree.osi_node = NULL; - sdp->rgsize = opts->rgsize; - sdp->qcsize = opts->qcsize; - sdp->jsize = opts->jsize; - sdp->md.journals = opts->journals; - sdp->device_fd = opts->dev.fd; - sdp->bsize = sdp->sd_sb.sb_bsize = bsize; - - if (compute_constants(sdp)) { - perror(_("Failed to compute file system constants")); - exit(1); - } - sdp->device.length = opts->dev.size / sdp->bsize; - if (opts->got_fssize) { - if (opts->fssize > sdp->device.length) { - fprintf(stderr, _("Specified size is bigger than the device.")); - die("%s %.2f %s (%"PRIu64" %s)\n", _("Device size:"), - opts->dev.size / ((float)(1 << 30)), _("GB"), - opts->dev.size / sdp->bsize, _("blocks")); - } - sdp->device.length = opts->fssize; - } - /* opts->jsize has already been max/min checked but we need to check it - makes sense for the device size, or set a sensible default, if one - will fit. For user-provided journal sizes, limit it to half of the fs. */ - if (!opts->got_jsize) { - int default_jsize = default_journal_size(sdp->bsize, sdp->device.length / opts->journals); - if (default_jsize < 0) { - fprintf(stderr, _("gfs2 will not fit on this device.\n")); - exit(1); - } - opts->jsize = (default_jsize * sdp->bsize) >> 20; - } else if ((((opts->jsize * opts->journals) << 20) / sdp->bsize) > (sdp->device.length / 2)) { - unsigned max_jsize = (sdp->device.length / 2 * sdp->bsize / opts->journals) >> 20; - - fprintf(stderr, _("gfs2 will not fit on this device.\n")); - if (max_jsize >= GFS2_MIN_JSIZE) - fprintf(stderr, _("Maximum size for %u journals on this device is %uMB.\n"), - opts->journals, max_jsize); - exit(1); - } - sdp->jsize = opts->jsize; -} - -static int probe_contents(struct mkfs_dev *dev) -{ - int ret; - const char *contents; - blkid_probe pr = blkid_new_probe(); - if (pr == NULL || blkid_probe_set_device(pr, dev->fd, 0, 0) != 0 - || blkid_probe_enable_superblocks(pr, TRUE) != 0 - || blkid_probe_enable_partitions(pr, TRUE) != 0) { - fprintf(stderr, _("Failed to create probe\n")); - return -1; - } - - if (!S_ISREG(dev->stat.st_mode) && blkid_probe_enable_topology(pr, TRUE) != 0) { - fprintf(stderr, _("Failed to create probe\n")); - return -1; - } - - ret = blkid_do_fullprobe(pr); - if (ret == -1) { - fprintf(stderr, _("Failed to probe device\n")); - return -1; - } - - if (ret == 1) - return 0; - - if (!blkid_probe_lookup_value(pr, "TYPE", &contents, NULL)) { - printf(_("It appears to contain an existing filesystem (%s)\n"), contents); - } else if (!blkid_probe_lookup_value(pr, "PTTYPE", &contents, NULL)) { - printf(_("It appears to contain a partition table (%s).\n"), contents); - } - - if (!S_ISREG(dev->stat.st_mode)) { - blkid_topology tp = blkid_probe_get_topology(pr); - if (tp != NULL) { - dev->alignment_offset = blkid_topology_get_alignment_offset(tp); - dev->logical_sector_size = blkid_topology_get_logical_sector_size(tp); - dev->minimum_io_size = blkid_topology_get_minimum_io_size(tp); - dev->optimal_io_size = blkid_topology_get_optimal_io_size(tp); - dev->physical_sector_size = blkid_topology_get_physical_sector_size(tp); - dev->got_topol = (dev->logical_sector_size != 0 && - dev->physical_sector_size != 0); - } - } - - blkid_free_probe(pr); - return 0; -} - -static void open_dev(struct mkfs_dev *dev, int withprobe) -{ - int error; - - dev->fd = open(dev->path, O_RDWR|O_CLOEXEC|O_EXCL); - if (dev->fd < 0) { - perror(dev->path); - exit(1); - } - - /* Freshen up the cache */ - posix_fadvise(dev->fd, 0, 0, POSIX_FADV_DONTNEED); - /* Turn off readahead, we're just writing new blocks */ - posix_fadvise(dev->fd, 0, 0, POSIX_FADV_RANDOM); - - error = fstat(dev->fd, &dev->stat); - if (error < 0) { - perror(dev->path); - exit(1); - } - - if (S_ISREG(dev->stat.st_mode)) { - dev->size = dev->stat.st_size; - } else if (S_ISBLK(dev->stat.st_mode)) { - dev->size = lseek(dev->fd, 0, SEEK_END); - if (dev->size < 1) { - fprintf(stderr, _("Device '%s' is too small\n"), dev->path); - exit(1); - } - } else { - fprintf(stderr, _("'%s' is not a block device or regular file\n"), dev->path); - exit(1); - } - if (withprobe && (probe_contents(dev) != 0)) - exit(1); -} - -int main(int argc, char *argv[]) -{ - struct gfs2_sbd sbd; - struct gfs2_sb sb; - struct mkfs_opts opts; - lgfs2_rgrps_t rgs; - uint64_t rgaddr; - int error; - unsigned bsize; - - setlocale(LC_ALL, ""); - textdomain("gfs2-utils"); - srandom(time(NULL) ^ getpid()); - - opts_init(&opts); - opts_get(argc, argv, &opts); - opts_check(&opts); - - open_dev(&opts.dev, !opts.got_topol); - bsize = choose_blocksize(&opts); - - if (S_ISREG(opts.dev.stat.st_mode)) { - opts.got_bsize = 1; /* Use default block size for regular files */ - } - - sbd_init(&sbd, &opts, bsize); - lgfs2_sb_init(&sb, bsize); - if (opts.debug) { - printf(_("File system options:\n")); - printf(" bsize = %u\n", sbd.bsize); - printf(" qcsize = %u\n", sbd.qcsize); - printf(" jsize = %u\n", sbd.jsize); - printf(" journals = %u\n", sbd.md.journals); - printf(" proto = %s\n", opts.lockproto); - printf(" table = %s\n", opts.locktable); - printf(" rgsize = %u\n", sbd.rgsize); - printf(" fssize = %"PRIu64"\n", opts.fssize); - printf(" sunit = %lu\n", opts.sunit); - printf(" swidth = %lu\n", opts.swidth); - } - rgs = rgs_init(&opts, &sbd); - warn_of_destruction(opts.dev.path); - - if (opts.confirm && !opts.override) - are_you_sure(); - - if (!S_ISREG(opts.dev.stat.st_mode) && opts.discard) { - if (!opts.quiet) { - printf("%s", _("Discarding device contents (may take a while on large devices): ")); - fflush(stdout); - } - discard_blocks(opts.dev.fd, opts.dev.size, opts.debug); - - if (!opts.quiet) - printf("%s", _("Done\n")); - } - rgaddr = lgfs2_rgrp_align_addr(rgs, LGFS2_SB_ADDR(&sbd) + 1); - error = place_journals(&sbd, rgs, &opts, &rgaddr); - if (error != 0) { - fprintf(stderr, _("Failed to create journals\n")); - exit(1); - } - error = place_rgrps(&sbd, rgs, &rgaddr, &opts); - if (error) { - fprintf(stderr, _("Failed to build resource groups\n")); - exit(1); - } - sbd.rgtree.osi_node = lgfs2_rgrps_root(rgs); // Temporary - - error = build_master(&sbd); - if (error) { - fprintf(stderr, _("Error building '%s': %s\n"), "master", strerror(errno)); - exit(EXIT_FAILURE); - } - sb.sb_master_dir = sbd.master_dir->i_di.di_num; - - error = lgfs2_build_jindex(sbd.master_dir, mkfs_journals, opts.journals); - if (error) { - fprintf(stderr, _("Error building '%s': %s\n"), "jindex", strerror(errno)); - exit(EXIT_FAILURE); - } - free(mkfs_journals); - error = build_per_node(&sbd); - if (error) { - fprintf(stderr, _("Error building '%s': %s\n"), "per_node", strerror(errno)); - exit(EXIT_FAILURE); - } - error = build_inum(&sbd); - if (error) { - fprintf(stderr, _("Error building '%s': %s\n"), "inum", strerror(errno)); - exit(EXIT_FAILURE); - } - gfs2_lookupi(sbd.master_dir, "inum", 4, &sbd.md.inum); - error = build_statfs(&sbd); - if (error) { - fprintf(stderr, _("Error building '%s': %s\n"), "statfs", strerror(errno)); - exit(EXIT_FAILURE); - } - gfs2_lookupi(sbd.master_dir, "statfs", 6, &sbd.md.statfs); - error = build_rindex(&sbd); - if (error) { - fprintf(stderr, _("Error building '%s': %s\n"), "rindex", strerror(errno)); - exit(EXIT_FAILURE); - } - if (!opts.quiet) { - printf("%s", _("Creating quota file: ")); - fflush(stdout); - } - error = build_quota(&sbd); - if (error) { - fprintf(stderr, _("Error building '%s': %s\n"), "quota", strerror(errno)); - exit(EXIT_FAILURE); - } - if (!opts.quiet) - printf("%s", _("Done\n")); - - build_root(&sbd); - sb.sb_root_dir = sbd.md.rooti->i_di.di_num; - - strncpy(sb.sb_lockproto, opts.lockproto, GFS2_LOCKNAME_LEN); - strncpy(sb.sb_locktable, opts.locktable, GFS2_LOCKNAME_LEN); - sb.sb_lockproto[GFS2_LOCKNAME_LEN - 1] = '\0'; - sb.sb_locktable[GFS2_LOCKNAME_LEN - 1] = '\0'; - - do_init_inum(&sbd); - do_init_statfs(&sbd); - - inode_put(&sbd.md.rooti); - inode_put(&sbd.master_dir); - inode_put(&sbd.md.inum); - inode_put(&sbd.md.statfs); - - lgfs2_rgrps_free(&rgs); - - if (!opts.quiet) { - printf("%s", _("Writing superblock and syncing: ")); - fflush(stdout); - } - - error = lgfs2_sb_write(&sb, opts.dev.fd, sbd.bsize); - if (error) { - perror(_("Failed to write superblock\n")); - exit(EXIT_FAILURE); - } - - error = fsync(opts.dev.fd); - if (error){ - perror(opts.dev.path); - exit(EXIT_FAILURE); - } - posix_fadvise(opts.dev.fd, 0, 0, POSIX_FADV_DONTNEED); - error = close(opts.dev.fd); - if (error){ - perror(opts.dev.path); - exit(EXIT_FAILURE); - } - - if (!opts.quiet) { - printf("%s", _("Done\n")); - print_results(&sb, &opts, sbd.rgrps, sbd.fssize); - } - return 0; -} diff --git a/tests/fsck.at b/tests/fsck.at index 97a00a9..39a04d0 100644 --- a/tests/fsck.at +++ b/tests/fsck.at @@ -54,16 +54,3 @@ AT_CHECK([gfs2_edit -p journal0 field di_header.mh_magic 0 $GFS_TGT], 0, [ignore AT_CHECK([fsck.gfs2 -y $GFS_TGT], 1, [ignore], [ignore]) AT_CHECK([fsck.gfs2 -n $GFS_TGT], 0, [ignore], [ignore]) AT_CLEANUP - -AT_SETUP([gfs2 format versions]) -AT_KEYWORDS(fsck.gfs2 fsck) -GFS_TGT_REGEN -AT_CHECK([mkfs.gfs2 -O -p lock_nolock ${GFS_TGT}], 0, [ignore], [ignore]) -AT_CHECK([echo "set sb { sb_fs_format: 1802 }" | gfs2l ${GFS_TGT}], 0, [ignore], [ignore]) -# Unsupported format, FSCK_USAGE == 16 -AT_CHECK([fsck.gfs2 -y $GFS_TGT], 16, [ignore], [ignore]) -# Format out of range -AT_CHECK([echo "set sb { sb_fs_format: 4242 }" | gfs2l ${GFS_TGT}], 0, [ignore], [ignore]) -AT_CHECK([fsck.gfs2 -y $GFS_TGT], 1, [ignore], [ignore]) -AT_CHECK([fsck.gfs2 -n $GFS_TGT], 0, [ignore], [ignore]) -AT_CLEANUP diff --git a/tests/fsck.at.bz1622050-1-fsck_gfs2_Don_t_check_fs_formats_we_don_t_recognise b/tests/fsck.at.bz1622050-1-fsck_gfs2_Don_t_check_fs_formats_we_don_t_recognise deleted file mode 100644 index 39a04d0..0000000 --- a/tests/fsck.at.bz1622050-1-fsck_gfs2_Don_t_check_fs_formats_we_don_t_recognise +++ /dev/null @@ -1,56 +0,0 @@ -AT_TESTED([fsck.gfs2]) -AT_BANNER([fsck.gfs2 tests]) - -AT_SETUP([Conflicting options]) -AT_KEYWORDS(fsck.gfs2 fsck) -# Error code 16 is FSCK_USAGE -AT_CHECK([fsck.gfs2 -y -n $GFS_TGT], 16, [ignore], [ignore]) -AT_CHECK([fsck.gfs2 -n -y $GFS_TGT], 16, [ignore], [ignore]) -AT_CHECK([fsck.gfs2 -n -p $GFS_TGT], 16, [ignore], [ignore]) -AT_CHECK([fsck.gfs2 -p -n $GFS_TGT], 16, [ignore], [ignore]) -AT_CHECK([fsck.gfs2 -y -p $GFS_TGT], 16, [ignore], [ignore]) -AT_CHECK([fsck.gfs2 -p -y $GFS_TGT], 16, [ignore], [ignore]) -AT_CLEANUP - -AT_SETUP([Fix invalid block sizes]) -AT_KEYWORDS(fsck.gfs2 fsck) -GFS_LANG_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], [set sb { sb_bsize: 0 }]) -GFS_LANG_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], [set sb { sb_bsize: 1 }]) -GFS_LANG_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], [set sb { sb_bsize: 513 }]) -GFS_LANG_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], [set sb { sb_bsize: 4095 }]) -GFS_LANG_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], [set sb { sb_bsize: 4097 }]) -AT_CLEANUP - -AT_SETUP([Fix invalid goal blocks]) -AT_KEYWORDS(fsck.gfs2 fsck) -GFS_LANG_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], [set '/' { di_goal_meta: 0 }]) -AT_CLEANUP - -AT_SETUP([Fix bad resource group #0]) -AT_KEYWORDS(fsck.gfs2 fsck) -GFS_NUKERG_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], [-r 0]) -AT_CLEANUP - -AT_SETUP([Fix bad resource group #1]) -AT_KEYWORDS(fsck.gfs2 fsck) -GFS_NUKERG_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], [-r 1]) -AT_CLEANUP - -#AT_SETUP([Fix bad rindex entry #0]) -#AT_KEYWORDS(fsck.gfs2 fsck) -#GFS_NUKERG_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], [-i 0]) -#AT_CLEANUP - -AT_SETUP([Fix bad rindex entry #1]) -AT_KEYWORDS(fsck.gfs2 fsck) -GFS_NUKERG_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], [-i 1]) -AT_CLEANUP - -AT_SETUP([Rebuild bad journal]) -AT_KEYWORDS(fsck.gfs2 fsck) -GFS_TGT_REGEN -AT_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([gfs2_edit -p journal0 field di_header.mh_magic 0 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([fsck.gfs2 -y $GFS_TGT], 1, [ignore], [ignore]) -AT_CHECK([fsck.gfs2 -n $GFS_TGT], 0, [ignore], [ignore]) -AT_CLEANUP diff --git a/tests/mkfs.at b/tests/mkfs.at index 4220567..ee444f5 100644 --- a/tests/mkfs.at +++ b/tests/mkfs.at @@ -112,8 +112,6 @@ AT_CLEANUP AT_SETUP([Device i/o limits handling]) AT_KEYWORDS(mkfs.gfs2 mkfs) AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=0:0:0:0:0 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=0:512:512:512:512 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([gfs2_edit -p sb field sb_bsize $GFS_TGT | tr -d '\n' ], 0, [4096], [ignore]) AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=7168:512:0:33553920:512 $GFS_TGT], 0, [ignore], [ignore]) AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=7168:512:8192:33553920:512 $GFS_TGT], 0, [ignore], [Warning: device is not properly aligned. This may harm performance. ]) @@ -124,8 +122,6 @@ AT_KEYWORDS(mkfs.gfs2 mkfs) AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=0:512:65536:393216:512 $GFS_TGT], 0, [ignore], [ignore]) # Check rgrp alignment to minimum_io_size: 65536 / 4096 == 16 AT_CHECK([gfs2_edit -p rindex $GFS_TGT | grep ri_addr | awk '{print $2, $2 % 16; if ($2 % 16 != 0) { exit 1 }}'], 0, [ignore], [ignore]) -# rhbz#1698858 -AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=0:512:131072:6291456:512 $GFS_TGT], 0, [ignore], [ignore]) AT_CLEANUP AT_SETUP([Values of rg_skip]) diff --git a/tests/mkfs.at.bz1698858-mkfs_gfs2_Improve_alignment_of_first_resource_group b/tests/mkfs.at.bz1698858-mkfs_gfs2_Improve_alignment_of_first_resource_group deleted file mode 100644 index ee444f5..0000000 --- a/tests/mkfs.at.bz1698858-mkfs_gfs2_Improve_alignment_of_first_resource_group +++ /dev/null @@ -1,167 +0,0 @@ -AT_TESTED([mkfs.gfs2]) -AT_BANNER([mkfs.gfs2 tests]) - -AT_SETUP([Locking protocol validation]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -AT_CHECK([$GFS_MKFS -p badprotocol $GFS_TGT], 255, [ignore], [ignore]) -AT_CLEANUP - -AT_SETUP([Resource group size validation]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -AT_CHECK([$GFS_MKFS -p lock_nolock -r 31 $GFS_TGT], 255, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -r 2049 $GFS_TGT], 255, [ignore], [ignore]) -AT_CLEANUP - -AT_SETUP([Journal size validation]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -AT_CHECK([$GFS_MKFS -p lock_nolock -J 7 $GFS_TGT], 255, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -J 1025 $GFS_TGT], 255, [ignore], [ignore]) -AT_CLEANUP - -AT_SETUP([Block count validation]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -GFS_TGT_REGEN -AT_CHECK([$GFS_MKFS -p lock_nolock -b 512 $GFS_TGT $(($(gfs_max_blocks 512)+1))], 255, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -b 4096 $GFS_TGT $(($(gfs_max_blocks 4096)+1))], 255, [ignore], [ignore]) -AT_CLEANUP - -AT_SETUP([Quota change file size validation]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -AT_CHECK([$GFS_MKFS -p lock_nolock -c 0 $GFS_TGT], 255, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -c 65 $GFS_TGT], 255, [ignore], [ignore]) -AT_CLEANUP - -AT_SETUP([Locking protocols]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock $GFS_TGT]) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_dlm -t foo:bar $GFS_TGT]) -AT_CLEANUP - -AT_SETUP([Valid block sizes 512-4096]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -b 512 $GFS_TGT]) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -b 1024 $GFS_TGT]) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -b 2048 $GFS_TGT]) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -b 4096 $GFS_TGT]) -AT_CLEANUP - -AT_SETUP([Max. blocks, min. block size]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -b 512 $GFS_TGT $(gfs_max_blocks 512)]) -AT_CLEANUP - -AT_SETUP([Max. blocks, max. block size]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -b 4096 $GFS_TGT $(gfs_max_blocks 4096)]) -AT_CLEANUP - -AT_SETUP([Max. resource group size]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -r 2048 $GFS_TGT]) -AT_CLEANUP - -AT_SETUP([Min. resource group size]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -r 32 $GFS_TGT]) -AT_CLEANUP - -AT_SETUP([Max. resource group size, min. block size]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -r 2048 -b 512 $GFS_TGT]) -AT_CLEANUP - -AT_SETUP([Max. journal size]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -J 1024 $GFS_TGT]) -AT_CLEANUP - -AT_SETUP([Min. journal size]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -J 8 $GFS_TGT]) -AT_CLEANUP - -AT_SETUP([Max. quota change file size]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -c 64 $GFS_TGT]) -AT_CLEANUP - -AT_SETUP([Min. quota change file size]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -c 1 $GFS_TGT]) -AT_CLEANUP - -AT_SETUP([Lock table validation]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -AT_CHECK([$GFS_MKFS -p lock_nolock -t "" $GFS_TGT], 255, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -t "123456789012345678901234567890123:12345678" $GFS_TGT], 255, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -t "12345678901234567:1234567890123456789012345678901" $GFS_TGT], 255, [ignore], [ignore]) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -t "12345678901234567890123456789012:123456789012345678901234567890" $GFS_TGT]) -AT_CHECK([$GFS_MKFS -p lock_dlm -t "" $GFS_TGT], 255, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_dlm -t "quite_long_cluster_name_test_here:intec34p" $GFS_TGT], 255, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_dlm -t "financial_cluster:this_time_we_test_fs_naming_len" $GFS_TGT], 255, [ignore], [ignore]) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_dlm -t "a_really_long_named_cluster_here:concurrently_lets_check_fs_len" $GFS_TGT]) -AT_CLEANUP - -# -o test_topology order: -# alignment_offset, -# logical_sector_size, -# minimum_io_size, -# optimal_io_size, -# physical_sector_size - -AT_SETUP([Device i/o limits handling]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=0:0:0:0:0 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=7168:512:0:33553920:512 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=7168:512:8192:33553920:512 $GFS_TGT], 0, [ignore], [Warning: device is not properly aligned. This may harm performance. -]) -AT_CLEANUP - -AT_SETUP([Resource group alignment]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=0:512:65536:393216:512 $GFS_TGT], 0, [ignore], [ignore]) -# Check rgrp alignment to minimum_io_size: 65536 / 4096 == 16 -AT_CHECK([gfs2_edit -p rindex $GFS_TGT | grep ri_addr | awk '{print $2, $2 % 16; if ($2 % 16 != 0) { exit 1 }}'], 0, [ignore], [ignore]) -AT_CLEANUP - -AT_SETUP([Values of rg_skip]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -AT_CHECK([$GFS_MKFS -p lock_nolock -r 2048 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([rgskipcheck.sh $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -r 1024 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([rgskipcheck.sh $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -r 512 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([rgskipcheck.sh $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -r 219 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([rgskipcheck.sh $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -r 32 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([rgskipcheck.sh $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=0:512:65536:393216:512 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([rgskipcheck.sh $GFS_TGT], 0, [ignore], [ignore]) -AT_CLEANUP - -AT_SETUP([Values of rg_data0, rg_data, rg_bitbytes]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -AT_CHECK([$GFS_MKFS -p lock_nolock -r 2048 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([rgrifieldscheck.sh $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -r 1024 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([rgrifieldscheck.sh $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -r 512 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([rgrifieldscheck.sh $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -r 219 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([rgrifieldscheck.sh $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -r 32 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([rgrifieldscheck.sh $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=0:512:65536:393216:512 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([rgrifieldscheck.sh $GFS_TGT], 0, [ignore], [ignore]) -AT_CLEANUP - -AT_SETUP([Small filesystems]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -GFS_TGT_SIZE(32M) -AT_CHECK([$GFS_MKFS -p lock_nolock $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([fsck.gfs2 -n $GFS_TGT], 0, [ignore], [ignore]) -GFS_TGT_SIZE(64M) -AT_CHECK([$GFS_MKFS -p lock_nolock -j2 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([fsck.gfs2 -n $GFS_TGT], 0, [ignore], [ignore]) -AT_CLEANUP diff --git a/tests/mkfs.at.bz1839219-mkfs_gfs2_Don_t_use_i_o_limits_hints_4K_for_block_size b/tests/mkfs.at.bz1839219-mkfs_gfs2_Don_t_use_i_o_limits_hints_4K_for_block_size deleted file mode 100644 index 3e3fb82..0000000 --- a/tests/mkfs.at.bz1839219-mkfs_gfs2_Don_t_use_i_o_limits_hints_4K_for_block_size +++ /dev/null @@ -1,169 +0,0 @@ -AT_TESTED([mkfs.gfs2]) -AT_BANNER([mkfs.gfs2 tests]) - -AT_SETUP([Locking protocol validation]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -AT_CHECK([$GFS_MKFS -p badprotocol $GFS_TGT], 255, [ignore], [ignore]) -AT_CLEANUP - -AT_SETUP([Resource group size validation]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -AT_CHECK([$GFS_MKFS -p lock_nolock -r 31 $GFS_TGT], 255, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -r 2049 $GFS_TGT], 255, [ignore], [ignore]) -AT_CLEANUP - -AT_SETUP([Journal size validation]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -AT_CHECK([$GFS_MKFS -p lock_nolock -J 7 $GFS_TGT], 255, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -J 1025 $GFS_TGT], 255, [ignore], [ignore]) -AT_CLEANUP - -AT_SETUP([Block count validation]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -GFS_TGT_REGEN -AT_CHECK([$GFS_MKFS -p lock_nolock -b 512 $GFS_TGT $(($(gfs_max_blocks 512)+1))], 255, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -b 4096 $GFS_TGT $(($(gfs_max_blocks 4096)+1))], 255, [ignore], [ignore]) -AT_CLEANUP - -AT_SETUP([Quota change file size validation]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -AT_CHECK([$GFS_MKFS -p lock_nolock -c 0 $GFS_TGT], 255, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -c 65 $GFS_TGT], 255, [ignore], [ignore]) -AT_CLEANUP - -AT_SETUP([Locking protocols]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock $GFS_TGT]) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_dlm -t foo:bar $GFS_TGT]) -AT_CLEANUP - -AT_SETUP([Valid block sizes 512-4096]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -b 512 $GFS_TGT]) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -b 1024 $GFS_TGT]) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -b 2048 $GFS_TGT]) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -b 4096 $GFS_TGT]) -AT_CLEANUP - -AT_SETUP([Max. blocks, min. block size]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -b 512 $GFS_TGT $(gfs_max_blocks 512)]) -AT_CLEANUP - -AT_SETUP([Max. blocks, max. block size]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -b 4096 $GFS_TGT $(gfs_max_blocks 4096)]) -AT_CLEANUP - -AT_SETUP([Max. resource group size]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -r 2048 $GFS_TGT]) -AT_CLEANUP - -AT_SETUP([Min. resource group size]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -r 32 $GFS_TGT]) -AT_CLEANUP - -AT_SETUP([Max. resource group size, min. block size]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -r 2048 -b 512 $GFS_TGT]) -AT_CLEANUP - -AT_SETUP([Max. journal size]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -J 1024 $GFS_TGT]) -AT_CLEANUP - -AT_SETUP([Min. journal size]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -J 8 $GFS_TGT]) -AT_CLEANUP - -AT_SETUP([Max. quota change file size]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -c 64 $GFS_TGT]) -AT_CLEANUP - -AT_SETUP([Min. quota change file size]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -c 1 $GFS_TGT]) -AT_CLEANUP - -AT_SETUP([Lock table validation]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -AT_CHECK([$GFS_MKFS -p lock_nolock -t "" $GFS_TGT], 255, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -t "123456789012345678901234567890123:12345678" $GFS_TGT], 255, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -t "12345678901234567:1234567890123456789012345678901" $GFS_TGT], 255, [ignore], [ignore]) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -t "12345678901234567890123456789012:123456789012345678901234567890" $GFS_TGT]) -AT_CHECK([$GFS_MKFS -p lock_dlm -t "" $GFS_TGT], 255, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_dlm -t "quite_long_cluster_name_test_here:intec34p" $GFS_TGT], 255, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_dlm -t "financial_cluster:this_time_we_test_fs_naming_len" $GFS_TGT], 255, [ignore], [ignore]) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_dlm -t "a_really_long_named_cluster_here:concurrently_lets_check_fs_len" $GFS_TGT]) -AT_CLEANUP - -# -o test_topology order: -# alignment_offset, -# logical_sector_size, -# minimum_io_size, -# optimal_io_size, -# physical_sector_size - -AT_SETUP([Device i/o limits handling]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=0:0:0:0:0 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=7168:512:0:33553920:512 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=7168:512:8192:33553920:512 $GFS_TGT], 0, [ignore], [Warning: device is not properly aligned. This may harm performance. -]) -AT_CLEANUP - -AT_SETUP([Resource group alignment]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=0:512:65536:393216:512 $GFS_TGT], 0, [ignore], [ignore]) -# Check rgrp alignment to minimum_io_size: 65536 / 4096 == 16 -AT_CHECK([gfs2_edit -p rindex $GFS_TGT | grep ri_addr | awk '{print $2, $2 % 16; if ($2 % 16 != 0) { exit 1 }}'], 0, [ignore], [ignore]) -# rhbz#1698858 -AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=0:512:131072:6291456:512 $GFS_TGT], 0, [ignore], [ignore]) -AT_CLEANUP - -AT_SETUP([Values of rg_skip]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -AT_CHECK([$GFS_MKFS -p lock_nolock -r 2048 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([rgskipcheck.sh $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -r 1024 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([rgskipcheck.sh $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -r 512 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([rgskipcheck.sh $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -r 219 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([rgskipcheck.sh $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -r 32 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([rgskipcheck.sh $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=0:512:65536:393216:512 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([rgskipcheck.sh $GFS_TGT], 0, [ignore], [ignore]) -AT_CLEANUP - -AT_SETUP([Values of rg_data0, rg_data, rg_bitbytes]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -AT_CHECK([$GFS_MKFS -p lock_nolock -r 2048 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([rgrifieldscheck.sh $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -r 1024 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([rgrifieldscheck.sh $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -r 512 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([rgrifieldscheck.sh $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -r 219 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([rgrifieldscheck.sh $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -r 32 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([rgrifieldscheck.sh $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=0:512:65536:393216:512 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([rgrifieldscheck.sh $GFS_TGT], 0, [ignore], [ignore]) -AT_CLEANUP - -AT_SETUP([Small filesystems]) -AT_KEYWORDS(mkfs.gfs2 mkfs) -GFS_TGT_SIZE(32M) -AT_CHECK([$GFS_MKFS -p lock_nolock $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([fsck.gfs2 -n $GFS_TGT], 0, [ignore], [ignore]) -GFS_TGT_SIZE(64M) -AT_CHECK([$GFS_MKFS -p lock_nolock -j2 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([fsck.gfs2 -n $GFS_TGT], 0, [ignore], [ignore]) -AT_CLEANUP