|
Packit |
6ef888 |
#include "clusterautoconfig.h"
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
#include <stdio.h>
|
|
Packit |
6ef888 |
#include <stdlib.h>
|
|
Packit |
6ef888 |
#include <string.h>
|
|
Packit |
6ef888 |
#include <stdint.h>
|
|
Packit |
6ef888 |
#include <inttypes.h>
|
|
Packit |
6ef888 |
#include <sys/types.h>
|
|
Packit |
6ef888 |
#include <sys/stat.h>
|
|
Packit |
6ef888 |
#include <fcntl.h>
|
|
Packit |
6ef888 |
#include <unistd.h>
|
|
Packit |
6ef888 |
#include <errno.h>
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
#include <linux/types.h>
|
|
Packit |
6ef888 |
#include "libgfs2.h"
|
|
Packit |
6ef888 |
#include "config.h"
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/**
|
|
Packit |
6ef888 |
* Given a number of blocks in a resource group, return the number of blocks
|
|
Packit |
6ef888 |
* needed for bitmaps. Also calculate the adjusted number of free data blocks
|
|
Packit |
6ef888 |
* in the resource group and store it in *ri_data.
|
|
Packit |
6ef888 |
*/
|
|
Packit |
6ef888 |
uint32_t rgblocks2bitblocks(const unsigned int bsize, const uint32_t rgblocks, uint32_t *ri_data)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
uint32_t mappable = 0;
|
|
Packit |
6ef888 |
uint32_t bitblocks = 0;
|
|
Packit |
6ef888 |
/* Number of blocks mappable by bitmap blocks with these header types */
|
|
Packit |
6ef888 |
const uint32_t blks_rgrp = GFS2_NBBY * (bsize - sizeof(struct gfs2_rgrp));
|
|
Packit |
6ef888 |
const uint32_t blks_meta = GFS2_NBBY * (bsize - sizeof(struct gfs2_meta_header));
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
while (blks_rgrp + (blks_meta * bitblocks) < ((rgblocks - bitblocks) & ~(uint32_t)3))
|
|
Packit |
6ef888 |
bitblocks++;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (bitblocks > 0)
|
|
Packit |
6ef888 |
mappable = blks_rgrp + (blks_meta * (bitblocks - 1));
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
*ri_data = (rgblocks - (bitblocks + 1)) & ~(uint32_t)3;
|
|
Packit |
6ef888 |
if (mappable < *ri_data)
|
|
Packit |
6ef888 |
bitblocks++;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
return bitblocks;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/**
|
|
Packit |
6ef888 |
* build_rgrps - write a bunch of resource groups to disk.
|
|
Packit |
6ef888 |
* If fd > 0, write the data to the given file handle.
|
|
Packit |
6ef888 |
* Otherwise, use gfs2 buffering in buf.c.
|
|
Packit |
6ef888 |
*/
|
|
Packit |
6ef888 |
int build_rgrps(struct gfs2_sbd *sdp, int do_write)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
struct osi_node *n, *next = NULL;
|
|
Packit |
6ef888 |
struct rgrp_tree *rl;
|
|
Packit |
6ef888 |
uint32_t rgblocks, bitblocks;
|
|
Packit |
6ef888 |
struct gfs2_rindex *ri;
|
|
Packit |
6ef888 |
struct gfs2_meta_header mh;
|
|
Packit |
6ef888 |
unsigned int x;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
mh.mh_magic = GFS2_MAGIC;
|
|
Packit |
6ef888 |
mh.mh_type = GFS2_METATYPE_RB;
|
|
Packit |
6ef888 |
mh.mh_format = GFS2_FORMAT_RB;
|
|
Packit |
6ef888 |
if (do_write)
|
|
Packit |
6ef888 |
n = osi_first(&sdp->rgtree);
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
n = osi_first(&sdp->rgcalc);
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
for (; n; n = next) {
|
|
Packit |
6ef888 |
next = osi_next(n);
|
|
Packit |
6ef888 |
rl = (struct rgrp_tree *)n;
|
|
Packit |
6ef888 |
ri = &rl->ri;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
bitblocks = rgblocks2bitblocks(sdp->bsize, rl->length, &rgblocks);
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
ri->ri_addr = rl->start;
|
|
Packit |
6ef888 |
ri->ri_length = bitblocks;
|
|
Packit |
6ef888 |
ri->ri_data0 = rl->start + bitblocks;
|
|
Packit |
6ef888 |
ri->ri_data = rgblocks;
|
|
Packit |
6ef888 |
ri->ri_bitbytes = rgblocks / GFS2_NBBY;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
memset(&rl->rg, 0, sizeof(rl->rg));
|
|
Packit |
6ef888 |
rl->rg.rg_header.mh_magic = GFS2_MAGIC;
|
|
Packit |
6ef888 |
rl->rg.rg_header.mh_type = GFS2_METATYPE_RG;
|
|
Packit |
6ef888 |
rl->rg.rg_header.mh_format = GFS2_FORMAT_RG;
|
|
Packit |
6ef888 |
rl->rg.rg_free = rgblocks;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (gfs2_compute_bitstructs(sdp->sd_sb.sb_bsize, rl))
|
|
Packit |
6ef888 |
return -1;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (do_write) {
|
|
Packit |
6ef888 |
for (x = 0; x < bitblocks; x++) {
|
|
Packit |
6ef888 |
rl->bits[x].bi_bh = bget(sdp, rl->start + x);
|
|
Packit |
6ef888 |
if (x)
|
|
Packit |
6ef888 |
gfs2_meta_header_out(&mh, rl->bits[x].bi_bh->b_data);
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
gfs2_rgrp_out(&rl->rg, rl->bits[x].bi_bh->b_data);
|
|
Packit |
6ef888 |
bmodified(rl->bits[x].bi_bh);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (cfg_debug) {
|
|
Packit |
6ef888 |
printf("\n");
|
|
Packit |
6ef888 |
gfs2_rindex_print(ri);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
sdp->blks_total += rgblocks;
|
|
Packit |
6ef888 |
sdp->fssize = ri->ri_data0 + ri->ri_data;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
return 0;
|
|
Packit |
6ef888 |
}
|