Exemple #1
0
/****************************************************************************
 * NAME: 	read_cbblfsck_record
 *
 * FUNCTION:	Copies stats from the clrbblks aggregate record into
 *		the communication area buffer, then writes the buffer
 *		to the device.
 *
 * PARAMETERS:	none
 *
 * NOTES:
 *
 * RETURNS:
 *      success: 0
 *      failure: something else
 */
int32 read_cbblfsck_record( ) 
{
    int32	   rcr_rc = 0;

    rcr_rc = ujfs_rw_diskblocks(LVHandle, cbblfsck_area_byteoff, 
				cbblfsck_area_size, 
				(void *)cbblfsck_recptr, GET);
    return( rcr_rc );
}				/* end read_cbblfsck_record() */
Exemple #2
0
/****************************************************************************
 * NAME: 	write_cbblfsck_record
 *
 * FUNCTION:	Copies stats from the clrbblks aggregate record into
 *		the communication area buffer, then writes the buffer
 *		to the device.
 *
 * PARAMETERS:	none
 *
 * NOTES:
 *
 * RETURNS:
 *      success: 0
 *      failure: something else
 */
int32 write_cbblfsck_record( ) 
{
    int32	   wcr_rc = 0;

    wcr_rc = ujfs_rw_diskblocks(LVHandle, cbblfsck_area_byteoff, 
				cbblfsck_area_size, 
				(void *)cbblfsck_recptr, PUT);

    return( wcr_rc );
}				/* end write_cbblfsck_record() */
Exemple #3
0
/*
 * NAME:        getLogpage(pno)
 *
 * FUNCTION:    if the specified log page is in buffer pool, return its
 *              index. Otherwise read log page into buffer pool.
 *
 * PARAMETERS:  pno -   log page number to look for.
 *
 * RETURNS:     0 - 3   - index of the buffer pool the page located
 *              REFORMAT_ERROR(-3)      - I/O error, reformat the log
 *              MAJOR_ERROR(-2)         - other major errors other than EIO.
 */
int32 getLogpage(
int pno)  /* page of log */
{
        int32 k, rc;
        uint32 actual;

        /*
         * is it in buffer pool ?
         */
        for (k = 0; k <= 3; k++)
                if (logptr[k] == pno) return(k);

        /*
         * read page into buffer pool into next slot
         * don't have to use llseek() here.  log dev will never be > 2 gig
         */
        nextrep = (nextrep + 1) % 4;
        if ( loglocation == INLINELOG )
                rc = ujfs_rw_diskblocks( logfd,
                        (uint64)(vopen[logminor].logxaddr+LOGPNTOB(pno)),
                        (unsigned)LOGPSIZE,
                        (char *)&logp[nextrep],
                        GET);
        else
                rc = ujfs_rw_diskblocks( logfd,
                        (uint64)LOGPNTOB(pno),
                        (unsigned)LOGPSIZE,
                        (char *)&logp[nextrep],
                        GET);

        if (rc !=  0 )
        {
                return(JLOG_READERROR1);
        }

        logptr[nextrep] = pno;
        return(nextrep);
}
Exemple #4
0
/*
 * NAME: ujfs_put_superblk
 *
 * FUNCTION: Write primary or secondary aggregate superblock
 *
 * PRE CONDITIONS:
 *
 * POST CONDITIONS:
 *
 * PARAMETERS:
 *      fd              - open port for device to write superblock to
 *      sb              - pointer to struct superblock to be written
 *      is_primary      - 0 value means we are putting the secondary superblock;
 *                        non-zero value means we are putting the primary
 *                        superblock.
 *
 * NOTES: The sizeof(struct superblock) is less than the amount of disk space
 *      being allowed for the superblock (SIZE_OF_SUPER).  This function will
 *      write 0's to the space following the actual superblock structure to fill
 *      the entire allocated disk space.
 *
 * RECOVERY OPERATION:
 *
 * DATA STRUCTURES:
 *
 * RETURNS:
 *      success: 0
 *      failure: any other value
 */
