|
Packit |
6ef888 |
#ifndef _FSCK_H
|
|
Packit |
6ef888 |
#define _FSCK_H
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
#include "libgfs2.h"
|
|
Packit |
6ef888 |
#include "osi_tree.h"
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
#define FSCK_HASH_SHIFT (13)
|
|
Packit |
6ef888 |
#define FSCK_HASH_SIZE (1 << FSCK_HASH_SHIFT)
|
|
Packit |
6ef888 |
#define FSCK_HASH_MASK (FSCK_HASH_SIZE - 1)
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
#define query(fmt, args...) fsck_query(fmt, ##args)
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/*
|
|
Packit |
6ef888 |
* Exit codes used by fsck-type programs
|
|
Packit |
6ef888 |
* Copied from e2fsck's e2fsck.h
|
|
Packit |
6ef888 |
*/
|
|
Packit |
6ef888 |
#define FSCK_OK 0 /* No errors */
|
|
Packit |
6ef888 |
#define FSCK_NONDESTRUCT 1 /* File system errors corrected */
|
|
Packit |
6ef888 |
#define FSCK_REBOOT 2 /* System should be rebooted */
|
|
Packit |
6ef888 |
#define FSCK_UNCORRECTED 4 /* File system errors left uncorrected */
|
|
Packit |
6ef888 |
#define FSCK_ERROR 8 /* Operational error */
|
|
Packit |
6ef888 |
#define FSCK_USAGE 16 /* Usage or syntax error */
|
|
Packit |
6ef888 |
#define FSCK_CANCELED 32 /* Aborted with a signal or ^C */
|
|
Packit |
6ef888 |
#define FSCK_LIBRARY 128 /* Shared library error */
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
#define BAD_POINTER_TOLERANCE 10 /* How many bad pointers is too many? */
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
struct gfs2_bmap {
|
|
Packit |
6ef888 |
uint64_t size;
|
|
Packit |
6ef888 |
uint64_t mapsize;
|
|
Packit |
6ef888 |
unsigned char *map;
|
|
Packit |
6ef888 |
};
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
struct inode_info
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
struct osi_node node;
|
|
Packit |
6ef888 |
struct gfs2_inum di_num;
|
|
Packit |
6ef888 |
uint32_t di_nlink; /* the number of links the inode
|
|
Packit |
6ef888 |
* thinks it has */
|
|
Packit |
6ef888 |
uint32_t counted_links; /* the number of links we've found */
|
|
Packit |
6ef888 |
};
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
struct dir_info
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
struct osi_node node;
|
|
Packit |
6ef888 |
struct gfs2_inum dinode;
|
|
Packit |
6ef888 |
uint64_t treewalk_parent;
|
|
Packit |
6ef888 |
struct gfs2_inum dotdot_parent;
|
|
Packit |
6ef888 |
uint32_t di_nlink;
|
|
Packit |
6ef888 |
uint32_t counted_links;
|
|
Packit |
6ef888 |
uint8_t checked:1;
|
|
Packit |
6ef888 |
};
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
struct dir_status {
|
|
Packit |
6ef888 |
uint8_t dotdir:1;
|
|
Packit |
6ef888 |
uint8_t dotdotdir:1;
|
|
Packit |
6ef888 |
int q;
|
|
Packit |
6ef888 |
uint32_t entry_count;
|
|
Packit |
6ef888 |
};
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
#define DUPFLAG_REF1_FOUND 1 /* Has the original reference been found? */
|
|
Packit |
6ef888 |
#define DUPFLAG_REF1_IS_DUPL 2 /* The original reference is also where we
|
|
Packit |
6ef888 |
determined there was a duplicate. */
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
struct duptree {
|
|
Packit |
6ef888 |
struct osi_node node;
|
|
Packit |
6ef888 |
int dup_flags;
|
|
Packit |
6ef888 |
int refs;
|
|
Packit |
6ef888 |
uint64_t block;
|
|
Packit |
6ef888 |
osi_list_t ref_inode_list; /* list of inodes referencing a dup block */
|
|
Packit |
6ef888 |
osi_list_t ref_invinode_list; /* list of invalid inodes referencing */
|
|
Packit |
6ef888 |
};
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
enum dup_ref_type {
|
|
Packit |
6ef888 |
ref_as_data = 0, /* dinode references this block as a data block */
|
|
Packit |
6ef888 |
ref_as_meta = 1, /* dinode references this block as a metadata block */
|
|
Packit |
6ef888 |
ref_as_ea = 2, /* dinode references this block as an extended attr */
|
|
Packit |
6ef888 |
ref_is_inode= 3, /* The reference is itself a dinode. In other words,
|
|
Packit |
6ef888 |
it's a dinode, not pointed to as data or
|
|
Packit |
6ef888 |
metadata */
|
|
Packit |
6ef888 |
ref_types = 4,
|
|
Packit |
6ef888 |
};
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
struct inode_with_dups {
|
|
Packit |
6ef888 |
osi_list_t list;
|
|
Packit |
6ef888 |
uint64_t block_no;
|
|
Packit |
6ef888 |
int dup_count;
|
|
Packit |
6ef888 |
int reftypecount[ref_types];
|
|
Packit |
6ef888 |
uint64_t parent;
|
|
Packit |
6ef888 |
char *name;
|
|
Packit |
6ef888 |
};
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
enum rgindex_trust_level { /* how far can we trust our RG index? */
|
|
Packit |
6ef888 |
blind_faith = 0, /* We'd like to trust the rgindex. We always used to
|
|
Packit |
6ef888 |
before bz 179069. This should cover most cases. */
|
|
Packit |
6ef888 |
ye_of_little_faith = 1, /* The rindex seems trustworthy but there's
|
|
Packit |
6ef888 |
rg damage that need to be fixed. */
|
|
Packit |
6ef888 |
open_minded = 2, /* At least 1 RG is corrupt. Try to calculate what it
|
|
Packit |
6ef888 |
should be, in a perfect world where our RGs are all
|
|
Packit |
6ef888 |
on even boundaries. Blue sky. Chirping birds. */
|
|
Packit |
6ef888 |
distrust = 3, /* The world isn't perfect, our RGs are not on nice neat
|
|
Packit |
6ef888 |
boundaries. The fs must have been messed with by
|
|
Packit |
6ef888 |
gfs2_grow or something. Count the RGs by hand. */
|
|
Packit |
6ef888 |
indignation = 4 /* Not only do we have corruption, but the rgrps
|
|
Packit |
6ef888 |
aren't on even boundaries, so this file system
|
|
Packit |
6ef888 |
must have been converted from gfs2_convert. */
|
|
Packit |
6ef888 |
};
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
struct error_block {
|
|
Packit |
6ef888 |
uint64_t metablk; /* metadata block where error was found */
|
|
Packit |
6ef888 |
int metaoff; /* offset in that metadata block where error found */
|
|
Packit |
6ef888 |
uint64_t errblk; /* error block */
|
|
Packit |
6ef888 |
};
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
extern struct gfs2_inode *fsck_load_inode(struct gfs2_sbd *sdp, uint64_t block);
|
|
Packit |
6ef888 |
extern struct gfs2_inode *fsck_inode_get(struct gfs2_sbd *sdp,
|
|
Packit |
6ef888 |
struct rgrp_tree *rgd,
|
|
Packit |
6ef888 |
struct gfs2_buffer_head *bh);
|
|
Packit |
6ef888 |
extern void fsck_inode_put(struct gfs2_inode **ip);
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
extern int initialize(struct gfs2_sbd *sdp, int force_check, int preen,
|
|
Packit |
6ef888 |
int *all_clean);
|
|
Packit |
6ef888 |
extern void destroy(struct gfs2_sbd *sdp);
|
|
Packit |
6ef888 |
extern int pass1(struct gfs2_sbd *sdp);
|
|
Packit |
6ef888 |
extern int pass1b(struct gfs2_sbd *sdp);
|
|
Packit |
6ef888 |
extern int pass1c(struct gfs2_sbd *sdp);
|
|
Packit |
6ef888 |
extern int pass2(struct gfs2_sbd *sdp);
|
|
Packit |
6ef888 |
extern int pass3(struct gfs2_sbd *sdp);
|
|
Packit |
6ef888 |
extern int pass4(struct gfs2_sbd *sdp);
|
|
Packit |
6ef888 |
extern int pass5(struct gfs2_sbd *sdp, struct gfs2_bmap *bl);
|
|
Packit |
6ef888 |
extern int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count,
|
|
Packit |
6ef888 |
int *sane);
|
|
Packit |
6ef888 |
extern int fsck_query(const char *format, ...)
|
|
Packit |
6ef888 |
__attribute__((format(printf,1,2)));
|
|
Packit |
6ef888 |
extern struct dir_info *dirtree_find(uint64_t block);
|
|
Packit |
6ef888 |
extern void dup_delete(struct duptree *dt);
|
|
Packit |
6ef888 |
extern void dirtree_delete(struct dir_info *b);
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* FIXME: Hack to get this going for pass2 - this should be pulled out
|
|
Packit |
6ef888 |
* of pass1 and put somewhere else... */
|
|
Packit |
6ef888 |
struct dir_info *dirtree_insert(struct gfs2_inum inum);
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
struct gfs2_options {
|
|
Packit |
6ef888 |
char *device;
|
|
Packit |
6ef888 |
unsigned int yes:1;
|
|
Packit |
6ef888 |
unsigned int no:1;
|
|
Packit |
6ef888 |
unsigned int query:1;
|
|
Packit |
6ef888 |
};
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
extern struct gfs2_options opts;
|
|
Packit |
6ef888 |
extern struct gfs2_inode *lf_dip; /* Lost and found directory inode */
|
|
Packit |
6ef888 |
extern int lf_was_created;
|
|
Packit |
6ef888 |
extern uint64_t last_fs_block, last_reported_block;
|
|
Packit |
6ef888 |
extern int64_t last_reported_fblock;
|
|
Packit |
6ef888 |
extern int skip_this_pass, fsck_abort;
|
|
Packit |
6ef888 |
extern int errors_found, errors_corrected;
|
|
Packit |
6ef888 |
extern uint64_t last_data_block;
|
|
Packit |
6ef888 |
extern uint64_t first_data_block;
|
|
Packit |
6ef888 |
extern struct osi_root dup_blocks;
|
|
Packit |
6ef888 |
extern struct osi_root dirtree;
|
|
Packit |
6ef888 |
extern struct osi_root inodetree;
|
|
Packit |
6ef888 |
extern int dups_found; /* How many duplicate references have we found? */
|
|
Packit |
6ef888 |
extern int dups_found_first; /* How many duplicates have we found the original
|
|
Packit |
6ef888 |
reference for? */
|
|
Packit |
6ef888 |
extern struct gfs_sb *sbd1;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
static inline int valid_block(struct gfs2_sbd *sdp, uint64_t blkno)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
return !((blkno > sdp->fssize) || (blkno <= LGFS2_SB_ADDR(sdp)) ||
|
|
Packit |
6ef888 |
(lgfs2_get_bitmap(sdp, blkno, NULL) < 0));
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
static inline int rgrp_contains_block(struct rgrp_tree *rgd, uint64_t blk)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
if (blk < rgd->ri.ri_addr)
|
|
Packit |
6ef888 |
return 0;
|
|
Packit |
6ef888 |
if (blk >= rgd->ri.ri_data0 + rgd->ri.ri_data)
|
|
Packit |
6ef888 |
return 0;
|
|
Packit |
6ef888 |
return 1;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
static inline int valid_block_ip(struct gfs2_inode *ip, uint64_t blk)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
struct gfs2_sbd *sdp = ip->i_sbd;
|
|
Packit |
6ef888 |
struct rgrp_tree *rgd = ip->i_rgd;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (blk > sdp->fssize)
|
|
Packit |
6ef888 |
return 0;
|
|
Packit |
6ef888 |
if (blk <= LGFS2_SB_ADDR(sdp))
|
|
Packit |
6ef888 |
return 0;
|
|
Packit |
6ef888 |
if (rgd == NULL || !rgrp_contains_block(rgd, blk)) {
|
|
Packit |
6ef888 |
rgd = gfs2_blk2rgrpd(sdp, blk);
|
|
Packit |
6ef888 |
if (rgd == NULL)
|
|
Packit |
6ef888 |
return 0;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
return rgrp_contains_block(rgd, blk);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
#endif /* _FSCK_H */
|