Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F3154407
pass1c.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
pass1c.c
View Options
#include "fsck.h"
#include "fsck_incore.h"
#include "bio.h"
#include "inode.h"
#include "util.h"
#include "block_list.h"
#include "metawalk.h"
static int remove_eattr_entry(struct fsck_sb *sdp, osi_buf_t *leaf_bh,
struct gfs_ea_header *curr,
struct gfs_ea_header *prev)
{
log_warn("Removing EA located in block #%"PRIu64".\n",
BH_BLKNO(leaf_bh));
if(!prev){
curr->ea_type = GFS_EATYPE_UNUSED;
} else {
prev->ea_rec_len =
cpu_to_gfs32(gfs32_to_cpu(curr->ea_rec_len) +
gfs32_to_cpu(prev->ea_rec_len));
if (curr->ea_flags & GFS_EAFLAG_LAST)
prev->ea_flags |= GFS_EAFLAG_LAST;
}
if(write_buf(sdp, leaf_bh, 0)){
stack;
log_err("EA removal failed.\n");
return -1;
}
return 0;
}
int check_eattr_indir(struct fsck_inode *ip, uint64_t block,
uint64_t parent, osi_buf_t **bh,
void *private)
{
int *update = (int *) private;
struct fsck_sb *sbp = ip->i_sbd;
struct block_query q;
osi_buf_t *indir_bh;
if(check_range(sbp, block)) {
log_err("Extended attributes indirect block out of range...removing\n");
ip->i_di.di_eattr = 0;
*update = 1;
return 1;
}
else if (block_check(sbp->bl, block, &q)) {
stack;
return -1;
}
else if(q.block_type != indir_blk) {
log_err("Extended attributes indirect block invalid...removing\n");
ip->i_di.di_eattr = 0;
*update = 1;
return 1;
}
else if(get_and_read_buf(sbp, block, &indir_bh, 0)){
log_warn("Unable to read EA leaf block #%"PRIu64".\n",
block);
ip->i_di.di_eattr = 0;
*update = 1;
return 1;
}
*bh = indir_bh;
return 0;
}
int check_eattr_leaf(struct fsck_inode *ip, uint64_t block,
uint64_t parent, osi_buf_t **bh, void *private)
{
int *update = (int *) private;
struct fsck_sb *sbp = ip->i_sbd;
struct block_query q;
osi_buf_t *leaf_bh;
if(check_range(sbp, block)) {
log_err("Extended attributes block out of range...removing\n");
ip->i_di.di_eattr = 0;
*update = 1;
return 1;
}
else if (block_check(sbp->bl, block, &q)) {
stack;
return -1;
}
else if(q.block_type != meta_eattr) {
log_err("Extended attributes block invalid...removing\n");
ip->i_di.di_eattr = 0;
*update = 1;
return 1;
}
else if(get_and_read_buf(sbp, block, &leaf_bh, 0)){
log_warn("Unable to read EA leaf block #%"PRIu64".\n",
block);
ip->i_di.di_eattr = 0;
*update = 1;
return 1;
}
*bh = leaf_bh;
return 0;
}
static int check_eattr_entry(struct fsck_inode *ip,
osi_buf_t *leaf_bh,
struct gfs_ea_header *ea_hdr,
struct gfs_ea_header *ea_hdr_prev,
void *private)
{
struct fsck_sb *sdp = ip->i_sbd;
char ea_name[256];
uint32_t offset = (uint32_t)(((unsigned long)ea_hdr) -
((unsigned long)BH_DATA(leaf_bh)));
uint32_t max_size = sdp->sb.sb_bsize;
if(!ea_hdr->ea_rec_len){
log_err("EA has rec length == 0\n");
ea_hdr->ea_flags |= GFS_EAFLAG_LAST;
ea_hdr->ea_rec_len = cpu_to_gfs32(max_size - offset);
if(remove_eattr_entry(sdp, leaf_bh, ea_hdr, ea_hdr_prev)){
stack;
return -1;
}
return 1;
}
if(offset + gfs32_to_cpu(ea_hdr->ea_rec_len) > max_size){
log_err("EA rec length too long\n");
ea_hdr->ea_flags |= GFS_EAFLAG_LAST;
ea_hdr->ea_rec_len = cpu_to_gfs32(max_size - offset);
if(remove_eattr_entry(sdp, leaf_bh, ea_hdr, ea_hdr_prev)){
stack;
return -1;
}
return 1;
}
if(offset + gfs32_to_cpu(ea_hdr->ea_rec_len) == max_size &&
(ea_hdr->ea_flags & GFS_EAFLAG_LAST) == 0){
log_err("last EA has no last entry flag\n");
ea_hdr->ea_flags |= GFS_EAFLAG_LAST;
if(remove_eattr_entry(sdp, leaf_bh, ea_hdr, ea_hdr_prev)){
stack;
return -1;
}
return 1;
}
if(!ea_hdr->ea_name_len){
log_err("EA has name length == 0\n");
if(remove_eattr_entry(sdp, leaf_bh, ea_hdr, ea_hdr_prev)){
stack;
return -1;
}
return 1;
}
memset(ea_name, 0, sizeof(ea_name));
strncpy(ea_name, (char *)ea_hdr + sizeof(struct gfs_ea_header),
ea_hdr->ea_name_len);
if(!GFS_EATYPE_VALID(ea_hdr->ea_type) &&
((ea_hdr_prev) || (!ea_hdr_prev && ea_hdr->ea_type))){
log_err("EA (%s) type is invalid (%d > %d).\n",
ea_name, ea_hdr->ea_type, GFS_EATYPE_LAST);
if(remove_eattr_entry(sdp, leaf_bh, ea_hdr, ea_hdr_prev)){
stack;
return -1;
}
return 1;
}
if(ea_hdr->ea_num_ptrs){
uint32 avail_size;
int max_ptrs;
avail_size = sdp->sb.sb_bsize - sizeof(struct gfs_meta_header);
max_ptrs = (gfs32_to_cpu(ea_hdr->ea_data_len)+avail_size-1)/avail_size;
if(max_ptrs > ea_hdr->ea_num_ptrs){
log_err("EA (%s) has incorrect number of pointers.\n", ea_name);
log_err(" Required: %d\n"
" Reported: %d\n",
max_ptrs, ea_hdr->ea_num_ptrs);
if(remove_eattr_entry(sdp, leaf_bh, ea_hdr, ea_hdr_prev)){
stack;
return -1;
}
return 1;
} else {
log_debug(" Pointers Required: %d\n"
" Pointers Reported: %d\n",
max_ptrs,
ea_hdr->ea_num_ptrs);
}
}
return 0;
}
int check_eattr_extentry(struct fsck_inode *ip, uint64_t *ea_ptr,
osi_buf_t *leaf_bh,
struct gfs_ea_header *ea_hdr,
struct gfs_ea_header *ea_hdr_prev,
void *private)
{
struct block_query q;
struct fsck_sb *sbp = ip->i_sbd;
if(block_check(sbp->bl, gfs64_to_cpu(*ea_ptr), &q)) {
stack;
return -1;
}
if(q.block_type != meta_eattr) {
if(remove_eattr_entry(sbp, leaf_bh, ea_hdr, ea_hdr_prev)){
stack;
return -1;
}
return 1;
}
return 0;
}
/* Go over all inodes with extended attributes and verify the EAs are
* valid */
int pass1c(struct fsck_sb *sbp)
{
uint64_t block_no = 0;
osi_buf_t *bh;
struct fsck_inode *ip = NULL;
int update = 0;
struct metawalk_fxns pass1c_fxns = { 0 };
int error = 0;
pass1c_fxns.check_eattr_indir = &check_eattr_indir;
pass1c_fxns.check_eattr_leaf = &check_eattr_leaf;
pass1c_fxns.check_eattr_entry = &check_eattr_entry;
pass1c_fxns.check_eattr_extentry = &check_eattr_extentry;
pass1c_fxns.private = (void *) &update;
log_info("Looking for inodes containing ea blocks...\n");
while (!find_next_block_type(sbp->bl, eattr_block, &block_no)) {
if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
return 0;
log_info("EA in inode %"PRIu64"\n", block_no);
if(get_and_read_buf(sbp, block_no, &bh, 0)) {
stack;
return -1;
}
if(copyin_inode(sbp, bh, &ip)) {
stack;
return -1;
}
log_debug("Found eattr at %"PRIu64"\n", ip->i_di.di_eattr);
/* FIXME: Handle walking the eattr here */
error = check_inode_eattr(ip, &pass1c_fxns);
if(error < 0) {
stack;
return -1;
}
if(update) {
gfs_dinode_out(&ip->i_di, BH_DATA(bh));
write_buf(sbp, bh, 0);
}
free_inode(&ip);
relse_buf(sbp, bh);
block_no++;
}
return 0;
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Wed, Feb 26, 1:04 PM (20 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1465369
Default Alt Text
pass1c.c (6 KB)
Attached To
Mode
rF Fence Agents
Attached
Detach File
Event Timeline
Log In to Comment