Logo Search packages:      
Sourcecode: redhat-cluster-suite version File versions  Download package

structures.c

/******************************************************************************
*******************************************************************************
**
**  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
**  Copyright (C) 2004 Red Hat, Inc.  All rights reserved.
**
**  This copyrighted material is made available to anyone wishing to use,
**  modify, copy, or redistribute it subject to the terms and conditions
**  of the GNU General Public License v.2.
**
*******************************************************************************
******************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <assert.h>
#include <time.h>

#include "global.h"
#include <linux/gfs_ondisk.h>
#include "osi_list.h"
#include "linux_endian.h"

#include "mkfs_gfs.h"


#define MKFS_ROOT_MODE              (0755)
#define MKFS_HIDDEN_MODE            (0600)


#define do_lseek(fd, off) \
{ \
  if (lseek((fd), (off), SEEK_SET) != (off)) \
    die("bad seek: %s on line %d of file %s\n", \
      strerror(errno),__LINE__, __FILE__); \
}

#define do_read(fd, buff, len) \
{ \
  if (read((fd), (buff), (len)) != (len)) \
    die("bad read: %s on line %d of file %s\n", \
      strerror(errno), __LINE__, __FILE__); \
}

#define do_write(fd, buff, len) \
{ \
  if (write((fd), (buff), (len)) != (len)) \
    die("bad write: %s on line %d of file %s\n", \
      strerror(errno), __LINE__, __FILE__); \
}





/**
 * rgrplength2bitblocks - blerg
 * @comline: the command line
 * @length: the number of blocks in a RG
 *
 * Give a number of blocks in a RG, figure out the number of blocks
 * needed for bitmaps.
 *
 * Returns: the number of bitmap blocks
 */

uint32 rgrplength2bitblocks(commandline_t *comline, uint32 length)
{
  uint32 bitbytes;
  uint32 old_blocks = 0, blocks;
  int tries = 0;

  for (;;)
  {
    bitbytes = (length - old_blocks) / GFS_NBBY;
    blocks = 1;

    if (bitbytes > comline->bsize - sizeof(struct gfs_rgrp))
    {
      bitbytes -= comline->bsize - sizeof(struct gfs_rgrp);
      blocks += DIV_RU(bitbytes, (comline->bsize - sizeof(struct gfs_meta_header)));
    }

    if (blocks == old_blocks)
      break;

    old_blocks = blocks;

    if (tries++ > 10)
      die("confused computing bitblock length\n");
  }

  return blocks;
}


/**
 * write_sb - write the superblock
 * @comline: the command line
 * @rlist: the list of RGs
 *
 */

void write_sb(commandline_t *comline, osi_list_t *rlist)
{
  struct gfs_sb *sb;
  rgrp_list_t *rl;
  uint64 jindex_dinode;
  char buf[comline->bsize];
  int x;


  memset(buf, 0, comline->bsize);

  for (x = 0; x < comline->sb_addr; x++)
  {
    do_lseek(comline->fd, x * comline->bsize);
    do_write(comline->fd, buf, comline->bsize);
  }


  /*  Figure out the location of the journal index inode  */

  rl = osi_list_entry(rlist->next, rgrp_list_t, list);

  jindex_dinode = rl->rg_offset + rgrplength2bitblocks(comline, rl->rg_length);


  /*  Now, fill in the superblock  */

  type_zalloc(sb, struct gfs_sb, 1);
  comline->sb = sb;


  sb->sb_header.mh_magic = GFS_MAGIC;
  sb->sb_header.mh_type = GFS_METATYPE_SB;
  sb->sb_header.mh_format = GFS_FORMAT_SB;

  sb->sb_fs_format = GFS_FORMAT_FS;
  sb->sb_multihost_format = GFS_FORMAT_MULTI;

  sb->sb_bsize = comline->bsize;
  sb->sb_bsize_shift = ffs(comline->bsize) - 1;
  sb->sb_seg_size = comline->seg_size;

  sb->sb_jindex_di.no_formal_ino = jindex_dinode;
  sb->sb_jindex_di.no_addr = jindex_dinode;
  sb->sb_rindex_di.no_formal_ino = jindex_dinode + 1;
  sb->sb_rindex_di.no_addr = jindex_dinode + 1;
  sb->sb_root_di.no_formal_ino = jindex_dinode + 4;
  sb->sb_root_di.no_addr = jindex_dinode + 4;

  strcpy(sb->sb_lockproto, comline->lockproto);
  strcpy(sb->sb_locktable, comline->locktable);

  sb->sb_quota_di.no_formal_ino = jindex_dinode + 2;
  sb->sb_quota_di.no_addr = jindex_dinode + 2;
  sb->sb_license_di.no_formal_ino = jindex_dinode + 3;
  sb->sb_license_di.no_addr = jindex_dinode + 3;


  gfs_sb_out(sb, buf);


  do_lseek(comline->fd, comline->sb_addr * comline->bsize);
  do_write(comline->fd, buf, comline->bsize);


  if (comline->debug)
  {
    printf("\nSuperblock:\n");
    gfs_sb_print(sb);
  }
}


/**
 * compute_height - give a file length and block size compute the file's height
 * @sz: the file size
 * @bsize: the blocksize
 *
 * Returns: the file height
 */

static unsigned int compute_height(uint64 sz, unsigned int bsize)
{
  uint32 diptrs = (bsize - sizeof(struct gfs_dinode)) / sizeof(uint64);
  uint32 inptrs = (bsize - sizeof(struct gfs_indirect)) / sizeof(uint64);
  unsigned int height;
  uint64 space, old_space;


  bsize -= sizeof(struct gfs_meta_header);

  height = 1;
  space = diptrs * bsize;


  for (;;)
  {
    if (sz <= space)
      break;

    old_space = space;

    height++;
    space *= inptrs;

    if (space / inptrs != old_space ||
      space % inptrs != 0)
      break;
  }


  return height;
}


/**
 * build_tree - build the pointers and indirect blocks for a file
 * @comline: the command line
 * @di: the dinode
 * @addr: the start of the file
 * @blocks: the number of blocks in the file
 *
 */

static void build_tree(commandline_t *comline, struct gfs_dinode *di, uint64 addr, unsigned int blocks)
{
  struct gfs_indirect ind;
  char *buf;
  unsigned int x, offset;
  unsigned int height;
  unsigned int indblocks;
  uint64 tmp_addr;
  unsigned int tmp_blocks;

  
  di->di_height = compute_height(di->di_size, comline->bsize);


  if (di->di_height == 1)
  {
    type_zalloc(buf, char, comline->bsize);

    for (x = 0; x < blocks; x++)
      ((uint64 *)(buf + sizeof(struct gfs_dinode)))[x] = cpu_to_gfs64(addr + x);

    gfs_dinode_out(di, buf);

    do_lseek(comline->fd, di->di_num.no_addr * comline->bsize);
    do_write(comline->fd, buf, comline->bsize);

    free(buf);
  }
  else
  {
    tmp_addr = addr;
    tmp_blocks = blocks;


    for (height = di->di_height; height > 1; height--)
    {
      memset(&ind, 0, sizeof(struct gfs_indirect));
      ind.in_header.mh_magic = GFS_MAGIC;
      ind.in_header.mh_type = GFS_METATYPE_IN;
      ind.in_header.mh_format = GFS_FORMAT_IN;


      indblocks = DIV_RU((tmp_blocks * sizeof(uint64)),
                   (comline->bsize - sizeof(struct gfs_indirect)));

      type_zalloc(buf, char, indblocks * comline->bsize);


      offset = 0;
      for (x = 0; x < tmp_blocks; x++)
      {
      if (!(offset % comline->bsize))
      {
        gfs_indirect_out(&ind, buf + offset);
        offset += sizeof(struct gfs_indirect);
      }

      *((uint64 *)(buf + offset)) = cpu_to_gfs64(tmp_addr + x);
      offset += sizeof(uint64);
      }


      do_lseek(comline->fd, comline->rgrp0_next * comline->bsize);
      do_write(comline->fd, buf, indblocks * comline->bsize);

      free(buf);

      tmp_addr = comline->rgrp0_next;
      tmp_blocks = indblocks;

      di->di_blocks += indblocks;

      comline->rgrp0_next += indblocks;
    }


    type_zalloc(buf, char, comline->bsize);

    for (x = 0; x < tmp_blocks; x++)
      ((uint64 *)(buf + sizeof(struct gfs_dinode)))[x] = cpu_to_gfs64(tmp_addr + x);

    gfs_dinode_out(di, buf);

    do_lseek(comline->fd, di->di_num.no_addr * comline->bsize);
    do_write(comline->fd, buf, comline->bsize);    

    free(buf);
  }
}


