⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jfs_imap.c

📁 jfs-2.4-1.1.7.tar.gz jfs 2.4-1.1.7 源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	ip->i_ino = inum;	address += inum >> 3;	/* 8 inodes per 4K page */	/* read the page of fixed disk inode (AIT) in raw mode */	mp = read_metapage(ip, address << sbi->l2nbperpage, PSIZE, 1);	if (mp == NULL) {		ip->i_sb = NULL;		ip->i_nlink = 1;	/* Don't want iput() deleting it */		iput(ip);		return (NULL);	}	/* get the pointer to the disk inode of interest */	dp = (struct dinode *) (mp->data);	dp += inum % 8;		/* 8 inodes per 4K page */	/* copy on-disk inode to in-memory inode */	if ((copy_from_dinode(dp, ip)) != 0) {		/* handle bad return by returning NULL for ip */		ip->i_sb = NULL;		ip->i_nlink = 1;	/* Don't want iput() deleting it */		iput(ip);		/* release the page */		release_metapage(mp);		return (NULL);	}	ip->i_mapping->a_ops = &jfs_aops;	ip->i_mapping->gfp_mask = GFP_NOFS;	if ((inum == FILESYSTEM_I) && (JFS_IP(ip)->ipimap == sbi->ipaimap)) {		sbi->gengen = le32_to_cpu(dp->di_gengen);		sbi->inostamp = le32_to_cpu(dp->di_inostamp);	}	/* release the page */	release_metapage(mp);	return (ip);}/* * NAME:        diWriteSpecial() * * FUNCTION:    Write the special inode to disk * * PARAMETERS: *      ip - special inode *	secondary - 1 if secondary aggregate inode table * * RETURN VALUES: none */void diWriteSpecial(struct inode *ip, int secondary){	struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);	uint address;	struct dinode *dp;	ino_t inum = ip->i_ino;	struct metapage *mp;	ip->i_state &= ~I_DIRTY;	if (secondary)		address = addressPXD(&sbi->ait2) >> sbi->l2nbperpage;	else		address = AITBL_OFF >> L2PSIZE;	ASSERT(inum < INOSPEREXT);	address += inum >> 3;	/* 8 inodes per 4K page */	/* read the page of fixed disk inode (AIT) in raw mode */	mp = read_metapage(ip, address << sbi->l2nbperpage, PSIZE, 1);	if (mp == NULL) {		jfs_err("diWriteSpecial: failed to read aggregate inode "			"extent!");		return;	}	/* get the pointer to the disk inode of interest */	dp = (struct dinode *) (mp->data);	dp += inum % 8;		/* 8 inodes per 4K page */	/* copy on-disk inode to in-memory inode */	copy_to_dinode(dp, ip);	memcpy(&dp->di_xtroot, &JFS_IP(ip)->i_xtroot, 288);	if (inum == FILESYSTEM_I)		dp->di_gengen = cpu_to_le32(sbi->gengen);	/* write the page */	write_metapage(mp);}/* * NAME:        diFreeSpecial() * * FUNCTION:    Free allocated space for special inode */void diFreeSpecial(struct inode *ip){	if (ip == NULL) {		jfs_err("diFreeSpecial called with NULL ip!");		return;	}	fsync_inode_data_buffers(ip);	truncate_inode_pages(ip->i_mapping, 0);	iput(ip);}/* * NAME:        diWrite() * * FUNCTION:    write the on-disk inode portion of the in-memory inode *		to its corresponding on-disk inode. * *		on entry, the specifed incore inode should itself *		specify the disk inode number corresponding to the *		incore inode (i.e. i_number should be initialized). * *		the inode contains the inode extent address for the disk *		inode.  with the inode extent address in hand, the *		page of the extent that contains the disk inode is *		read and the disk inode portion of the incore inode *		is copied to the disk inode. *		 * PARAMETERS: *	tid -  transacation id *      ip  -  pointer to incore inode to be written to the inode extent. * * RETURN VALUES: *      0       - success *      -EIO  	- i/o error. */int diWrite(tid_t tid, struct inode *ip){	struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);	struct jfs_inode_info *jfs_ip = JFS_IP(ip);	int rc = 0;	s32 ino;	struct dinode *dp;	s64 blkno;	int block_offset;	int inodes_left;	struct metapage *mp;	uint pageno;	int rel_inode;	int dioffset;	struct inode *ipimap;	uint type;	lid_t lid;	struct tlock *ditlck, *tlck;	struct linelock *dilinelock, *ilinelock;	struct lv *lv;	int n;	ipimap = jfs_ip->ipimap;	ino = ip->i_ino & (INOSPERIAG - 1);	if (!addressPXD(&(jfs_ip->ixpxd)) ||	    (lengthPXD(&(jfs_ip->ixpxd)) !=	     JFS_IP(ipimap)->i_imap->im_nbperiext)) {		jfs_error(ip->i_sb, "diWrite: ixpxd invalid");		return -EIO;	}	/*	 * read the page of disk inode containing the specified inode:	 */	/* compute the block address of the page */	blkno = INOPBLK(&(jfs_ip->ixpxd), ino, sbi->l2nbperpage);	rel_inode = (ino & (INOSPERPAGE - 1));	pageno = blkno >> sbi->l2nbperpage;	if ((block_offset = ((u32) blkno & (sbi->nbperpage - 1)))) {		/*		 * OS/2 didn't always align inode extents on page boundaries		 */		inodes_left =		    (sbi->nbperpage - block_offset) << sbi->l2niperblk;		if (rel_inode < inodes_left)			rel_inode += block_offset << sbi->l2niperblk;		else {			pageno += 1;			rel_inode -= inodes_left;		}	}	/* read the page of disk inode */      retry:	mp = read_metapage(ipimap, pageno << sbi->l2nbperpage, PSIZE, 1);	if (mp == 0)		return -EIO;	/* get the pointer to the disk inode */	dp = (struct dinode *) mp->data;	dp += rel_inode;	dioffset = (ino & (INOSPERPAGE - 1)) << L2DISIZE;	/*	 * acquire transaction lock on the on-disk inode;	 * N.B. tlock is acquired on ipimap not ip;	 */	if ((ditlck =	     txLock(tid, ipimap, mp, tlckINODE | tlckENTRY)) == NULL)		goto retry;	dilinelock = (struct linelock *) & ditlck->lock;	/*	 * copy btree root from in-memory inode to on-disk inode	 *	 * (tlock is taken from inline B+-tree root in in-memory	 * inode when the B+-tree root is updated, which is pointed 	 * by jfs_ip->blid as well as being on tx tlock list)	 *	 * further processing of btree root is based on the copy 	 * in in-memory inode, where txLog() will log from, and, 	 * for xtree root, txUpdateMap() will update map and reset	 * XAD_NEW bit;	 */	if (S_ISDIR(ip->i_mode) && (lid = jfs_ip->xtlid)) {		/*		 * This is the special xtree inside the directory for storing		 * the directory table		 */		xtpage_t *p, *xp;		xad_t *xad;		jfs_ip->xtlid = 0;		tlck = lid_to_tlock(lid);		assert(tlck->type & tlckXTREE);		tlck->type |= tlckBTROOT;		tlck->mp = mp;		ilinelock = (struct linelock *) & tlck->lock;		/*		 * copy xtree root from inode to dinode:		 */		p = &jfs_ip->i_xtroot;		xp = (xtpage_t *) &dp->di_dirtable;		lv = ilinelock->lv;		for (n = 0; n < ilinelock->index; n++, lv++) {			memcpy(&xp->xad[lv->offset], &p->xad[lv->offset],			       lv->length << L2XTSLOTSIZE);		}		/* reset on-disk (metadata page) xtree XAD_NEW bit */		xad = &xp->xad[XTENTRYSTART];		for (n = XTENTRYSTART;		     n < le16_to_cpu(xp->header.nextindex); n++, xad++)			if (xad->flag & (XAD_NEW | XAD_EXTENDED))				xad->flag &= ~(XAD_NEW | XAD_EXTENDED);	}	if ((lid = jfs_ip->blid) == 0)		goto inlineData;	jfs_ip->blid = 0;	tlck = lid_to_tlock(lid);	type = tlck->type;	tlck->type |= tlckBTROOT;	tlck->mp = mp;	ilinelock = (struct linelock *) & tlck->lock;	/*	 *      regular file: 16 byte (XAD slot) granularity	 */	if (type & tlckXTREE) {		xtpage_t *p, *xp;		xad_t *xad;		/*		 * copy xtree root from inode to dinode:		 */		p = &jfs_ip->i_xtroot;		xp = &dp->di_xtroot;		lv = ilinelock->lv;		for (n = 0; n < ilinelock->index; n++, lv++) {			memcpy(&xp->xad[lv->offset], &p->xad[lv->offset],			       lv->length << L2XTSLOTSIZE);		}		/* reset on-disk (metadata page) xtree XAD_NEW bit */		xad = &xp->xad[XTENTRYSTART];		for (n = XTENTRYSTART;		     n < le16_to_cpu(xp->header.nextindex); n++, xad++)			if (xad->flag & (XAD_NEW | XAD_EXTENDED))				xad->flag &= ~(XAD_NEW | XAD_EXTENDED);	}	/*	 *      directory: 32 byte (directory entry slot) granularity	 */	else if (type & tlckDTREE) {		dtpage_t *p, *xp;		/*		 * copy dtree root from inode to dinode:		 */		p = (dtpage_t *) &jfs_ip->i_dtroot;		xp = (dtpage_t *) & dp->di_dtroot;		lv = ilinelock->lv;		for (n = 0; n < ilinelock->index; n++, lv++) {			memcpy(&xp->slot[lv->offset], &p->slot[lv->offset],			       lv->length << L2DTSLOTSIZE);		}	} else {		jfs_err("diWrite: UFO tlock");	}      inlineData:	/*	 * copy inline symlink from in-memory inode to on-disk inode	 */	if (S_ISLNK(ip->i_mode) && ip->i_size < IDATASIZE) {		lv = & dilinelock->lv[dilinelock->index];		lv->offset = (dioffset + 2 * 128) >> L2INODESLOTSIZE;		lv->length = 2;		memcpy(&dp->di_fastsymlink, jfs_ip->i_inline, IDATASIZE);		dilinelock->index++;	}	/*	 * copy inline data from in-memory inode to on-disk inode:	 * 128 byte slot granularity	 */	if (test_cflag(COMMIT_Inlineea, ip)) {		lv = & dilinelock->lv[dilinelock->index];		lv->offset = (dioffset + 3 * 128) >> L2INODESLOTSIZE;		lv->length = 1;		memcpy(&dp->di_inlineea, jfs_ip->i_inline_ea, INODESLOTSIZE);		dilinelock->index++;		clear_cflag(COMMIT_Inlineea, ip);	}	/*	 *      lock/copy inode base: 128 byte slot granularity	 */// baseDinode:	lv = & dilinelock->lv[dilinelock->index];	lv->offset = dioffset >> L2INODESLOTSIZE;	copy_to_dinode(dp, ip);	if (test_and_clear_cflag(COMMIT_Dirtable, ip)) {		lv->length = 2;		memcpy(&dp->di_dirtable, &jfs_ip->i_dirtable, 96);	} else		lv->length = 1;	dilinelock->index++;#ifdef _JFS_FASTDASD	/*	 * We aren't logging changes to the DASD used in directory inodes,	 * but we need to write them to disk.  If we don't unmount cleanly,	 * mount will recalculate the DASD used.	 */	if (S_ISDIR(ip->i_mode)	    && (ip->i_ipmnt->i_mntflag & JFS_DASD_ENABLED))		bcopy(&ip->i_DASD, &dp->di_DASD, sizeof(struct dasd));#endif				/*  _JFS_FASTDASD */	/* release the buffer holding the updated on-disk inode. 	 * the buffer will be later written by commit processing.	 */	write_metapage(mp);	return (rc);}/* * NAME:        diFree(ip) * * FUNCTION:    free a specified inode from the inode working map *		for a fileset or aggregate. * *		if the inode to be freed represents the first (only) *		free inode within the iag, the iag will be placed on *		the ag free inode list. *	 *		freeing the inode will cause the inode extent to be *		freed if the inode is the only allocated inode within *		the extent.  in this case all the disk resource backing *		up the inode extent will be freed. in addition, the iag *		will be placed on the ag extent free list if the extent *		is the first free extent in the iag.  if freeing the *		extent also means that no free inodes will exist for *		the iag, the iag will also be removed from the ag free *		inode list. * *		the iag describing the inode will be freed if the extent *		is to be freed and it is the only backed extent within *		the iag.  in this case, the iag will be removed from the *		ag free extent list and ag free inode list and placed on *		the inode map's free iag list. * *		a careful update approach is used to provide consistency *		in the face of updates to multiple buffers.  under this *		approach, all required buffers are obtained before making *		any updates and are held until all updates are complete. * * PARAMETERS: *      ip  	- inode to be freed. * * RETURN VALUES: *      0       - success *      -EIO  	- i/o error. */int diFree(struct inode *ip){	int rc;	ino_t inum = ip->i_ino;	struct iag *iagp, *aiagp, *biagp, *ciagp, *diagp;	struct metapage *mp, *amp, *bmp, *cmp, *dmp;	int iagno, ino, extno, bitno, sword, agno;	int back, fwd;	u32 bitmap, mask;	struct inode *ipimap = JFS_SBI(ip->i_sb)->ipimap;	struct inomap *imap = JFS_IP(ipimap)->i_imap;	pxd_t freepxd;	tid_t tid;	struct inode *iplist[3];	struct tlock *tlck;	struct pxd_lock *pxdlock;	/*	 * This is just to suppress compiler warnings.  The same logic that	 * references these variables is used to initialize them.	 */	aiagp = biagp = ciagp = diagp = NULL;	/* get the iag number containing the inode.	 */	iagno = INOTOIAG(inum);	/* make sure that the iag is contained within 	 * the map.	 */	if (iagno >= imap->im_nextiag) {		dump_mem("imap", imap, 32);		jfs_error(ip->i_sb,			  "diFree: inum = %d, iagno = %d, nextiag = %d",			  (uint) inum, iagno, imap->im_nextiag);		return -EIO;	}	/* get the allocation group for this ino.	 */	agno = JFS_IP(ip)->agno;	/* Lock the AG specific inode map information	 */	AG_LOCK(imap, agno);	/* Obtain read lock in imap inode.  Don't release it until we have	 * read all of the IAG's that we are going to.	 */	IREAD_LOCK(ipimap);	/* read the iag.	 */	if ((rc = diIAGRead(imap, iagno, &mp))) {		IREAD_UNLOCK(ipimap);		AG_UNLOCK(imap, agno);		return (rc);	}	iagp = (struct iag *) mp->data;	/* get the inode number and extent number of the inode within	 * the iag and the inode number within the extent.	 */	ino = inum & (INOSPERIAG - 1);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -