示例#1
0
/******************************************************************
 * NAME: 	OpenFilSys
 *
 * FUNCTION: 	Read the superblock into a buffer.  
 *		Extract various pieces of information.
 *		Release the buffer.
 *
 * PARAMETERS:	none
 *
 * NOTES:
 *
 * RETURNS:
 *      success: 0
 *      failure: something else
 */
int32 OpenFilSys( void )
{
	int32			rc;
	struct superblock	*sb;
	buf_t			*bp;

	/*
	 *	validate and retrieve fs parameters from superblock
	 */
	/* try to read the primary superblock */
	rc = bRawRead(LVHandle, (int64)SUPER1_OFF, (int32)PAGESIZE, &bp);
	if (rc != 0)  {
		/* try to read the secondary superblock */
		rc = bRawRead(LVHandle, (int64)SUPER2_OFF, (int32)PAGESIZE, &bp);
		if (rc != 0)  {
#ifdef _JFS_DEBUG
	printf("OpenFilSys: i/o error: rc=%d\n", rc);
#endif
			return CBBL_CANTREADSBLKS;
			}
		}

	sb = (struct superblock *)bp->b_data;

	/* check magic/version number */
	if (strncmp(sb->s_magic,JFS_MAGIC,(unsigned)strlen(JFS_MAGIC))
	 || (sb->s_version != JFS_VERSION))  {
		return CBBL_INVALMAGORVERS;
		}

	if (sb->s_state & FM_DIRTY)  {
		return CBBL_FSDIRTY;
		}

	fsMount->bsize = sb->s_bsize;
	fsMount->l2bsize = sb->s_l2bsize;
	fsMount->l2bfactor = sb->s_l2bfactor;
	fsMount->nbperpage = PAGESIZE >> fsMount->l2bsize;
	fsMount->l2nbperpage = log2shift(fsMount->nbperpage);

	fsMount->FSSize = sb->s_size >> sb->s_l2bfactor;
	
	fsMount->AGSize = sb->s_agsize;
#ifdef _JFS_DEBUG
	printf("superblock: attribute:0x%08x state:0x%08x\n",
		 sb->s_flag, sb->s_state);
	printf("superblock: bsize:%d FSSize:%lld\n",
		fsMount->bsize, fsMount->FSSize);
#endif
	agg_recptr->fs_blksize = sb->s_bsize;	/* aggregate block size */
	agg_recptr->lv_blksize = sb->s_pbsize;	/* device block size	*/
	agg_recptr->fs_lv_ratio = sb->s_bsize / sb->s_pbsize;
	agg_recptr->fs_last_metablk = addressPXD( &sb->s_aim2 ) +
					lengthPXD( &sb->s_aim2);  
	agg_recptr->fs_first_wspblk = addressPXD( &sb->s_fsckpxd );

	bRelease(bp);

	return rc;
}						/* end OpenFilSys() */
示例#2
0
文件: file.c 项目: Abioy/kasan
static int jfs_open(struct inode *inode, struct file *file)
{
	int rc;

	if ((rc = dquot_file_open(inode, file)))
		return rc;

	/*
	 * We attempt to allow only one "active" file open per aggregate
	 * group.  Otherwise, appending to files in parallel can cause
	 * fragmentation within the files.
	 *
	 * If the file is empty, it was probably just created and going
	 * to be written to.  If it has a size, we'll hold off until the
	 * file is actually grown.
	 */
	if (S_ISREG(inode->i_mode) && file->f_mode & FMODE_WRITE &&
	    (inode->i_size == 0)) {
		struct jfs_inode_info *ji = JFS_IP(inode);
		spin_lock_irq(&ji->ag_lock);
		if (ji->active_ag == -1) {
			struct jfs_sb_info *jfs_sb = JFS_SBI(inode->i_sb);
			ji->active_ag = BLKTOAG(addressPXD(&ji->ixpxd), jfs_sb);
			atomic_inc( &jfs_sb->bmap->db_active[ji->active_ag]);
		}
		spin_unlock_irq(&ji->ag_lock);
	}

	return 0;
}
示例#3
0
void display_xtpage(xtpage_t *xtree)
{

        char            flag_names[64];


        *flag_names = 0;
        if (xtree->header.flag & BT_ROOT)
                strcat(flag_names, "BT_ROOT  ");
        if (xtree->header.flag & BT_LEAF)
                strcat(flag_names, "BT_LEAF  ");
        if (xtree->header.flag & BT_INTERNAL)
                strcat(flag_names, "BT_INTERNAL  ");
        if (xtree->header.flag & BT_RIGHTMOST)
                strcat(flag_names, "BT_RIGHTMOST  ");
        if (xtree->header.flag & BT_LEFTMOST)
                strcat(flag_names, "BT_LEFTMOST  ");

        printf("[1] flag\t0x%02x\t%s\n", xtree->header.flag, flag_names);
        printf("[2] nextindex\t%d\t\t", xtree->header.nextindex);
        printf("[5] self.addr1\t0x%02x\n", xtree->header.self.addr1);
        printf("[3] maxentry\t%d\t\t", xtree->header.maxentry);
        printf("[6] self.addr2\t0x%08x\n", xtree->header.self.addr2);
        printf("[4] self.len\t0x%06x\t", xtree->header.self.len);
        printf("    self.addr\t%lld\n", addressPXD(&xtree->header.self));
}  /* end display_xtpage */
int sba_jfs_find_journal_entries(void)
{
	char *data;
	
	if ((data = read_block(JFS_SUPER)) != NULL) {
		int i;

		struct jfs_superblock *jfs_sb = (struct jfs_superblock *)data;
		sba_debug(1, "magic number = %s\n", jfs_sb->s_magic);
		sba_debug(1, "block size = %d\n", jfs_sb->s_bsize);

		jfs_jour_start = addressPXD(&jfs_sb->s_logpxd);
		jfs_jour_size = lengthPXD(&jfs_sb->s_logpxd);

		sba_debug(1, "log address = %d\n", jfs_jour_start);
		sba_debug(1, "log size = %d\n", jfs_jour_size);

		for (i = 0; i < jfs_jour_size; i ++) {
			ht_add(h_sba_jfs_journal, i+jfs_jour_start);
		}

		sba_debug(1, "Added log blocks from %d to %d\n", jfs_jour_start, jfs_jour_start + jfs_jour_size - 1);
		free_page((int)data);
	}

	return 1;
}
示例#5
0
void walk_dtree( int	device,
		 uint64	block,
		 uint32	length,
		 int64	*total_nblocks)
{
    int	rc;
    dtpage_t	dtree_buffer;
    uint8	*stbl;
    idtentry_t	*cur_entry;
    uint64	first_block, cur_block, last_block;
    uint32	cur_length;
    int32	lastindex, index;
    int32	thisindex;

    /*
     * Read the page from disk
     */
    rc = ujfs_rw_diskblocks( device, block << sb.s_l2bsize,
		length << sb.s_l2bsize, &dtree_buffer, GET );

    if( dtree_buffer.header.flag & BT_LEAF ) {
	/*
	 * Nothing to do, since the data here is not pointing to blocks
	 */
	return;
    }

    /*
     * Mark blocks for each entry and visit that page
     */
    lastindex = dtree_buffer.header.nextindex;
    stbl = (uint8 *)&(dtree_buffer.slot[dtree_buffer.header.stblindex]);
    for( index = 0; index < lastindex; index++ ) {
	/*
	 * This is an internal page of the d-tree.  Mark these blocks and
	 * then walk that page
	 */
	thisindex = stbl[index];
	cur_entry = (idtentry_t *)&(dtree_buffer.slot[thisindex]);
	first_block = addressPXD( &(cur_entry->xd) );
	cur_length = lengthPXD( &(cur_entry->xd) );
	*total_nblocks += cur_length;
	last_block = first_block + cur_length;
	for( cur_block = first_block; cur_block < last_block; cur_block++ ) {
	    markit( cur_block, 0 );
	}

	walk_dtree( device, first_block, cur_length, total_nblocks);
    }
}
示例#6
0
char display_internal_slots(
dtslot_t        *slot,
int8            *stbl,
int8            nextindex,
int32           *changed)
{
        int32           i;
        idtentry_t      *entry;
        int64           node_address;
        char            result;
        int32           slot_number;

        for (i = 0; i < nextindex; i++) {
                slot_number = stbl[i];
                entry = (idtentry_t *)&(slot[slot_number]);
                node_address = addressPXD(&(entry->xd));

                printf("stbl[%d] = %d\n", i, slot_number);
                printf("[1] xd.len\t    0x%06x\t\t", entry->xd.len);
                printf("[4] next\t%d\n", entry->next);
                printf("[2] xd.addr1\t  0x%02x\t\t\t", entry->xd.addr1);
                printf("[5] namlen\t%d\n", entry->namlen);
                printf("[3] xd.addr2\t  0x%08x\t\t", entry->xd.addr2);
                printf("     xd.addr\t%lld\n", node_address);
#ifdef  _JFS_UNICODE
                printf("[6] name\t%.11ls\n", entry->name);
#else
                printf("[6] name\t%.22s\n", entry->name);
#endif
                printf("addressPXD(xd)\t%lld\n", node_address);

                result = prompt("dtree: press enter for next or [u]p, [d]own or e[x]it > ");
                if (result == 'x' || result == 'u' )
                        return result;
                else if (result != 'd' && entry->next >= 0) {
                        result = display_slot(slot, entry->next, 0, changed);
                        if (result == 'x' || result == 'u' )
                                return result;
                }
                if (result == 'd')
                        /* descend to the child node */
                        return(display_extent_page(node_address));
        }
        return result;
}
示例#7
0
void walk_dir(	int	device,
		dtroot_t	*root_header,
		int64	*total_nblocks)
{
    int32	index, lastindex;
    uint64	first_block, cur_block, last_block;
    idtentry_t	*cur_entry;	
    uint32	length;

    if( root_header->header.flag & BT_LEAF ) {
	/*
	 * Nothing to do, since the data here is not pointing to blocks
	 */
	return;
    }

    /*
     * Have root of directory inode btree.
     * Walk tree marking all blocks allocated.
     */
    lastindex = root_header->header.nextindex;
    for( index = 0; index < lastindex; index++ ) {
	/*
	 * This is an internal page of the d-tree.  Mark these blocks and
	 * then walk that page
	 */
	cur_entry =
	    (idtentry_t *)&(root_header->slot[root_header->header.stbl[index]]);
	first_block = addressPXD( &(cur_entry->xd) );
	length = lengthPXD( &(cur_entry->xd) );
	*total_nblocks += length;
	last_block = first_block + length;
	for( cur_block = first_block; cur_block < last_block; cur_block++ ) {
	    markit( cur_block, 0 );
	}

	walk_dtree( device, first_block, length, total_nblocks);
    }
}
示例#8
0
/*
 *	chkSuper()
 *
 * validate the superblock of the file system to be mounted and 
 * get the file system parameters.
 *
 * returns
 *	0 with fragsize set if check successful
 *	error code if not successful
 */
static int chkSuper(struct super_block *sb)
{
	int rc = 0;
	struct jfs_sb_info *sbi = JFS_SBI(sb);
	struct jfs_superblock *j_sb;
	struct buffer_head *bh;
	int AIM_bytesize, AIT_bytesize;
	int expected_AIM_bytesize, expected_AIT_bytesize;
	s64 AIM_byte_addr, AIT_byte_addr, fsckwsp_addr;
	s64 byte_addr_diff0, byte_addr_diff1;
	s32 bsize;

	if ((rc = readSuper(sb, &bh)))
		return rc;
	j_sb = (struct jfs_superblock *)bh->b_data;

	/*
	 * validate superblock
	 */
	/* validate fs signature */
	if (strncmp(j_sb->s_magic, JFS_MAGIC, 4) ||
	    le32_to_cpu(j_sb->s_version) > JFS_VERSION) {
		rc = -EINVAL;
		goto out;
	}

	bsize = le32_to_cpu(j_sb->s_bsize);
#ifdef _JFS_4K
	if (bsize != PSIZE) {
		jfs_err("Currently only 4K block size supported!");
		rc = -EINVAL;
		goto out;
	}
#endif				/* _JFS_4K */

	jfs_info("superblock: flag:0x%08x state:0x%08x size:0x%Lx",
		 le32_to_cpu(j_sb->s_flag), le32_to_cpu(j_sb->s_state),
		 (unsigned long long) le64_to_cpu(j_sb->s_size));

	/* validate the descriptors for Secondary AIM and AIT */
	if ((j_sb->s_flag & cpu_to_le32(JFS_BAD_SAIT)) !=
	    cpu_to_le32(JFS_BAD_SAIT)) {
		expected_AIM_bytesize = 2 * PSIZE;
		AIM_bytesize = lengthPXD(&(j_sb->s_aim2)) * bsize;
		expected_AIT_bytesize = 4 * PSIZE;
		AIT_bytesize = lengthPXD(&(j_sb->s_ait2)) * bsize;
		AIM_byte_addr = addressPXD(&(j_sb->s_aim2)) * bsize;
		AIT_byte_addr = addressPXD(&(j_sb->s_ait2)) * bsize;
		byte_addr_diff0 = AIT_byte_addr - AIM_byte_addr;
		fsckwsp_addr = addressPXD(&(j_sb->s_fsckpxd)) * bsize;
		byte_addr_diff1 = fsckwsp_addr - AIT_byte_addr;
		if ((AIM_bytesize != expected_AIM_bytesize) ||
		    (AIT_bytesize != expected_AIT_bytesize) ||
		    (byte_addr_diff0 != AIM_bytesize) ||
		    (byte_addr_diff1 <= AIT_bytesize))
			j_sb->s_flag |= cpu_to_le32(JFS_BAD_SAIT);
	}

	if ((j_sb->s_flag & cpu_to_le32(JFS_GROUPCOMMIT)) !=
	    cpu_to_le32(JFS_GROUPCOMMIT))
		j_sb->s_flag |= cpu_to_le32(JFS_GROUPCOMMIT);

	/* validate fs state */
	if (j_sb->s_state != cpu_to_le32(FM_CLEAN) &&
	    !(sb->s_flags & MS_RDONLY)) {
		jfs_err("jfs_mount: Mount Failure: File System Dirty.");
		rc = -EINVAL;
		goto out;
	}

	sbi->state = le32_to_cpu(j_sb->s_state);
	sbi->mntflag = le32_to_cpu(j_sb->s_flag);

	/*
	 * JFS always does I/O by 4K pages.  Don't tell the buffer cache
	 * that we use anything else (leave s_blocksize alone).
	 */
	sbi->bsize = bsize;
	sbi->l2bsize = le16_to_cpu(j_sb->s_l2bsize);

	/*
	 * For now, ignore s_pbsize, l2bfactor.  All I/O going through buffer
	 * cache.
	 */
	sbi->nbperpage = PSIZE >> sbi->l2bsize;
	sbi->l2nbperpage = L2PSIZE - sbi->l2bsize;
	sbi->l2niperblk = sbi->l2bsize - L2DISIZE;
	if (sbi->mntflag & JFS_INLINELOG)
		sbi->logpxd = j_sb->s_logpxd;
	else {
		sbi->logdev = new_decode_dev(le32_to_cpu(j_sb->s_logdev));
		memcpy(sbi->uuid, j_sb->s_uuid, sizeof(sbi->uuid));
		memcpy(sbi->loguuid, j_sb->s_loguuid, sizeof(sbi->uuid));
	}
	sbi->fsckpxd = j_sb->s_fsckpxd;
	sbi->ait2 = j_sb->s_ait2;

      out:
	brelse(bh);
	return rc;
}
示例#9
0
void directory()
{
        char            cmd_line[80];
        dtpage_t        dtree;
        int32           i;
        dinode_t        inode;
        int64           inode_address;
        ino_t           inum;
        int64           node_address;
        idtentry_t      *node_entry;
        dtroot_t        *root;
        dtslot_t        *slot;
        uint8           *stbl;
        char            *token;
        ino_t           which_table = FILESYSTEM_I;

        token = strtok(0, "     ");
        if (token == 0) {
                fputs("directory: Please enter: inum [fileset]\ndirectory> ",
                        stdout);
                gets(cmd_line);
                token=strtok(cmd_line, "        ");
                if (token == 0)
                        return;
        }
        errno = 0;
        inum = strtoul(token, 0, 0);
        if (inum == 0 && errno) {
                fputs("directory: invalid inum\n\n", stderr);
                return;
        }
        token = strtok(0, "     ");
        if (token) {
                if (token[0] != '0') {
                        fputs("directory: invalid fileset\n\n", stderr);
                        return;
                }
        }
        if (strtok(0, "         ")) {
                fputs("directory: Too many arguments\n\n", stderr);
                return;
        }

        if (find_inode(inum, which_table, &inode_address) ||
            xRead(inode_address, sizeof(dinode_t), (char *)&inode)) {
                fputs("directory: error reading inode\n\n", stderr);
                return;
        }
        if ((inode.di_mode & IFMT) != IFDIR) {
                fputs("directory: Not a directory!\n", stderr);
                return;
        }

        root = (dtroot_t *)&(inode.di_btroot);
        printf("idotdot = %d\n\n", root->header.idotdot);

        if (root->header.flag & BT_LEAF) {
                if (root->header.nextindex == 0) {
                        fputs("Empty directory.\n", stdout);
                        return;
                }

                for (i = 0; i < root->header.nextindex; i++) {
                        print_direntry(root->slot, root->header.stbl[i]);
                }
                return;
        }

        /* Root is not a leaf node, we must descend to the leftmost leaf */

        node_entry = (idtentry_t *)&(root->slot[root->header.stbl[0]]);
descend:
        node_address = addressPXD(&(node_entry->xd)) << l2bsize;
        if (xRead(node_address, sizeof(dtpage_t), (char *)&dtree)) {
                fputs("Directory:  Error reading dtree node\n", stderr);
                return;
        }
        stbl = (uint8 *)&(dtree.slot[dtree.header.stblindex]);
        if (!(dtree.header.flag & BT_LEAF)) {
                node_entry = (idtentry_t *)&(dtree.slot[stbl[0]]);
                goto descend;
        }

        /* dtree (contained in node) is the left-most leaf node */

next_leaf:
        for (i = 0; i < dtree.header.nextindex; i++) {
                print_direntry(dtree.slot, stbl[i]);
        }
        if (dtree.header.next) {
                if (xRead(dtree.header.next << l2bsize, sizeof(dtpage_t),
                          (char *)&dtree)) {
                        fputs("directory: Error reading leaf node\n", stderr);
                        return;
                }
                stbl = (uint8 *)&(dtree.slot[dtree.header.stblindex]);
                goto next_leaf;
        }
        return;
}
示例#10
0
int32 display_super2( struct superblock *sb)
{
	char	*aix_platform;
	char	*os2_platform;
	char	cmdline[512];
	int32	field;
	char	*dir_posix;
	char	*dir_unicode;
	int32	rc = XPEEK_OK;
	char	*state;
	char	*token;
	char	*commit;
	char	*groupcommit;
	char	*lazycommit;
	char	*tmpfs;
	char	*inlinelog;
	char	*inlinemove;
	char	*badsait;
	char	*sparse;                                              /* @F1 */
	char	*dasdenabled;                                      /* @F1 */
	char	*dasdprime;                                          /* @F1 */

changed:
	switch (sb->s_state)
	{
	case FM_CLEAN:
		state="CLEAN";
		break;
	case FM_MOUNT:
		state="MOUNT";
		break;
	case FM_DIRTY:
		state="DIRTY";
		break;
	case FM_LOGREDO:
		state="LOGREDO";
		break;
	default:
		state="Unknown State";
		break;
	}
	if  (sb->s_flag & JFS_AIX)
		aix_platform="AIX";
	else
		aix_platform="   ";
	if  (sb->s_flag & JFS_OS2)
		os2_platform="OS2";
	else
		os2_platform="   ";
	if  (sb->s_flag & JFS_DFS)
		dir_posix="DFS";
	else
		dir_posix="   ";
	if  (sb->s_flag & JFS_UNICODE)
		dir_unicode="UNICODE";
	else
		dir_unicode="       ";
	if  (sb->s_flag & JFS_GROUPCOMMIT)
		groupcommit="GROUPCOMMIT";
	else
		groupcommit="           ";
	if  (sb->s_flag & JFS_LAZYCOMMIT)
		lazycommit="LAZYCOMMIT";
	else
		lazycommit="          ";
	if  (sb->s_flag & JFS_TMPFS)
		tmpfs="TMPFS";
	else
		tmpfs="     ";
	if  (sb->s_flag & JFS_INLINELOG)
		inlinelog="INLINELOG";
	else
		inlinelog="         ";
	if  (sb->s_flag & JFS_INLINEMOVE)
		inlinemove="INLINEMOVE";
	else
		inlinemove="          ";
	if  (sb->s_flag & JFS_BAD_SAIT)
		badsait="BAD_SAIT";
	else
		badsait="        ";
	if  (sb->s_flag & JFS_SPARSE)                                   /* @F1 */
		sparse="SPARSE";                                         /* @F1 */
	else                                                                       /* @F1 */
		sparse="         ";                                           /* @F1 */
	if  (sb->s_flag & JFS_DASD_ENABLED)                         /* @F1 */
		dasdenabled="DASD_ENABLED";                       /* @F1 */
	else                                                                        /* @F1 */
		dasdenabled="         ";                                    /* @F1 */
	if  (sb->s_flag & JFS_DASD_PRIME)                              /* @F1 */
		dasdprime="DASD_PRIME";                                /* @F1 */
	else                                                                          /* @F1 */
		dasdprime="         ";                                         /* @F1 */

	printf("[1] s_magic:\t\t'%4.4s'\t\t", &(sb->s_magic));
	printf("[16] s_aim2.len:\t%d\n", sb->s_aim2.len);
	printf("[2] s_version:\t\t%d\t\t", sb->s_version);
	printf("[17] s_aim2.addr1:\t0x%02x\n", sb->s_aim2.addr1);
	printf("[3] s_size:\t0x%016llx\t", sb->s_size);
	printf("[18] s_aim2.addr2:\t0x%08x\n", sb->s_aim2.addr2);
	printf("[4] s_bsize:\t\t%d\t\t", sb->s_bsize);
	printf("     s_aim2.address:\t%lld\n", addressPXD(&sb->s_aim2));
	printf("[5] s_l2bsize:\t\t%d\t\t", sb->s_l2bsize);
	printf("[19] s_logdev:\t\t0x%08x\n", sb->s_logdev);
	printf("[6] s_l2bfactor:\t%d\t\t", sb->s_l2bfactor);
	printf("[20] s_logserial:\t0x%08x\n", sb->s_logserial);
	printf("[7] s_pbsize:\t\t%d\t\t", sb->s_pbsize);
	printf("[21] s_logpxd.len:\t%d\n", sb->s_logpxd.len);
	printf("[8] s_l2pbsize:\t\t%d\t\t", sb->s_l2pbsize);
	printf("[22] s_logpxd.addr1:\t0x%02x\n", sb->s_logpxd.addr1);
	printf("[9]  s_agsize:\t\t0x%08x\t", sb->s_agsize);
	printf("[23] s_logpxd.addr2:\t0x%08x\n", sb->s_logpxd.addr2);
	printf("[10] s_flag:\t\t0x%08x\t", sb->s_flag);
	printf("     s_logpxd.address:\t%lld\n", addressPXD(&sb->s_logpxd));
	printf("    %s   %s   %s   %s   %s\t",
		aix_platform, os2_platform, dir_posix, dir_unicode, tmpfs );    /* @F1 */
	printf("[24] s_fsckpxd.len:\t%d\n", sb->s_fsckpxd.len);
	printf("    %s   %s   %s\t", groupcommit, lazycommit, badsait );         /* @F1 */
	printf("[25] s_fsckpxd.addr1:\t0x%02x\n", sb->s_fsckpxd.addr1);
	printf("    %s   %s   %s\t", sparse, inlinelog, inlinemove );                  /* @F1 */
	printf("[26] s_fsckpxd.addr2:\t0x%08x\n", sb->s_fsckpxd.addr2);
	printf("    %s   %s\t\t", dasdenabled, dasdprime);                             /* @F1 */
	printf("     s_fsckpxd.address:\t%lld\n", addressPXD(&sb->s_fsckpxd));
	printf("[11] s_state:\t\t0x%08x\t", sb->s_state);
	printf("[27] s_fsckloglen:\t%ld\t\n", sb->s_fsckloglen);
	printf("\t%13s\t\t\t", state);
	printf("[28] s_fscklog:\t\t%d\t\n", sb->s_fscklog);
	printf("[12] s_compress:\t%d\t\t",sb->s_compress);
	printf("[29] s_fpack:\t\t'%8s'\n", &(sb->s_fpack));
	printf("[13] s_ait2.len:\t%d\t\t", sb->s_ait2.len);
	printf("[30] s_attach:\t\t%1d\n", sb->s_attach);
	printf("[14] s_ait2.addr1:\t0x%02x\t\t", sb->s_ait2.addr1);
	printf("[31] totalUsable: 0x%016llx\n", sb->totalUsable);
	printf("[15] s_ait2.addr2:\t0x%08x\t", sb->s_ait2.addr2);
	printf("[32] minFree:\t  0x%016llx\n", sb->minFree);
	printf("     s_ait2.address:\t%lld\t\t", addressPXD(&sb->s_ait2));
	printf("[33] realFree:\t  0x%016llx\n", sb->realFree);

retry:
	fputs("display_super: [m]odify or e[x]it: ", stdout);
	gets(cmdline);
	token = strtok(cmdline, " 	");
	if (token == 0 || token[0] != 'm')
		return rc;
	
	field = m_parse(cmdline, 33, &token);
	if (field == 0)
		goto retry;

	switch (field)
	{
	case 1:
		strncpy(sb->s_magic, token, 4);
		break;
	case 2:
		sb->s_version = strtoul(token, 0, 0);
		break;
	case 3:
		sb->s_size = strtoll(token, 0, 16);
		break;
	case 4:
		sb->s_bsize = strtol(token, 0, 0);
		break;
	case 5:
		sb->s_l2bsize = strtol(token, 0, 0);
		break;
	case 6:
		sb->s_l2bfactor = strtol(token, 0, 0);
		break;
	case 7:
		sb->s_pbsize = strtol(token, 0, 0);
		break;
	case 8:
		sb->s_l2pbsize = strtol(token, 0, 0);
		break;
	case 9:
		sb->s_agsize = strtoul(token, 0, 16);
		break;
	case 10:
		sb->s_flag = strtoul(token, 0, 16);
		break;
	case 11:
		sb->s_state = strtoul(token, 0, 16);
		break;
	case 12:
		sb->s_compress = strtoul(token, 0, 0);
		break;
	case 13:
		sb->s_ait2.len = strtoul(token, 0, 0);
		break;
	case 14:
		sb->s_ait2.addr1 = strtoul(token, 0, 16);
		break;
	case 15:
		sb->s_ait2.addr2 = strtoul(token, 0, 16);
		break;
	case 16:
		sb->s_aim2.len = strtoul(token, 0, 0);
		break;
	case 17:
		sb->s_aim2.addr1 = strtoul(token, 0, 16);
		break;
	case 18:
		sb->s_aim2.addr2 = strtoul(token, 0, 16);
		break;
	case 19:
		sb->s_logdev = strtoul(token, 0, 16);
		break;
	case 20:
		sb->s_logserial = strtol(token, 0, 16);
		break;
	case 21:
		sb->s_logpxd.len = strtoul(token, 0, 0);
		break;
	case 22:
		sb->s_logpxd.addr1 = strtoul(token, 0, 16);
		break;
	case 23:
		sb->s_logpxd.addr2 = strtoul(token, 0, 16);
		break;
	case 24:
		sb->s_fsckpxd.len = strtoul(token, 0, 0);
		break;
	case 25:
		sb->s_fsckpxd.addr1 = strtoul(token, 0, 16);
		break;
	case 26:
		sb->s_fsckpxd.addr2 = strtoul(token, 0, 16);
		break;
	case 27:
		sb->s_fsckloglen = strtol(token, 0, 0);
		break;
	case 28:
		sb->s_fscklog = strtol(token, 0, 0);
		break;
	case 29:
		strncpy(sb->s_fpack, token, 8);
		break;
	case 30:
		sb->s_attach = strtol(token, 0, 0);
		break;
	case 31:
		sb->totalUsable = strtoull(token, 0, 16);
		break;
	case 32:
		sb->minFree = strtoull(token, 0, 16);
		break;
	case 33:
		sb->realFree = strtoull(token, 0, 16);
		break;
	default:
		fputs("display_super: Field number out of range\n", stderr);
		goto retry;
	}
	rc = XPEEK_CHANGED;
	goto changed;
}
示例#11
0
/****************************************************************************
 * NAME: 	process_Inode_Dtree 
 *		
 * FUNCTION:	Traverse the dtree of the given directory inode
 *		looking for allocated extents containing bad blocks.
 *
 * PARAMETERS:	
 *	dip		ptr to the owning disk inode in a buffer
 *
 *	doRelocate	 0 => this is not the JFS Bad Block inode
 *			!0 => this is the JFS Bad Block inode
 *
 * NOTES:	
 *
 * RETURNS:
 *      success: 0
 *      failure: something else
 */