/**
 * fill_jindex - create the journal index data
 * @comline: the command line
 * @jlist: the list of journals
 *
 * Returns: a pointer data for the jindex
 */

static char *fill_jindex(commandline_t *comline, osi_list_t *jlist)
{
  journal_list_t *jl;
  struct gfs_jindex ji;
  osi_list_t *tmp;
  char *buf;
  unsigned int j = 0;


  type_alloc(buf, char, comline->journals * sizeof(struct gfs_jindex));


  for (tmp = jlist->next; tmp != jlist; tmp = tmp->next)
  {
    jl = osi_list_entry(tmp, journal_list_t, list);

    memset(&ji, 0, sizeof(struct gfs_jindex));

    ji.ji_addr = jl->start;
    ji.ji_nsegment = jl->segments;

    gfs_jindex_out(&ji, buf + j * sizeof(struct gfs_jindex));

    j++;
  }


  if (comline->debug)
  {
    printf("\nJournal Index data:\n");

    for (j = 0; j < comline->journals; j++)
    {
      gfs_jindex_in(&ji, buf + j * sizeof(struct gfs_jindex));

      printf("\n  Journal %d\n", j);
      gfs_jindex_print(&ji);
    }
  }


  return buf;
}


/**
 * write_jindex - write out the journal index
 * @comline: the command line
 * @jlist: the list of journals
 *
 */

void write_jindex(commandline_t *comline, osi_list_t *jlist)
{
  struct gfs_dinode di;
  struct gfs_meta_header jd;
  char *buf, *data;
  uint64 addr;
  unsigned int blocks;
  unsigned int x, left, jbsize = comline->bsize - sizeof(struct gfs_meta_header);


  memset(&di, 0, sizeof(struct gfs_dinode));
 
  di.di_header.mh_magic = GFS_MAGIC;
  di.di_header.mh_type = GFS_METATYPE_DI;
  di.di_header.mh_format = GFS_FORMAT_DI;

  di.di_num = comline->sb->sb_jindex_di;

  di.di_mode = MKFS_HIDDEN_MODE;
  di.di_nlink = 1;
  di.di_size = comline->journals * sizeof(struct gfs_jindex);
  di.di_blocks = 1;
  di.di_atime = di.di_mtime = di.di_ctime = time(NULL);

  di.di_flags = GFS_DIF_JDATA;
  di.di_payload_format = GFS_FORMAT_JI;
  di.di_type = GFS_FILE_REG;


  data = fill_jindex(comline, jlist);


  if (di.di_size < comline->bsize - sizeof(struct gfs_dinode))
  {
    type_zalloc(buf, char, comline->bsize);

    gfs_dinode_out(&di, buf);

    memcpy(buf + sizeof(struct gfs_dinode), data, comline->journals * sizeof(struct gfs_jindex));

    do_lseek(comline->fd, di.di_num.no_addr * comline->bsize);
    do_write(comline->fd, buf, comline->bsize);

    free(buf);
  }
  else
  {
    blocks = DIV_RU(di.di_size, (comline->bsize - sizeof(struct gfs_meta_header)));
    di.di_blocks += blocks;

    addr = comline->rgrp0_next;


    memset(&jd, 0, sizeof(struct gfs_meta_header));
    jd.mh_magic = GFS_MAGIC;
    jd.mh_type = GFS_METATYPE_JD;
    jd.mh_format = GFS_FORMAT_JD;


    type_zalloc(buf, char, blocks * comline->bsize);

    left = comline->journals * sizeof(struct gfs_jindex);
    for (x = 0; x < blocks; x++)
    {
      gfs_meta_header_out(&jd, buf + x * comline->bsize);
      memcpy(buf + x * comline->bsize + sizeof(struct gfs_meta_header),
           data + x * jbsize,
           (left > jbsize) ? jbsize : left);
      left -= jbsize;
    }


    do_lseek(comline->fd, addr * comline->bsize);
    do_write(comline->fd, buf, blocks * comline->bsize);

    free(buf);


    comline->rgrp0_next += blocks;

    build_tree(comline, &di, addr, blocks);
  }


  free(data);


  if (comline->debug)
  {
    printf("\nJournal index dinode:\n");
    gfs_dinode_print(&di);
  }
}


