/* * 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 ); }
/* * 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); }
/* * 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); }