int32 process_Inode_Dtree( dinode_t *dip, int8 doRelocate )
{
    int32	pid_rc = 0;
    int32 relocate_rc = 0;
    dtpage_t	*p; 
    int8	*stbl;
    int32	i;	
    pxd_t	*pxd;
    int64	xaddr, lmxaddr, xlastblk;
    int32	xlen;
    int8	didRelocate = 0;
    cbbl_bdblk_recptr bdblk_recptr = NULL;
    int32	pList;

    ULONG 	pListLen = 0;
    clrbblks_t	pData;
    ULONG 	pDataLen = 0;
    int64		lmpg_addr;
    int32		lmxlen;
    dtpage_t 	next_dtpg;  	/* next dtpage to work on  */
    dtpage_t 	*pnext_dtpg;
    int32 	ndtpg_inx; 	/* the next index in next_dtpg to work on */

	/* 
	 * we start with the root 
	 */
    pnext_dtpg = p = (dtpage_t *)&dip->di_btroot;

	/* 
	 * is it leaf, i.e., inode inline data ? 
	 */
    if (p->header.flag & BT_LEAF)  {
	goto out;
	}
	
    p->header.next = 0;
	/* 
	 * save leftmost dtpage xaddr 
	 */
    lmpg_addr = 0;

    stbl = DT_GETSTBL(p);
    pxd = (pxd_t *)&p->slot[stbl[0]];
	/* 
	 * save leftmost child dtpage extent 
	 */
    lmxaddr = addressPXD(pxd); /* leftmost child xaddr */
    lmxlen = lengthPXD(pxd);
    ndtpg_inx = 0;

	/*
	 * scan each level of dtree
	 */
    while(1)  {
	/*
	 * scan each dtpage of current level of dtree
	 */
	while(1)  {
	    stbl = DT_GETSTBL(p);

		/*
		 * scan each idtentry in current dtpage
		 */
	    for (i = ndtpg_inx; i < p->header.nextindex; i++) {
		pxd = (pxd_t *)&p->slot[stbl[i]];

			/* 
			 * does the extent contain at least 1 
			 * bad block? 
			 */ 
		xaddr = addressPXD(pxd);
		xlen = lengthPXD(pxd);

		pid_rc = baltree_search( xaddr, &bdblk_recptr );
		if( pid_rc != 0 ) {  /* something fatal on search */
		    return( pid_rc );
		    }
		else if( bdblk_recptr == NULL ) {  /* hit end of tree w/o match */
		    continue;
		    }  /* end hit end of tree w/o match */

		xlastblk = xaddr + xlen - 1;
		if( bdblk_recptr->fs_blkno <= xlastblk ) { /*
				* the extent contains at least 1 bad block
				*/
#ifdef _JFS_DEBUG
	printf("bad block 0x0%llx found in dtree for inode %d\n", 
		bdblk_recptr->fs_blkno, dip->di_number );
#endif
		    if( !doRelocate ) { /* relocation not requested */
			pid_rc = we_DidntTryTo_Relocate( xaddr,
							     xlastblk,
							     bdblk_recptr
							    );
			}  /* end relocation not requested */
		    else {  /* relocation is requested */
			pDataLen = sizeof(clrbblks_t);
			pData.flag = CLRBBLKS_RELOCATE | IFDIR | DTPAGE;
//PS24072004			pData.dev = lvMount->LVNumber;
			pData.dev = LVNumber;
			pData.fileset = dip->di_fileset;
			pData.inostamp = dip->di_inostamp;
			pData.ino = dip->di_number;
			pData.gen = dip->di_gen;
			pData.xoff = lmpg_addr; /* leftmost page 
						 * describing this level 
						 */
			pData.old_xaddr = xaddr;
			pData.new_xaddr = 0;
			pData.xlen = xlen;
			pData.agg_blksize = agg_recptr->fs_blksize;
				/*
				 * attempt to relocate the extent
				 */
			didRelocate = 0;
			relocate_rc = fscntl(	JFSCTL_CLRBBLKS,
						(void *)&pList, &pListLen,
						(void *)&pData, &pDataLen
						);
			if( (relocate_rc == 0) && 
			    (pData.new_xaddr != 0) ) {  /*
				* extent has been relocated 
				*/
			    didRelocate = -1;
			    }  /* end extent has been relocated */	
				/*
				 * Now handle the individual bad block(s) 
				 * in the extent
				 */
			if( didRelocate ) {  /* 
				* actually did relocate 
				*/
			    pid_rc = we_Did_Relocate( xaddr, 
							  xlastblk,
							  bdblk_recptr 
							  );
			    }  /* end actually did relocate */
			else {  /* tried but failed to relocate */
			    pid_rc = we_Couldnt_Relocate( xaddr, 
							      xlastblk,
							      bdblk_recptr, 
							      relocate_rc 
							     );
			    }  /* end else tried but failed to relocate */
			}  /* end else relocation is requested */
		    }  /* end the extent contains at least 1 bad block */
		}  /* end for loop */

		/* 
		 * read in next/right sibling dtpage 
		 */
	    if (p->header.next != 0) {
		xaddr = p->header.next;
		pid_rc = pRead(fsMount, xaddr, fsMount->nbperpage, &next_dtpg);
		if (pid_rc != 0) {
		    return CBBL_CANTREADNEXTDTPG; /* i/o error */
		    }

		pnext_dtpg = p = &next_dtpg;
		ndtpg_inx = 0;
		}
	    else
		break;
	    } /* end while current level scan */

		/*
		 * descend: read leftmost dtpage of next lower level of dtree
		 */
		/* 
		 * the first child of the dtroot split may not have PSIZE 
		 */ 
	pid_rc = pRead(fsMount, lmxaddr, lmxlen, &next_dtpg);
	if ( pid_rc != 0 )  {
	    return CBBL_CANTREADLMDTCHILD; /* i/o error */
	    }

	pnext_dtpg = p = &next_dtpg;

		/* 
		 * for dir, the leaf contains data, its pxd info 
		 * has been reported by the parent page. so we stop here 
		 */
	if (p->header.flag & BT_LEAF) {
	    break;
	    }

		/* 
		 * save leftmost dtpage xaddr 
		 */
	lmpg_addr = lmxaddr;

	stbl = DT_GETSTBL(p);
	pxd = (pxd_t *)&p->slot[stbl[0]];
		/* 
		 * save leftmost child dtpage extent 
		 */
	lmxaddr = addressPXD(pxd); /* leftmost child xaddr */
	lmxlen = lengthPXD(pxd);
	ndtpg_inx = 0;
	}  /* end while scan each level of tree */

	/* reset global state variable for the inode */
out:
	pnext_dtpg = NULL;

	return pid_rc;
}					/* end process_Inode_Dtree() */
示例#12
0
/****************************************************************************
 * NAME: 	process_FilesetInodes 
 *
 * FUNCTION:	Reads in the fileset inode extents, one by one, and for
 *		each in-use inode, calls process_Inode() to scan for 
 *		blocks on the bad block list and handle any that are 
 *		detected.
 *
 * PARAMETERS:	none
 *
 * NOTES:
 *
 * RETURNS:
 *      success: 0
 *      failure: something else
 */