/**
 * fill_rindex - create the resource group index data
 * @comline: the command line
 * @rlist: the list of RGs
 *
 * Returns: a pointer data for the rindex
 */

static char *fill_rindex(commandline_t *comline, osi_list_t *rlist)
{
  struct gfs_rindex *ri, rindex;
  rgrp_list_t *rl;
  osi_list_t *tmp;
  char *buf;
  unsigned int r = 0;
  uint32 length, blocks;


  type_alloc(buf, char, comline->rgrps * sizeof(struct gfs_rindex));


  for (tmp = rlist->next; tmp != rlist; tmp = tmp->next)
  {
    rl = osi_list_entry(tmp, rgrp_list_t, list);

    length = rgrplength2bitblocks(comline, rl->rg_length);

    blocks = rl->rg_length - length;
    blocks -= blocks % GFS_NBBY;
    comline->fssize += blocks;

    type_zalloc(ri, struct gfs_rindex, 1);
    rl->ri = ri;

    ri->ri_addr = rl->rg_offset;
    ri->ri_length = length;

    ri->ri_data1 = rl->rg_offset + length;
    ri->ri_data = blocks;

    ri->ri_bitbytes = blocks / GFS_NBBY;

    gfs_rindex_out(ri, buf + r * sizeof(struct gfs_rindex));

    r++;
  }


  if (comline->debug)
  {
    printf("\nResource Index data:\n");

    for (r = 0; r < comline->rgrps; r++)
    {
      gfs_rindex_in(&rindex, buf + r * sizeof(struct gfs_rindex));

      printf("\n  Resource index %d\n", r);
      gfs_rindex_print(&rindex);
    }
  }


  return buf;
}


/**
 * write_rindex - write out the resource group index
 * @comline: the command line
 * @jlist: the list of RGs
 *
 */

void write_rindex(commandline_t *comline, osi_list_t *rlist)
{
  struct gfs_dinode di;
  struct gfs_meta_header jd;
  char *buf, *data;
  uint64 addr;
  unsigned int blocks;
  unsigned int x, left, jbsize = comline->bsize - sizeof(struct gfs_meta_header);


  memset(&di, 0, sizeof(struct gfs_dinode));

  di.di_header.mh_magic = GFS_MAGIC;
  di.di_header.mh_type = GFS_METATYPE_DI;
  di.di_header.mh_format = GFS_FORMAT_DI;

  di.di_num = comline->sb->sb_rindex_di;

  di.di_mode = MKFS_HIDDEN_MODE;
  di.di_nlink = 1;
  di.di_size = comline->rgrps * sizeof(struct gfs_rindex);
  di.di_blocks = 1;
  di.di_atime = di.di_mtime = di.di_ctime = time(NULL);

  di.di_flags = GFS_DIF_JDATA;
  di.di_payload_format = GFS_FORMAT_RI;
  di.di_type = GFS_FILE_REG;


  data = fill_rindex(comline, rlist);


  if (di.di_size < comline->bsize - sizeof(struct gfs_dinode))
  {
    type_zalloc(buf, char, comline->bsize);

    gfs_dinode_out(&di, buf);
    
    memcpy(buf + sizeof(struct gfs_dinode), data, comline->rgrps * sizeof(struct gfs_rindex));

    do_lseek(comline->fd, di.di_num.no_addr * comline->bsize);
    do_write(comline->fd, buf, comline->bsize);

    free(buf);
  }
  else
  {
    blocks = DIV_RU(di.di_size, (comline->bsize - sizeof(struct gfs_meta_header)));
    di.di_blocks += blocks;

    addr = comline->rgrp0_next;


    memset(&jd, 0, sizeof(struct gfs_meta_header));
    jd.mh_magic = GFS_MAGIC;
    jd.mh_type = GFS_METATYPE_JD;
    jd.mh_format = GFS_FORMAT_JD;


    type_zalloc(buf, char, blocks * comline->bsize);

    left = comline->rgrps * sizeof(struct gfs_rindex);
    for (x = 0; x < blocks; x++)
    {
      gfs_meta_header_out(&jd, buf + x * comline->bsize);
      memcpy(buf + x * comline->bsize + sizeof(struct gfs_meta_header),
           data + x * jbsize,
           (left > jbsize) ? jbsize : left);
      left -= jbsize;
    }


    do_lseek(comline->fd, addr * comline->bsize);
    do_write(comline->fd, buf, blocks * comline->bsize);

    free(buf);


    comline->rgrp0_next += blocks;

    build_tree(comline, &di, addr, blocks);
  }


  free(data);


  if (comline->debug)
  {
    printf("\nResource index dinode:\n");
    gfs_dinode_print(&di);
  }
}


