Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F2822711
basic.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
basic.c
View Options
#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 <stdint.h>
#include <inttypes.h>
#include "gfs_ondisk.h"
#include "linux_endian.h"
#include "gfs_debug.h"
#include "basic.h"
#include "block_device.h"
/**
* verify_block_size -
* @bsize:
*
*/
static int
verify_block_size(unsigned int bsize)
{
unsigned int x = 512;
for (;;) {
if (!x)
return -1;
if (x == bsize)
return 0;
x <<= 1;
}
}
/**
* verify_gfs -
*
*/
void
verify_gfs(void)
{
char buf[GFS_BASIC_BLOCK];
struct gfs_sb sb;
if (device_size < (GFS_SB_ADDR + 1) * GFS_BASIC_BLOCK)
return;
do_lseek(device_fd, GFS_SB_ADDR * GFS_BASIC_BLOCK);
do_read(device_fd, buf, GFS_BASIC_BLOCK);
gfs_sb_in(&sb, buf);
if (sb.sb_header.mh_magic != GFS_MAGIC ||
sb.sb_header.mh_type != GFS_METATYPE_SB ||
sb.sb_bsize != 1 << sb.sb_bsize_shift ||
verify_block_size(sb.sb_bsize))
return;
if (!block_size || block_size == sb.sb_bsize) {
unsigned int x;
is_gfs = TRUE;
block_size = sb.sb_bsize;
block_size_shift = sb.sb_bsize_shift;
sd_diptrs = (block_size - sizeof(struct gfs_dinode)) / sizeof(uint64_t);
sd_inptrs = (block_size - sizeof(struct gfs_indirect)) / sizeof(uint64_t);
sd_jbsize = block_size - sizeof(struct gfs_meta_header);
sd_hash_bsize = block_size / 2;
sd_hash_ptrs = sd_hash_bsize / sizeof(uint64_t);
sd_heightsize[0] = block_size - sizeof(struct gfs_dinode);
sd_heightsize[1] = block_size * sd_diptrs;
for (x = 2;; x++) {
uint64_t space = sd_heightsize[x - 1] * sd_inptrs;
uint64_t d = space / sd_inptrs;
uint32_t m = space % sd_inptrs;
if (d != sd_heightsize[x - 1] || m)
break;
sd_heightsize[x] = space;
}
sd_max_height = x;
sd_jheightsize[0] = block_size - sizeof(struct gfs_dinode);
sd_jheightsize[1] = sd_jbsize * sd_diptrs;
for (x = 2;; x++) {
uint64_t space = sd_jheightsize[x - 1] * sd_inptrs;
uint64_t d = space / sd_inptrs;
uint32_t m = space % sd_inptrs;
if (d != sd_jheightsize[x - 1] || m)
break;
sd_jheightsize[x] = space;
}
sd_max_jheight = x;
}
}
/**
* must_be_gfs -
*
*/
void
must_be_gfs(void)
{
if (!is_gfs)
die("not a gfs filesystem\n");
}
/**
* scan_device -
*
*/
void
scan_device(void)
{
char data[GFS_BASIC_BLOCK];
uint64_t bb;
struct gfs_meta_header mh;
for (bb = 0; (bb + 1) * GFS_BASIC_BLOCK <= device_size; bb++) {
do_lseek(device_fd, bb * GFS_BASIC_BLOCK);
do_read(device_fd, data, GFS_BASIC_BLOCK);
gfs_meta_header_in(&mh, data);
if (mh.mh_magic == GFS_MAGIC &&
mh.mh_type && mh.mh_type <= GFS_METATYPE_EA)
printf("sector %"PRIu64": type %u\n",
bb, mh.mh_type);
}
}
/**
* print_superblock -
*
*/
void
print_superblock(void)
{
char *data;
struct gfs_sb sb;
must_be_gfs();
data = get_block(GFS_SB_ADDR * GFS_BASIC_BLOCK / block_size, TRUE);
gfs_sb_in(&sb, data);
free(data);
gfs_sb_print(&sb);
}
/**
* print_bitmaps -
* @data:
* @offset:
*
*/
static void
print_bitmaps(char *data, unsigned int offset)
{
unsigned int bn = 0;
unsigned int bit;
unsigned char value;
char *type;
printf("\n");
for (; offset < block_size; offset++) {
for (bit = 0; bit < GFS_NBBY; bit++) {
value = data[offset];
value = (value >> (bit * GFS_BIT_SIZE)) & GFS_BIT_MASK;
switch (value) {
case GFS_BLKST_FREE:
type = "free";
break;
case GFS_BLKST_USED:
type = "used data";
break;
case GFS_BLKST_FREEMETA:
type = "free meta";
break;
case GFS_BLKST_USEDMETA:
type = "used meta";
break;
default:
ASSERT(FALSE,);
}
printf(" block %u: %s\n", bn, type);
bn++;
}
}
}
/**
* print_stuffed_hash -
* @data:
*
*/
static void
print_stuffed_hash(char *data)
{
uint64_t *p = (uint64_t *)(data + sizeof(struct gfs_dinode));
uint64_t *end = (uint64_t *)(((char *)p) + block_size / 2);
uint64_t this, last = 0;
unsigned int run = 0;
int first = TRUE;
printf("\n");
for (; p < end; p++) {
this = gfs64_to_cpu(*p);
if (first) {
first = FALSE;
run = 1;
} else {
if (this == last)
run++;
else {
printf(" pointer: %"PRIu64" (%u)\n",
last, run);
run = 1;
}
}
last = this;
}
printf(" pointer: %"PRIu64" (%u)\n",
last, run);
}
/**
* print_dirents -
* @data:
* @offset:
*
* Make this more robust
*
*/
void
print_dirents(char *data, unsigned int offset)
{
struct gfs_dirent de;
for (; offset < block_size; offset += de.de_rec_len) {
printf("\n");
gfs_dirent_in(&de, data + offset);
if (sizeof(struct gfs_dirent) + de.de_name_len > de.de_rec_len)
continue;
if (offset + sizeof(struct gfs_dirent) + de.de_name_len > block_size)
break;
if (de.de_inum.no_formal_ino)
gfs_dirent_print(&de, data + offset + sizeof(struct gfs_dirent));
}
}
/**
* print_pointers -
* @data:
* @offset:
*
*/
static void
print_pointers(char *data, unsigned int offset)
{
uint64_t *p = (uint64_t *)(data + offset);
uint64_t *end = (uint64_t *)(data + block_size);
unsigned int x = 0;
printf("\n");
for (; p < end; p++, x++)
if (*p)
printf(" pointer #%u: %"PRIu64"\n",
x, gfs64_to_cpu(*p));
}
/**
* identify_block -
*
*/
void
identify_block(void)
{
char *data;
struct gfs_meta_header mh;
must_be_gfs();
data = get_block(block_number, TRUE);
gfs_meta_header_in(&mh, data);
if (mh.mh_magic != GFS_MAGIC) {
printf("Not GFS metadata\n");
free(data);
return;
}
switch (mh.mh_type) {
case GFS_METATYPE_NONE:
printf("GFS_METATYPE_NONE\n");
break;
case GFS_METATYPE_SB:
printf("Super\n");
if (verbose) {
struct gfs_sb sb;
gfs_sb_in(&sb, data);
gfs_sb_print(&sb);
}
break;
case GFS_METATYPE_RG:
printf("Resource Group Header\n");
if (verbose) {
struct gfs_rgrp rg;
gfs_rgrp_in(&rg, data);
gfs_rgrp_print(&rg);
if (verbose > 1)
print_bitmaps(data, sizeof(struct gfs_rgrp));
}
break;
case GFS_METATYPE_RB:
printf("Resource Group Bitmap\n");
if (verbose) {
gfs_meta_header_print(&mh);
if (verbose > 1)
print_bitmaps(data, sizeof(struct gfs_meta_header));
}
break;
case GFS_METATYPE_DI:
printf("Dinode\n");
if (verbose) {
struct gfs_dinode di;
gfs_dinode_in(&di, data);
gfs_dinode_print(&di);
if (verbose > 1) {
if (di.di_height)
print_pointers(data, sizeof(struct gfs_dinode));
else {
if (di.di_type == GFS_FILE_REG)
printf("\n stuffed data\n");
else if (di.di_type == GFS_FILE_DIR &&
(di.di_flags & GFS_DIF_EXHASH))
print_stuffed_hash(data);
else if (di.di_type == GFS_FILE_DIR)
print_dirents(data, sizeof(struct gfs_dinode));
else if (di.di_type == GFS_FILE_LNK)
printf("\nsymlink to %s\n",
data + sizeof(struct gfs_dinode));
}
}
}
break;
case GFS_METATYPE_IN:
printf("Indirect\n");
if (verbose) {
struct gfs_indirect in;
gfs_indirect_in(&in, data);
gfs_indirect_print(&in);
if (verbose > 1) {
print_pointers(data, sizeof(struct gfs_indirect));
}
}
break;
case GFS_METATYPE_LF:
printf("Directory Leaf\n");
if (verbose) {
struct gfs_leaf lf;
gfs_leaf_in(&lf, data);
gfs_leaf_print(&lf);
if (verbose > 1)
print_dirents(data, sizeof(struct gfs_leaf));
}
break;
case GFS_METATYPE_JD:
printf("Journaled Data\n");
if (verbose)
gfs_meta_header_print(&mh);
break;
case GFS_METATYPE_LH:
printf("Log Header\n");
if (verbose) {
struct gfs_log_header lh;
gfs_log_header_in(&lh, data);
gfs_log_header_print(&lh);
}
break;
case GFS_METATYPE_LD:
printf("Lock Descriptor\n");
if (verbose) {
struct gfs_log_descriptor ld;
gfs_desc_in(&ld, data);
gfs_desc_print(&ld);
}
break;
case GFS_METATYPE_EA:
printf("Extended Attribute\n");
if (verbose)
gfs_meta_header_print(&mh);
break;
default:
printf("Unknown metadata type\n");
if (verbose)
gfs_meta_header_print(&mh);
break;
}
free(data);
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Sat, Jan 25, 6:28 AM (1 d, 7 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1321521
Default Alt Text
basic.c (7 KB)
Attached To
Mode
rF Fence Agents
Attached
Detach File
Event Timeline
Log In to Comment