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

📄 jfs_dmap.c

📁 jfs-2.4-1.1.7.tar.gz jfs 2.4-1.1.7 源码
💻 C
📖 第 1 页 / 共 5 页
字号:
			if (rc == 0) {				DBALLOC(bmp->db_DBmap, bmp->db_mapsize,					*results, nblocks);				mark_metapage_dirty(mp);			}			release_metapage(mp);			goto read_unlock;		}		release_metapage(mp);		IREAD_UNLOCK(ipbmap);	}	/* try to satisfy the allocation request with blocks within	 * the same allocation group as the hint.	 */	IWRITE_LOCK(ipbmap);	if ((rc = dbAllocAG(bmp, agno, nblocks, l2nb, results))	    != -ENOSPC) {		if (rc == 0)			DBALLOC(bmp->db_DBmap, bmp->db_mapsize,				*results, nblocks);		goto write_unlock;	}	IWRITE_UNLOCK(ipbmap);      pref_ag:	/*	 * Let dbNextAG recommend a preferred allocation group	 */	agno = dbNextAG(ipbmap);	IWRITE_LOCK(ipbmap);	/* Try to allocate within this allocation group.  if that fails, try to	 * allocate anywhere in the map.	 */	if ((rc = dbAllocAG(bmp, agno, nblocks, l2nb, results)) == -ENOSPC)		rc = dbAllocAny(bmp, nblocks, l2nb, results);	if (rc == 0) {		DBALLOC(bmp->db_DBmap, bmp->db_mapsize, *results, nblocks);	}      write_unlock:	IWRITE_UNLOCK(ipbmap);	return (rc);      read_unlock:	IREAD_UNLOCK(ipbmap);	return (rc);}#ifdef _NOTYET/* * NAME:	dbAllocExact() * * FUNCTION:    try to allocate the requested extent; * * PARAMETERS: *      ip	- pointer to in-core inode; *      blkno	- extent address; *      nblocks	- extent length; * * RETURN VALUES: *      0	- success *      -ENOSPC	- insufficient disk resources *      -EIO	- i/o error */int dbAllocExact(struct inode *ip, s64 blkno, int nblocks){	int rc;	struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap;	struct bmap *bmp = JFS_SBI(ip->i_sb)->bmap;	struct dmap *dp;	s64 lblkno;	struct metapage *mp;	IREAD_LOCK(ipbmap);	/*	 * validate extent request:	 *	 * note: defragfs policy:	 *  max 64 blocks will be moved.  	 *  allocation request size must be satisfied from a single dmap.	 */	if (nblocks <= 0 || nblocks > BPERDMAP || blkno >= bmp->db_mapsize) {		IREAD_UNLOCK(ipbmap);		return -EINVAL;	}	if (nblocks > ((s64) 1 << bmp->db_maxfreebud)) {		/* the free space is no longer available */		IREAD_UNLOCK(ipbmap);		return -ENOSPC;	}	/* read in the dmap covering the extent */	lblkno = BLKTODMAP(blkno, bmp->db_l2nbperpage);	mp = read_metapage(ipbmap, lblkno, PSIZE, 0);	if (mp == NULL) {		IREAD_UNLOCK(ipbmap);		return -EIO;	}	dp = (struct dmap *) mp->data;	/* try to allocate the requested extent */	rc = dbAllocNext(bmp, dp, blkno, nblocks);	IREAD_UNLOCK(ipbmap);	if (rc == 0) {		DBALLOC(bmp->db_DBmap, bmp->db_mapsize, blkno, nblocks);		mark_metapage_dirty(mp);	}	release_metapage(mp);	return (rc);}#endif /* _NOTYET *//* * NAME:	dbReAlloc() * * FUNCTION:    attempt to extend a current allocation by a specified *		number of blocks. * *		this routine attempts to satisfy the allocation request *		by first trying to extend the existing allocation in *		place by allocating the additional blocks as the blocks *		immediately following the current allocation.  if these *		blocks are not available, this routine will attempt to *		allocate a new set of contiguous blocks large enough *		to cover the existing allocation plus the additional *		number of blocks required. * * PARAMETERS: *      ip	    -  pointer to in-core inode requiring allocation. *      blkno	    -  starting block of the current allocation. *      nblocks	    -  number of contiguous blocks within the current *		       allocation. *      addnblocks  -  number of blocks to add to the allocation. *      results	-      on successful return, set to the starting block number *		       of the existing allocation if the existing allocation *		       was extended in place or to a newly allocated contiguous *		       range if the existing allocation could not be extended *		       in place. * * RETURN VALUES: *      0	- success *      -ENOSPC	- insufficient disk resources *      -EIO	- i/o error */intdbReAlloc(struct inode *ip,	  s64 blkno, s64 nblocks, s64 addnblocks, s64 * results){	int rc;	/* try to extend the allocation in place.	 */	if ((rc = dbExtend(ip, blkno, nblocks, addnblocks)) == 0) {		*results = blkno;		return (0);	} else {		if (rc != -ENOSPC)			return (rc);	}	/* could not extend the allocation in place, so allocate a	 * new set of blocks for the entire request (i.e. try to get	 * a range of contiguous blocks large enough to cover the	 * existing allocation plus the additional blocks.)	 */	return (dbAlloc		(ip, blkno + nblocks - 1, addnblocks + nblocks, results));}/* * NAME:	dbExtend() * * FUNCTION:    attempt to extend a current allocation by a specified *		number of blocks. * *		this routine attempts to satisfy the allocation request *		by first trying to extend the existing allocation in *		place by allocating the additional blocks as the blocks *		immediately following the current allocation. * * PARAMETERS: *      ip	    -  pointer to in-core inode requiring allocation. *      blkno	    -  starting block of the current allocation. *      nblocks	    -  number of contiguous blocks within the current *		       allocation. *      addnblocks  -  number of blocks to add to the allocation. * * RETURN VALUES: *      0	- success *      -ENOSPC	- insufficient disk resources *      -EIO	- i/o error */static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks){	struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);	s64 lblkno, lastblkno, extblkno;	uint rel_block;	struct metapage *mp;	struct dmap *dp;	int rc;	struct inode *ipbmap = sbi->ipbmap;	struct bmap *bmp;	/*	 * We don't want a non-aligned extent to cross a page boundary	 */	if (((rel_block = blkno & (sbi->nbperpage - 1))) &&	    (rel_block + nblocks + addnblocks > sbi->nbperpage))		return -ENOSPC;	/* get the last block of the current allocation */	lastblkno = blkno + nblocks - 1;	/* determine the block number of the block following	 * the existing allocation.	 */	extblkno = lastblkno + 1;	IREAD_LOCK(ipbmap);	/* better be within the file system */	bmp = sbi->bmap;	if (lastblkno < 0 || lastblkno >= bmp->db_mapsize) {		IREAD_UNLOCK(ipbmap);		jfs_error(ip->i_sb,			  "dbExtend: the block is outside the filesystem");		return -EIO;	}	/* we'll attempt to extend the current allocation in place by	 * allocating the additional blocks as the blocks immediately	 * following the current allocation.  we only try to extend the	 * current allocation in place if the number of additional blocks	 * can fit into a dmap, the last block of the current allocation	 * is not the last block of the file system, and the start of the	 * inplace extension is not on an allocation group boundry.	 */	if (addnblocks > BPERDMAP || extblkno >= bmp->db_mapsize ||	    (extblkno & (bmp->db_agsize - 1)) == 0) {		IREAD_UNLOCK(ipbmap);		return -ENOSPC;	}	/* get the buffer for the dmap containing the first block	 * of the extension.	 */	lblkno = BLKTODMAP(extblkno, bmp->db_l2nbperpage);	mp = read_metapage(ipbmap, lblkno, PSIZE, 0);	if (mp == NULL) {		IREAD_UNLOCK(ipbmap);		return -EIO;	}	DBALLOCCK(bmp->db_DBmap, bmp->db_mapsize, blkno, nblocks);	dp = (struct dmap *) mp->data;	/* try to allocate the blocks immediately following the	 * current allocation.	 */	rc = dbAllocNext(bmp, dp, extblkno, (int) addnblocks);	IREAD_UNLOCK(ipbmap);	/* were we successful ? */	if (rc == 0) {		DBALLOC(bmp->db_DBmap, bmp->db_mapsize, extblkno,			addnblocks);		write_metapage(mp);	} else		/* we were not successful */		release_metapage(mp);	return (rc);}/* * NAME:	dbAllocNext() * * FUNCTION:    attempt to allocate the blocks of the specified block *		range within a dmap. * * PARAMETERS: *      bmp	-  pointer to bmap descriptor *      dp	-  pointer to dmap. *      blkno	-  starting block number of the range. *      nblocks	-  number of contiguous free blocks of the range. * * RETURN VALUES: *      0	- success *      -ENOSPC	- insufficient disk resources *      -EIO	- i/o error * * serialization: IREAD_LOCK(ipbmap) held on entry/exit; */static int dbAllocNext(struct bmap * bmp, struct dmap * dp, s64 blkno,		       int nblocks){	int dbitno, word, rembits, nb, nwords, wbitno, nw;	int l2size;	s8 *leaf;	u32 mask;	if (dp->tree.leafidx != cpu_to_le32(LEAFIND)) {		jfs_error(bmp->db_ipbmap->i_sb,			  "dbAllocNext: Corrupt dmap page");		return -EIO;	}	/* pick up a pointer to the leaves of the dmap tree.	 */	leaf = dp->tree.stree + le32_to_cpu(dp->tree.leafidx);	/* determine the bit number and word within the dmap of the	 * starting block.	 */	dbitno = blkno & (BPERDMAP - 1);	word = dbitno >> L2DBWORD;	/* check if the specified block range is contained within	 * this dmap.	 */	if (dbitno + nblocks > BPERDMAP)		return -ENOSPC;	/* check if the starting leaf indicates that anything	 * is free.	 */	if (leaf[word] == NOFREE)		return -ENOSPC;	/* check the dmaps words corresponding to block range to see	 * if the block range is free.  not all bits of the first and	 * last words may be contained within the block range.  if this	 * is the case, we'll work against those words (i.e. partial first	 * and/or last) on an individual basis (a single pass) and examine	 * the actual bits to determine if they are free.  a single pass	 * will be used for all dmap words fully contained within the	 * specified range.  within this pass, the leaves of the dmap	 * tree will be examined to determine if the blocks are free. a	 * single leaf may describe the free space of multiple dmap	 * words, so we may visit only a subset of the actual leaves	 * corresponding to the dmap words of the block range.	 */	for (rembits = nblocks; rembits > 0; rembits -= nb, dbitno += nb) {		/* determine the bit number within the word and		 * the number of bits within the word.		 */		wbitno = dbitno & (DBWORD - 1);		nb = min(rembits, DBWORD - wbitno);		/* check if only part of the word is to be examined.		 */		if (nb < DBWORD) {			/* check if the bits are free.			 */			mask = (ONES << (DBWORD - nb) >> wbitno);			if ((mask & ~le32_to_cpu(dp->wmap[word])) != mask)				return -ENOSPC;			word += 1;		} else {			/* one or more dmap words are fully contained			 * within the block range.  determine how many			 * words and how many bits.			 */			nwords = rembits >> L2DBWORD;			nb = nwords << L2DBWORD;			/* now examine the appropriate leaves to determine			 * if the blocks are free.			 */			while (nwords > 0) {				/* does the leaf describe any free space ?				 */				if (leaf[word] < BUDMIN)					return -ENOSPC;				/* determine the l2 number of bits provided				 * by this leaf.				 */				l2size =				    min((int)leaf[word], NLSTOL2BSZ(nwords));				/* determine how many words were handled.				 */				nw = BUDSIZE(l2size, BUDMIN);				nwords -= nw;				word += nw;			}		}	}	/* allocate the blocks.	 */	return (dbAllocDmap(bmp, dp, blkno, nblocks));}/* * NAME:	dbAllocNear() * * FUNCTION:    attempt to allocate a number of contiguous free blocks near *		a specified block (hint) within a dmap. * *		starting with the dmap leaf that covers the hint, we'll *		check the next four contiguous leaves for sufficient free *		space.  if sufficient free space is found, we'll allocate *		the desired free space. * * PARAMETERS: *      bmp	-  pointer to bmap descriptor *      dp	-  pointer to dmap. *      blkno	-  block number to allocate near. *      nblocks	-  actual number of contiguous free blocks desired. *      l2nb	-  log2 number of contiguous free blocks desired. *      results	-  on successful return, set to the starting block number *		   of the newly allocated range. * * RETURN VALUES: *      0	- success *      -ENOSPC	- insufficient disk resources *      -EIO	- i/o error * * serialization: IREAD_LOCK(ipbmap) held on entry/exit; */static intdbAllocNear(struct bmap * bmp,	    struct dmap * dp, s64 blkno, int nblocks, int l2nb, s64 * results){

⌨️ 快捷键说明

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