/**
 * write_root - write out the root dinode
 * @comline: the command line
 *
 */

void write_root(commandline_t *comline)
{
  struct gfs_dinode di;
  struct gfs_dirent de;

  char buf[comline->bsize];


  memset(&di, 0, sizeof(struct gfs_dinode));
  memset(buf, 0, comline->bsize);


  di.di_header.mh_magic = GFS_MAGIC;
  di.di_header.mh_type = GFS_METATYPE_DI;
  di.di_header.mh_format = GFS_FORMAT_DI;

  di.di_num = comline->sb->sb_root_di;

  di.di_mode = MKFS_ROOT_MODE;
  di.di_nlink = 2;
  di.di_size = comline->bsize - sizeof(struct gfs_dinode);
  di.di_blocks = 1;
  di.di_atime = di.di_mtime = di.di_ctime = time(NULL);

  di.di_flags = GFS_DIF_JDATA;
  di.di_payload_format = GFS_FORMAT_DE;
  di.di_type = GFS_FILE_DIR;

  di.di_entries = 2;

  gfs_dinode_out(&di, buf);


  /*  Fill in .  */

  memset(&de, 0, sizeof(struct gfs_dirent));

  de.de_inum = comline->sb->sb_root_di;
  de.de_hash = gfs_dir_hash(".", 1);
  de.de_rec_len = GFS_DIRENT_SIZE(1);
  de.de_name_len = 1;
  de.de_type = GFS_FILE_DIR;

  gfs_dirent_out(&de, buf + sizeof(struct gfs_dinode));
  memcpy(buf + sizeof(struct gfs_dinode) + sizeof(struct gfs_dirent), ".", 1);

  if (comline->debug)
  {
    printf("\nRoot Dinode dirent:\n");
    gfs_dirent_print(&de, ".");
  }


  /*  Fill in ..  */

  memset(&de, 0, sizeof(struct gfs_dirent));

  de.de_inum = comline->sb->sb_root_di;
  de.de_hash = gfs_dir_hash("..", 2);
  de.de_rec_len = comline->bsize - GFS_DIRENT_SIZE(1) - sizeof(struct gfs_dinode);
  de.de_name_len = 2;
  de.de_type = GFS_FILE_DIR;

  gfs_dirent_out(&de, buf + sizeof(struct gfs_dinode) + GFS_DIRENT_SIZE(1));
  memcpy(buf + sizeof(struct gfs_dinode) + GFS_DIRENT_SIZE(1) + sizeof(struct gfs_dirent), "..", 2);

  if (comline->debug)
  {
    printf("\nRoot Dinode dirent:\n");
    gfs_dirent_print(&de, "..");
  }


  do_lseek(comline->fd, di.di_num.no_addr * comline->bsize);
  do_write(comline->fd, buf, comline->bsize);


  if (comline->debug)
  {
    printf("\nRoot dinode:\n");
    gfs_dinode_print(&di);
  }
}


/**
 * write_quota - write out the quota dinode
 * @comline: the command line
 *
 */

