Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *   Copyright (C) International Business Machines Corp., 2000-2004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/quotaops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include "jfs_incore.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include "jfs_inode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include "jfs_superblock.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include "jfs_dmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include "jfs_extent.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include "jfs_debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * forward references
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) static int extBalloc(struct inode *, s64, s64 *, s64 *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #ifdef _NOTYET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) static int extBrealloc(struct inode *, s64, s64, s64 *, s64 *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) static s64 extRoundDown(s64 nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define DPD(a)		(printk("(a): %d\n",(a)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define DPC(a)		(printk("(a): %c\n",(a)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define DPL1(a)					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) {						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	if ((a) >> 32)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 		printk("(a): %x%08x  ",(a));	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	else					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 		printk("(a): %x  ",(a) << 32);	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define DPL(a)					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) {						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	if ((a) >> 32)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 		printk("(a): %x%08x\n",(a));	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	else					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 		printk("(a): %x\n",(a) << 32);	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define DPD1(a)		(printk("(a): %d  ",(a)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #define DPX(a)		(printk("(a): %08x\n",(a)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define DPX1(a)		(printk("(a): %08x  ",(a)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define DPS(a)		(printk("%s\n",(a)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define DPE(a)		(printk("\nENTERING: %s\n",(a)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define DPE1(a)		(printk("\nENTERING: %s",(a)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #define DPS1(a)		(printk("  %s  ",(a)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  * NAME:	extAlloc()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  * FUNCTION:	allocate an extent for a specified page range within a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  *		file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  * PARAMETERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  *	ip	- the inode of the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  *	xlen	- requested extent length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  *	pno	- the starting page number with the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  *	xp	- pointer to an xad.  on entry, xad describes an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)  *		  extent that is used as an allocation hint if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)  *		  xaddr of the xad is non-zero.  on successful exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)  *		  the xad describes the newly allocated extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)  *	abnr	- bool indicating whether the newly allocated extent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)  *		  should be marked as allocated but not recorded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  * RETURN VALUES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  *	0	- success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  *	-EIO	- i/o error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)  *	-ENOSPC	- insufficient disk resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	s64 nxlen, nxaddr, xoff, hint, xaddr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	int xflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	/* This blocks if we are low on resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	txBeginAnon(ip->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	/* Avoid race with jfs_commit_inode() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	mutex_lock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	/* validate extent length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	if (xlen > MAXXLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		xlen = MAXXLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	/* get the page's starting extent offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	xoff = pno << sbi->l2nbperpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	/* check if an allocation hint was provided */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	if ((hint = addressXAD(xp))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		/* get the size of the extent described by the hint */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		nxlen = lengthXAD(xp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		/* check if the hint is for the portion of the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		 * immediately previous to the current allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		 * request and if hint extent has the same abnr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		 * value as the current request.  if so, we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		 * extend the hint extent to include the current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		 * extent if we can allocate the blocks immediately
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		 * following the hint extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		if (offsetXAD(xp) + nxlen == xoff &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		    abnr == ((xp->flag & XAD_NOTRECORDED) ? true : false))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 			xaddr = hint + nxlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		/* adjust the hint to the last block of the extent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		hint += (nxlen - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	/* allocate the disk blocks for the extent.  initially, extBalloc()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	 * will try to allocate disk blocks for the requested size (xlen).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	 * if this fails (xlen contiguous free blocks not available), it'll
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	 * try to allocate a smaller number of blocks (producing a smaller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	 * extent), with this smaller number of blocks consisting of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	 * requested number of blocks rounded down to the next smaller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	 * power of 2 number (i.e. 16 -> 8).  it'll continue to round down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	 * and retry the allocation until the number of blocks to allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	 * is smaller than the number of blocks per page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	nxlen = xlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	if ((rc = extBalloc(ip, hint ? hint : INOHINT(ip), &nxlen, &nxaddr))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		mutex_unlock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		return (rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	/* Allocate blocks to quota. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	rc = dquot_alloc_block(ip, nxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		dbFree(ip, nxaddr, (s64) nxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		mutex_unlock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	/* determine the value of the extent flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	xflag = abnr ? XAD_NOTRECORDED : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	/* if we can extend the hint extent to cover the current request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	 * extend it.  otherwise, insert a new extent to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	 * cover the current request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	if (xaddr && xaddr == nxaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		rc = xtExtend(0, ip, xoff, (int) nxlen, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		rc = xtInsert(0, ip, xflag, xoff, (int) nxlen, &nxaddr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	/* if the extend or insert failed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	 * free the newly allocated blocks and return the error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		dbFree(ip, nxaddr, nxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		dquot_free_block(ip, nxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		mutex_unlock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		return (rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	/* set the results of the extent allocation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	XADaddress(xp, nxaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	XADlength(xp, nxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	XADoffset(xp, xoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	xp->flag = xflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	mark_inode_dirty(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	mutex_unlock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	 * COMMIT_SyncList flags an anonymous tlock on page that is on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	 * sync list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	 * We need to commit the inode to get the page written disk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	if (test_and_clear_cflag(COMMIT_Synclist,ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		jfs_commit_inode(ip, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #ifdef _NOTYET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)  * NAME:	extRealloc()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)  * FUNCTION:	extend the allocation of a file extent containing a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)  *		partial back last page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)  * PARAMETERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)  *	ip	- the inode of the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)  *	cp	- cbuf for the partial backed last page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)  *	xlen	- request size of the resulting extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)  *	xp	- pointer to an xad. on successful exit, the xad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)  *		  describes the newly allocated extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)  *	abnr	- bool indicating whether the newly allocated extent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)  *		  should be marked as allocated but not recorded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)  * RETURN VALUES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)  *	0	- success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)  *	-EIO	- i/o error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)  *	-ENOSPC	- insufficient disk resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, bool abnr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	struct super_block *sb = ip->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	s64 xaddr, xlen, nxaddr, delta, xoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	s64 ntail, nextend, ninsert;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	int rc, nbperpage = JFS_SBI(sb)->nbperpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	int xflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	/* This blocks if we are low on resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	txBeginAnon(ip->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	mutex_lock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	/* validate extent length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	if (nxlen > MAXXLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		nxlen = MAXXLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	/* get the extend (partial) page's disk block address and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	 * number of blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	xaddr = addressXAD(xp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	xlen = lengthXAD(xp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	xoff = offsetXAD(xp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	/* if the extend page is abnr and if the request is for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	 * the extent to be allocated and recorded,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	 * make the page allocated and recorded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	if ((xp->flag & XAD_NOTRECORDED) && !abnr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		xp->flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		if ((rc = xtUpdate(0, ip, xp)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 			goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	/* try to allocated the request number of blocks for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	 * extent.  dbRealloc() first tries to satisfy the request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	 * by extending the allocation in place. otherwise, it will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	 * try to allocate a new set of blocks large enough for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	 * request.  in satisfying a request, dbReAlloc() may allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	 * less than what was request but will always allocate enough
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	 * space as to satisfy the extend page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	if ((rc = extBrealloc(ip, xaddr, xlen, &nxlen, &nxaddr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	/* Allocat blocks to quota. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	rc = dquot_alloc_block(ip, nxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		dbFree(ip, nxaddr, (s64) nxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		mutex_unlock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	delta = nxlen - xlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	/* check if the extend page is not abnr but the request is abnr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	 * and the allocated disk space is for more than one page.  if this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	 * is the case, there is a miss match of abnr between the extend page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	 * and the one or more pages following the extend page.  as a result,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	 * two extents will have to be manipulated. the first will be that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	 * of the extent of the extend page and will be manipulated thru
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	 * an xtExtend() or an xtTailgate(), depending upon whether the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	 * disk allocation occurred as an inplace extension.  the second
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	 * extent will be manipulated (created) through an xtInsert() and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	 * will be for the pages following the extend page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	if (abnr && (!(xp->flag & XAD_NOTRECORDED)) && (nxlen > nbperpage)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		ntail = nbperpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		nextend = ntail - xlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		ninsert = nxlen - nbperpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		xflag = XAD_NOTRECORDED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		ntail = nxlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		nextend = delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		ninsert = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		xflag = xp->flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	/* if we were able to extend the disk allocation in place,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	 * extend the extent.  otherwise, move the extent to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	 * new disk location.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	if (xaddr == nxaddr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		/* extend the extent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		if ((rc = xtExtend(0, ip, xoff + xlen, (int) nextend, 0))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 			dbFree(ip, xaddr + xlen, delta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 			dquot_free_block(ip, nxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 			goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		 * move the extent to a new location:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		 * xtTailgate() accounts for relocated tail extent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		if ((rc = xtTailgate(0, ip, xoff, (int) ntail, nxaddr, 0))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 			dbFree(ip, nxaddr, nxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 			dquot_free_block(ip, nxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 			goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	/* check if we need to also insert a new extent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	if (ninsert) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		/* perform the insert.  if it fails, free the blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 		 * to be inserted and make it appear that we only did
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		 * the xtExtend() or xtTailgate() above.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		xaddr = nxaddr + ntail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		if (xtInsert (0, ip, xflag, xoff + ntail, (int) ninsert,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 			      &xaddr, 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 			dbFree(ip, xaddr, (s64) ninsert);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 			delta = nextend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 			nxlen = ntail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 			xflag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	/* set the return results */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	XADaddress(xp, nxaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	XADlength(xp, nxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	XADoffset(xp, xoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	xp->flag = xflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	mark_inode_dirty(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	mutex_unlock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	return (rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) #endif			/* _NOTYET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)  * NAME:	extHint()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)  * FUNCTION:	produce an extent allocation hint for a file offset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)  * PARAMETERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)  *	ip	- the inode of the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)  *	offset  - file offset for which the hint is needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)  *	xp	- pointer to the xad that is to be filled in with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)  *		  the hint.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)  * RETURN VALUES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)  *	0	- success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)  *	-EIO	- i/o error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) int extHint(struct inode *ip, s64 offset, xad_t * xp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	struct super_block *sb = ip->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	int nbperpage = JFS_SBI(sb)->nbperpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	s64 prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	s64 xaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	int xlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	int xflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	/* init the hint as "no hint provided" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	XADaddress(xp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	/* determine the starting extent offset of the page previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	 * to the page containing the offset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	prev = ((offset & ~POFFSET) >> JFS_SBI(sb)->l2bsize) - nbperpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	/* if the offset is in the first page of the file, no hint provided.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	if (prev < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	rc = xtLookup(ip, prev, nbperpage, &xflag, &xaddr, &xlen, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	if ((rc == 0) && xlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		if (xlen != nbperpage) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 			jfs_error(ip->i_sb, "corrupt xtree\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 			rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		XADaddress(xp, xaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		XADlength(xp, xlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 		XADoffset(xp, prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		 * only preserve the abnr flag within the xad flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		 * of the returned hint.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		xp->flag  = xflag & XAD_NOTRECORDED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 		rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	return (rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)  * NAME:	extRecord()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)  * FUNCTION:	change a page with a file from not recorded to recorded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)  * PARAMETERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)  *	ip	- inode of the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)  *	cp	- cbuf of the file page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)  * RETURN VALUES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)  *	0	- success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)  *	-EIO	- i/o error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)  *	-ENOSPC	- insufficient disk resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) int extRecord(struct inode *ip, xad_t * xp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	txBeginAnon(ip->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	mutex_lock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	/* update the extent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	rc = xtUpdate(0, ip, xp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	mutex_unlock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) #ifdef _NOTYET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)  * NAME:	extFill()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)  * FUNCTION:	allocate disk space for a file page that represents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)  *		a file hole.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)  * PARAMETERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)  *	ip	- the inode of the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)  *	cp	- cbuf of the file page represent the hole.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)  * RETURN VALUES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)  *	0	- success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)  *	-EIO	- i/o error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)  *	-ENOSPC	- insufficient disk resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) int extFill(struct inode *ip, xad_t * xp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	int rc, nbperpage = JFS_SBI(ip->i_sb)->nbperpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	s64 blkno = offsetXAD(xp) >> ip->i_blkbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) //	assert(ISSPARSE(ip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	/* initialize the extent allocation hint */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	XADaddress(xp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	/* allocate an extent to fill the hole */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	if ((rc = extAlloc(ip, nbperpage, blkno, xp, false)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 		return (rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	assert(lengthPXD(xp) == nbperpage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) #endif			/* _NOTYET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)  * NAME:	extBalloc()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)  * FUNCTION:	allocate disk blocks to form an extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)  *		initially, we will try to allocate disk blocks for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)  *		requested size (nblocks).  if this fails (nblocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)  *		contiguous free blocks not available), we'll try to allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)  *		a smaller number of blocks (producing a smaller extent), with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)  *		this smaller number of blocks consisting of the requested
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)  *		number of blocks rounded down to the next smaller power of 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)  *		number (i.e. 16 -> 8).  we'll continue to round down and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)  *		retry the allocation until the number of blocks to allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)  *		is smaller than the number of blocks per page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)  * PARAMETERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)  *	ip	 - the inode of the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)  *	hint	 - disk block number to be used as an allocation hint.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)  *	*nblocks - pointer to an s64 value.  on entry, this value specifies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)  *		   the desired number of block to be allocated. on successful
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)  *		   exit, this value is set to the number of blocks actually
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)  *		   allocated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)  *	blkno	 - pointer to a block address that is filled in on successful
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)  *		   return with the starting block number of the newly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)  *		   allocated block range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)  * RETURN VALUES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)  *	0	- success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)  *	-EIO	- i/o error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)  *	-ENOSPC	- insufficient disk resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	struct jfs_inode_info *ji = JFS_IP(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	s64 nb, nblks, daddr, max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	int rc, nbperpage = sbi->nbperpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	struct bmap *bmp = sbi->bmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	int ag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	/* get the number of blocks to initially attempt to allocate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	 * we'll first try the number of blocks requested unless this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	 * number is greater than the maximum number of contiguous free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	 * blocks in the map. in that case, we'll start off with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	 * maximum free.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	max = (s64) 1 << bmp->db_maxfreebud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	if (*nblocks >= max && *nblocks > nbperpage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 		nb = nblks = (max > nbperpage) ? max : nbperpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		nb = nblks = *nblocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	/* try to allocate blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	while ((rc = dbAlloc(ip, hint, nb, &daddr)) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		/* if something other than an out of space error,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 		 * stop and return this error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 		if (rc != -ENOSPC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 			return (rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 		/* decrease the allocation request size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		nb = min(nblks, extRoundDown(nb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 		/* give up if we cannot cover a page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 		if (nb < nbperpage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 			return (rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	*nblocks = nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	*blkno = daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	if (S_ISREG(ip->i_mode) && (ji->fileset == FILESYSTEM_I)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 		ag = BLKTOAG(daddr, sbi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 		spin_lock_irq(&ji->ag_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		if (ji->active_ag == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 			atomic_inc(&bmp->db_active[ag]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 			ji->active_ag = ag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 		} else if (ji->active_ag != ag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 			atomic_dec(&bmp->db_active[ji->active_ag]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 			atomic_inc(&bmp->db_active[ag]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 			ji->active_ag = ag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 		spin_unlock_irq(&ji->ag_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) #ifdef _NOTYET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)  * NAME:	extBrealloc()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)  * FUNCTION:	attempt to extend an extent's allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)  *		Initially, we will try to extend the extent's allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)  *		in place.  If this fails, we'll try to move the extent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)  *		to a new set of blocks.  If moving the extent, we initially
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)  *		will try to allocate disk blocks for the requested size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)  *		(newnblks).  if this fails (new contiguous free blocks not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)  *		available), we'll try to allocate a smaller number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)  *		blocks (producing a smaller extent), with this smaller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)  *		number of blocks consisting of the requested number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)  *		blocks rounded down to the next smaller power of 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)  *		number (i.e. 16 -> 8).  We'll continue to round down and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)  *		retry the allocation until the number of blocks to allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)  *		is smaller than the number of blocks per page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)  * PARAMETERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)  *	ip	 - the inode of the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)  *	blkno	 - starting block number of the extents current allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)  *	nblks	 - number of blocks within the extents current allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)  *	newnblks - pointer to a s64 value.  on entry, this value is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)  *		   the new desired extent size (number of blocks).  on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)  *		   successful exit, this value is set to the extent's actual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)  *		   new size (new number of blocks).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)  *	newblkno - the starting block number of the extents new allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)  * RETURN VALUES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)  *	0	- success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)  *	-EIO	- i/o error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)  *	-ENOSPC	- insufficient disk resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) extBrealloc(struct inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	    s64 blkno, s64 nblks, s64 * newnblks, s64 * newblkno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	/* try to extend in place */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	if ((rc = dbExtend(ip, blkno, nblks, *newnblks - nblks)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 		*newblkno = blkno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 		return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 		if (rc != -ENOSPC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 			return (rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	/* in place extension not possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	 * try to move the extent to a new set of blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	return (extBalloc(ip, blkno, newnblks, newblkno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) #endif			/* _NOTYET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)  * NAME:	extRoundDown()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)  * FUNCTION:	round down a specified number of blocks to the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)  *		smallest power of 2 number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)  * PARAMETERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)  *	nb	- the inode of the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)  * RETURN VALUES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)  *	next smallest power of 2 number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) static s64 extRoundDown(s64 nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	u64 m, k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	for (i = 0, m = (u64) 1 << 63; i < 64; i++, m >>= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 		if (m & nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	i = 63 - i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	k = (u64) 1 << i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	k = ((k - 1) & nb) ? k : k >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	return (k);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }