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

📄 jfs_extent.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *   Copyright (C) International Business Machines Corp., 2000-2004 * *   This program is free software;  you can redistribute it and/or modify *   it under the terms of the GNU General Public License as published by *   the Free Software Foundation; either version 2 of the License, or *   (at your option) any later version. * *   This program is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY;  without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See *   the GNU General Public License for more details. * *   You should have received a copy of the GNU General Public License *   along with this program;  if not, write to the Free Software *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <linux/fs.h>#include <linux/quotaops.h>#include "jfs_incore.h"#include "jfs_inode.h"#include "jfs_superblock.h"#include "jfs_dmap.h"#include "jfs_extent.h"#include "jfs_debug.h"/* * forward references */static int extBalloc(struct inode *, s64, s64 *, s64 *);#ifdef _NOTYETstatic int extBrealloc(struct inode *, s64, s64, s64 *, s64 *);#endifstatic s64 extRoundDown(s64 nb);#define DPD(a)		(printk("(a): %d\n",(a)))#define DPC(a)		(printk("(a): %c\n",(a)))#define DPL1(a)					\{						\	if ((a) >> 32)				\		printk("(a): %x%08x  ",(a));	\	else					\		printk("(a): %x  ",(a) << 32);	\}#define DPL(a)					\{						\	if ((a) >> 32)				\		printk("(a): %x%08x\n",(a));	\	else					\		printk("(a): %x\n",(a) << 32);	\}#define DPD1(a)		(printk("(a): %d  ",(a)))#define DPX(a)		(printk("(a): %08x\n",(a)))#define DPX1(a)		(printk("(a): %08x  ",(a)))#define DPS(a)		(printk("%s\n",(a)))#define DPE(a)		(printk("\nENTERING: %s\n",(a)))#define DPE1(a)		(printk("\nENTERING: %s",(a)))#define DPS1(a)		(printk("  %s  ",(a)))/* * NAME:	extAlloc() * * FUNCTION:	allocate an extent for a specified page range within a *		file. * * PARAMETERS: *	ip	- the inode of the file. *	xlen	- requested extent length. *	pno	- the starting page number with the file. *	xp	- pointer to an xad.  on entry, xad describes an *		  extent that is used as an allocation hint if the *		  xaddr of the xad is non-zero.  on successful exit, *		  the xad describes the newly allocated extent. *	abnr	- bool indicating whether the newly allocated extent *		  should be marked as allocated but not recorded. * * RETURN VALUES: *	0	- success *	-EIO	- i/o error. *	-ENOSPC	- insufficient disk resources. */intextAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr){	struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);	s64 nxlen, nxaddr, xoff, hint, xaddr = 0;	int rc;	int xflag;	/* This blocks if we are low on resources */	txBeginAnon(ip->i_sb);	/* Avoid race with jfs_commit_inode() */	mutex_lock(&JFS_IP(ip)->commit_mutex);	/* validate extent length */	if (xlen > MAXXLEN)		xlen = MAXXLEN;	/* get the page's starting extent offset */	xoff = pno << sbi->l2nbperpage;	/* check if an allocation hint was provided */	if ((hint = addressXAD(xp))) {		/* get the size of the extent described by the hint */		nxlen = lengthXAD(xp);		/* check if the hint is for the portion of the file		 * immediately previous to the current allocation		 * request and if hint extent has the same abnr		 * value as the current request.  if so, we can		 * extend the hint extent to include the current		 * extent if we can allocate the blocks immediately		 * following the hint extent.		 */		if (offsetXAD(xp) + nxlen == xoff &&		    abnr == ((xp->flag & XAD_NOTRECORDED) ? true : false))			xaddr = hint + nxlen;		/* adjust the hint to the last block of the extent */		hint += (nxlen - 1);	}	/* allocate the disk blocks for the extent.  initially, extBalloc()	 * will try to allocate disk blocks for the requested size (xlen).	 * if this fails (xlen contiguous free blocks not avaliable), it'll	 * try to allocate a smaller number of blocks (producing a smaller	 * extent), with this smaller number of blocks consisting of the	 * requested number of blocks rounded down to the next smaller	 * power of 2 number (i.e. 16 -> 8).  it'll continue to round down	 * and retry the allocation until the number of blocks to allocate	 * is smaller than the number of blocks per page.	 */	nxlen = xlen;	if ((rc = extBalloc(ip, hint ? hint : INOHINT(ip), &nxlen, &nxaddr))) {		mutex_unlock(&JFS_IP(ip)->commit_mutex);		return (rc);	}	/* Allocate blocks to quota. */	if (DQUOT_ALLOC_BLOCK(ip, nxlen)) {		dbFree(ip, nxaddr, (s64) nxlen);		mutex_unlock(&JFS_IP(ip)->commit_mutex);		return -EDQUOT;	}	/* determine the value of the extent flag */	xflag = abnr ? XAD_NOTRECORDED : 0;	/* if we can extend the hint extent to cover the current request,	 * extend it.  otherwise, insert a new extent to	 * cover the current request.	 */	if (xaddr && xaddr == nxaddr)		rc = xtExtend(0, ip, xoff, (int) nxlen, 0);	else		rc = xtInsert(0, ip, xflag, xoff, (int) nxlen, &nxaddr, 0);	/* if the extend or insert failed,	 * free the newly allocated blocks and return the error.	 */	if (rc) {		dbFree(ip, nxaddr, nxlen);		DQUOT_FREE_BLOCK(ip, nxlen);		mutex_unlock(&JFS_IP(ip)->commit_mutex);		return (rc);	}	/* set the results of the extent allocation */	XADaddress(xp, nxaddr);	XADlength(xp, nxlen);	XADoffset(xp, xoff);	xp->flag = xflag;	mark_inode_dirty(ip);	mutex_unlock(&JFS_IP(ip)->commit_mutex);	/*	 * COMMIT_SyncList flags an anonymous tlock on page that is on	 * sync list.	 * We need to commit the inode to get the page written disk.	 */	if (test_and_clear_cflag(COMMIT_Synclist,ip))		jfs_commit_inode(ip, 0);	return (0);}#ifdef _NOTYET/* * NAME:	extRealloc() * * FUNCTION:	extend the allocation of a file extent containing a *		partial back last page. * * PARAMETERS: *	ip	- the inode of the file. *	cp	- cbuf for the partial backed last page. *	xlen	- request size of the resulting extent. *	xp	- pointer to an xad. on successful exit, the xad *		  describes the newly allocated extent. *	abnr	- bool indicating whether the newly allocated extent *		  should be marked as allocated but not recorded. * * RETURN VALUES: *	0	- success *	-EIO	- i/o error. *	-ENOSPC	- insufficient disk resources. */int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, bool abnr){	struct super_block *sb = ip->i_sb;	s64 xaddr, xlen, nxaddr, delta, xoff;	s64 ntail, nextend, ninsert;	int rc, nbperpage = JFS_SBI(sb)->nbperpage;	int xflag;	/* This blocks if we are low on resources */	txBeginAnon(ip->i_sb);	mutex_lock(&JFS_IP(ip)->commit_mutex);	/* validate extent length */	if (nxlen > MAXXLEN)		nxlen = MAXXLEN;	/* get the extend (partial) page's disk block address and	 * number of blocks.	 */	xaddr = addressXAD(xp);	xlen = lengthXAD(xp);	xoff = offsetXAD(xp);	/* if the extend page is abnr and if the request is for	 * the extent to be allocated and recorded,	 * make the page allocated and recorded.	 */	if ((xp->flag & XAD_NOTRECORDED) && !abnr) {		xp->flag = 0;		if ((rc = xtUpdate(0, ip, xp)))			goto exit;	}	/* try to allocated the request number of blocks for the	 * extent.  dbRealloc() first tries to satisfy the request	 * by extending the allocation in place. otherwise, it will	 * try to allocate a new set of blocks large enough for the	 * request.  in satisfying a request, dbReAlloc() may allocate	 * less than what was request but will always allocate enough	 * space as to satisfy the extend page.	 */	if ((rc = extBrealloc(ip, xaddr, xlen, &nxlen, &nxaddr)))		goto exit;	/* Allocat blocks to quota. */	if (DQUOT_ALLOC_BLOCK(ip, nxlen)) {		dbFree(ip, nxaddr, (s64) nxlen);		mutex_unlock(&JFS_IP(ip)->commit_mutex);		return -EDQUOT;	}	delta = nxlen - xlen;	/* check if the extend page is not abnr but the request is abnr	 * and the allocated disk space is for more than one page.  if this	 * is the case, there is a miss match of abnr between the extend page	 * and the one or more pages following the extend page.  as a result,	 * two extents will have to be manipulated. the first will be that	 * of the extent of the extend page and will be manipulated thru	 * an xtExtend() or an xtTailgate(), depending upon whether the	 * disk allocation occurred as an inplace extension.  the second	 * extent will be manipulated (created) through an xtInsert() and	 * will be for the pages following the extend page.	 */	if (abnr && (!(xp->flag & XAD_NOTRECORDED)) && (nxlen > nbperpage)) {		ntail = nbperpage;		nextend = ntail - xlen;		ninsert = nxlen - nbperpage;		xflag = XAD_NOTRECORDED;	} else {		ntail = nxlen;		nextend = delta;		ninsert = 0;		xflag = xp->flag;	}	/* if we were able to extend the disk allocation in place,	 * extend the extent.  otherwise, move the extent to a	 * new disk location.	 */	if (xaddr == nxaddr) {		/* extend the extent */		if ((rc = xtExtend(0, ip, xoff + xlen, (int) nextend, 0))) {			dbFree(ip, xaddr + xlen, delta);			DQUOT_FREE_BLOCK(ip, nxlen);			goto exit;		}	} else {		/*		 * move the extent to a new location:		 *		 * xtTailgate() accounts for relocated tail extent;		 */		if ((rc = xtTailgate(0, ip, xoff, (int) ntail, nxaddr, 0))) {			dbFree(ip, nxaddr, nxlen);			DQUOT_FREE_BLOCK(ip, nxlen);			goto exit;		}	}	/* check if we need to also insert a new extent */	if (ninsert) {		/* perform the insert.  if it fails, free the blocks		 * to be inserted and make it appear that we only did		 * the xtExtend() or xtTailgate() above.		 */		xaddr = nxaddr + ntail;		if (xtInsert (0, ip, xflag, xoff + ntail, (int) ninsert,			      &xaddr, 0)) {			dbFree(ip, xaddr, (s64) ninsert);			delta = nextend;			nxlen = ntail;			xflag = 0;		}	}

⌨️ 快捷键说明

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