Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F3152420
basic.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
basic.c
View Options
/******************************************************************************
*******************************************************************************
**
** 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 <stdint.h>
#include <inttypes.h>
#include <linux/gfs2_ondisk.h>
#include "linux_endian.h"
#include "gfs2_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_gfs2 -
*
*/
void
verify_gfs2(void)
{
char buf[GFS2_BASIC_BLOCK];
struct gfs2_sb sb;
if (device_size < (GFS2_SB_ADDR + 1) * GFS2_BASIC_BLOCK)
return;
do_lseek(device_fd, GFS2_SB_ADDR * GFS2_BASIC_BLOCK);
do_read(device_fd, buf, GFS2_BASIC_BLOCK);
gfs2_sb_in(&sb, buf);
if (sb.sb_header.mh_magic != GFS2_MAGIC ||
sb.sb_header.mh_type != GFS2_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_gfs2 = TRUE;
block_size = sb.sb_bsize;
block_size_shift = sb.sb_bsize_shift;
sd_diptrs = (block_size - sizeof(struct gfs2_dinode)) / sizeof(uint64_t);
sd_inptrs = (block_size - sizeof(struct gfs2_meta_header)) / sizeof(uint64_t);
sd_jbsize = block_size - sizeof(struct gfs2_meta_header);
sd_hash_bsize = block_size / 2;
sd_hash_ptrs = sd_hash_bsize / sizeof(uint64_t);
sd_heightsize[0] = block_size - sizeof(struct gfs2_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 gfs2_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_gfs2 -
*
*/
void
must_be_gfs2(void)
{
if (!is_gfs2)
die("not a gfs2 filesystem\n");
}
/**
* scan_device -
*
*/
void
scan_device(void)
{
char data[GFS2_BASIC_BLOCK];
uint64_t bb;
struct gfs2_meta_header mh;
for (bb = 0; (bb + 1) * GFS2_BASIC_BLOCK <= device_size; bb++) {
do_lseek(device_fd, bb * GFS2_BASIC_BLOCK);
do_read(device_fd, data, GFS2_BASIC_BLOCK);
gfs2_meta_header_in(&mh, data);
if (mh.mh_magic == GFS2_MAGIC &&
mh.mh_type && mh.mh_type <= GFS2_METATYPE_EA)
printf("sector %"PRIu64": type %u\n",
bb, mh.mh_type);
}
}
/**
* print_superblock -
*
*/
void
print_superblock(void)
{
char *data;
struct gfs2_sb sb;
must_be_gfs2();
data = get_block(GFS2_SB_ADDR * GFS2_BASIC_BLOCK / block_size, TRUE);
gfs2_sb_in(&sb, data);
free(data);
gfs2_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 < GFS2_NBBY; bit++) {
value = data[offset];
value = (value >> (bit * GFS2_BIT_SIZE)) & GFS2_BIT_MASK;
switch (value) {
case GFS2_BLKST_FREE:
type = "free";
break;
case GFS2_BLKST_USED:
type = "used data";
break;
case GFS2_BLKST_INVALID:
type = "invalid";
break;
case GFS2_BLKST_DINODE:
type = "dinode";
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 gfs2_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 = le64_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 gfs2_dirent de;
for (; offset < block_size; offset += de.de_rec_len) {
printf("\n");
gfs2_dirent_in(&de, data + offset);
if (sizeof(struct gfs2_dirent) + de.de_name_len > de.de_rec_len)
continue;
if (offset + sizeof(struct gfs2_dirent) + de.de_name_len > block_size)
break;
if (de.de_inum.no_formal_ino)
gfs2_dirent_print(&de, data + offset + sizeof(struct gfs2_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, le64_to_cpu(*p));
}
/**
* identify_block -
*
*/
void
identify_block(void)
{
char *data;
struct gfs2_meta_header mh;
must_be_gfs2();
data = get_block(block_number, TRUE);
gfs2_meta_header_in(&mh, data);
if (mh.mh_magic != GFS2_MAGIC) {
printf("Not GFS2 metadata\n");
free(data);
return;
}
switch (mh.mh_type) {
case GFS2_METATYPE_NONE:
printf("GFS2_METATYPE_NONE\n");
break;
case GFS2_METATYPE_SB:
printf("Super\n");
if (verbose) {
struct gfs2_sb sb;
gfs2_sb_in(&sb, data);
gfs2_sb_print(&sb);
}
break;
case GFS2_METATYPE_RG:
printf("Resource Group Header\n");
if (verbose) {
struct gfs2_rgrp rg;
gfs2_rgrp_in(&rg, data);
gfs2_rgrp_print(&rg);
if (verbose > 1)
print_bitmaps(data, sizeof(struct gfs2_rgrp));
}
break;
case GFS2_METATYPE_RB:
printf("Resource Group Bitmap\n");
if (verbose) {
gfs2_meta_header_print(&mh);
if (verbose > 1)
print_bitmaps(data, sizeof(struct gfs2_meta_header));
}
break;
case GFS2_METATYPE_DI:
printf("Dinode\n");
if (verbose) {
struct gfs2_dinode di;
gfs2_dinode_in(&di, data);
gfs2_dinode_print(&di);
if (verbose > 1) {
if (di.di_height)
print_pointers(data, sizeof(struct gfs2_dinode));
else {
if (S_ISREG(di.di_mode))
printf("\n stuffed data\n");
else if (S_ISDIR(di.di_mode) &&
(di.di_flags & GFS2_DIF_EXHASH))
print_stuffed_hash(data);
else if (S_ISDIR(di.di_mode))
print_dirents(data, sizeof(struct gfs2_dinode));
else if (S_ISLNK(di.di_mode))
printf("\nsymlink to %s\n",
data + sizeof(struct gfs2_dinode));
}
}
}
break;
case GFS2_METATYPE_IN:
printf("Indirect\n");
if (verbose) {
gfs2_meta_header_print(&mh);
if (verbose > 1) {
print_pointers(data, sizeof(struct gfs2_meta_header));
}
}
break;
case GFS2_METATYPE_LF:
printf("Directory Leaf\n");
if (verbose) {
struct gfs2_leaf lf;
gfs2_leaf_in(&lf, data);
gfs2_leaf_print(&lf);
if (verbose > 1)
print_dirents(data, sizeof(struct gfs2_leaf));
}
break;
case GFS2_METATYPE_JD:
printf("Journaled Data\n");
if (verbose)
gfs2_meta_header_print(&mh);
break;
case GFS2_METATYPE_LH:
printf("Log Header\n");
if (verbose) {
struct gfs2_log_header lh;
gfs2_log_header_in(&lh, data);
gfs2_log_header_print(&lh);
}
break;
case GFS2_METATYPE_LD:
printf("Lock Descriptor\n");
if (verbose) {
struct gfs2_log_descriptor ld;
gfs2_log_descriptor_in(&ld, data);
gfs2_log_descriptor_print(&ld);
}
break;
case GFS2_METATYPE_LB:
printf("Generic Log Block\n");
if (verbose)
gfs2_meta_header_print(&mh);
break;
case GFS2_METATYPE_EA:
printf("Extended Attribute\n");
if (verbose)
gfs2_meta_header_print(&mh);
break;
case GFS2_METATYPE_ED:
printf("Extended Attribute Data\n");
if (verbose)
gfs2_meta_header_print(&mh);
break;
case GFS2_METATYPE_UT:
printf("Unlinked Tags\n");
if (verbose)
gfs2_meta_header_print(&mh);
break;
case GFS2_METATYPE_QC:
printf("Quota Changes\n");
if (verbose)
gfs2_meta_header_print(&mh);
break;
default:
printf("Unknown metadata type\n");
if (verbose)
gfs2_meta_header_print(&mh);
break;
}
free(data);
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Mon, Feb 24, 9:58 PM (13 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1455852
Default Alt Text
basic.c (8 KB)
Attached To
Mode
rF Fence Agents
Attached
Detach File
Event Timeline
Log In to Comment