void write_quota(commandline_t *comline)
{
  struct gfs_dinode di;
  struct gfs_quota qu;

  char buf[comline->bsize];


  memset(&di, 0, sizeof(struct gfs_dinode));
  memset(buf, 0, comline->bsize);


  di.di_header.mh_magic = GFS_MAGIC;
  di.di_header.mh_type = GFS_METATYPE_DI;
  di.di_header.mh_format = GFS_FORMAT_DI;

  di.di_num = comline->sb->sb_quota_di;

  di.di_mode = MKFS_HIDDEN_MODE;
  di.di_nlink = 1;
  di.di_size = 2 * sizeof(struct gfs_quota);
  di.di_blocks = 1;
  di.di_atime = di.di_mtime = di.di_ctime = time(NULL);

  di.di_flags = GFS_DIF_JDATA;
  di.di_payload_format = GFS_FORMAT_QU;
  di.di_type = GFS_FILE_REG;

  gfs_dinode_out(&di, buf);


  /*  Fill in the root user quota  */

  memset(&qu, 0, sizeof(struct gfs_quota));
  qu.qu_value = comline->rgrp0_next - comline->sb->sb_jindex_di.no_addr;

  gfs_quota_out(&qu, buf + sizeof(struct gfs_dinode));

  if (comline->debug)
  {
    printf("\nRoot user quota:\n");
    gfs_quota_print(&qu);
  }


  /*  Fill in the root group quota  */

  memset(&qu, 0, sizeof(struct gfs_quota));
  qu.qu_value = comline->rgrp0_next - comline->sb->sb_jindex_di.no_addr;

  gfs_quota_out(&qu, buf + sizeof(struct gfs_dinode) + sizeof(struct gfs_quota));

  if (comline->debug)
  {
    printf("\nRoot group quota:\n");
    gfs_quota_print(&qu);
  }


  do_lseek(comline->fd, di.di_num.no_addr * comline->bsize);
  do_write(comline->fd, buf, comline->bsize);


  if (comline->debug)
  {
    printf("\nQuota dinode:\n");
    gfs_dinode_print(&di);
  }
}


/**
 * write_license - write out the quota dinode
 * @comline: the command line
 *
 */

void write_license(commandline_t *comline)
{
  struct gfs_dinode di;

  char buf[comline->bsize];


  memset(&di, 0, sizeof(struct gfs_dinode));
  memset(buf, 0, comline->bsize);


  di.di_header.mh_magic = GFS_MAGIC;
  di.di_header.mh_type = GFS_METATYPE_DI;
  di.di_header.mh_format = GFS_FORMAT_DI;

  di.di_num = comline->sb->sb_license_di;

  di.di_mode = MKFS_HIDDEN_MODE;
  di.di_nlink = 1;
  di.di_size = 0;
  di.di_blocks = 1;
  di.di_atime = di.di_mtime = di.di_ctime = time(NULL);

  di.di_flags = GFS_DIF_JDATA;
  di.di_payload_format = GFS_FORMAT_QU;
  di.di_type = GFS_FILE_REG;

  gfs_dinode_out(&di, buf);


  do_lseek(comline->fd, di.di_num.no_addr * comline->bsize);
  do_write(comline->fd, buf, comline->bsize);


  if (comline->debug)
  {
    printf("\nLicense dinode:\n");
    gfs_dinode_print(&di);
  }
}


/**
 * write_rgrps - write out the resource group headers
 * @comline: the command line
 * @rlist: the RG list
 *
 */

