/* assign a buffer for the page */ mp = get_metapage(ipimap, blkno, PSIZE, 0); if (!mp) { /* * This is very unlikely since we just created the * extent, but let's try to handle it correctly */ xtTruncate(tid, ipimap, ipimap->i_size - PSIZE, COMMIT_PWMAP);  txAbort(tid, 0); txEnd(tid);  /* release the inode map lock */ IWRITE_UNLOCK(ipimap);  rc = -EIO; goto out; } iagp = (struct iag *) mp->data;  /* init the iag */ memset(iagp, 0, sizeof(struct iag)); iagp->iagnum = cpu_to_le32(iagno); iagp->inofreefwd = iagp->inofreeback = cpu_to_le32(-1); iagp->extfreefwd = iagp->extfreeback = cpu_to_le32(-1); iagp->iagfree = cpu_to_le32(-1); iagp->nfreeinos = 0; iagp->nfreeexts = cpu_to_le32(EXTSPERIAG);  /* initialize the free inode summary map (free extent * summary map initialization handled by bzero). */ for (i = 0; i < SMAPSZ; i++) iagp->inosmap[i] = cpu_to_le32(ONES);  /* * Write and sync the metapage */ flush_metapage(mp);  
diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp){	int rc;	int iagno, i, xlen;	struct inode *ipimap;	struct super_block *sb;	struct jfs_sb_info *sbi;	struct metapage *mp;	struct iag *iagp;	s64 xaddr = 0;	s64 blkno;	tid_t tid;#ifdef _STILL_TO_PORT	xad_t xad;#endif				/*  _STILL_TO_PORT */	struct inode *iplist[1];	/* pick up pointers to the inode map and mount inodes */	ipimap = imap->im_ipimap;	sb = ipimap->i_sb;	sbi = JFS_SBI(sb);	/* acquire the free iag lock */	IAGFREE_LOCK(imap);	/* if there are any iags on the inode map free iag list, 	 * allocate the iag from the head of the list.	 */	if (imap->im_freeiag >= 0) {		/* pick up the iag number at the head of the list */		iagno = imap->im_freeiag;		/* determine the logical block number of the iag */		blkno = IAGTOLBLK(iagno, sbi->l2nbperpage);	} else {		/* no free iags. the inode map will have to be extented		 * to include a new iag.		 */		/* acquire inode map lock */		IWRITE_LOCK(ipimap);		if (ipimap->i_size >> L2PSIZE != imap->im_nextiag + 1) {			IWRITE_UNLOCK(ipimap);			IAGFREE_UNLOCK(imap);			jfs_error(imap->im_ipimap->i_sb,				  "diNewIAG: ipimap->i_size is wrong");			return -EIO;		}		/* get the next avaliable iag number */		iagno = imap->im_nextiag;		/* make sure that we have not exceeded the maximum inode		 * number limit.		 */		if (iagno > (MAXIAGS - 1)) {			/* release the inode map lock */			IWRITE_UNLOCK(ipimap);			rc = -ENOSPC;			goto out;		}		/*		 * synchronously append new iag page.		 */		/* determine the logical address of iag page to append */		blkno = IAGTOLBLK(iagno, sbi->l2nbperpage);		/* Allocate extent for new iag page */		xlen = sbi->nbperpage;		if ((rc = dbAlloc(ipimap, 0, (s64) xlen, &xaddr))) {			/* release the inode map lock */			IWRITE_UNLOCK(ipimap);			goto out;		}		/* assign a buffer for the page */		mp = get_metapage(ipimap, xaddr, PSIZE, 1);		if (!mp) {			/* Free the blocks allocated for the iag since it was			 * not successfully added to the inode map			 */			dbFree(ipimap, xaddr, (s64) xlen);			/* release the inode map lock */			IWRITE_UNLOCK(ipimap);			rc = -EIO;			goto out;		}		iagp = (struct iag *) mp->data;		/* init the iag */		memset(iagp, 0, sizeof(struct iag));		iagp->iagnum = cpu_to_le32(iagno);		iagp->inofreefwd = iagp->inofreeback = cpu_to_le32(-1);		iagp->extfreefwd = iagp->extfreeback = cpu_to_le32(-1);		iagp->iagfree = cpu_to_le32(-1);		iagp->nfreeinos = 0;		iagp->nfreeexts = cpu_to_le32(EXTSPERIAG);		/* initialize the free inode summary map (free extent		 * summary map initialization handled by bzero).		 */		for (i = 0; i < SMAPSZ; i++)			iagp->inosmap[i] = cpu_to_le32(ONES);		/*		 * Invalidate the page after writing and syncing it.		 * After it's initialized, we access it in a different		 * address space		 */		set_bit(META_discard, &mp->flag);		flush_metapage(mp);		/*		 * start tyransaction of update of the inode map		 * addressing structure pointing to the new iag page;		 */		tid = txBegin(sb, COMMIT_FORCE);		down(&JFS_IP(ipimap)->commit_sem);		/* update the inode map addressing structure to point to it */		if ((rc =		     xtInsert(tid, ipimap, 0, blkno, xlen, &xaddr, 0))) {			txEnd(tid);			up(&JFS_IP(ipimap)->commit_sem);			/* Free the blocks allocated for the iag since it was			 * not successfully added to the inode map			 */			dbFree(ipimap, xaddr, (s64) xlen);			/* release the inode map lock */			IWRITE_UNLOCK(ipimap);			goto out;		}		/* update the inode map's inode to reflect the extension */		ipimap->i_size += PSIZE;		inode_add_bytes(ipimap, PSIZE);		/*		 * txCommit(COMMIT_FORCE) will synchronously write address 		 * index pages and inode after commit in careful update order 		 * of address index pages (right to left, bottom up);		 */		iplist[0] = ipimap;		rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE);		txEnd(tid);		up(&JFS_IP(ipimap)->commit_sem);		duplicateIXtree(sb, blkno, xlen, &xaddr);		/* update the next avaliable iag number */		imap->im_nextiag += 1;		/* Add the iag to the iag free list so we don't lose the iag		 * if a failure happens now.		 */		imap->im_freeiag = iagno;		/* Until we have logredo working, we want the imap inode &		 * control page to be up to date.		 */		diSync(ipimap);		/* release the inode map lock */		IWRITE_UNLOCK(ipimap);	}	/* obtain read lock on map */	IREAD_LOCK(ipimap);	/* read the iag */	if ((rc = diIAGRead(imap, iagno, &mp))) {		IREAD_UNLOCK(ipimap);		rc = -EIO;		goto out;	}	iagp = (struct iag *) mp->data;	/* remove the iag from the iag free list */	imap->im_freeiag = le32_to_cpu(iagp->iagfree);	iagp->iagfree = cpu_to_le32(-1);	/* set the return iag number and buffer pointer */	*iagnop = iagno;	*mpp = mp;      out:	/* release the iag free lock */	IAGFREE_UNLOCK(imap);	return (rc);}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/d2e83707edbe6a2520591141421d26a87414a1b9/jfs_imap.c/clean/fs/jfs/jfs_imap.c