int32 process_FilesetInodes ( ) 
{
    int32	pfsi_rc = 0;
    dinode_t	*inoptr = NULL;
    dinomap_t	*icp;
    int64	xaddr;
    int32	xlen;
    int8	isBadBlockInode = 0;

	/*
	 * scan each IAG in the file set 
	 */
    icp = (dinomap_t *)&IMap.ctl; 
    for ( agg_recptr->iag_idx = 0; 
	  (	(agg_recptr->iag_idx < icp->in_nextiag) && 
		(pfsi_rc == 0) &&
		(agg_recptr->bdblk_baltree.seq_list != NULL)	); 
	  agg_recptr->iag_idx++) {  /* for each IAG */

	 	/* 
		 * read in the next IAG 
		 */
	pfsi_rc = readIMapSequential(&iagbuf);
		/*
		 * process the extents described by the IAG
		 */
	for ( agg_recptr->extent_idx = 0; 
	     (  	(agg_recptr->extent_idx < EXTSPERIAG) && 
		(pfsi_rc == 0) &&
		(agg_recptr->bdblk_baltree.seq_list != NULL)	); 
	    agg_recptr->extent_idx++) {  /* for each extent in the IAG */
		/*
		 * Get the address and length of the extent
		 */
	    xaddr = addressPXD(&iagbuf.inoext[agg_recptr->extent_idx]);
	    xlen = lengthPXD(&iagbuf.inoext[agg_recptr->extent_idx]);
		/* 
		 * If the extent isn't allocated, bump current inode number
		 */
	    if( xaddr == 0 ) {  /* not allocated */
		agg_recptr->this_inonum += INOSPEREXT;
		}
	    else {  /* extent is allocated */
		/*
		 * Otherwise, read in the inode extent
		 */
		pfsi_rc = pRead(fsMount, xaddr, xlen, (void *)ixbuf);
			/*
			 * process the inodes in the extent 
			 */
		for ( agg_recptr->inode_idx = 0; 
	 	      (	(agg_recptr->inode_idx < INOSPEREXT) && 
			(pfsi_rc == 0) &&
			(agg_recptr->bdblk_baltree.seq_list != NULL)	); 
		      agg_recptr->inode_idx++) {  /* 
				* for each inode in the extent
				*/
		    inoptr = &ixbuf[agg_recptr->inode_idx];
			/*
			 * if the inode isn't in use, just
			 * increment the inode number
			 */
		    if( (inoptr->di_nlink == 0) || 
			(inoptr->di_inostamp != DIIMap.di_inostamp) ) {
			agg_recptr->this_inonum += 1;
			}
			/*
			 * otherwise, scan the inode for bad blocks 
			 * allocated to it and, if possible, relocate
			 * their contents and get them transferred to 
			 * the JFS Bad Block Inode 
			 */
		    else {  /* the inode is in use */
			pfsi_rc = process_Inode( isBadBlockInode, inoptr );
				/*
				 * increment to the next inode
				 */
			agg_recptr->this_inonum += 1; 
			}  /* end else the inode is in use */
		    }  /* end for each inode in the extent */
		}  /* end else extent is allocated */
	    }  /* end for each extent in the IAG */ 
	}  /* end for each IAG */

    return( pfsi_rc );
}				/* end process_FilesetInodes() */
/* look at jfs_logredo() and logRead() from logredo in jfsutils */
int sba_jfs_handle_journal_block(int sector, char *data)
{
	int off;
	int ret;
	struct logpage *lp;
	struct lrd *ld;
	char *log_data_ptr;
	void *ptr;
	int ld_flag;
	int nwords;
	int type = JOURNAL_DATA_BLOCK;

	if (sba_jfs_journal_super_block(sector)) {
		return JOURNAL_SUPER_BLOCK;
	}

	/* each log page that is written is of the form "struct logpage" */
	lp = (struct logpage *)data;
	off = lp->h.eor & (LOGPSIZE - 1);

	sba_debug(0, "The end of log offset of last record write = %d (h), %d (t)\n", lp->h.eor, lp->t.eor);
	sba_debug(0, "offset is %d head %u tail %u\n", off, (unsigned int)&(lp->h), (unsigned int)&(lp->t));

	ld = kmalloc(sizeof(struct logpage), GFP_KERNEL);
	log_data_ptr = kmalloc(4096, GFP_KERNEL);
	
	nwords = LOGRDSIZE/4;
	ret = sba_jfs_get_next_log_record(nwords, (int *)ld, data, &off);
	ld_flag = 1;

	while (ret >= 0) {

		if (ld_flag) {
			sba_debug(0, "Length = %d , Backchain = %d\n", ld->length, ld->backchain);

			long long blocknr = -1;

			switch (ld->type) {
				case LOG_COMMIT:
					sba_debug(0, "Found a LOG_COMMIT record\n");
					type = JOURNAL_COMMIT_BLOCK;
					break;

				case LOG_MOUNT:
					sba_debug(0, "Found a LOG_MOUNT record\n");
					break;

				case LOG_SYNCPT:
					sba_debug(0, "Found a LOG_SYNCPT record\n");
					break;

				case LOG_REDOPAGE:
					sba_debug(0, "Found a LOG_REDOPAGE record (address %lld, length %d)\n", 
					addressPXD(&ld->log.redopage.pxd), lengthPXD(&ld->log.redopage.pxd));
					blocknr = addressPXD(&ld->log.redopage.pxd);
					break;

				case LOG_NOREDOPAGE:
					sba_debug(0, "Found a LOG_NOREDOPAGE record (address %lld length %d)\n", 
					addressPXD(&ld->log.noredopage.pxd), lengthPXD(&ld->log.noredopage.pxd));
					blocknr = addressPXD(&ld->log.noredopage.pxd);
					break;

				case LOG_NOREDOINOEXT:
					sba_debug(0, "Found a LOG_NOREDOINOEXT record (address %lld length %d)\n", 
					addressPXD(&ld->log.noredoinoext.pxd), lengthPXD(&ld->log.noredoinoext.pxd));
					blocknr = addressPXD(&ld->log.noredoinoext.pxd);
					break;

				case LOG_UPDATEMAP:
					sba_debug(0, "Found a LOG_UPDATEMAP record (address %lld length %d nxd %d)\n", 
					addressPXD(&ld->log.updatemap.pxd), lengthPXD(&ld->log.updatemap.pxd), ld->log.updatemap.nxd);
					blocknr = addressPXD(&ld->log.updatemap.pxd);
					break;

				default:
					sba_debug(1, "Found an UNKNOWN record\n");
					break;
			}

			if (blocknr != -1) {
				if (sba_jfs_insert_journaled_blocks(blocknr) == -1) {
					sba_debug(1, "Error: inserting blk=%lld into journaled blocks list\n", blocknr);
				}
			}

			sba_debug(0, "Next offset = %d\n", off);
		}
		else {
			sba_debug(0, "Skipping data = %d words\n", nwords);
		}

		if (ld_flag) {
			if (ld->length > 0) {
				nwords = (ld->length + 3) / 4;
				ptr = log_data_ptr;
				ld_flag = 0;
			}
			else {
				nwords = LOGRDSIZE/4;
				ptr = ld;
				ld_flag = 1;
			}
		}
		else {
			nwords = LOGRDSIZE/4;
			ptr = ld;
			ld_flag = 1;
		}

		ret = sba_jfs_get_next_log_record(nwords, (int *)ptr, data, &off);
	}

	return type;
}
示例#14
0
int32 validfs( HFILE device )
{
    uint64	num_log_blocks;
    int32	rc;
    uint64	first_block, last_block;
    uint32	length, inode_address;
    uint64	index;
    struct dinode	inode_buffer;
    int64	total_nblocks;

    /*
     * Initialize internal block map
     */
    num_log_blocks = sb.s_size >> sb.s_l2bfactor;

    rc = calc_map_size( num_log_blocks, sb.s_bsize, sb.s_agsize );
    if( rc != 0 ) {
	printf("Failure creating internal block map.\n");
    }

    /*
     * Mark fixed items allocated; these are only the items which aren't mapped
     * by one of the inode tables.
     */
    /*
     * Reserved blocks
     */
    length = AGGR_RSVD_BYTES >> sb.s_l2bsize;
    first_block = 0;
    last_block = first_block + length;
    for( index = first_block; index < last_block; index++ ) {
	markit( index, 0 );
    }

    /*
     * Primary superblock
     */
    length = SIZE_OF_SUPER >> sb.s_l2bsize;
    first_block = SUPER1_OFF >> sb.s_l2bsize;
    last_block = first_block + length;
    for( index = first_block; index < last_block; index++ ) {
	markit( index, 0 );
    }

    /*
     * Secondary superblock
     */
    first_block = SUPER2_OFF >> sb.s_l2bsize;
    last_block = first_block + length;
    for( index = first_block; index < last_block; index++ ) {
	markit( index, 0 );
    }

    /*
     * Walk aggregate inode table; marking blocks seen
     */
    rc = ujfs_rwinode( device, &inode_buffer, AGGREGATE_I, GET, sb.s_bsize,
			AGGREGATE_I );
    if( rc != 0 ) return(rc);

    rc = walk_ait( device, &inode_buffer, TRUE );
    if( rc != 0 ) {
	printf(
	"Failed walking aggregate inode table, or difference in inode maps.\n");
    }

    /*
     * Walk secondary aggregate inode table; marking blocks seen
     */
    inode_address = (AGGREGATE_I * sizeof(struct dinode)) +
			( addressPXD(&(sb.s_ait2)) << sb.s_l2bsize );
    rc = ujfs_rw_diskblocks( device, inode_address, sizeof(struct dinode),
				&inode_buffer, GET );
    if( rc != 0 ) return(rc);

    rc = walk_ait( device, &inode_buffer, FALSE );
    if( rc != 0 ) {
	printf(
	"Failed walking secondary inode table, or difference in inode maps.\n");
    }

    /*
     * Since we don't walk the inodes of the secondary inode table we need to
     * be sure and mark the blocks for the map's addressing structure
     */
    total_nblocks = 0;
    walk_inode_tree(device, (xtpage_t *)&inode_buffer.di_btroot,
			&total_nblocks, 0);
    if( inode_buffer.di_nblocks != total_nblocks )
    {
	error++;
	printf(
 "Secondary AIT Inode %d (fileset: %d) nblocks bad, disk: %lld, actual: %lld\n",
		inode_buffer.di_number, inode_buffer.di_fileset,
		inode_buffer.di_nblocks, total_nblocks);
    }

    /*
     * Now the bitmaps are marked, fill in the rest of the maps and compare
     * with the maps on disk
     */
    rc = compare_maps( device, num_log_blocks, sb.s_bsize );

    return(rc);
}
示例#15
0
/*
 * Read the specified extent as an extent of IAG's
 * If its offset is 0 skip the first page since this is a control page.
 * For all other IAGs need to mark blocks:
 *	- mark the blocks for any allocated extents for the IAG
 *	- read the extent and mark blocks for any allocated inodes
 * Note: the blocks owned by the table itself will be marked when the inode for
 *	 the table is seen.
 */
