Exemple #1
0
/*
 * NAME: ujfs_init_superblock
 *
 * FUNCTION: Initialize primary and secondary aggregate superblock and write to
 *      disk
 *
 * PRE CONDITIONS:
 *
 * POST CONDITIONS:
 *
 * PARAMETERS:
 *      aggr_superblock         - structure to be filled in with superblock
 *                                information.
 *      dev_ptr                 - open port for device to write superblock to
 *      volume_label            - Volume label for superblock
 *      number_of_blocks        - Number of blocks for aggregate
 *      compress                - Whether this is a compressed aggregate
 *      fs_block_size           - block size for aggregate
 *      phys_block_size         - physical block size for device
 *      type_jfs                - JFS type to create; s_flag field of superblock
 *      secondary_ait_address   - block offset of first extent of secondary
 *                                aggregate inode table
 *      secondary_ait_length    - number of blocks of first extent of secondary
 *                                aggregate inode table
 *      fsck_svclog_length      - number of blocks of fsck_wspace_length is
 *                                intended for the fsck service log.
 *      ag_size                 - AG size
 *      fsck_wspace_address     - block offset of start of fsck working space
 *      fsck_wspace_length      - number of blocks of fsck working space
 *      logloc                  - block offset of start of log in aggr.
 *      logsize                 - number of blocks of log in aggr.
 *      secondary_aim_address   - block offset of first extent of secondary
 *                                aggregate inode map
 *      secondary_aim_length    - number of blocks of first extent of secondary
 *                                aggregate inode map
 *
 * RETURNS:
 *      0: success
 *      Any other return value indicates failure
 */
int32 ujfs_init_superblock( struct superblock   *aggr_superblock,
                            HFILE               dev_ptr,
                            char                *volume_label,
                            int64               number_of_blocks,
                            uint32              compress,
                            int32               fs_block_size,
                            int32               phys_block_size,
                            uint32              type_jfs,
                            int64               secondary_ait_address,
                            int32               secondary_ait_length,
                            int32               ag_size,
                            int64               fsck_wspace_address,
                            int32               fsck_wspace_length,
                            int32               fsck_svclog_length,
                            int64               logloc,
                            int32               logsize,
                            int64               secondary_aim_address,
                            int32               secondary_aim_length )
{
    int32       rc;

    /*
     * Initialize all of the fields of the superblock
     */
    strncpy(aggr_superblock->s_magic, JFS_MAGIC, strlen(JFS_MAGIC));
    aggr_superblock->s_version = JFS_VERSION;
    aggr_superblock->s_logdev = 0;
    aggr_superblock->s_logserial = 0;
    aggr_superblock->s_size = (number_of_blocks * fs_block_size) /
                              phys_block_size;
    aggr_superblock->s_bsize = fs_block_size;
    aggr_superblock->s_l2bsize = log2shift( aggr_superblock->s_bsize );
    aggr_superblock->s_l2bfactor = log2shift( aggr_superblock->s_bsize /
                                              phys_block_size );
    aggr_superblock->s_pbsize = phys_block_size;
    aggr_superblock->s_l2pbsize = log2shift( aggr_superblock->s_pbsize );
    aggr_superblock->s_agsize = ag_size;
    aggr_superblock->s_flag = type_jfs;
    aggr_superblock->s_compress = compress;
    aggr_superblock->s_state = FM_CLEAN;
    strncpy(aggr_superblock->s_fpack, volume_label, LV_NAME_SIZE );

    PXDaddress( &(aggr_superblock->s_ait2), secondary_ait_address );
    PXDlength( &(aggr_superblock->s_ait2), secondary_ait_length );

    PXDaddress( &(aggr_superblock->s_aim2), secondary_aim_address );
    PXDlength( &(aggr_superblock->s_aim2), secondary_aim_length );

    PXDaddress( &(aggr_superblock->s_fsckpxd), fsck_wspace_address );
    PXDlength( &(aggr_superblock->s_fsckpxd), fsck_wspace_length );
    aggr_superblock->s_fscklog = 0;
    aggr_superblock->s_fsckloglen = fsck_svclog_length;

    PXDaddress( &(aggr_superblock->s_logpxd), logloc );
    PXDlength( &(aggr_superblock->s_logpxd), logsize );

#ifdef	_JFS_DFS_LFS
    aggr_superblock->s_attach = 0;
    aggr_superblock->totalUsable = (aggr_superblock->s_size
                                        << aggr_superblock->s_l2pbsize) >> 10;
    aggr_superblock->minFree = 0;
    aggr_superblock->realFree = 0;
#endif	/* _JFS_DFS_LFS */
    aggr_superblock->s_time.tv_sec = (uint32) time( NULL );

    /*
     * Write both the primary and secondary superblocks to disk if valid
     */
    rc = ujfs_validate_super( aggr_superblock );
    if( rc != 0 ) {
        return rc;
    }
    rc = ujfs_put_superblk( dev_ptr, aggr_superblock, 1 );
    if( rc != 0 ) return rc;

    rc = ujfs_put_superblk( dev_ptr, aggr_superblock, 0 );

    return( rc );
}
Exemple #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);
}
Exemple #3
0
/*
 * NAME:        jfs_defragfs()
 *
 * FUNCTION:    relocate specified extent for defragfs()
 *              optionally commiting the operation.
 */
