示例#1
0
/*
 * NAME:	free_ea_wmap(inode)
 *
 * FUNCTION:	free uncommitted extended attributes from working map
 *
 */
static inline void free_ea_wmap(struct inode *inode)
{
    dxd_t *ea = &JFS_IP(inode)->ea;

    if (ea->flag & DXD_EXTENT) {
        /* free EA pages from cache */
        invalidate_dxd_metapages(inode, *ea);
        dbFree(inode, addressDXD(ea), lengthDXD(ea));
    }
    ea->flag = 0;
}
示例#2
0
/*
 * NAME:	jfs_free_zero_link()
 *
 * FUNCTION:	for non-directory, called by iClose(),
 *		free resources of a file from cache and WORKING map
 *		for a file previously committed with zero link count
 *		while associated with a pager object,
 *
 * PARAMETER:	ip	- pointer to inode of file.
 */
void jfs_free_zero_link(struct inode *ip)
{
    int type;

    jfs_info("jfs_free_zero_link: ip = 0x%p", ip);

    /* return if not reg or symbolic link or if size is
     * already ok.
     */
    type = ip->i_mode & S_IFMT;

    switch (type) {
    case S_IFREG:
        break;
    case S_IFLNK:
        /* if its contained in inode nothing to do */
        if (ip->i_size < IDATASIZE)
            return;
        break;
    default:
        return;
    }

    /*
     * free EA
     */
    if (JFS_IP(ip)->ea.flag & DXD_EXTENT) {
        s64 xaddr = addressDXD(&JFS_IP(ip)->ea);
        int xlen = lengthDXD(&JFS_IP(ip)->ea);
        struct maplock maplock;	/* maplock for COMMIT_WMAP */
        struct pxd_lock *pxdlock;	/* maplock for COMMIT_WMAP */

        /* free EA pages from cache */
        invalidate_dxd_metapages(ip, JFS_IP(ip)->ea);

        /* free EA extent from working block map */
        maplock.index = 1;
        pxdlock = (struct pxd_lock *) & maplock;
        pxdlock->flag = mlckFREEPXD;
        PXDaddress(&pxdlock->pxd, xaddr);
        PXDlength(&pxdlock->pxd, xlen);
        txFreeMap(ip, pxdlock, NULL, COMMIT_WMAP);
    }

    /*
     * free ACL
     */
    if (JFS_IP(ip)->acl.flag & DXD_EXTENT) {
        s64 xaddr = addressDXD(&JFS_IP(ip)->acl);
        int xlen = lengthDXD(&JFS_IP(ip)->acl);
        struct maplock maplock;	/* maplock for COMMIT_WMAP */
        struct pxd_lock *pxdlock;	/* maplock for COMMIT_WMAP */

        invalidate_dxd_metapages(ip, JFS_IP(ip)->acl);

        /* free ACL extent from working block map */
        maplock.index = 1;
        pxdlock = (struct pxd_lock *) & maplock;
        pxdlock->flag = mlckFREEPXD;
        PXDaddress(&pxdlock->pxd, xaddr);
        PXDlength(&pxdlock->pxd, xlen);
        txFreeMap(ip, pxdlock, NULL, COMMIT_WMAP);
    }

    /*
     * free xtree/data (truncate to zero length):
     * free xtree/data pages from cache, and
     * free xtree/data blocks from working block map;
     */
    if (ip->i_size)
        xtTruncate(0, ip, 0, COMMIT_WMAP);
}
示例#3
0
/****************************************************************************
 * NAME: 	process_Inode_EA 
 *		
 * FUNCTION:	If the extent containing the Extended Attributes for the
 *		given inode contains any bad blocks, handle it.
 *
 * 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
 *
 *	didRelocate	ptr to var in which to return:
 *				 0 if the extent was not relocated
 *				!0 if the extent was relocated
 *
 * NOTES:	
 *
 * RETURNS:
 *      success: 0
 *      failure: something else
 */
int32 process_Inode_EA( dinode_t *dip, int8 doRelocate, int8 *didRelocate )
{
    int32 	sea_rc = 0;
    int32 	relocate_rc = 0;
    int64 	ext_firstblk, ext_lastblk;
    int32 	ext_len;
    cbbl_bdblk_recptr bdblk_recptr = NULL;
    cbbl_bdblk_recptr next_bdblk_recptr;
    int32	pList;
    ULONG 	pListLen = 0;
    clrbblks_t	pData;
    ULONG 	pDataLen = 0;

    ext_firstblk = addressDXD( &(dip->di_ea) );
    ext_len = lengthDXD( &(dip->di_ea) );
    ext_lastblk = ext_firstblk + ext_len - 1;

	/*
	 * find the first entry in bad block list with key greater 
	 * than or equal to the first block in this extent 
	 */
    sea_rc = baltree_search( ext_firstblk, &bdblk_recptr );
    if( sea_rc != 0 ) {  /* something fatal on search */
	return( sea_rc );
	}
    else if( bdblk_recptr == NULL ) {  /* hit end of tree w/o match */
	return( sea_rc );
	}  /* end hit end of tree w/o match */

    if( bdblk_recptr->fs_blkno <= ext_lastblk ) { /*
				* the extent contains at least 1 bad block
				*/
#ifdef _JFS_DEBUG
	printf("bad block 0x0%llx found in EA for inode %d\n", 
		bdblk_recptr->fs_blkno, dip->di_number );
#endif
	if( !doRelocate ) { /* relocation not requested */
	    sea_rc = we_DidntTryTo_Relocate(	ext_firstblk, 
						ext_lastblk,
						bdblk_recptr 
						);
	    }  /* end not asked to relocate */
	else {  /* relocation is requested */
	    pDataLen = sizeof(clrbblks_t);
	    pData.flag = CLRBBLKS_RELOCATE | CLRBBLKS_EA;
//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.old_xaddr = ext_firstblk;
	    pData.new_xaddr = 0;
	    pData.xlen = ext_len;
	    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 EA
		 */
	    if( !(*didRelocate) ) {  /* tried and failed to relocate */
		sea_rc = we_Couldnt_Relocate(	ext_firstblk, 
							ext_lastblk,
							bdblk_recptr, 
							relocate_rc 
							);
		}  /* end tried and failed to relocate */
	    else {  /* actually did relocate */
		sea_rc = we_Did_Relocate(	ext_firstblk, 
						ext_lastblk,
						bdblk_recptr 
						);
		}  /* else end actually did relocate */
	    }  /* end else relocation is requested */
	}  /* end the extent contains at least 1 bad block */

    return( sea_rc );
}				/* end process_Inode_EA()		*/
示例#4
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++;
	    }
	}
    }
}