void walk_iag_extent( int	device,
		      xad_t	*extent,
		      boolean_t	is_primary,
		      dinomap_t	*control_page,
		      dinomap_t	*disk_cp,
		      struct list_item	**top_iagfree,
		      struct list_item	**top_inofree,
		      struct list_item	**top_extfree,
		      int32	inostamp )
{
    uint64	offset, address, count, end;
    uint32	length, page_length;
    iag_t	iag_buffer;
    int32	index, rc, extdx;
    pxd_t	*inoext_ptr;
    uint32	map, found_map;
    uint32	agno;
    ino_t	start_inum;
    uint32	mymap[EXTSPERIAG];
    int16	seen_extent = 0, free_inodes = 0;

    offset = offsetXAD( extent );
    address = addressXAD( extent );
    length = lengthXAD( extent );
    page_length = PSIZE >> sb.s_l2bsize;

    if( offset == 0 ) {
	/*
	 * Read in the disk control page now.  We will compare it after all the
	 * other pages of the map have been processed.
	 */
	rc = ujfs_rw_diskblocks( device, address << sb.s_l2bsize,
				 sizeof(dinomap_t), disk_cp, GET );
	if( rc != 0 ) exit(rc);

	address += page_length;
	length -= page_length;
    }

    while( length > 0 ) {
	/*
	 * Clear map to use for tracking inodes seen
	 */
	memset( mymap, 0, EXTSPERIAG * sizeof(uint32));

	/*
	 * Read next IAG
	 */
	rc = ujfs_rw_diskblocks( device, address << sb.s_l2bsize, PSIZE,
				 &iag_buffer, GET );
	if( rc != 0 ) exit(rc);
	length -= page_length;
	address += page_length;

	control_page->in_nextiag = iag_buffer.iagnum + 1;
	if( iag_buffer.iagfree != -1 ) {
	    /*
	     * We have an item on the iagfree list following this one.
	     */
	    rc = search_and_add(top_iagfree, iag_buffer.iagfree, DISK_LIST);
	    if( rc != 0 ) {
		printf("Bad iagfree item on-disk: %d\n", iag_buffer.iagfree);
	    }
	}

	agno = iag_buffer.agstart / sb.s_agsize;
	if( iag_buffer.extfreefwd != -1 ) {
	    /*
	     * We have an item on the extfree list following this one.
	     */
	    rc = search_and_add(&(top_extfree[agno]), iag_buffer.extfreefwd,
			DISK_LIST);
	    if( rc != 0 ) {
		printf("Bad extfree[%d] item on-disk: %d\n", agno,
			iag_buffer.extfreefwd);
	    }
	}

	if( iag_buffer.inofreefwd != -1 ) {
	    /*
	     * We have an item on the inofree list following this one.
	     */
	    rc = search_and_add(&(top_inofree[agno]), iag_buffer.inofreefwd,
			DISK_LIST);
	    if( rc != 0 ) {
		printf("Bad inofree[%d] item on-disk: %d\n", agno,
			iag_buffer.inofreefwd);
	    }
	}

	/*
	 * Mark blocks for any allocated inode extents
	 */
	for( index = 0; index < SMAPSZ; index++ ) {
	    map = iag_buffer.extsmap[index];
	    inoext_ptr = iag_buffer.inoext + (index * EXTSPERSUM);
	    for( extdx = 0; extdx < EXTSPERSUM, map != 0; extdx++, map <<= 1) {
		if( (map & HIGHORDER) != 0 ) {
		    seen_extent++;

		    /*
		     * Count inodes for allocated inode extents
		     */
		    control_page->in_numinos += NUM_INODE_PER_EXTENT;
		    control_page->in_agctl[agno].numinos +=
					NUM_INODE_PER_EXTENT;

		    address = count = addressPXD(inoext_ptr + extdx);
		    end = count + inoext_ptr[extdx].len;
		    for( ; count < end; count++) {
			markit( count, 0 );
		    }

		    if( is_primary == TRUE ) {
			/*
			 * Now need to read inodes and mark blocks for them
			 * Only do this for the primary inode table
			 */
			start_inum = (iag_buffer.iagnum << L2INOSPERIAG) +
				(index << (L2EXTSPERSUM + L2INOSPEREXT)) +
				(extdx << L2INOSPEREXT);
			walk_inoext( device, address, inoext_ptr[extdx].len,
				iag_buffer.wmap[(index * EXTSPERSUM) + extdx],
				control_page, agno, start_inum, &found_map,
				inostamp );
			mymap[(index * EXTSPERSUM) + extdx] = found_map;
			if( ~found_map != 0 ) free_inodes = 1;
		    }
		}
	    }
	}

	if( seen_extent == 0 ) {
	    /*
	     * No extents for this IAG, add it to iagfree list
	     */
	    rc = search_and_add(top_iagfree, iag_buffer.iagnum, FOUND_LIST);
	    if( rc != 0 ) {
		printf("Bad iagfree item found: %d\n", iag_buffer.iagnum);
	    }
	} else if( seen_extent != EXTSPERIAG ) {
	    /*
	     * Have free extents in this IAG, add to AG free extent list
	     */
	    rc = search_and_add(&(top_extfree[agno]), iag_buffer.iagnum,
			FOUND_LIST);
	    if( rc != 0 ) {
		printf("Bad extfree[%d] item found: %d\n", agno,
			iag_buffer.iagnum);
	    }
	}
	if( free_inodes != 0 ) {
	    /*
	     * We have some free inodes in the extent
	     */
	    rc = search_and_add(&(top_inofree[agno]), iag_buffer.iagnum,
			FOUND_LIST);
	    if( rc != 0 ) {
		printf("Bad inofree[%d] item found: %d\n", agno,
			iag_buffer.iagnum);
	    }
	}

	if( is_primary ) {
	    /*
	     * Compare map found by walking extents to the on-disk version
	     */
	    rc = memcmp( mymap, iag_buffer.wmap, EXTSPERIAG * sizeof(uint32));
	    if( rc != 0 ) {
		error++;
		printf("Miscompare of inode wmap of IAG %d.\n",
			iag_buffer.iagnum);
		print_uint_array ("Found map:", mymap, EXTSPERIAG);
		print_uint_array ("Disk wmap:", iag_buffer.wmap, EXTSPERIAG);
	    }

	    rc = memcmp( mymap, iag_buffer.pmap, EXTSPERIAG * sizeof(uint32));
	    if( rc != 0 ) {
		error++;
		printf("Miscompare of inode pmap of IAG %d.\n",
			iag_buffer.iagnum);
		print_uint_array ("Found map:", mymap, EXTSPERIAG);
		print_uint_array ("Disk pmap:", iag_buffer.pmap, EXTSPERIAG);
	    }
	}
    }
}
示例#16
0
void walk_inoext( int		device,
		  uint64	address,
		  uint32	length,
		  uint32	wmap,
		  dinomap_t	*control_page,
		  uint32	agno,
		  ino_t		start_inum,
		  uint32	*found_map,
		  int32		inostamp )
{
    dinode_t	*next_inode;
    uint32	left_to_read = length << sb.s_l2bsize;
    uint64	cur_address = address << sb.s_l2bsize;
    int32	index, rc;
    uint32	map = wmap;
    char	page_buffer[PSIZE];
    ino_t	cur_inum = start_inum;
    uint32	mask = HIGHORDER;
    uint64	first_block, cur_block, last_block;
    uint32	num_blocks;
    int64	total_nblocks;

    *found_map = 0;

    while( (left_to_read > 0) ) {
	/*
	 * Read next page of inodes for this extent
	 */
	rc = ujfs_rw_diskblocks( device, cur_address, PSIZE, page_buffer, GET );
	cur_address += PSIZE;
	left_to_read -= PSIZE;

	next_inode = (dinode_t *)page_buffer;
	for( index = 0; index < INOSPERPAGE;
	     index++, next_inode++, cur_inum++, map <<= 1, mask >>= 1 ) {
	    /*
	     * Initialize count for this inode's number of blocks
	     */
	    total_nblocks = 0;

	    /*
	     * If this inode is allocated, mark blocks for its b-tree
	     */
	    if( (map & HIGHORDER) != 0 ) {
		if( next_inode->di_nlink <= 0 ) {
		    error++;
		    printf("Inode %d (fileset: %d) link count bad: %d\n",
			next_inode->di_number, next_inode->di_fileset,
			next_inode->di_nlink);
		} else {
		    *found_map |= mask;
		}

		/*
		 * Account for any blocks used by EA for this inode
		 */
		if( next_inode->di_ea.flag & DXD_EXTENT ) {
		    first_block = addressDXD(&(next_inode->di_ea));
		    num_blocks = lengthDXD(&(next_inode->di_ea));
		    total_nblocks += num_blocks;
		    last_block = first_block + num_blocks;
		    for( cur_block = first_block; cur_block < last_block;
				cur_block++ ) {
			markit( cur_block, 0 );
		    }
		}

		if( (next_inode->di_fileset == AGGREGATE_I) &&
			(next_inode->di_number == FILESYSTEM_I) ) {
		    /*
		     * Need to account for inode map's blocks
		     */
		    walk_inode_tree(device, (xtpage_t *)&next_inode->di_btroot,
					&total_nblocks, 0);

		    /*
		     * Need to walk this tree of inodes
		     */
		    rc = walk_ait( device, next_inode, TRUE );
		    if( rc != 0 ) {
			error++;
			printf("Problem with Fileset Inode Allocation Map.\n");
		    }
		} else if( (next_inode->di_fileset == AGGREGATE_I) &&
			(next_inode->di_number == BADBLOCK_I) ) {
		    walk_inode_tree(device, (xtpage_t *)&next_inode->di_btroot,
					&total_nblocks, BADBLOCK);
		} else if( next_inode->di_mode & IFDIR ) {
		    /*
		     * Need to walk the extents as directory extents
		     */
		    walk_dir( device, (dtroot_t *)&(next_inode->di_btroot),
				&total_nblocks);
		} else {
		    walk_inode_tree(device, (xtpage_t *)&next_inode->di_btroot,
					&total_nblocks, 0);
		}

		/*
		 * Now total_nblocks contains the total number of blocks
		 * actually allocated for this inode.  Compare this to the
		 * on-disk information.
		 */
		if( next_inode->di_nblocks != total_nblocks ) {
		    error++;
		    printf(
	       "Inode %d (fileset: %d) nblocks bad, disk: %lld, actual: %lld\n",
			next_inode->di_number, next_inode->di_fileset,
			next_inode->di_nblocks, total_nblocks);
		}
	    } else {
		if( next_inode->di_number == cur_inum &&
			next_inode->di_inostamp == inostamp &&
			addressPXD(&(next_inode->di_ixpxd)) == address &&
			lengthPXD(&(next_inode->di_ixpxd)) == length &&
			next_inode->di_nlink > 0 ) {
		    error++;
		    printf("Inode %d (fileset: %d) link count bad: %d\n",
				next_inode->di_number, next_inode->di_fileset,
				next_inode->di_nlink);
		    *found_map |= mask;
		}
		control_page->in_numfree++;
		control_page->in_agctl[agno].numfree++;
	    }
	}
    }
}
示例#17
0
/*
 *	jfs_extendfs()
 *
 * function: extend file system;
 *
 *   |-------------------------------|----------|----------|
 *   file system space               fsck       inline log
 *                                   workspace  space
 *
 * input:
 *	new LVSize: in LV blocks (required)
 *	new LogSize: in LV blocks (optional)
 *	new FSSize: in LV blocks (optional)
 *
 * new configuration:
 * 1. set new LogSize as specified or default from new LVSize;
 * 2. compute new FSCKSize from new LVSize;
 * 3. set new FSSize as MIN(FSSize, LVSize-(LogSize+FSCKSize)) where
 *    assert(new FSSize >= old FSSize),
 *    i.e., file system must not be shrinked;
 */