int32 jfs_defragfs(
	char	*pData,		/* pointer to buffer containing plist */ 
	uint32	lenData,	/* length of buffer */
	uint16	*pbufsize)	/* pointer of buffer length */ 
{
	int32	rc = 0;
	defragfs_t	pList, *p = &pList;
	uint32	xtype;
	int64	offset, xoff, oxaddr, nxaddr;
	int32	xlen;
	inode_t	*ipmnt, *ipimap, *ipbmap;
	inode_t	*ip = NULL;
	xad_t	oxad;
	pxd_t	opxd;
        mode_t	imode;
        int32	tid;
        inode_t	*iplist[1];
	struct vfs *vfsp;

	if (rc = KernCopyIn(&pList, pData, lenData))
		return rc;

	/* get the 'mount' inode */
        for (vfsp = vfs_anchor; vfsp != NULL; vfsp = vfsp->vfs_next)
		if (vfsp->vfs_vpfsi->vpi_drive == pList.dev)
			break;
	if (vfsp == NULL)
		return EINVAL;

	xtype = pList.flag;

	/* sync at start of defragfs ? */
	if (xtype & DEFRAGFS_SYNC)
	{
jEVENT(0,("jfs_defragfs: DEFRAGFS_SYNC\n"));

		if ((vfsp->vfs_flag & VFS_READONLY) ||
		    (vfsp->vfs_flag & VFS_ACCEPT))
			return 0;

		ipimap = (inode_t *)vfsp->vfs_data;
		ipmnt = ipimap->i_ipmnt;
		ipbmap = ipmnt->i_ipbmap;

		/* sync the file system */
		iSyncFS(vfsp);

		/* write dirty pages of imap */
		diSync(ipimap);

		/* write dirty pages of bmap */
		dbSync(ipbmap);

		return 0;
	}
	else if (!(xtype & DEFRAGFS_RELOCATE))
		return EINVAL;

	if (vfsp->vfs_flag & VFS_READONLY)
		return EROFS;

	if (vfsp->vfs_flag & VFS_ACCEPT)
		return EINVAL;

	/* get the relocation parameter */
        xoff = pList.xoff;
        oxaddr = pList.old_xaddr;
        nxaddr = pList.new_xaddr;
        xlen = pList.xlen;

jEVENT(0,("jfs_defragfs: i:%d xtype:0x%08x xoff:%lld xlen:%d xaddr:%lld:%lld\n",
	pList.ino, xtype, xoff, xlen, oxaddr, nxaddr));

	/* get the object inode if it exist */
	ICACHE_LOCK();
	rc = iget(vfsp, pList.ino, &ip, 0);
	ICACHE_UNLOCK();
	if(rc)
        {
jEVENT(0,("jfs_defragfs: stale target object.\n"));
		rc = ESTALE;  /* stale object ENOENT */
		goto out1;
        }

	IWRITE_LOCK(ip);
	
	/* validate inode */
	if (ip->i_nlink == 0  
	|| ip->i_gen != pList.gen
	|| ip->i_fileset != pList.fileset
	|| ip->i_inostamp != pList.inostamp)
	{
jEVENT(0,("jfs_defragfs: stale target object.\n"));
		rc = ESTALE;  /* stale object ENOENT */
		goto out1;
	}
	
	/* validate object type: regular file or directory */
	imode = ip->i_mode & IFMT;
	switch(imode)
	{
	case IFREG:
	case IFDIR:
		break;
	default:
		rc = ESTALE;	/* invalid object type ENOENT */
		goto out1;
	}

	/*
	 * try to allocate new destination extent
	 */
	if (rc = dbAllocExact(ip, nxaddr, xlen))
        {
jEVENT(0,("jfs_defragfs: stale destination extent.\n"));
		rc = ENOSPC;
		goto out1;
        }

	iBindCache(ip);

	/*
	 *	regular file: 
         */
	if (imode == IFREG)
	{
		/*
		 * automatic commit before and after each relocation 
		 * may be skipped after more experience;
		 */
		/*
		 * commit any update before relocation
		 */
		if (ip->i_flag & IUPD)
		{
			ip->i_flag |= IFSYNC;

			txBegin(ip->i_ipmnt, &tid, 0);
			iplist[0] = ip;
			rc = txCommit(tid, 1, &iplist[0], 0);
			if (rc)
				goto out2;
			txEnd(tid);
		}

		/*
		 *	relocate either xtpage or data extent
		 */
		txBegin(ip->i_ipmnt, &tid, 0);

		/* source extent xad */
		XADoffset(&oxad, xoff);
		XADaddress(&oxad, oxaddr);
		XADlength(&oxad, xlen);

		rc = xtRelocate(tid, ip, &oxad, nxaddr, xtype);
		if (rc)
			goto out2;

		iplist[0] = ip;
		rc = txCommit(tid, 1, &iplist[0], 0);
		if (rc)
			goto out2;

		txEnd(tid);
		goto out1;
	}
	/*
	 *	directory:
	 */
	else  /* IFDIR */
	{
		/*
		 *	relocate dtpage
		 */
		txBegin(ip->i_ipmnt, &tid, 0);

		/* source extent pxd */
		PXDaddress(&opxd, oxaddr);
		PXDlength(&opxd, xlen);
	
		rc = dtRelocate(tid, ip, xoff, &opxd, nxaddr); 
		if (rc)
			goto out2;

		iplist[0] = ip;
		rc = txCommit(tid, 1, &iplist[0], 0);
		if (rc)
			goto out2;

		txEnd(tid);
		goto out1;
	}

out2:
	dbFree(ip, nxaddr, xlen) ;

out1:
	if (ip)
	{
		IWRITE_UNLOCK(ip);

		ICACHE_LOCK();
		iput(ip, NULL);
		ICACHE_UNLOCK();
	}

jEVENT(0,("jfs_defragfs: rc=%d\n", rc));
	return (rc);
}