int32 ujfs_put_superblk( HFILE                  fd,
                         struct superblock      *sb,
                         int16                  is_primary )
{
    char        buf[SIZE_OF_SUPER];
    int32       rc;

    memset( buf, 0, SIZE_OF_SUPER );
    memcpy( buf, sb, sizeof(*sb) );
    rc = ujfs_rw_diskblocks( fd, (is_primary ? SUPER1_OFF : SUPER2_OFF),
                             SIZE_OF_SUPER, buf, PUT );

    return rc;
}
Exemple #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);
    }
}
Exemple #6
0
/*
 * NAME: ujfs_get_superblk
 *
 * FUNCTION: read either the primary or secondary superblock from the specified
 *      device
 *
 * PRE CONDITIONS:
 *
 * POST CONDITIONS:
 *
 * PARAMETERS:
 *      fd              - open port for device to read superblock from
 *      sb              - pointer to struct superblock to be filled in on return
 *      is_primary      - 0 indicates to retrieve secondary superblock,
 *                        otherwise retrieve primary superblock
 *
 * NOTES:
 *
 * RECOVERY OPERATION:
 *
 * DATA STRUCTURES:
 *
 * RETURNS:
 *      success: 0
 *      failure: any other value
 */
int32 ujfs_get_superblk( HFILE                  fd,
                         struct superblock      *sb,
                         int32                  is_primary)
{
    int32       rc;
    char        buf[SIZE_OF_SUPER];
    struct superblock   *sblk = (struct superblock *)buf;

    rc = ujfs_rw_diskblocks( fd, (is_primary ? SUPER1_OFF : SUPER2_OFF),
                             SIZE_OF_SUPER, sblk, GET );
    if( rc != 0 ) return rc;

    memcpy( sb, sblk, sizeof(*sb) );
    return 0;
}
Exemple #7
0
void walk_internal_page(int	device,
			uint64	block,
			uint32	length,
			int64	*total_nblocks,
			int32	flag)
{
    int	rc;
    xtpage_t	xtree_page;
    int32	lastindex, index;
    uint64	first_block, cur_block, last_block;
    uint32	cur_length;
    int32	leafbad;

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

    /*
     * Mark the blocks for the page; if internal page walk down page
     */
    leafbad = (xtree_page.header.flag & BT_LEAF) ? flag : 0;
    lastindex = xtree_page.header.nextindex;
    for( index = XTENTRYSTART; index < lastindex; index++ ) {
	/*
	 * This is actual data of the inode, mark these blocks
	 */
	first_block = addressXAD( &(xtree_page.xad[index]) );
	cur_length = lengthXAD( &(xtree_page.xad[index]) );
	*total_nblocks += cur_length;
	last_block = first_block + cur_length;
	for( cur_block = first_block; cur_block < last_block; cur_block++ ) {
	    markit( cur_block, leafbad );
	}

	if( xtree_page.header.flag & BT_INTERNAL ) {
	    /*
	     * This is an internal page of the b-tree.  Walk the page.
	     */
	    walk_internal_page(device, first_block, cur_length, total_nblocks,
			flag);
	}
    }
}
Exemple #8
0
void walk_internal_iag( int		device,
			xad_t		*top_page,
			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 )
{
    int32	rc, index, lastindex;
    uint64	block;
    uint32	length;
    xtpage_t	xtree_page;

    block = addressXAD(top_page);
    length = lengthXAD(top_page);

    rc = ujfs_rw_diskblocks( device, block << sb.s_l2bsize,
		length << sb.s_l2bsize, &xtree_page, GET );

    /*
     * Walk the IAG page unless this is another internal page, then we need to
     * walk it as an internal page again.
     */
    lastindex = xtree_page.header.nextindex;
    for( index = XTENTRYSTART; index < lastindex; index++ ) {
	if( xtree_page.header.flag & BT_LEAF ) {
	    walk_iag_extent( device, &(xtree_page.xad[index]), is_primary,
				control_page, disk_cp, top_iagfree,
				top_inofree, top_extfree, inostamp );
	} else {
	    walk_internal_iag( device, &(xtree_page.xad[index]), is_primary,
				control_page, disk_cp, top_iagfree,
				top_inofree, top_extfree, inostamp );
	}
    }
}
Exemple #9
0
void alter()
{
	int64	address;
	int64	block;
	uint8	*buffer;
	uint8	byte;
	char	cmdline[512];
	char	*hexstring;
	uint32	hex_length;
	uint32	length;
	uint32	offset;
	char	*ptr;
	char	*token;

	token = strtok(0, " 	");
	if (token == 0) {
		fputs("alter: Please enter: block offset hex-digits> ", stdout);
		gets(cmdline);
		token = strtok(cmdline, " 	");
		if (token == 0)
			return;
	}
	errno = 0;
	block = strtoull(token, 0, 0);
	if (block == 0 && errno) {
		fputs("alter: invalid block\n\n", stderr);
		return;
	}
	address = block << l2bsize;

	token = strtok(0, " 	");
	if (!token) {
		fputs("alter:  Not enought arguments!\n", stderr);
		return;
	}
	offset = strtoul(token, 0, 16);
	if (offset == 0 && errno) {
		fputs("alter: invalid offset\n", stderr);
		return;
	}
	hexstring = strtok(0, " 	");
	if (!hexstring) {
		fputs("alter: Not enough arguments!\n", stderr);
		return;
	}
	if (strtok(0, " 	")) {
		fputs("alter: Too many arguments!\n", stderr);
		return;
	}
	hex_length = strlen(hexstring);
	if (hex_length & 1) {
		/* odd number of hex digits */
		fputs("alter: hex string must have even number of digits!\n",
			stderr);
		return;
	}

	/* Round length of data up to next full physical block */

	length = ( offset + hex_length + bsize - 1 ) & ~(bsize - 1);

	buffer = (char *)malloc(length);
	if (!buffer) {
		fputs("alter: malloc failure!\n", stderr);
		return;
	}
	if (ujfs_rw_diskblocks(fd, address, length, buffer, GET)) {
		fputs("alter: failed reading disk data!\n", stderr);
		free(buffer);
		return;
	}
	for (ptr = hexstring; *ptr; ptr++) {
		if (*ptr >= '0' && *ptr <= '9')
			byte = *ptr - '0';
		else if (*ptr >='a' &&  *ptr <= 'f')
			byte = *ptr - 'a' + 10;
		else if (*ptr >='A' &&  *ptr <= 'F')
			byte = *ptr - 'A' + 10;
		else {
			fputs("alter: invalid hex digit!\n", stderr);
			free(buffer);
			return;
		}

		ptr++;
		byte <<= 4;

		if (*ptr >= '0' && *ptr <= '9')
			byte += *ptr - '0';
		else if (*ptr >='a' &&  *ptr <= 'f')
			byte += *ptr - 'a' + 10;
		else if (*ptr >='A' &&  *ptr <= 'F')
			byte += *ptr - 'A' + 10;
		else {
			fputs("alter: invalid hex digit!\n", stderr);
			free(buffer);
			return;
		}

		buffer[offset++] = byte;
	}
	if (ujfs_rw_diskblocks(fd, address, length, buffer, PUT))
		fputs("alter: failed writing disk data!\n", stderr);

	free (buffer);
	return;
}
Exemple #10
0
/*
 * NAME:        setLogpage(pno, eor, pmax, buf)
 *
 * FUNCTION:    Forms consistent log page and returns eor and pmax values.
 *
 *              During the first release the following conditions are
 *              assumed:
 *              1) No corrupted write during power failure
 *              2) No split write
 *              3) No out-of-order sector write
 *
 *              If the header and trailer in the page are not equal, a
 *              system crash happened during this page write. It
 *              is reconciled as follows:
 *
 *              1) if h.page != t.page, the smaller value is taken and
 *                 the eor fields set to LOGPHDSIZE.
 *                 reason: This can happen when a old page is over-written
 *                 by a new page and the system crashed. So this page
 *                 should be considered not written.
 *              2) if h.eor != t.eor, the smaller value is taken.
 *                 reason: The last log page was rewritten for each
 *                 commit record. A system crash happened during the
 *                 page rewriting. Since we assume that no corrupted write
 *                 no split write and out-of-order sector write, the
 *                 previous successfuly writing is still good
 *              3) if no record ends on the page (eor = 8), still return it.
 *                 Let the caller determine whether a) a good long log record
 *                 ends on the next log page. or b) it is the first page of the
 *                 last long log record and system was crashed when its second
 *                 page is written.
 *
 *
 * RETURNS:     0                       - ok
 *              REFORMAT_ERROR(-3)      - I/O error, reformat log
 *              MAJOR_ERROR(-2)         - other major error
 */