int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
{
	int rc = 0;
	struct jfs_sb_info *sbi = JFS_SBI(sb);
	struct inode *ipbmap = sbi->ipbmap;
	struct inode *ipbmap2;
	struct inode *ipimap = sbi->ipimap;
	struct jfs_log *log = sbi->log;
	struct bmap *bmp = sbi->bmap;
	s64 newLogAddress, newFSCKAddress;
	int newFSCKSize;
	s64 newMapSize = 0, mapSize;
	s64 XAddress, XSize, nblocks, xoff, xaddr, t64;
	s64 oldLVSize;
	s64 newFSSize;
	s64 VolumeSize;
	int newNpages = 0, nPages, newPage, xlen, t32;
	int tid;
	int log_formatted = 0;
	struct inode *iplist[1];
	struct jfs_superblock *j_sb, *j_sb2;
	uint old_agsize;
	struct buffer_head *bh, *bh2;

	/* If the volume hasn't grown, get out now */

	if (sbi->mntflag & JFS_INLINELOG)
		oldLVSize = addressPXD(&sbi->logpxd) + lengthPXD(&sbi->logpxd);
	else
		oldLVSize = addressPXD(&sbi->fsckpxd) +
		    lengthPXD(&sbi->fsckpxd);

	if (oldLVSize >= newLVSize) {
		printk(KERN_WARNING
		       "jfs_extendfs: volume hasn't grown, returning\n");
		goto out;
	}

	VolumeSize = sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits;

	if (VolumeSize) {
		if (newLVSize > VolumeSize) {
			printk(KERN_WARNING "jfs_extendfs: invalid size\n");
			rc = -EINVAL;
			goto out;
		}
	} else {
		/* check the device */
		bh = sb_bread(sb, newLVSize - 1);
		if (!bh) {
			printk(KERN_WARNING "jfs_extendfs: invalid size\n");
			rc = -EINVAL;
			goto out;
		}
		bforget(bh);
	}

	/* Can't extend write-protected drive */

	if (isReadOnly(ipbmap)) {
		printk(KERN_WARNING "jfs_extendfs: read-only file system\n");
		rc = -EROFS;
		goto out;
	}

	/*
	 *	reconfigure LV spaces
	 *	---------------------
	 *
	 * validate new size, or, if not specified, determine new size
	 */

	/*
	 * reconfigure inline log space:
	 */
	if ((sbi->mntflag & JFS_INLINELOG)) {
		if (newLogSize == 0) {
			/*
			 * no size specified: default to 1/256 of aggregate
			 * size; rounded up to a megabyte boundary;
			 */
			newLogSize = newLVSize >> 8;
			t32 = (1 << (20 - sbi->l2bsize)) - 1;
			newLogSize = (newLogSize + t32) & ~t32;
			newLogSize =
			    min(newLogSize, MEGABYTE32 >> sbi->l2bsize);
		} else {
int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
{
	int rc = 0;
	struct jfs_sb_info *sbi = JFS_SBI(sb);
	struct inode *ipbmap = sbi->ipbmap;
	struct inode *ipbmap2;
	struct inode *ipimap = sbi->ipimap;
	struct jfs_log *log = sbi->log;
	struct bmap *bmp = sbi->bmap;
	s64 newLogAddress, newFSCKAddress;
	int newFSCKSize;
	s64 newMapSize = 0, mapSize;
	s64 XAddress, XSize, nblocks, xoff, xaddr, t64;
	s64 oldLVSize;
	s64 newFSSize;
	s64 VolumeSize;
	int newNpages = 0, nPages, newPage, xlen, t32;
	int tid;
	int log_formatted = 0;
	struct inode *iplist[1];
	struct jfs_superblock *j_sb, *j_sb2;
	s64 old_agsize;
	int agsizechanged = 0;
	struct buffer_head *bh, *bh2;

	

	if (sbi->mntflag & JFS_INLINELOG)
		oldLVSize = addressPXD(&sbi->logpxd) + lengthPXD(&sbi->logpxd);
	else
		oldLVSize = addressPXD(&sbi->fsckpxd) +
		    lengthPXD(&sbi->fsckpxd);

	if (oldLVSize >= newLVSize) {
		printk(KERN_WARNING
		       "jfs_extendfs: volume hasn't grown, returning\n");
		goto out;
	}

	VolumeSize = sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits;

	if (VolumeSize) {
		if (newLVSize > VolumeSize) {
			printk(KERN_WARNING "jfs_extendfs: invalid size\n");
			rc = -EINVAL;
			goto out;
		}
	} else {
		
		bh = sb_bread(sb, newLVSize - 1);
		if (!bh) {
			printk(KERN_WARNING "jfs_extendfs: invalid size\n");
			rc = -EINVAL;
			goto out;
		}
		bforget(bh);
	}

	

	if (isReadOnly(ipbmap)) {
		printk(KERN_WARNING "jfs_extendfs: read-only file system\n");
		rc = -EROFS;
		goto out;
	}


	if ((sbi->mntflag & JFS_INLINELOG)) {
		if (newLogSize == 0) {
			newLogSize = newLVSize >> 8;
			t32 = (1 << (20 - sbi->l2bsize)) - 1;
			newLogSize = (newLogSize + t32) & ~t32;
			newLogSize =
			    min(newLogSize, MEGABYTE32 >> sbi->l2bsize);
		} else {