void write_rgrps(commandline_t *comline, osi_list_t *rlist)
{
  struct gfs_rgrp rg;
  struct gfs_meta_header rb;
  rgrp_list_t *rl;
  osi_list_t *tmp;
  char *buf, *data;
  unsigned int x, offset;
  unsigned int byte, bit;
  unsigned int blk_count;
  unsigned int r = 0;


  memset(&rb, 0, sizeof(struct gfs_meta_header));
  rb.mh_magic = GFS_MAGIC;
  rb.mh_type = GFS_METATYPE_RB;
  rb.mh_format = GFS_FORMAT_RB;


  for (tmp = rlist->next; tmp != rlist; tmp = tmp->next)
  {
    rl = osi_list_entry(tmp, rgrp_list_t, list);

    memset(&rg, 0, sizeof(struct gfs_rgrp));
    rg.rg_header.mh_magic = GFS_MAGIC;
    rg.rg_header.mh_type = GFS_METATYPE_RG;
    rg.rg_header.mh_format = GFS_FORMAT_RG;
    rg.rg_free = rl->ri->ri_data;

    type_zalloc(data, char, rl->ri->ri_bitbytes);
    type_zalloc(buf, char, rl->ri->ri_length * comline->bsize);


    /*  Deal with the special case of the first dinode  */

    if (!r)
    {
      if (comline->rgrp0_next > rl->ri->ri_data1 + rl->ri->ri_data)
      die("RG 0 is full.\n");

      /*  Compensate for the hidden dinodes  */

      *data = (GFS_BLKST_USEDMETA << 3 * GFS_BIT_SIZE) |
      (GFS_BLKST_USEDMETA << 2 * GFS_BIT_SIZE) |
        (GFS_BLKST_USEDMETA << GFS_BIT_SIZE) |
          GFS_BLKST_USEDMETA;
      *(data + 1) = GFS_BLKST_USEDMETA;
      rg.rg_free -= 5;
      rg.rg_useddi = 5;

      /*  Compensate for the data the hidden dinodes point to  */

      for (x = rl->ri->ri_data1 + 5; x < comline->rgrp0_next; x++)
      {
      byte = (x - rl->ri->ri_data1) / GFS_NBBY;
      bit = (x - rl->ri->ri_data1) % GFS_NBBY;

      data[byte] |= GFS_BLKST_USEDMETA << (bit * GFS_BIT_SIZE);

      rg.rg_free--;
      rg.rg_usedmeta++;
      }
    }


    gfs_rgrp_out(&rg, buf);
    offset = sizeof(struct gfs_rgrp);
    blk_count = 1;

    for (x = 0; x < rl->ri->ri_bitbytes; x++)
    {
      if (!(offset % comline->bsize))
      {
      gfs_meta_header_out(&rb, buf + offset);
      offset += sizeof(struct gfs_meta_header);
      blk_count++;
      }

      buf[offset] = data[x];
      offset++;
    }

    if (blk_count != rl->ri->ri_length)
      die("RG underflow (rg = %u, blk_count = %u, rl->ri->ri_length = %u)\n",
        r, blk_count, rl->ri->ri_length);


    do_lseek(comline->fd, rl->ri->ri_addr * comline->bsize);
    do_write(comline->fd, buf, rl->ri->ri_length * comline->bsize);


    free(buf);
    free(data);


    if (comline->debug)
    {
      printf("\nResource group header %d\n", r);
      gfs_rgrp_print(&rg);
    }

    r++;
  }
}


/**
 * write_journals - write out the journal log headers
 * @comline: the command line
 * @rlist: the RG list
 *
 */

void write_journals(commandline_t *comline, osi_list_t *jlist)
{
  struct gfs_log_header lh;
  journal_list_t *jl;
  osi_list_t *tmp;
  char buf[comline->bsize];
  uint32 seg, sequence;
  int x = 0;


  srandom(time(NULL));


  for (tmp = jlist->next; tmp != jlist; tmp = tmp->next)
  {
    jl = osi_list_entry(tmp, journal_list_t, list);

    if (comline->debug)
      printf("Starting journal %d\n", x++);

    sequence = jl->segments / (RAND_MAX + 1.0) * random();

    for (seg = 0; seg < jl->segments; seg++)
    {
      memset(buf, 0, comline->bsize);
      memset(&lh, 0, sizeof(struct gfs_log_header));

      lh.lh_header.mh_magic = GFS_MAGIC;
      lh.lh_header.mh_type = GFS_METATYPE_LH;
      lh.lh_header.mh_format = GFS_FORMAT_LH;
      lh.lh_flags = GFS_LOG_HEAD_UNMOUNT;
      lh.lh_first = jl->start + seg * comline->seg_size;
      lh.lh_sequence = sequence;
      /*  Don't care about tail  */
      /*  Don't care about log dump  */

      gfs_log_header_out(&lh, buf);
      gfs_log_header_out(&lh, buf + GFS_BASIC_BLOCK - sizeof(struct gfs_log_header));

      do_lseek(comline->fd, lh.lh_first * comline->bsize);
      do_write(comline->fd, buf, comline->bsize);

      if (++sequence == jl->segments)
      sequence = 0;

      if (!(seg % 100))
      if (comline->debug)
        printf("seg #%u\n", seg);
      
    }
  }
}



Generated by  Doxygen 1.6.0   Back to index