setLogpage(int32 pno,   /* page number of log           */
        int32 *eor,     /* log header eor to return     */
        int32 *pmax,    /* log header page number to return */
        int32 buf)      /* logp[] index number for page */
{
        int32 diff1, diff2, rc;
        unsigned long  actual;

        /* check that header and trailer are the same
         */
        if ((diff1 = (logp[buf].h.page - logp[buf].t.page)) != 0)
        {       if (diff1 > 0)
                        logp[buf].h.page = logp[buf].t.page;
                else
                        logp[buf].t.page = logp[buf].h.page;

                logp[buf].h.eor = logp[buf].t.eor = LOGPHDRSIZE;
                                                /* empty page */
        }

        if ((diff2 = (logp[buf].h.eor - logp[buf].t.eor)) != 0)
        {       if (diff2 > 0)
                        logp[buf].h.eor = logp[buf].t.eor;
                else
                        logp[buf].t.eor = logp[buf].h.eor;

        }

        /* if any difference write the page out
         */
        if (diff1 || diff2)
        {
                rc = ujfs_rw_diskblocks(logfd,
                        (uint64)(vopen[logminor].logxaddr+LOGPNTOB(pno)),
                                        (unsigned long)LOGPSIZE,
                                        (char *)&logp[buf],
                                        PUT);
                if ( rc != 0 )
                {
                        sprintf( message_parm_0, "(d) %d", pno  );
                        msgprms[0] = message_parm_0;
                        msgprmidx[0] = 0;
                        sprintf( message_parm_1, "(d) %d", rc  );
                        msgprms[1] = message_parm_1;
                        msgprmidx[1] = 0;
                        fsck_send_msg( lrdo_SLPWRITEFAIL, 0, 2 );

                        return(JLOG_WRITEERROR1);
                }
        }

        /*
         * At this point, it is still possible that logp[buf].h.eor
         * is LOGPHDRSIZE, but we return it anyway. The caller will make
         * decision.
         */

        *eor = logp[buf].h.eor;
        *pmax = logp[buf].h.page;

        return (0);
}
Exemple #11
0
/*
 * NAME:	jfs_logform
 * FUNCTION:	format file system log
 *
 * RETURN:	0 -	successful
 *		-1 -	error occur 
 *
 */
int32 jfs_logform(
        int32   fd, 	   /* for inline log, this is a file descriptor
			    * for an opened device to write log.
			    * for outline log, it is -1 */
	int32   aggr_blk_size, /* aggregate block size in bytes */
        int32   s_l2bsize, /* log2 of aggregate block size in bytes */
	uint32  s_flag,    /* fs superblock s_flag is passed in   */
        int64   log_start, /* offset of the start of inline log in 
			    * number of aggr. blocks. for outline log
			    * it is set as zero */
        int32   log_len,   /* inline log length in number of aggr. blks 
			    * for outline log, it is zero */
	char *  dev_name,  /* logical volume of the outline log device  
			    * for inline log, it is NULL */
	int32   nblks      /* size of the outline log in 512 byte blocks
			    * for inline log, it is zero */
)
{
        ULONG Action;
        int64	log_len_in_bytes;
        char  parms = 0;
        unsigned long parmlen = sizeof(parms);
        ULONG actual;
        struct DPB dev;
        unsigned long devlen = sizeof(dev);

	int32 oflag,logfd,npages,rc,k,dblks,total_blks;
	char  logpages[4 * LOGPSIZE];
	logpage_t *logp;		/* array of 4 log pages */
	static logsuper_t log_sup;
	struct lrd *lrd_ptr;
	int64  log_begin;  /* the location of the beginning of the log inside
			    * of the file system. ( in bytes )
			    */
	int64 log_contwt;
	char answer;
	int16 inlinelog = (s_flag & JFS_INLINELOG );
	int    Working_counter;
	char *Working[5];

#define LOGBUFSIZE	4 * LOGPSIZE
	logp = (logpage_t *) &logpages;
	Working[0] = "   |\r";
	Working[1] = "   /\r";
	Working[2] = "   -\r";
	Working[3] = "   \\\r";

   /*
    * check to see whether standard out has been redirected, and
    * set the flag accordingly.
    */
  if( (ujfs_stdout_redirected()) != 0 ) {
    stdout_redirected = 1;
    }
  else {
    stdout_redirected = 0;
    }

	/* 
	 * if it is an outline log, do device check and open device
	 */
	if (!inlinelog )
	{
		/*  open the device 
	 	*/
		if (DosOpen(dev_name, (unsigned long *)&logfd, &Action, 0, 0, 
			OPEN_ACTION_OPEN_IF_EXISTS,
			OPEN_FLAGS_DASD | OPEN_FLAGS_FAIL_ON_ERROR |
			OPEN_SHARE_DENYREADWRITE | OPEN_ACCESS_READWRITE, 0))
                	goto errout;
		fd = logfd;

		/*
		 * Lock the drive
		 */
		rc = DosDevIOCtl(fd, IOCTL_DISK, DSK_LOCKDRIVE, 
				&parms, sizeof(parms),
				&parmlen, &parms, sizeof(parms), &parmlen);

		/*
	 	* validate/determine device size.
	 	* for bringup allow ioctl to fail or to report zero size.
	 	*/
		rc = DosDevIOCtl(fd, IOCTL_DISK, DSK_GETDEVICEPARAMS, &parms,
                         sizeof(parms), &parmlen, &dev, sizeof(dev), &devlen);
		if (rc == NO_ERROR)
		{
			total_blks = dev.dev_bpb.total_sectors +
			dev.dev_bpb.large_total_sectors;
			if (total_blks > 0)
			{
				dblks = (nblks == 0) ? total_blks :
					MIN(nblks,total_blks);
			}
		}

		if ((npages = dblks/(LOGPSIZE/512)) == 0)
		{
			printf("ioctl failed \n");
			printf("try again but specify number of blocks \n");
			return -1;
		}	

		/* before we destroy anything in the log, try to
		 * confirm with the user
	 	 */
			while(TRUE) {
				printf("logform: destroy %s (y)?",dev_name);
				fflush(stdout);
				answer = getchar();
				if(answer == 'n' || answer == 'N') exit(1);
				else if(answer == 'y' || answer == 'Y' ||
							answer == '\n') break;
				while((answer = getchar()) != '\n');
			}
        rc = write_bootsec(fd, &(dev.dev_bpb), "jfslog", 1);

	}
/***************************************************************************/
	else {  /* the fs has an inlinelog  */
		log_len_in_bytes = ((int64) log_len) << s_l2bsize;
		npages = log_len_in_bytes / LOGPSIZE; 
		}

		/* 
		 * init log superblock: log page 1
		 */
	log_sup.magic = LOGMAGIC;
	log_sup.version = LOGVERSION;
	log_sup.state = LOGREDONE;
	log_sup.flag = s_flag;  /* assign fs s_flag to log superblock.
				 * currently s_flag carries the inlinelog
				 * info and commit option ( i.e. group commit
				 * or lazy commit, etc.. )
				 */
	log_sup.size = npages;
	log_sup.bsize = aggr_blk_size;
	log_sup.l2bsize = s_l2bsize; 
	log_sup.end = 2*LOGPSIZE + LOGPHDRSIZE + LOGRDSIZE;

	/* find the log superblock location 
	 */
	log_begin = log_start << s_l2bsize;
	rc = ujfs_rw_diskblocks(fd, (log_begin+LOGPSIZE), (unsigned)LOGPSIZE,
					(char *)&log_sup, PUT);
	if ( rc != 0 )
		goto errout;

	/*
	 * init device pages 2 to npages-1 as log data pages:
	 *
	 * log page sequence number (lpsn) initialization:
	 * the N (= npages-2) data pages of the log is maintained as 
	 * a circular file for the log records;
	 * lpsn grows by 1 monotonically as each log page is written 
	 * to the circular file of the log;
	 * Since the AIX DUMMY log record is dropped for this XJFS, 
	 * and setLogpage() will not reset the page number even if
	 * the eor is equal to LOGPHDRSIZE. In order for binary search
	 * still work in find log end process, we have to simulate the
	 * log wrap situation at the log format time.
	 * The 1st log page written will have the highest lpsn. Then
	 * the succeeding log pages will have ascending order of
	 * the lspn starting from 0, ... (N-2)
	 */

	/* 
		initialize 1st 2 log pages to be written: lpsn = N-1, 0
		and also a SYNCPT log record is written to the N-1 page 
	
		Since the log is always an even number of meg, if we
		write 2 pages before entering the loop, we are assured
		that the log will end after a 4 page buffer.
	*/

	logp[0].h.eor = logp[0].t.eor = LOGPHDRSIZE + LOGRDSIZE;
	logp[0].h.page = logp[0].t.page = npages - 3;
	lrd_ptr = (struct lrd *)&logp[0].data;
	lrd_ptr->logtid = 0;
	lrd_ptr->backchain = 0;
	lrd_ptr->type = LOG_SYNCPT;
	lrd_ptr->length = 0;
	lrd_ptr->log.syncpt.sync = 0;

	logp[1].h.eor = logp[1].t.eor = LOGPHDRSIZE;
	logp[1].h.page = logp[1].t.page = 0;
	lrd_ptr = (struct lrd *)&logp[1].data;
	lrd_ptr->logtid = 0;
	lrd_ptr->backchain = 0;
	lrd_ptr->type = LOG_SYNCPT;
	lrd_ptr->length = 0;
	lrd_ptr->log.syncpt.sync = 0;

	rc = ujfs_rw_diskblocks(fd, (log_begin+2*LOGPSIZE), 
					(unsigned) 2*LOGPSIZE,
					(char *)&(logp[0]), PUT);
	if ( rc != 0 )
{
printf("Error RW 2\n");
		goto errout;
}

	/* initialize buffer to write 4 pages at a time */
	logp[0].h.eor = logp[0].t.eor = LOGPHDRSIZE;

	logp[2].h.eor = logp[2].t.eor = LOGPHDRSIZE;
	lrd_ptr = (struct lrd *)&logp[2].data;
	lrd_ptr->logtid = 0;
	lrd_ptr->backchain = 0;
	lrd_ptr->type = LOG_SYNCPT;
	lrd_ptr->length = 0;
	lrd_ptr->log.syncpt.sync = 0;

	logp[3].h.eor = logp[3].t.eor = LOGPHDRSIZE;
	lrd_ptr = (struct lrd *)&logp[3].data;
	lrd_ptr->logtid = 0;
	lrd_ptr->backchain = 0;
	lrd_ptr->type = LOG_SYNCPT;
	lrd_ptr->length = 0;
	lrd_ptr->log.syncpt.sync = 0;

	/* initialize succeeding log  pages: lpsn = 1, 2, ..., (N-2) */
	Working_counter = 0;
	log_contwt = log_begin + LOGBUFSIZE;
	for ( k = 1; k < npages - 4; k+=4 )
	{
		logp[0].h.page = logp[0].t.page = k;
		logp[1].h.page = logp[1].t.page = k + 1;
		logp[2].h.page = logp[2].t.page = k + 2;
		logp[3].h.page = logp[3].t.page = k + 3;
		rc = ujfs_rw_diskblocks(fd, log_contwt, 
				(unsigned) LOGBUFSIZE, (char *)&(logp[0]), PUT);
		if (rc != 0 )
{
printf("Error RW 3\n");
		goto errout;
}
		log_contwt += LOGBUFSIZE;

		if( !stdout_redirected ) {
  			Working_counter++;
			switch( Working_counter ) {
			    case( 100 ):
				DosPutMessage( 1, strlen(Working[0]), Working[0] );
				fflush( stdout );
				break;
			    case( 200 ):
				DosPutMessage( 1, strlen(Working[1]), Working[1] );
				fflush( stdout );
				break;
			    case( 300 ):
				DosPutMessage( 1, strlen(Working[2]), Working[2] );
				fflush( stdout );
				break;
			    case( 400 ):
				DosPutMessage( 1, strlen(Working[3]), Working[3] );
				fflush( stdout );
				Working_counter = 0;
				break;
			    default:
				break;
			}
		}
	}
	if (!inlinelog)
	{
        	rc = DosDevIOCtl(fd, IOCTL_DISK, DSK_UNLOCKDRIVE, &parms,
				 sizeof(parms), &parmlen, &parms,
				 sizeof(parms), &parmlen);
        	rc = DosClose(fd);
	}

	return(0);

errout:
	if (rc == ERROR_WRITE_PROTECT)
		message_user(ERROR_WRITE_PROTECT, NULL, 0, STDOUT_CODE,
			     NO_RESPONSE, OSO_MSG);
	return(-1);

}
Exemple #12
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);
}
Exemple #13
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);
	    }
	}
    }
}
Exemple #14
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++;
	    }
	}
    }
}