VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   33 Branches   55 Tags
1a59d1b8e05ea (Thomas Gleixner   2019-05-27 08:55:05 +0200    1) // SPDX-License-Identifier: GPL-2.0-or-later
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700    2) /*
6b6bf51081a27 (Dave Kleikamp     2005-05-04 09:11:49 -0500    3)  *   Copyright (C) International Business Machines Corp., 2000-2005
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700    4)  */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700    5) /*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500    6)  *	jfs_xtree.c: extent allocation descriptor B+-tree manager
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700    7)  */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700    8) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700    9) #include <linux/fs.h>
b2e03ca7485ca (Alexey Dobriyan   2008-05-13 08:22:10 -0500   10) #include <linux/module.h>
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   11) #include <linux/quotaops.h>
b2e03ca7485ca (Alexey Dobriyan   2008-05-13 08:22:10 -0500   12) #include <linux/seq_file.h>
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   13) #include "jfs_incore.h"
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   14) #include "jfs_filsys.h"
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   15) #include "jfs_metapage.h"
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   16) #include "jfs_dmap.h"
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   17) #include "jfs_dinode.h"
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   18) #include "jfs_superblock.h"
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   19) #include "jfs_debug.h"
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   20) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   21) /*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   22)  * xtree local flag
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   23)  */
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500   24) #define XT_INSERT	0x00000001
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   25) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   26) /*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500   27)  *	xtree key/entry comparison: extent offset
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   28)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   29)  * return:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500   30)  *	-1: k < start of extent
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500   31)  *	 0: start_of_extent <= k <= end_of_extent
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500   32)  *	 1: k > end_of_extent
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   33)  */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   34) #define XT_CMP(CMP, K, X, OFFSET64)\
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   35) {\
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500   36) 	OFFSET64 = offsetXAD(X);\
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500   37) 	(CMP) = ((K) >= OFFSET64 + lengthXAD(X)) ? 1 :\
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500   38) 		((K) < OFFSET64) ? -1 : 0;\
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   39) }
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   40) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   41) /* write a xad entry */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   42) #define XT_PUTENTRY(XAD, FLAG, OFF, LEN, ADDR)\
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   43) {\
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500   44) 	(XAD)->flag = (FLAG);\
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500   45) 	XADoffset((XAD), (OFF));\
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500   46) 	XADlength((XAD), (LEN));\
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500   47) 	XADaddress((XAD), (ADDR));\
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   48) }
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   49) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   50) #define XT_PAGE(IP, MP) BT_PAGE(IP, MP, xtpage_t, i_xtroot)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   51) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   52) /* get page buffer for specified block address */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   53) /* ToDo: Replace this ugly macro with a function */
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700   54) #define XT_GETPAGE(IP, BN, MP, SIZE, P, RC)				\
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700   55) do {									\
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700   56) 	BT_GETPAGE(IP, BN, MP, xtpage_t, SIZE, P, RC, i_xtroot);	\
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700   57) 	if (!(RC)) {							\
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700   58) 		if ((le16_to_cpu((P)->header.nextindex) < XTENTRYSTART) || \
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700   59) 		    (le16_to_cpu((P)->header.nextindex) >		\
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700   60) 		     le16_to_cpu((P)->header.maxentry)) ||		\
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700   61) 		    (le16_to_cpu((P)->header.maxentry) >		\
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700   62) 		     (((BN) == 0) ? XTROOTMAXSLOT : PSIZE >> L2XTSLOTSIZE))) { \
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700   63) 			jfs_error((IP)->i_sb,				\
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700   64) 				  "XT_GETPAGE: xtree page corrupt\n");	\
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700   65) 			BT_PUTPAGE(MP);					\
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700   66) 			MP = NULL;					\
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700   67) 			RC = -EIO;					\
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700   68) 		}							\
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700   69) 	}								\
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700   70) } while (0)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   71) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   72) /* for consistency */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   73) #define XT_PUTPAGE(MP) BT_PUTPAGE(MP)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   74) 
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500   75) #define XT_GETSEARCH(IP, LEAF, BN, MP, P, INDEX) \
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   76) 	BT_GETSEARCH(IP, LEAF, BN, MP, xtpage_t, P, INDEX, i_xtroot)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   77) /* xtree entry parameter descriptor */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   78) struct xtsplit {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   79) 	struct metapage *mp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   80) 	s16 index;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   81) 	u8 flag;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   82) 	s64 off;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   83) 	s64 addr;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   84) 	int len;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   85) 	struct pxdlist *pxdlist;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   86) };
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   87) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   88) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   89) /*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500   90)  *	statistics
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   91)  */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   92) #ifdef CONFIG_JFS_STATISTICS
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   93) static struct {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   94) 	uint search;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   95) 	uint fastSearch;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   96) 	uint split;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   97) } xtStat;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   98) #endif
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   99) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  100) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  101) /*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  102)  * forward references
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  103)  */
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600  104) static int xtSearch(struct inode *ip, s64 xoff, s64 *next, int *cmpp,
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600  105) 		    struct btstack * btstack, int flag);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  106) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  107) static int xtSplitUp(tid_t tid,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  108) 		     struct inode *ip,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  109) 		     struct xtsplit * split, struct btstack * btstack);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  110) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  111) static int xtSplitPage(tid_t tid, struct inode *ip, struct xtsplit * split,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  112) 		       struct metapage ** rmpp, s64 * rbnp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  113) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  114) static int xtSplitRoot(tid_t tid, struct inode *ip,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  115) 		       struct xtsplit * split, struct metapage ** rmpp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  116) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  117) #ifdef _STILL_TO_PORT
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  118) static int xtDeleteUp(tid_t tid, struct inode *ip, struct metapage * fmp,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  119) 		      xtpage_t * fp, struct btstack * btstack);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  120) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  121) static int xtSearchNode(struct inode *ip,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  122) 			xad_t * xad,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  123) 			int *cmpp, struct btstack * btstack, int flag);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  124) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  125) static int xtRelink(tid_t tid, struct inode *ip, xtpage_t * fp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  126) #endif				/*  _STILL_TO_PORT */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  127) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  128) /*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  129)  *	xtLookup()
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  130)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  131)  * function: map a single page into a physical extent;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  132)  */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  133) int xtLookup(struct inode *ip, s64 lstart,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  134) 	     s64 llen, int *pflag, s64 * paddr, s32 * plen, int no_check)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  135) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  136) 	int rc = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  137) 	struct btstack btstack;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  138) 	int cmp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  139) 	s64 bn;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  140) 	struct metapage *mp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  141) 	xtpage_t *p;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  142) 	int index;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  143) 	xad_t *xad;
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600  144) 	s64 next, size, xoff, xend;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  145) 	int xlen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  146) 	s64 xaddr;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  147) 
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600  148) 	*paddr = 0;
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600  149) 	*plen = llen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  150) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  151) 	if (!no_check) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  152) 		/* is lookup offset beyond eof ? */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  153) 		size = ((u64) ip->i_size + (JFS_SBI(ip->i_sb)->bsize - 1)) >>
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  154) 		    JFS_SBI(ip->i_sb)->l2bsize;
fec1878fe952b (Dave Kleikamp     2009-01-09 15:42:04 -0600  155) 		if (lstart >= size)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  156) 			return 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  157) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  158) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  159) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  160) 	 * search for the xad entry covering the logical extent
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  161) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  162) //search:
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600  163) 	if ((rc = xtSearch(ip, lstart, &next, &cmp, &btstack, 0))) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  164) 		jfs_err("xtLookup: xtSearch returned %d", rc);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  165) 		return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  166) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  167) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  168) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  169) 	 *	compute the physical extent covering logical extent
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  170) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  171) 	 * N.B. search may have failed (e.g., hole in sparse file),
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  172) 	 * and returned the index of the next entry.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  173) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  174) 	/* retrieve search result */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  175) 	XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  176) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  177) 	/* is xad found covering start of logical extent ?
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  178) 	 * lstart is a page start address,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  179) 	 * i.e., lstart cannot start in a hole;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  180) 	 */
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600  181) 	if (cmp) {
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600  182) 		if (next)
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600  183) 			*plen = min(next - lstart, llen);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  184) 		goto out;
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600  185) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  186) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  187) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  188) 	 * lxd covered by xad
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  189) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  190) 	xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  191) 	xoff = offsetXAD(xad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  192) 	xlen = lengthXAD(xad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  193) 	xend = xoff + xlen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  194) 	xaddr = addressXAD(xad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  195) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  196) 	/* initialize new pxd */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  197) 	*pflag = xad->flag;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  198) 	*paddr = xaddr + (lstart - xoff);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  199) 	/* a page must be fully covered by an xad */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  200) 	*plen = min(xend - lstart, llen);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  201) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  202)       out:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  203) 	XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  204) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  205) 	return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  206) }
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  207) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  208) /*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  209)  *	xtSearch()
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  210)  *
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  211)  * function:	search for the xad entry covering specified offset.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  212)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  213)  * parameters:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  214)  *	ip	- file object;
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  215)  *	xoff	- extent offset;
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  216)  *	nextp	- address of next extent (if any) for search miss
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  217)  *	cmpp	- comparison result:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  218)  *	btstack - traverse stack;
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  219)  *	flag	- search process flag (XT_INSERT);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  220)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  221)  * returns:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  222)  *	btstack contains (bn, index) of search path traversed to the entry.
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  223)  *	*cmpp is set to result of comparison with the entry returned.
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  224)  *	the page containing the entry is pinned at exit.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  225)  */
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600  226) static int xtSearch(struct inode *ip, s64 xoff,	s64 *nextp,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  227) 		    int *cmpp, struct btstack * btstack, int flag)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  228) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  229) 	struct jfs_inode_info *jfs_ip = JFS_IP(ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  230) 	int rc = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  231) 	int cmp = 1;		/* init for empty page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  232) 	s64 bn;			/* block number */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  233) 	struct metapage *mp;	/* page buffer */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  234) 	xtpage_t *p;		/* page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  235) 	xad_t *xad;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  236) 	int base, index, lim, btindex;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  237) 	struct btframe *btsp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  238) 	int nsplit = 0;		/* number of pages to split */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  239) 	s64 t64;
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600  240) 	s64 next = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  241) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  242) 	INCREMENT(xtStat.search);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  243) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  244) 	BT_CLR(btstack);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  245) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  246) 	btstack->nsplit = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  247) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  248) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  249) 	 *	search down tree from root:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  250) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  251) 	 * between two consecutive entries of <Ki, Pi> and <Kj, Pj> of
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  252) 	 * internal page, child page Pi contains entry with k, Ki <= K < Kj.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  253) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  254) 	 * if entry with search key K is not found
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  255) 	 * internal page search find the entry with largest key Ki
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  256) 	 * less than K which point to the child page to search;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  257) 	 * leaf page search find the entry with smallest key Kj
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  258) 	 * greater than K so that the returned index is the position of
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  259) 	 * the entry to be shifted right for insertion of new entry.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  260) 	 * for empty tree, search key is greater than any key of the tree.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  261) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  262) 	 * by convention, root bn = 0.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  263) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  264) 	for (bn = 0;;) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  265) 		/* get/pin the page to search */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  266) 		XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  267) 		if (rc)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  268) 			return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  269) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  270) 		/* try sequential access heuristics with the previous
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  271) 		 * access entry in target leaf page:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  272) 		 * once search narrowed down into the target leaf,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  273) 		 * key must either match an entry in the leaf or
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  274) 		 * key entry does not exist in the tree;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  275) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  276) //fastSearch:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  277) 		if ((jfs_ip->btorder & BT_SEQUENTIAL) &&
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  278) 		    (p->header.flag & BT_LEAF) &&
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  279) 		    (index = jfs_ip->btindex) <
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  280) 		    le16_to_cpu(p->header.nextindex)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  281) 			xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  282) 			t64 = offsetXAD(xad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  283) 			if (xoff < t64 + lengthXAD(xad)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  284) 				if (xoff >= t64) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  285) 					*cmpp = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  286) 					goto out;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  287) 				}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  288) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  289) 				/* stop sequential access heuristics */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  290) 				goto binarySearch;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  291) 			} else {	/* (t64 + lengthXAD(xad)) <= xoff */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  292) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  293) 				/* try next sequential entry */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  294) 				index++;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  295) 				if (index <
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  296) 				    le16_to_cpu(p->header.nextindex)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  297) 					xad++;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  298) 					t64 = offsetXAD(xad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  299) 					if (xoff < t64 + lengthXAD(xad)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  300) 						if (xoff >= t64) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  301) 							*cmpp = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  302) 							goto out;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  303) 						}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  304) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  305) 						/* miss: key falls between
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  306) 						 * previous and this entry
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  307) 						 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  308) 						*cmpp = 1;
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600  309) 						next = t64;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  310) 						goto out;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  311) 					}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  312) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  313) 					/* (xoff >= t64 + lengthXAD(xad));
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  314) 					 * matching entry may be further out:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  315) 					 * stop heuristic search
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  316) 					 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  317) 					/* stop sequential access heuristics */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  318) 					goto binarySearch;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  319) 				}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  320) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  321) 				/* (index == p->header.nextindex);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  322) 				 * miss: key entry does not exist in
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  323) 				 * the target leaf/tree
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  324) 				 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  325) 				*cmpp = 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  326) 				goto out;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  327) 			}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  328) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  329) 			/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  330) 			 * if hit, return index of the entry found, and
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  331) 			 * if miss, where new entry with search key is
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  332) 			 * to be inserted;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  333) 			 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  334) 		      out:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  335) 			/* compute number of pages to split */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  336) 			if (flag & XT_INSERT) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  337) 				if (p->header.nextindex ==	/* little-endian */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  338) 				    p->header.maxentry)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  339) 					nsplit++;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  340) 				else
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  341) 					nsplit = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  342) 				btstack->nsplit = nsplit;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  343) 			}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  344) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  345) 			/* save search result */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  346) 			btsp = btstack->top;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  347) 			btsp->bn = bn;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  348) 			btsp->index = index;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  349) 			btsp->mp = mp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  350) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  351) 			/* update sequential access heuristics */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  352) 			jfs_ip->btindex = index;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  353) 
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600  354) 			if (nextp)
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600  355) 				*nextp = next;
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600  356) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  357) 			INCREMENT(xtStat.fastSearch);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  358) 			return 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  359) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  360) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  361) 		/* well, ... full search now */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  362) 	      binarySearch:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  363) 		lim = le16_to_cpu(p->header.nextindex) - XTENTRYSTART;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  364) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  365) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  366) 		 * binary search with search key K on the current page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  367) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  368) 		for (base = XTENTRYSTART; lim; lim >>= 1) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  369) 			index = base + (lim >> 1);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  370) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  371) 			XT_CMP(cmp, xoff, &p->xad[index], t64);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  372) 			if (cmp == 0) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  373) 				/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  374) 				 *	search hit
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  375) 				 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  376) 				/* search hit - leaf page:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  377) 				 * return the entry found
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  378) 				 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  379) 				if (p->header.flag & BT_LEAF) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  380) 					*cmpp = cmp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  381) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  382) 					/* compute number of pages to split */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  383) 					if (flag & XT_INSERT) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  384) 						if (p->header.nextindex ==
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  385) 						    p->header.maxentry)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  386) 							nsplit++;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  387) 						else
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  388) 							nsplit = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  389) 						btstack->nsplit = nsplit;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  390) 					}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  391) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  392) 					/* save search result */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  393) 					btsp = btstack->top;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  394) 					btsp->bn = bn;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  395) 					btsp->index = index;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  396) 					btsp->mp = mp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  397) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  398) 					/* init sequential access heuristics */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  399) 					btindex = jfs_ip->btindex;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  400) 					if (index == btindex ||
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  401) 					    index == btindex + 1)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  402) 						jfs_ip->btorder = BT_SEQUENTIAL;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  403) 					else
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  404) 						jfs_ip->btorder = BT_RANDOM;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  405) 					jfs_ip->btindex = index;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  406) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  407) 					return 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  408) 				}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  409) 				/* search hit - internal page:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  410) 				 * descend/search its child page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  411) 				 */
6b6bf51081a27 (Dave Kleikamp     2005-05-04 09:11:49 -0500  412) 				if (index < le16_to_cpu(p->header.nextindex)-1)
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600  413) 					next = offsetXAD(&p->xad[index + 1]);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  414) 				goto next;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  415) 			}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  416) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  417) 			if (cmp > 0) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  418) 				base = index + 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  419) 				--lim;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  420) 			}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  421) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  422) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  423) 		/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  424) 		 *	search miss
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  425) 		 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  426) 		 * base is the smallest index with key (Kj) greater than
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  427) 		 * search key (K) and may be zero or maxentry index.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  428) 		 */
6b6bf51081a27 (Dave Kleikamp     2005-05-04 09:11:49 -0500  429) 		if (base < le16_to_cpu(p->header.nextindex))
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600  430) 			next = offsetXAD(&p->xad[base]);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  431) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  432) 		 * search miss - leaf page:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  433) 		 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  434) 		 * return location of entry (base) where new entry with
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  435) 		 * search key K is to be inserted.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  436) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  437) 		if (p->header.flag & BT_LEAF) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  438) 			*cmpp = cmp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  439) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  440) 			/* compute number of pages to split */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  441) 			if (flag & XT_INSERT) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  442) 				if (p->header.nextindex ==
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  443) 				    p->header.maxentry)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  444) 					nsplit++;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  445) 				else
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  446) 					nsplit = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  447) 				btstack->nsplit = nsplit;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  448) 			}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  449) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  450) 			/* save search result */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  451) 			btsp = btstack->top;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  452) 			btsp->bn = bn;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  453) 			btsp->index = base;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  454) 			btsp->mp = mp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  455) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  456) 			/* init sequential access heuristics */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  457) 			btindex = jfs_ip->btindex;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  458) 			if (base == btindex || base == btindex + 1)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  459) 				jfs_ip->btorder = BT_SEQUENTIAL;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  460) 			else
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  461) 				jfs_ip->btorder = BT_RANDOM;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  462) 			jfs_ip->btindex = base;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  463) 
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600  464) 			if (nextp)
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600  465) 				*nextp = next;
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600  466) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  467) 			return 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  468) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  469) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  470) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  471) 		 * search miss - non-leaf page:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  472) 		 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  473) 		 * if base is non-zero, decrement base by one to get the parent
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  474) 		 * entry of the child page to search.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  475) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  476) 		index = base ? base - 1 : base;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  477) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  478) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  479) 		 * go down to child page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  480) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  481) 	      next:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  482) 		/* update number of pages to split */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  483) 		if (p->header.nextindex == p->header.maxentry)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  484) 			nsplit++;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  485) 		else
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  486) 			nsplit = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  487) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  488) 		/* push (bn, index) of the parent page/entry */
17e6afc75ad01 (Dave Kleikamp     2007-01-09 08:57:34 -0600  489) 		if (BT_STACK_FULL(btstack)) {
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700  490) 			jfs_error(ip->i_sb, "stack overrun!\n");
17e6afc75ad01 (Dave Kleikamp     2007-01-09 08:57:34 -0600  491) 			XT_PUTPAGE(mp);
17e6afc75ad01 (Dave Kleikamp     2007-01-09 08:57:34 -0600  492) 			return -EIO;
17e6afc75ad01 (Dave Kleikamp     2007-01-09 08:57:34 -0600  493) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  494) 		BT_PUSH(btstack, bn, index);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  495) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  496) 		/* get the child page block number */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  497) 		bn = addressXAD(&p->xad[index]);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  498) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  499) 		/* unpin the parent page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  500) 		XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  501) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  502) }
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  503) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  504) /*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  505)  *	xtInsert()
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  506)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  507)  * function:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  508)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  509)  * parameter:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  510)  *	tid	- transaction id;
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  511)  *	ip	- file object;
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  512)  *	xflag	- extent flag (XAD_NOTRECORDED):
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  513)  *	xoff	- extent offset;
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  514)  *	xlen	- extent length;
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  515)  *	xaddrp	- extent address pointer (in/out):
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  516)  *		if (*xaddrp)
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  517)  *			caller allocated data extent at *xaddrp;
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  518)  *		else
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  519)  *			allocate data extent and return its xaddr;
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  520)  *	flag	-
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  521)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  522)  * return:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  523)  */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  524) int xtInsert(tid_t tid,		/* transaction id */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  525) 	     struct inode *ip, int xflag, s64 xoff, s32 xlen, s64 * xaddrp,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  526) 	     int flag)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  527) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  528) 	int rc = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  529) 	s64 xaddr, hint;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  530) 	struct metapage *mp;	/* meta-page buffer */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  531) 	xtpage_t *p;		/* base B+-tree index page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  532) 	s64 bn;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  533) 	int index, nextindex;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  534) 	struct btstack btstack;	/* traverse stack */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  535) 	struct xtsplit split;	/* split information */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  536) 	xad_t *xad;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  537) 	int cmp;
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600  538) 	s64 next;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  539) 	struct tlock *tlck;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  540) 	struct xtlock *xtlck;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  541) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  542) 	jfs_info("xtInsert: nxoff:0x%lx nxlen:0x%x", (ulong) xoff, xlen);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  543) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  544) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  545) 	 *	search for the entry location at which to insert:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  546) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  547) 	 * xtFastSearch() and xtSearch() both returns (leaf page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  548) 	 * pinned, index at which to insert).
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  549) 	 * n.b. xtSearch() may return index of maxentry of
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  550) 	 * the full page.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  551) 	 */
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600  552) 	if ((rc = xtSearch(ip, xoff, &next, &cmp, &btstack, XT_INSERT)))
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  553) 		return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  554) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  555) 	/* retrieve search result */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  556) 	XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  557) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  558) 	/* This test must follow XT_GETSEARCH since mp must be valid if
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  559) 	 * we branch to out: */
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600  560) 	if ((cmp == 0) || (next && (xlen > next - xoff))) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  561) 		rc = -EEXIST;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  562) 		goto out;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  563) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  564) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  565) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  566) 	 * allocate data extent requested
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  567) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  568) 	 * allocation hint: last xad
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  569) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  570) 	if ((xaddr = *xaddrp) == 0) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  571) 		if (index > XTENTRYSTART) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  572) 			xad = &p->xad[index - 1];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  573) 			hint = addressXAD(xad) + lengthXAD(xad) - 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  574) 		} else
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  575) 			hint = 0;
5dd4056db8438 (Christoph Hellwig 2010-03-03 09:05:00 -0500  576) 		if ((rc = dquot_alloc_block(ip, xlen)))
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  577) 			goto out;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  578) 		if ((rc = dbAlloc(ip, hint, (s64) xlen, &xaddr))) {
5dd4056db8438 (Christoph Hellwig 2010-03-03 09:05:00 -0500  579) 			dquot_free_block(ip, xlen);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  580) 			goto out;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  581) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  582) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  583) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  584) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  585) 	 *	insert entry for new extent
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  586) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  587) 	xflag |= XAD_NEW;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  588) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  589) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  590) 	 *	if the leaf page is full, split the page and
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  591) 	 *	propagate up the router entry for the new page from split
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  592) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  593) 	 * The xtSplitUp() will insert the entry and unpin the leaf page.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  594) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  595) 	nextindex = le16_to_cpu(p->header.nextindex);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  596) 	if (nextindex == le16_to_cpu(p->header.maxentry)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  597) 		split.mp = mp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  598) 		split.index = index;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  599) 		split.flag = xflag;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  600) 		split.off = xoff;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  601) 		split.len = xlen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  602) 		split.addr = xaddr;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  603) 		split.pxdlist = NULL;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  604) 		if ((rc = xtSplitUp(tid, ip, &split, &btstack))) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  605) 			/* undo data extent allocation */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  606) 			if (*xaddrp == 0) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  607) 				dbFree(ip, xaddr, (s64) xlen);
5dd4056db8438 (Christoph Hellwig 2010-03-03 09:05:00 -0500  608) 				dquot_free_block(ip, xlen);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  609) 			}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  610) 			return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  611) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  612) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  613) 		*xaddrp = xaddr;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  614) 		return 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  615) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  616) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  617) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  618) 	 *	insert the new entry into the leaf page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  619) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  620) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  621) 	 * acquire a transaction lock on the leaf page;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  622) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  623) 	 * action: xad insertion/extension;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  624) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  625) 	BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  626) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  627) 	/* if insert into middle, shift right remaining entries. */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  628) 	if (index < nextindex)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  629) 		memmove(&p->xad[index + 1], &p->xad[index],
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  630) 			(nextindex - index) * sizeof(xad_t));
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  631) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  632) 	/* insert the new entry: mark the entry NEW */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  633) 	xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  634) 	XT_PUTENTRY(xad, xflag, xoff, xlen, xaddr);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  635) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  636) 	/* advance next available entry index */
891456227881d (Marcin Slusarz    2008-02-13 15:34:20 -0600  637) 	le16_add_cpu(&p->header.nextindex, 1);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  638) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  639) 	/* Don't log it if there are no links to the file */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  640) 	if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  641) 		tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  642) 		xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  643) 		xtlck->lwm.offset =
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  644) 		    (xtlck->lwm.offset) ? min(index,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  645) 					      (int)xtlck->lwm.offset) : index;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  646) 		xtlck->lwm.length =
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  647) 		    le16_to_cpu(p->header.nextindex) - xtlck->lwm.offset;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  648) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  649) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  650) 	*xaddrp = xaddr;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  651) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  652)       out:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  653) 	/* unpin the leaf page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  654) 	XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  655) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  656) 	return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  657) }
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  658) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  659) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  660) /*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  661)  *	xtSplitUp()
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  662)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  663)  * function:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  664)  *	split full pages as propagating insertion up the tree
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  665)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  666)  * parameter:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  667)  *	tid	- transaction id;
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  668)  *	ip	- file object;
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  669)  *	split	- entry parameter descriptor;
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  670)  *	btstack - traverse stack from xtSearch()
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  671)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  672)  * return:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  673)  */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  674) static int
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  675) xtSplitUp(tid_t tid,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  676) 	  struct inode *ip, struct xtsplit * split, struct btstack * btstack)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  677) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  678) 	int rc = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  679) 	struct metapage *smp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  680) 	xtpage_t *sp;		/* split page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  681) 	struct metapage *rmp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  682) 	s64 rbn;		/* new right page block number */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  683) 	struct metapage *rcmp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  684) 	xtpage_t *rcp;		/* right child page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  685) 	s64 rcbn;		/* right child page block number */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  686) 	int skip;		/* index of entry of insertion */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  687) 	int nextindex;		/* next available entry index of p */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  688) 	struct btframe *parent;	/* parent page entry on traverse stack */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  689) 	xad_t *xad;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  690) 	s64 xaddr;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  691) 	int xlen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  692) 	int nsplit;		/* number of pages split */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  693) 	struct pxdlist pxdlist;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  694) 	pxd_t *pxd;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  695) 	struct tlock *tlck;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  696) 	struct xtlock *xtlck;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  697) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  698) 	smp = split->mp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  699) 	sp = XT_PAGE(ip, smp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  700) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  701) 	/* is inode xtree root extension/inline EA area free ? */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  702) 	if ((sp->header.flag & BT_ROOT) && (!S_ISDIR(ip->i_mode)) &&
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  703) 	    (le16_to_cpu(sp->header.maxentry) < XTROOTMAXSLOT) &&
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  704) 	    (JFS_IP(ip)->mode2 & INLINEEA)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  705) 		sp->header.maxentry = cpu_to_le16(XTROOTMAXSLOT);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  706) 		JFS_IP(ip)->mode2 &= ~INLINEEA;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  707) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  708) 		BT_MARK_DIRTY(smp, ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  709) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  710) 		 * acquire a transaction lock on the leaf page;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  711) 		 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  712) 		 * action: xad insertion/extension;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  713) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  714) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  715) 		/* if insert into middle, shift right remaining entries. */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  716) 		skip = split->index;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  717) 		nextindex = le16_to_cpu(sp->header.nextindex);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  718) 		if (skip < nextindex)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  719) 			memmove(&sp->xad[skip + 1], &sp->xad[skip],
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  720) 				(nextindex - skip) * sizeof(xad_t));
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  721) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  722) 		/* insert the new entry: mark the entry NEW */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  723) 		xad = &sp->xad[skip];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  724) 		XT_PUTENTRY(xad, split->flag, split->off, split->len,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  725) 			    split->addr);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  726) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  727) 		/* advance next available entry index */
891456227881d (Marcin Slusarz    2008-02-13 15:34:20 -0600  728) 		le16_add_cpu(&sp->header.nextindex, 1);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  729) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  730) 		/* Don't log it if there are no links to the file */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  731) 		if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  732) 			tlck = txLock(tid, ip, smp, tlckXTREE | tlckGROW);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  733) 			xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  734) 			xtlck->lwm.offset = (xtlck->lwm.offset) ?
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  735) 			    min(skip, (int)xtlck->lwm.offset) : skip;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  736) 			xtlck->lwm.length =
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  737) 			    le16_to_cpu(sp->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  738) 			    xtlck->lwm.offset;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  739) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  740) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  741) 		return 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  742) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  743) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  744) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  745) 	 * allocate new index blocks to cover index page split(s)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  746) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  747) 	 * allocation hint: ?
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  748) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  749) 	if (split->pxdlist == NULL) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  750) 		nsplit = btstack->nsplit;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  751) 		split->pxdlist = &pxdlist;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  752) 		pxdlist.maxnpxd = pxdlist.npxd = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  753) 		pxd = &pxdlist.pxd[0];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  754) 		xlen = JFS_SBI(ip->i_sb)->nbperpage;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  755) 		for (; nsplit > 0; nsplit--, pxd++) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  756) 			if ((rc = dbAlloc(ip, (s64) 0, (s64) xlen, &xaddr))
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  757) 			    == 0) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  758) 				PXDaddress(pxd, xaddr);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  759) 				PXDlength(pxd, xlen);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  760) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  761) 				pxdlist.maxnpxd++;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  762) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  763) 				continue;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  764) 			}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  765) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  766) 			/* undo allocation */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  767) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  768) 			XT_PUTPAGE(smp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  769) 			return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  770) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  771) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  772) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  773) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  774) 	 * Split leaf page <sp> into <sp> and a new right page <rp>.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  775) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  776) 	 * The split routines insert the new entry into the leaf page,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  777) 	 * and acquire txLock as appropriate.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  778) 	 * return <rp> pinned and its block number <rpbn>.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  779) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  780) 	rc = (sp->header.flag & BT_ROOT) ?
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  781) 	    xtSplitRoot(tid, ip, split, &rmp) :
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  782) 	    xtSplitPage(tid, ip, split, &rmp, &rbn);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  783) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  784) 	XT_PUTPAGE(smp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  785) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  786) 	if (rc)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  787) 		return -EIO;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  788) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  789) 	 * propagate up the router entry for the leaf page just split
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  790) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  791) 	 * insert a router entry for the new page into the parent page,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  792) 	 * propagate the insert/split up the tree by walking back the stack
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  793) 	 * of (bn of parent page, index of child page entry in parent page)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  794) 	 * that were traversed during the search for the page that split.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  795) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  796) 	 * the propagation of insert/split up the tree stops if the root
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  797) 	 * splits or the page inserted into doesn't have to split to hold
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  798) 	 * the new entry.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  799) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  800) 	 * the parent entry for the split page remains the same, and
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  801) 	 * a new entry is inserted at its right with the first key and
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  802) 	 * block number of the new right page.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  803) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  804) 	 * There are a maximum of 3 pages pinned at any time:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  805) 	 * right child, left parent and right parent (when the parent splits)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  806) 	 * to keep the child page pinned while working on the parent.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  807) 	 * make sure that all pins are released at exit.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  808) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  809) 	while ((parent = BT_POP(btstack)) != NULL) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  810) 		/* parent page specified by stack frame <parent> */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  811) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  812) 		/* keep current child pages <rcp> pinned */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  813) 		rcmp = rmp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  814) 		rcbn = rbn;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  815) 		rcp = XT_PAGE(ip, rcmp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  816) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  817) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  818) 		 * insert router entry in parent for new right child page <rp>
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  819) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  820) 		/* get/pin the parent page <sp> */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  821) 		XT_GETPAGE(ip, parent->bn, smp, PSIZE, sp, rc);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  822) 		if (rc) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  823) 			XT_PUTPAGE(rcmp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  824) 			return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  825) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  826) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  827) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  828) 		 * The new key entry goes ONE AFTER the index of parent entry,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  829) 		 * because the split was to the right.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  830) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  831) 		skip = parent->index + 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  832) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  833) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  834) 		 * split or shift right remaining entries of the parent page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  835) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  836) 		nextindex = le16_to_cpu(sp->header.nextindex);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  837) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  838) 		 * parent page is full - split the parent page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  839) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  840) 		if (nextindex == le16_to_cpu(sp->header.maxentry)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  841) 			/* init for parent page split */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  842) 			split->mp = smp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  843) 			split->index = skip;	/* index at insert */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  844) 			split->flag = XAD_NEW;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  845) 			split->off = offsetXAD(&rcp->xad[XTENTRYSTART]);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  846) 			split->len = JFS_SBI(ip->i_sb)->nbperpage;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  847) 			split->addr = rcbn;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  848) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  849) 			/* unpin previous right child page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  850) 			XT_PUTPAGE(rcmp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  851) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  852) 			/* The split routines insert the new entry,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  853) 			 * and acquire txLock as appropriate.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  854) 			 * return <rp> pinned and its block number <rpbn>.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  855) 			 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  856) 			rc = (sp->header.flag & BT_ROOT) ?
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  857) 			    xtSplitRoot(tid, ip, split, &rmp) :
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  858) 			    xtSplitPage(tid, ip, split, &rmp, &rbn);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  859) 			if (rc) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  860) 				XT_PUTPAGE(smp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  861) 				return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  862) 			}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  863) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  864) 			XT_PUTPAGE(smp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  865) 			/* keep new child page <rp> pinned */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  866) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  867) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  868) 		 * parent page is not full - insert in parent page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  869) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  870) 		else {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  871) 			/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  872) 			 * insert router entry in parent for the right child
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  873) 			 * page from the first entry of the right child page:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  874) 			 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  875) 			/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  876) 			 * acquire a transaction lock on the parent page;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  877) 			 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  878) 			 * action: router xad insertion;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  879) 			 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  880) 			BT_MARK_DIRTY(smp, ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  881) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  882) 			/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  883) 			 * if insert into middle, shift right remaining entries
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  884) 			 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  885) 			if (skip < nextindex)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  886) 				memmove(&sp->xad[skip + 1], &sp->xad[skip],
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  887) 					(nextindex -
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  888) 					 skip) << L2XTSLOTSIZE);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  889) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  890) 			/* insert the router entry */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  891) 			xad = &sp->xad[skip];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  892) 			XT_PUTENTRY(xad, XAD_NEW,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  893) 				    offsetXAD(&rcp->xad[XTENTRYSTART]),
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  894) 				    JFS_SBI(ip->i_sb)->nbperpage, rcbn);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  895) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  896) 			/* advance next available entry index. */
891456227881d (Marcin Slusarz    2008-02-13 15:34:20 -0600  897) 			le16_add_cpu(&sp->header.nextindex, 1);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  898) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  899) 			/* Don't log it if there are no links to the file */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  900) 			if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  901) 				tlck = txLock(tid, ip, smp,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  902) 					      tlckXTREE | tlckGROW);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  903) 				xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  904) 				xtlck->lwm.offset = (xtlck->lwm.offset) ?
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  905) 				    min(skip, (int)xtlck->lwm.offset) : skip;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  906) 				xtlck->lwm.length =
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  907) 				    le16_to_cpu(sp->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  908) 				    xtlck->lwm.offset;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  909) 			}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  910) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  911) 			/* unpin parent page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  912) 			XT_PUTPAGE(smp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  913) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  914) 			/* exit propagate up */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  915) 			break;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  916) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  917) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  918) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  919) 	/* unpin current right page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  920) 	XT_PUTPAGE(rmp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  921) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  922) 	return 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  923) }
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  924) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  925) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  926) /*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  927)  *	xtSplitPage()
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  928)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  929)  * function:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  930)  *	split a full non-root page into
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  931)  *	original/split/left page and new right page
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  932)  *	i.e., the original/split page remains as left page.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  933)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  934)  * parameter:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  935)  *	int		tid,
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  936)  *	struct inode	*ip,
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  937)  *	struct xtsplit	*split,
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  938)  *	struct metapage	**rmpp,
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  939)  *	u64		*rbnp,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  940)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  941)  * return:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  942)  *	Pointer to page in which to insert or NULL on error.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  943)  */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  944) static int
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  945) xtSplitPage(tid_t tid, struct inode *ip,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  946) 	    struct xtsplit * split, struct metapage ** rmpp, s64 * rbnp)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  947) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  948) 	int rc = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  949) 	struct metapage *smp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  950) 	xtpage_t *sp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  951) 	struct metapage *rmp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  952) 	xtpage_t *rp;		/* new right page allocated */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  953) 	s64 rbn;		/* new right page block number */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  954) 	struct metapage *mp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  955) 	xtpage_t *p;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  956) 	s64 nextbn;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  957) 	int skip, maxentry, middle, righthalf, n;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  958) 	xad_t *xad;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  959) 	struct pxdlist *pxdlist;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  960) 	pxd_t *pxd;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  961) 	struct tlock *tlck;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  962) 	struct xtlock *sxtlck = NULL, *rxtlck = NULL;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  963) 	int quota_allocation = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  964) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  965) 	smp = split->mp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  966) 	sp = XT_PAGE(ip, smp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  967) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  968) 	INCREMENT(xtStat.split);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  969) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  970) 	pxdlist = split->pxdlist;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  971) 	pxd = &pxdlist->pxd[pxdlist->npxd];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  972) 	pxdlist->npxd++;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  973) 	rbn = addressPXD(pxd);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  974) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  975) 	/* Allocate blocks to quota. */
5dd4056db8438 (Christoph Hellwig 2010-03-03 09:05:00 -0500  976) 	rc = dquot_alloc_block(ip, lengthPXD(pxd));
5dd4056db8438 (Christoph Hellwig 2010-03-03 09:05:00 -0500  977) 	if (rc)
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500  978) 		goto clean_up;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  979) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  980) 	quota_allocation += lengthPXD(pxd);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  981) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  982) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  983) 	 * allocate the new right page for the split
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  984) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  985) 	rmp = get_metapage(ip, rbn, PSIZE, 1);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  986) 	if (rmp == NULL) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  987) 		rc = -EIO;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  988) 		goto clean_up;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  989) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  990) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  991) 	jfs_info("xtSplitPage: ip:0x%p smp:0x%p rmp:0x%p", ip, smp, rmp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  992) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  993) 	BT_MARK_DIRTY(rmp, ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  994) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  995) 	 * action: new page;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  996) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  997) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  998) 	rp = (xtpage_t *) rmp->data;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  999) 	rp->header.self = *pxd;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1000) 	rp->header.flag = sp->header.flag & BT_TYPE;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1001) 	rp->header.maxentry = sp->header.maxentry;	/* little-endian */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1002) 	rp->header.nextindex = cpu_to_le16(XTENTRYSTART);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1003) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1004) 	BT_MARK_DIRTY(smp, ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1005) 	/* Don't log it if there are no links to the file */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1006) 	if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1007) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1008) 		 * acquire a transaction lock on the new right page;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1009) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1010) 		tlck = txLock(tid, ip, rmp, tlckXTREE | tlckNEW);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1011) 		rxtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1012) 		rxtlck->lwm.offset = XTENTRYSTART;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1013) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1014) 		 * acquire a transaction lock on the split page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1015) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1016) 		tlck = txLock(tid, ip, smp, tlckXTREE | tlckGROW);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1017) 		sxtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1018) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1019) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1020) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1021) 	 * initialize/update sibling pointers of <sp> and <rp>
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1022) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1023) 	nextbn = le64_to_cpu(sp->header.next);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1024) 	rp->header.next = cpu_to_le64(nextbn);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1025) 	rp->header.prev = cpu_to_le64(addressPXD(&sp->header.self));
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1026) 	sp->header.next = cpu_to_le64(rbn);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1027) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1028) 	skip = split->index;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1029) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1030) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1031) 	 *	sequential append at tail (after last entry of last page)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1032) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1033) 	 * if splitting the last page on a level because of appending
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1034) 	 * a entry to it (skip is maxentry), it's likely that the access is
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1035) 	 * sequential. adding an empty page on the side of the level is less
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1036) 	 * work and can push the fill factor much higher than normal.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1037) 	 * if we're wrong it's no big deal -  we will do the split the right
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1038) 	 * way next time.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1039) 	 * (it may look like it's equally easy to do a similar hack for
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1040) 	 * reverse sorted data, that is, split the tree left, but it's not.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1041) 	 * Be my guest.)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1042) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1043) 	if (nextbn == 0 && skip == le16_to_cpu(sp->header.maxentry)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1044) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1045) 		 * acquire a transaction lock on the new/right page;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1046) 		 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1047) 		 * action: xad insertion;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1048) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1049) 		/* insert entry at the first entry of the new right page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1050) 		xad = &rp->xad[XTENTRYSTART];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1051) 		XT_PUTENTRY(xad, split->flag, split->off, split->len,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1052) 			    split->addr);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1053) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1054) 		rp->header.nextindex = cpu_to_le16(XTENTRYSTART + 1);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1055) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1056) 		if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1057) 			/* rxtlck->lwm.offset = XTENTRYSTART; */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1058) 			rxtlck->lwm.length = 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1059) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1060) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1061) 		*rmpp = rmp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1062) 		*rbnp = rbn;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1063) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1064) 		jfs_info("xtSplitPage: sp:0x%p rp:0x%p", sp, rp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1065) 		return 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1066) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1067) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1068) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1069) 	 *	non-sequential insert (at possibly middle page)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1070) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1071) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1072) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1073) 	 * update previous pointer of old next/right page of <sp>
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1074) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1075) 	if (nextbn != 0) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1076) 		XT_GETPAGE(ip, nextbn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1077) 		if (rc) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1078) 			XT_PUTPAGE(rmp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1079) 			goto clean_up;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1080) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1081) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1082) 		BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1083) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1084) 		 * acquire a transaction lock on the next page;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1085) 		 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1086) 		 * action:sibling pointer update;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1087) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1088) 		if (!test_cflag(COMMIT_Nolink, ip))
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1089) 			tlck = txLock(tid, ip, mp, tlckXTREE | tlckRELINK);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1090) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1091) 		p->header.prev = cpu_to_le64(rbn);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1092) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1093) 		/* sibling page may have been updated previously, or
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1094) 		 * it may be updated later;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1095) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1096) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1097) 		XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1098) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1099) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1100) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1101) 	 * split the data between the split and new/right pages
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1102) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1103) 	maxentry = le16_to_cpu(sp->header.maxentry);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1104) 	middle = maxentry >> 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1105) 	righthalf = maxentry - middle;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1106) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1107) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1108) 	 * skip index in old split/left page - insert into left page:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1109) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1110) 	if (skip <= middle) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1111) 		/* move right half of split page to the new right page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1112) 		memmove(&rp->xad[XTENTRYSTART], &sp->xad[middle],
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1113) 			righthalf << L2XTSLOTSIZE);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1114) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1115) 		/* shift right tail of left half to make room for new entry */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1116) 		if (skip < middle)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1117) 			memmove(&sp->xad[skip + 1], &sp->xad[skip],
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1118) 				(middle - skip) << L2XTSLOTSIZE);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1119) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1120) 		/* insert new entry */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1121) 		xad = &sp->xad[skip];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1122) 		XT_PUTENTRY(xad, split->flag, split->off, split->len,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1123) 			    split->addr);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1124) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1125) 		/* update page header */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1126) 		sp->header.nextindex = cpu_to_le16(middle + 1);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1127) 		if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1128) 			sxtlck->lwm.offset = (sxtlck->lwm.offset) ?
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1129) 			    min(skip, (int)sxtlck->lwm.offset) : skip;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1130) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1131) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1132) 		rp->header.nextindex =
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1133) 		    cpu_to_le16(XTENTRYSTART + righthalf);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1134) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1135) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1136) 	 * skip index in new right page - insert into right page:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1137) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1138) 	else {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1139) 		/* move left head of right half to right page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1140) 		n = skip - middle;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1141) 		memmove(&rp->xad[XTENTRYSTART], &sp->xad[middle],
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1142) 			n << L2XTSLOTSIZE);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1143) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1144) 		/* insert new entry */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1145) 		n += XTENTRYSTART;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1146) 		xad = &rp->xad[n];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1147) 		XT_PUTENTRY(xad, split->flag, split->off, split->len,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1148) 			    split->addr);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1149) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1150) 		/* move right tail of right half to right page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1151) 		if (skip < maxentry)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1152) 			memmove(&rp->xad[n + 1], &sp->xad[skip],
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1153) 				(maxentry - skip) << L2XTSLOTSIZE);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1154) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1155) 		/* update page header */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1156) 		sp->header.nextindex = cpu_to_le16(middle);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1157) 		if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1158) 			sxtlck->lwm.offset = (sxtlck->lwm.offset) ?
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1159) 			    min(middle, (int)sxtlck->lwm.offset) : middle;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1160) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1161) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1162) 		rp->header.nextindex = cpu_to_le16(XTENTRYSTART +
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1163) 						   righthalf + 1);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1164) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1165) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1166) 	if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1167) 		sxtlck->lwm.length = le16_to_cpu(sp->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1168) 		    sxtlck->lwm.offset;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1169) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1170) 		/* rxtlck->lwm.offset = XTENTRYSTART; */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1171) 		rxtlck->lwm.length = le16_to_cpu(rp->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1172) 		    XTENTRYSTART;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1173) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1174) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1175) 	*rmpp = rmp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1176) 	*rbnp = rbn;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1177) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1178) 	jfs_info("xtSplitPage: sp:0x%p rp:0x%p", sp, rp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1179) 	return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1180) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1181)       clean_up:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1182) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1183) 	/* Rollback quota allocation. */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1184) 	if (quota_allocation)
5dd4056db8438 (Christoph Hellwig 2010-03-03 09:05:00 -0500 1185) 		dquot_free_block(ip, quota_allocation);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1186) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1187) 	return (rc);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1188) }
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1189) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1190) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1191) /*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1192)  *	xtSplitRoot()
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1193)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1194)  * function:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1195)  *	split the full root page into original/root/split page and new
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1196)  *	right page
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1197)  *	i.e., root remains fixed in tree anchor (inode) and the root is
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1198)  *	copied to a single new right child page since root page <<
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1199)  *	non-root page, and the split root page contains a single entry
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1200)  *	for the new right child page.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1201)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1202)  * parameter:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1203)  *	int		tid,
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1204)  *	struct inode	*ip,
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1205)  *	struct xtsplit	*split,
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1206)  *	struct metapage	**rmpp)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1207)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1208)  * return:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1209)  *	Pointer to page in which to insert or NULL on error.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1210)  */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1211) static int
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1212) xtSplitRoot(tid_t tid,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1213) 	    struct inode *ip, struct xtsplit * split, struct metapage ** rmpp)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1214) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1215) 	xtpage_t *sp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1216) 	struct metapage *rmp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1217) 	xtpage_t *rp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1218) 	s64 rbn;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1219) 	int skip, nextindex;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1220) 	xad_t *xad;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1221) 	pxd_t *pxd;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1222) 	struct pxdlist *pxdlist;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1223) 	struct tlock *tlck;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1224) 	struct xtlock *xtlck;
5dd4056db8438 (Christoph Hellwig 2010-03-03 09:05:00 -0500 1225) 	int rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1226) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1227) 	sp = &JFS_IP(ip)->i_xtroot;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1228) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1229) 	INCREMENT(xtStat.split);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1230) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1231) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1232) 	 *	allocate a single (right) child page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1233) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1234) 	pxdlist = split->pxdlist;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1235) 	pxd = &pxdlist->pxd[pxdlist->npxd];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1236) 	pxdlist->npxd++;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1237) 	rbn = addressPXD(pxd);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1238) 	rmp = get_metapage(ip, rbn, PSIZE, 1);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1239) 	if (rmp == NULL)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1240) 		return -EIO;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1241) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1242) 	/* Allocate blocks to quota. */
5dd4056db8438 (Christoph Hellwig 2010-03-03 09:05:00 -0500 1243) 	rc = dquot_alloc_block(ip, lengthPXD(pxd));
5dd4056db8438 (Christoph Hellwig 2010-03-03 09:05:00 -0500 1244) 	if (rc) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1245) 		release_metapage(rmp);
5dd4056db8438 (Christoph Hellwig 2010-03-03 09:05:00 -0500 1246) 		return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1247) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1248) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1249) 	jfs_info("xtSplitRoot: ip:0x%p rmp:0x%p", ip, rmp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1250) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1251) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1252) 	 * acquire a transaction lock on the new right page;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1253) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1254) 	 * action: new page;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1255) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1256) 	BT_MARK_DIRTY(rmp, ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1257) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1258) 	rp = (xtpage_t *) rmp->data;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1259) 	rp->header.flag =
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1260) 	    (sp->header.flag & BT_LEAF) ? BT_LEAF : BT_INTERNAL;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1261) 	rp->header.self = *pxd;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1262) 	rp->header.nextindex = cpu_to_le16(XTENTRYSTART);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1263) 	rp->header.maxentry = cpu_to_le16(PSIZE >> L2XTSLOTSIZE);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1264) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1265) 	/* initialize sibling pointers */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1266) 	rp->header.next = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1267) 	rp->header.prev = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1268) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1269) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1270) 	 * copy the in-line root page into new right page extent
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1271) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1272) 	nextindex = le16_to_cpu(sp->header.maxentry);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1273) 	memmove(&rp->xad[XTENTRYSTART], &sp->xad[XTENTRYSTART],
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1274) 		(nextindex - XTENTRYSTART) << L2XTSLOTSIZE);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1275) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1276) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1277) 	 * insert the new entry into the new right/child page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1278) 	 * (skip index in the new right page will not change)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1279) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1280) 	skip = split->index;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1281) 	/* if insert into middle, shift right remaining entries */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1282) 	if (skip != nextindex)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1283) 		memmove(&rp->xad[skip + 1], &rp->xad[skip],
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1284) 			(nextindex - skip) * sizeof(xad_t));
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1285) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1286) 	xad = &rp->xad[skip];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1287) 	XT_PUTENTRY(xad, split->flag, split->off, split->len, split->addr);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1288) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1289) 	/* update page header */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1290) 	rp->header.nextindex = cpu_to_le16(nextindex + 1);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1291) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1292) 	if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1293) 		tlck = txLock(tid, ip, rmp, tlckXTREE | tlckNEW);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1294) 		xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1295) 		xtlck->lwm.offset = XTENTRYSTART;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1296) 		xtlck->lwm.length = le16_to_cpu(rp->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1297) 		    XTENTRYSTART;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1298) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1299) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1300) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1301) 	 *	reset the root
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1302) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1303) 	 * init root with the single entry for the new right page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1304) 	 * set the 1st entry offset to 0, which force the left-most key
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1305) 	 * at any level of the tree to be less than any search key.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1306) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1307) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1308) 	 * acquire a transaction lock on the root page (in-memory inode);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1309) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1310) 	 * action: root split;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1311) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1312) 	BT_MARK_DIRTY(split->mp, ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1313) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1314) 	xad = &sp->xad[XTENTRYSTART];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1315) 	XT_PUTENTRY(xad, XAD_NEW, 0, JFS_SBI(ip->i_sb)->nbperpage, rbn);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1316) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1317) 	/* update page header of root */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1318) 	sp->header.flag &= ~BT_LEAF;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1319) 	sp->header.flag |= BT_INTERNAL;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1320) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1321) 	sp->header.nextindex = cpu_to_le16(XTENTRYSTART + 1);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1322) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1323) 	if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1324) 		tlck = txLock(tid, ip, split->mp, tlckXTREE | tlckGROW);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1325) 		xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1326) 		xtlck->lwm.offset = XTENTRYSTART;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1327) 		xtlck->lwm.length = 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1328) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1329) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1330) 	*rmpp = rmp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1331) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1332) 	jfs_info("xtSplitRoot: sp:0x%p rp:0x%p", sp, rp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1333) 	return 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1334) }
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1335) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1336) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1337) /*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1338)  *	xtExtend()
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1339)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1340)  * function: extend in-place;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1341)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1342)  * note: existing extent may or may not have been committed.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1343)  * caller is responsible for pager buffer cache update, and
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1344)  * working block allocation map update;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1345)  * update pmap: alloc whole extended extent;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1346)  */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1347) int xtExtend(tid_t tid,		/* transaction id */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1348) 	     struct inode *ip, s64 xoff,	/* delta extent offset */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1349) 	     s32 xlen,		/* delta extent length */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1350) 	     int flag)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1351) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1352) 	int rc = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1353) 	int cmp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1354) 	struct metapage *mp;	/* meta-page buffer */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1355) 	xtpage_t *p;		/* base B+-tree index page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1356) 	s64 bn;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1357) 	int index, nextindex, len;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1358) 	struct btstack btstack;	/* traverse stack */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1359) 	struct xtsplit split;	/* split information */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1360) 	xad_t *xad;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1361) 	s64 xaddr;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1362) 	struct tlock *tlck;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1363) 	struct xtlock *xtlck = NULL;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1364) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1365) 	jfs_info("xtExtend: nxoff:0x%lx nxlen:0x%x", (ulong) xoff, xlen);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1366) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1367) 	/* there must exist extent to be extended */
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600 1368) 	if ((rc = xtSearch(ip, xoff - 1, NULL, &cmp, &btstack, XT_INSERT)))
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1369) 		return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1370) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1371) 	/* retrieve search result */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1372) 	XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1373) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1374) 	if (cmp != 0) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1375) 		XT_PUTPAGE(mp);
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700 1376) 		jfs_error(ip->i_sb, "xtSearch did not find extent\n");
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1377) 		return -EIO;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1378) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1379) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1380) 	/* extension must be contiguous */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1381) 	xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1382) 	if ((offsetXAD(xad) + lengthXAD(xad)) != xoff) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1383) 		XT_PUTPAGE(mp);
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700 1384) 		jfs_error(ip->i_sb, "extension is not contiguous\n");
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1385) 		return -EIO;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1386) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1387) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1388) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1389) 	 * acquire a transaction lock on the leaf page;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1390) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1391) 	 * action: xad insertion/extension;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1392) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1393) 	BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1394) 	if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1395) 		tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1396) 		xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1397) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1398) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1399) 	/* extend will overflow extent ? */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1400) 	xlen = lengthXAD(xad) + xlen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1401) 	if ((len = xlen - MAXXLEN) <= 0)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1402) 		goto extendOld;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1403) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1404) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1405) 	 *	extent overflow: insert entry for new extent
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1406) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1407) //insertNew:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1408) 	xoff = offsetXAD(xad) + MAXXLEN;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1409) 	xaddr = addressXAD(xad) + MAXXLEN;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1410) 	nextindex = le16_to_cpu(p->header.nextindex);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1411) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1412) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1413) 	 *	if the leaf page is full, insert the new entry and
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1414) 	 *	propagate up the router entry for the new page from split
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1415) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1416) 	 * The xtSplitUp() will insert the entry and unpin the leaf page.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1417) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1418) 	if (nextindex == le16_to_cpu(p->header.maxentry)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1419) 		/* xtSpliUp() unpins leaf pages */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1420) 		split.mp = mp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1421) 		split.index = index + 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1422) 		split.flag = XAD_NEW;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1423) 		split.off = xoff;	/* split offset */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1424) 		split.len = len;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1425) 		split.addr = xaddr;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1426) 		split.pxdlist = NULL;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1427) 		if ((rc = xtSplitUp(tid, ip, &split, &btstack)))
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1428) 			return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1429) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1430) 		/* get back old page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1431) 		XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1432) 		if (rc)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1433) 			return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1434) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1435) 		 * if leaf root has been split, original root has been
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1436) 		 * copied to new child page, i.e., original entry now
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1437) 		 * resides on the new child page;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1438) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1439) 		if (p->header.flag & BT_INTERNAL) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1440) 			ASSERT(p->header.nextindex ==
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1441) 			       cpu_to_le16(XTENTRYSTART + 1));
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1442) 			xad = &p->xad[XTENTRYSTART];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1443) 			bn = addressXAD(xad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1444) 			XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1445) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1446) 			/* get new child page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1447) 			XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1448) 			if (rc)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1449) 				return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1450) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1451) 			BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1452) 			if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1453) 				tlck = txLock(tid, ip, mp, tlckXTREE|tlckGROW);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1454) 				xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1455) 			}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1456) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1457) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1458) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1459) 	 *	insert the new entry into the leaf page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1460) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1461) 	else {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1462) 		/* insert the new entry: mark the entry NEW */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1463) 		xad = &p->xad[index + 1];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1464) 		XT_PUTENTRY(xad, XAD_NEW, xoff, len, xaddr);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1465) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1466) 		/* advance next available entry index */
891456227881d (Marcin Slusarz    2008-02-13 15:34:20 -0600 1467) 		le16_add_cpu(&p->header.nextindex, 1);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1468) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1469) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1470) 	/* get back old entry */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1471) 	xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1472) 	xlen = MAXXLEN;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1473) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1474) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1475) 	 * extend old extent
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1476) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1477)       extendOld:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1478) 	XADlength(xad, xlen);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1479) 	if (!(xad->flag & XAD_NEW))
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1480) 		xad->flag |= XAD_EXTENDED;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1481) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1482) 	if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1483) 		xtlck->lwm.offset =
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1484) 		    (xtlck->lwm.offset) ? min(index,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1485) 					      (int)xtlck->lwm.offset) : index;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1486) 		xtlck->lwm.length =
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1487) 		    le16_to_cpu(p->header.nextindex) - xtlck->lwm.offset;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1488) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1489) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1490) 	/* unpin the leaf page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1491) 	XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1492) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1493) 	return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1494) }
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1495) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1496) #ifdef _NOTYET
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1497) /*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1498)  *	xtTailgate()
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1499)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1500)  * function: split existing 'tail' extent
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1501)  *	(split offset >= start offset of tail extent), and
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1502)  *	relocate and extend the split tail half;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1503)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1504)  * note: existing extent may or may not have been committed.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1505)  * caller is responsible for pager buffer cache update, and
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1506)  * working block allocation map update;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1507)  * update pmap: free old split tail extent, alloc new extent;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1508)  */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1509) int xtTailgate(tid_t tid,		/* transaction id */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1510) 	       struct inode *ip, s64 xoff,	/* split/new extent offset */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1511) 	       s32 xlen,	/* new extent length */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1512) 	       s64 xaddr,	/* new extent address */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1513) 	       int flag)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1514) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1515) 	int rc = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1516) 	int cmp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1517) 	struct metapage *mp;	/* meta-page buffer */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1518) 	xtpage_t *p;		/* base B+-tree index page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1519) 	s64 bn;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1520) 	int index, nextindex, llen, rlen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1521) 	struct btstack btstack;	/* traverse stack */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1522) 	struct xtsplit split;	/* split information */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1523) 	xad_t *xad;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1524) 	struct tlock *tlck;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1525) 	struct xtlock *xtlck = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1526) 	struct tlock *mtlck;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1527) 	struct maplock *pxdlock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1528) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1529) /*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1530) printf("xtTailgate: nxoff:0x%lx nxlen:0x%x nxaddr:0x%lx\n",
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1531) 	(ulong)xoff, xlen, (ulong)xaddr);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1532) */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1533) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1534) 	/* there must exist extent to be tailgated */
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600 1535) 	if ((rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, XT_INSERT)))
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1536) 		return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1537) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1538) 	/* retrieve search result */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1539) 	XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1540) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1541) 	if (cmp != 0) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1542) 		XT_PUTPAGE(mp);
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700 1543) 		jfs_error(ip->i_sb, "couldn't find extent\n");
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1544) 		return -EIO;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1545) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1546) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1547) 	/* entry found must be last entry */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1548) 	nextindex = le16_to_cpu(p->header.nextindex);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1549) 	if (index != nextindex - 1) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1550) 		XT_PUTPAGE(mp);
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700 1551) 		jfs_error(ip->i_sb, "the entry found is not the last entry\n");
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1552) 		return -EIO;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1553) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1554) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1555) 	BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1556) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1557) 	 * acquire tlock of the leaf page containing original entry
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1558) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1559) 	if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1560) 		tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1561) 		xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1562) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1563) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1564) 	/* completely replace extent ? */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1565) 	xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1566) /*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1567) printf("xtTailgate: xoff:0x%lx xlen:0x%x xaddr:0x%lx\n",
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1568) 	(ulong)offsetXAD(xad), lengthXAD(xad), (ulong)addressXAD(xad));
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1569) */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1570) 	if ((llen = xoff - offsetXAD(xad)) == 0)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1571) 		goto updateOld;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1572) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1573) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1574) 	 *	partially replace extent: insert entry for new extent
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1575) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1576) //insertNew:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1577) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1578) 	 *	if the leaf page is full, insert the new entry and
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1579) 	 *	propagate up the router entry for the new page from split
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1580) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1581) 	 * The xtSplitUp() will insert the entry and unpin the leaf page.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1582) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1583) 	if (nextindex == le16_to_cpu(p->header.maxentry)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1584) 		/* xtSpliUp() unpins leaf pages */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1585) 		split.mp = mp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1586) 		split.index = index + 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1587) 		split.flag = XAD_NEW;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1588) 		split.off = xoff;	/* split offset */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1589) 		split.len = xlen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1590) 		split.addr = xaddr;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1591) 		split.pxdlist = NULL;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1592) 		if ((rc = xtSplitUp(tid, ip, &split, &btstack)))
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1593) 			return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1594) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1595) 		/* get back old page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1596) 		XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1597) 		if (rc)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1598) 			return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1599) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1600) 		 * if leaf root has been split, original root has been
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1601) 		 * copied to new child page, i.e., original entry now
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1602) 		 * resides on the new child page;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1603) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1604) 		if (p->header.flag & BT_INTERNAL) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1605) 			ASSERT(p->header.nextindex ==
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1606) 			       cpu_to_le16(XTENTRYSTART + 1));
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1607) 			xad = &p->xad[XTENTRYSTART];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1608) 			bn = addressXAD(xad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1609) 			XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1610) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1611) 			/* get new child page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1612) 			XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1613) 			if (rc)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1614) 				return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1615) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1616) 			BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1617) 			if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1618) 				tlck = txLock(tid, ip, mp, tlckXTREE|tlckGROW);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1619) 				xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1620) 			}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1621) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1622) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1623) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1624) 	 *	insert the new entry into the leaf page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1625) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1626) 	else {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1627) 		/* insert the new entry: mark the entry NEW */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1628) 		xad = &p->xad[index + 1];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1629) 		XT_PUTENTRY(xad, XAD_NEW, xoff, xlen, xaddr);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1630) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1631) 		/* advance next available entry index */
891456227881d (Marcin Slusarz    2008-02-13 15:34:20 -0600 1632) 		le16_add_cpu(&p->header.nextindex, 1);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1633) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1634) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1635) 	/* get back old XAD */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1636) 	xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1637) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1638) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1639) 	 * truncate/relocate old extent at split offset
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1640) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1641)       updateOld:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1642) 	/* update dmap for old/committed/truncated extent */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1643) 	rlen = lengthXAD(xad) - llen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1644) 	if (!(xad->flag & XAD_NEW)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1645) 		/* free from PWMAP at commit */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1646) 		if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1647) 			mtlck = txMaplock(tid, ip, tlckMAP);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1648) 			pxdlock = (struct maplock *) & mtlck->lock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1649) 			pxdlock->flag = mlckFREEPXD;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1650) 			PXDaddress(&pxdlock->pxd, addressXAD(xad) + llen);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1651) 			PXDlength(&pxdlock->pxd, rlen);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1652) 			pxdlock->index = 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1653) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1654) 	} else
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1655) 		/* free from WMAP */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1656) 		dbFree(ip, addressXAD(xad) + llen, (s64) rlen);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1657) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1658) 	if (llen)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1659) 		/* truncate */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1660) 		XADlength(xad, llen);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1661) 	else
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1662) 		/* replace */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1663) 		XT_PUTENTRY(xad, XAD_NEW, xoff, xlen, xaddr);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1664) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1665) 	if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1666) 		xtlck->lwm.offset = (xtlck->lwm.offset) ?
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1667) 		    min(index, (int)xtlck->lwm.offset) : index;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1668) 		xtlck->lwm.length = le16_to_cpu(p->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1669) 		    xtlck->lwm.offset;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1670) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1671) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1672) 	/* unpin the leaf page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1673) 	XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1674) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1675) 	return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1676) }
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1677) #endif /* _NOTYET */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1678) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1679) /*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1680)  *	xtUpdate()
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1681)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1682)  * function: update XAD;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1683)  *
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1684)  *	update extent for allocated_but_not_recorded or
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1685)  *	compressed extent;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1686)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1687)  * parameter:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1688)  *	nxad	- new XAD;
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1689)  *		logical extent of the specified XAD must be completely
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 1690)  *		contained by an existing XAD;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1691)  */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1692) int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1693) {				/* new XAD */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1694) 	int rc = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1695) 	int cmp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1696) 	struct metapage *mp;	/* meta-page buffer */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1697) 	xtpage_t *p;		/* base B+-tree index page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1698) 	s64 bn;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1699) 	int index0, index, newindex, nextindex;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1700) 	struct btstack btstack;	/* traverse stack */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1701) 	struct xtsplit split;	/* split information */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1702) 	xad_t *xad, *lxad, *rxad;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1703) 	int xflag;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1704) 	s64 nxoff, xoff;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1705) 	int nxlen, xlen, lxlen, rxlen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1706) 	s64 nxaddr, xaddr;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1707) 	struct tlock *tlck;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1708) 	struct xtlock *xtlck = NULL;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1709) 	int newpage = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1710) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1711) 	/* there must exist extent to be tailgated */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1712) 	nxoff = offsetXAD(nxad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1713) 	nxlen = lengthXAD(nxad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1714) 	nxaddr = addressXAD(nxad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1715) 
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600 1716) 	if ((rc = xtSearch(ip, nxoff, NULL, &cmp, &btstack, XT_INSERT)))
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1717) 		return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1718) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1719) 	/* retrieve search result */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1720) 	XT_GETSEARCH(ip, btstack.top, bn, mp, p, index0);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1721) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1722) 	if (cmp != 0) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1723) 		XT_PUTPAGE(mp);
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700 1724) 		jfs_error(ip->i_sb, "Could not find extent\n");
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1725) 		return -EIO;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1726) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1727) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1728) 	BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1729) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1730) 	 * acquire tlock of the leaf page containing original entry
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1731) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1732) 	if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1733) 		tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1734) 		xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1735) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1736) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1737) 	xad = &p->xad[index0];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1738) 	xflag = xad->flag;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1739) 	xoff = offsetXAD(xad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1740) 	xlen = lengthXAD(xad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1741) 	xaddr = addressXAD(xad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1742) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1743) 	/* nXAD must be completely contained within XAD */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1744) 	if ((xoff > nxoff) ||
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1745) 	    (nxoff + nxlen > xoff + xlen)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1746) 		XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1747) 		jfs_error(ip->i_sb,
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700 1748) 			  "nXAD in not completely contained within XAD\n");
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1749) 		return -EIO;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1750) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1751) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1752) 	index = index0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1753) 	newindex = index + 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1754) 	nextindex = le16_to_cpu(p->header.nextindex);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1755) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1756) #ifdef  _JFS_WIP_NOCOALESCE
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1757) 	if (xoff < nxoff)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1758) 		goto updateRight;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1759) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1760) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1761) 	 * replace XAD with nXAD
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1762) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1763)       replace:			/* (nxoff == xoff) */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1764) 	if (nxlen == xlen) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1765) 		/* replace XAD with nXAD:recorded */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1766) 		*xad = *nxad;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1767) 		xad->flag = xflag & ~XAD_NOTRECORDED;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1768) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1769) 		goto out;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1770) 	} else			/* (nxlen < xlen) */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1771) 		goto updateLeft;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1772) #endif				/* _JFS_WIP_NOCOALESCE */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1773) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1774) /* #ifdef _JFS_WIP_COALESCE */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1775) 	if (xoff < nxoff)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1776) 		goto coalesceRight;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1777) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1778) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1779) 	 * coalesce with left XAD
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1780) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1781) //coalesceLeft: /* (xoff == nxoff) */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1782) 	/* is XAD first entry of page ? */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1783) 	if (index == XTENTRYSTART)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1784) 		goto replace;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1785) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1786) 	/* is nXAD logically and physically contiguous with lXAD ? */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1787) 	lxad = &p->xad[index - 1];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1788) 	lxlen = lengthXAD(lxad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1789) 	if (!(lxad->flag & XAD_NOTRECORDED) &&
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1790) 	    (nxoff == offsetXAD(lxad) + lxlen) &&
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1791) 	    (nxaddr == addressXAD(lxad) + lxlen) &&
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1792) 	    (lxlen + nxlen < MAXXLEN)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1793) 		/* extend right lXAD */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1794) 		index0 = index - 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1795) 		XADlength(lxad, lxlen + nxlen);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1796) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1797) 		/* If we just merged two extents together, need to make sure the
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1798) 		 * right extent gets logged.  If the left one is marked XAD_NEW,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1799) 		 * then we know it will be logged.  Otherwise, mark as
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1800) 		 * XAD_EXTENDED
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1801) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1802) 		if (!(lxad->flag & XAD_NEW))
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1803) 			lxad->flag |= XAD_EXTENDED;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1804) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1805) 		if (xlen > nxlen) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1806) 			/* truncate XAD */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1807) 			XADoffset(xad, xoff + nxlen);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1808) 			XADlength(xad, xlen - nxlen);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1809) 			XADaddress(xad, xaddr + nxlen);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1810) 			goto out;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1811) 		} else {	/* (xlen == nxlen) */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1812) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1813) 			/* remove XAD */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1814) 			if (index < nextindex - 1)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1815) 				memmove(&p->xad[index], &p->xad[index + 1],
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1816) 					(nextindex - index -
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1817) 					 1) << L2XTSLOTSIZE);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1818) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1819) 			p->header.nextindex =
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1820) 			    cpu_to_le16(le16_to_cpu(p->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1821) 					1);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1822) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1823) 			index = index0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1824) 			newindex = index + 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1825) 			nextindex = le16_to_cpu(p->header.nextindex);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1826) 			xoff = nxoff = offsetXAD(lxad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1827) 			xlen = nxlen = lxlen + nxlen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1828) 			xaddr = nxaddr = addressXAD(lxad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1829) 			goto coalesceRight;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1830) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1831) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1832) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1833) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1834) 	 * replace XAD with nXAD
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1835) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1836)       replace:			/* (nxoff == xoff) */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1837) 	if (nxlen == xlen) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1838) 		/* replace XAD with nXAD:recorded */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1839) 		*xad = *nxad;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1840) 		xad->flag = xflag & ~XAD_NOTRECORDED;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1841) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1842) 		goto coalesceRight;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1843) 	} else			/* (nxlen < xlen) */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1844) 		goto updateLeft;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1845) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1846) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1847) 	 * coalesce with right XAD
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1848) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1849)       coalesceRight:		/* (xoff <= nxoff) */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1850) 	/* is XAD last entry of page ? */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1851) 	if (newindex == nextindex) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1852) 		if (xoff == nxoff)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1853) 			goto out;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1854) 		goto updateRight;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1855) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1856) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1857) 	/* is nXAD logically and physically contiguous with rXAD ? */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1858) 	rxad = &p->xad[index + 1];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1859) 	rxlen = lengthXAD(rxad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1860) 	if (!(rxad->flag & XAD_NOTRECORDED) &&
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1861) 	    (nxoff + nxlen == offsetXAD(rxad)) &&
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1862) 	    (nxaddr + nxlen == addressXAD(rxad)) &&
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1863) 	    (rxlen + nxlen < MAXXLEN)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1864) 		/* extend left rXAD */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1865) 		XADoffset(rxad, nxoff);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1866) 		XADlength(rxad, rxlen + nxlen);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1867) 		XADaddress(rxad, nxaddr);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1868) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1869) 		/* If we just merged two extents together, need to make sure
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1870) 		 * the left extent gets logged.  If the right one is marked
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1871) 		 * XAD_NEW, then we know it will be logged.  Otherwise, mark as
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1872) 		 * XAD_EXTENDED
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1873) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1874) 		if (!(rxad->flag & XAD_NEW))
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1875) 			rxad->flag |= XAD_EXTENDED;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1876) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1877) 		if (xlen > nxlen)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1878) 			/* truncate XAD */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1879) 			XADlength(xad, xlen - nxlen);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1880) 		else {		/* (xlen == nxlen) */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1881) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1882) 			/* remove XAD */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1883) 			memmove(&p->xad[index], &p->xad[index + 1],
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1884) 				(nextindex - index - 1) << L2XTSLOTSIZE);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1885) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1886) 			p->header.nextindex =
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1887) 			    cpu_to_le16(le16_to_cpu(p->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1888) 					1);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1889) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1890) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1891) 		goto out;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1892) 	} else if (xoff == nxoff)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1893) 		goto out;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1894) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1895) 	if (xoff >= nxoff) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1896) 		XT_PUTPAGE(mp);
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700 1897) 		jfs_error(ip->i_sb, "xoff >= nxoff\n");
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1898) 		return -EIO;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1899) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1900) /* #endif _JFS_WIP_COALESCE */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1901) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1902) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1903) 	 * split XAD into (lXAD, nXAD):
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1904) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1905) 	 *          |---nXAD--->
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1906) 	 * --|----------XAD----------|--
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1907) 	 *   |-lXAD-|
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1908) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1909)       updateRight:		/* (xoff < nxoff) */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1910) 	/* truncate old XAD as lXAD:not_recorded */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1911) 	xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1912) 	XADlength(xad, nxoff - xoff);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1913) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1914) 	/* insert nXAD:recorded */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1915) 	if (nextindex == le16_to_cpu(p->header.maxentry)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1916) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1917) 		/* xtSpliUp() unpins leaf pages */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1918) 		split.mp = mp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1919) 		split.index = newindex;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1920) 		split.flag = xflag & ~XAD_NOTRECORDED;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1921) 		split.off = nxoff;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1922) 		split.len = nxlen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1923) 		split.addr = nxaddr;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1924) 		split.pxdlist = NULL;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1925) 		if ((rc = xtSplitUp(tid, ip, &split, &btstack)))
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1926) 			return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1927) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1928) 		/* get back old page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1929) 		XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1930) 		if (rc)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1931) 			return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1932) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1933) 		 * if leaf root has been split, original root has been
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1934) 		 * copied to new child page, i.e., original entry now
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1935) 		 * resides on the new child page;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1936) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1937) 		if (p->header.flag & BT_INTERNAL) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1938) 			ASSERT(p->header.nextindex ==
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1939) 			       cpu_to_le16(XTENTRYSTART + 1));
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1940) 			xad = &p->xad[XTENTRYSTART];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1941) 			bn = addressXAD(xad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1942) 			XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1943) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1944) 			/* get new child page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1945) 			XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1946) 			if (rc)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1947) 				return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1948) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1949) 			BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1950) 			if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1951) 				tlck = txLock(tid, ip, mp, tlckXTREE|tlckGROW);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1952) 				xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1953) 			}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1954) 		} else {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1955) 			/* is nXAD on new page ? */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1956) 			if (newindex >
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1957) 			    (le16_to_cpu(p->header.maxentry) >> 1)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1958) 				newindex =
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1959) 				    newindex -
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1960) 				    le16_to_cpu(p->header.nextindex) +
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1961) 				    XTENTRYSTART;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1962) 				newpage = 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1963) 			}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1964) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1965) 	} else {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1966) 		/* if insert into middle, shift right remaining entries */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1967) 		if (newindex < nextindex)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1968) 			memmove(&p->xad[newindex + 1], &p->xad[newindex],
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1969) 				(nextindex - newindex) << L2XTSLOTSIZE);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1970) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1971) 		/* insert the entry */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1972) 		xad = &p->xad[newindex];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1973) 		*xad = *nxad;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1974) 		xad->flag = xflag & ~XAD_NOTRECORDED;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1975) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1976) 		/* advance next available entry index. */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1977) 		p->header.nextindex =
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1978) 		    cpu_to_le16(le16_to_cpu(p->header.nextindex) + 1);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1979) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1980) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1981) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1982) 	 * does nXAD force 3-way split ?
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1983) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1984) 	 *          |---nXAD--->|
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1985) 	 * --|----------XAD-------------|--
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1986) 	 *   |-lXAD-|           |-rXAD -|
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1987) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1988) 	if (nxoff + nxlen == xoff + xlen)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1989) 		goto out;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1990) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1991) 	/* reorient nXAD as XAD for further split XAD into (nXAD, rXAD) */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1992) 	if (newpage) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1993) 		/* close out old page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1994) 		if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1995) 			xtlck->lwm.offset = (xtlck->lwm.offset) ?
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1996) 			    min(index0, (int)xtlck->lwm.offset) : index0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1997) 			xtlck->lwm.length =
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1998) 			    le16_to_cpu(p->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 1999) 			    xtlck->lwm.offset;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2000) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2001) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2002) 		bn = le64_to_cpu(p->header.next);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2003) 		XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2004) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2005) 		/* get new right page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2006) 		XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2007) 		if (rc)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2008) 			return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2009) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2010) 		BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2011) 		if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2012) 			tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2013) 			xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2014) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2015) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2016) 		index0 = index = newindex;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2017) 	} else
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2018) 		index++;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2019) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2020) 	newindex = index + 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2021) 	nextindex = le16_to_cpu(p->header.nextindex);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2022) 	xlen = xlen - (nxoff - xoff);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2023) 	xoff = nxoff;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2024) 	xaddr = nxaddr;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2025) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2026) 	/* recompute split pages */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2027) 	if (nextindex == le16_to_cpu(p->header.maxentry)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2028) 		XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2029) 
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600 2030) 		if ((rc = xtSearch(ip, nxoff, NULL, &cmp, &btstack, XT_INSERT)))
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2031) 			return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2032) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2033) 		/* retrieve search result */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2034) 		XT_GETSEARCH(ip, btstack.top, bn, mp, p, index0);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2035) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2036) 		if (cmp != 0) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2037) 			XT_PUTPAGE(mp);
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700 2038) 			jfs_error(ip->i_sb, "xtSearch failed\n");
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2039) 			return -EIO;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2040) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2041) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2042) 		if (index0 != index) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2043) 			XT_PUTPAGE(mp);
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700 2044) 			jfs_error(ip->i_sb, "unexpected value of index\n");
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2045) 			return -EIO;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2046) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2047) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2048) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2049) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2050) 	 * split XAD into (nXAD, rXAD)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2051) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2052) 	 *          ---nXAD---|
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2053) 	 * --|----------XAD----------|--
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2054) 	 *                    |-rXAD-|
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2055) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2056)       updateLeft:		/* (nxoff == xoff) && (nxlen < xlen) */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2057) 	/* update old XAD with nXAD:recorded */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2058) 	xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2059) 	*xad = *nxad;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2060) 	xad->flag = xflag & ~XAD_NOTRECORDED;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2061) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2062) 	/* insert rXAD:not_recorded */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2063) 	xoff = xoff + nxlen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2064) 	xlen = xlen - nxlen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2065) 	xaddr = xaddr + nxlen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2066) 	if (nextindex == le16_to_cpu(p->header.maxentry)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2067) /*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2068) printf("xtUpdate.updateLeft.split p:0x%p\n", p);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2069) */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2070) 		/* xtSpliUp() unpins leaf pages */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2071) 		split.mp = mp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2072) 		split.index = newindex;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2073) 		split.flag = xflag;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2074) 		split.off = xoff;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2075) 		split.len = xlen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2076) 		split.addr = xaddr;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2077) 		split.pxdlist = NULL;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2078) 		if ((rc = xtSplitUp(tid, ip, &split, &btstack)))
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2079) 			return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2080) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2081) 		/* get back old page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2082) 		XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2083) 		if (rc)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2084) 			return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2085) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2086) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2087) 		 * if leaf root has been split, original root has been
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2088) 		 * copied to new child page, i.e., original entry now
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2089) 		 * resides on the new child page;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2090) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2091) 		if (p->header.flag & BT_INTERNAL) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2092) 			ASSERT(p->header.nextindex ==
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2093) 			       cpu_to_le16(XTENTRYSTART + 1));
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2094) 			xad = &p->xad[XTENTRYSTART];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2095) 			bn = addressXAD(xad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2096) 			XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2097) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2098) 			/* get new child page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2099) 			XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2100) 			if (rc)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2101) 				return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2102) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2103) 			BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2104) 			if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2105) 				tlck = txLock(tid, ip, mp, tlckXTREE|tlckGROW);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2106) 				xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2107) 			}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2108) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2109) 	} else {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2110) 		/* if insert into middle, shift right remaining entries */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2111) 		if (newindex < nextindex)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2112) 			memmove(&p->xad[newindex + 1], &p->xad[newindex],
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2113) 				(nextindex - newindex) << L2XTSLOTSIZE);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2114) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2115) 		/* insert the entry */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2116) 		xad = &p->xad[newindex];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2117) 		XT_PUTENTRY(xad, xflag, xoff, xlen, xaddr);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2118) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2119) 		/* advance next available entry index. */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2120) 		p->header.nextindex =
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2121) 		    cpu_to_le16(le16_to_cpu(p->header.nextindex) + 1);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2122) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2123) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2124)       out:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2125) 	if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2126) 		xtlck->lwm.offset = (xtlck->lwm.offset) ?
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2127) 		    min(index0, (int)xtlck->lwm.offset) : index0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2128) 		xtlck->lwm.length = le16_to_cpu(p->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2129) 		    xtlck->lwm.offset;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2130) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2131) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2132) 	/* unpin the leaf page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2133) 	XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2134) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2135) 	return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2136) }
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2137) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2138) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2139) /*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2140)  *	xtAppend()
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2141)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2142)  * function: grow in append mode from contiguous region specified ;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2143)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2144)  * parameter:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2145)  *	tid		- transaction id;
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2146)  *	ip		- file object;
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2147)  *	xflag		- extent flag:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2148)  *	xoff		- extent offset;
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2149)  *	maxblocks	- max extent length;
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2150)  *	xlen		- extent length (in/out);
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2151)  *	xaddrp		- extent address pointer (in/out):
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2152)  *	flag		-
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2153)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2154)  * return:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2155)  */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2156) int xtAppend(tid_t tid,		/* transaction id */
63f83c9fcf40a (Dave Kleikamp     2006-10-02 09:55:27 -0500 2157) 	     struct inode *ip, int xflag, s64 xoff, s32 maxblocks,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2158) 	     s32 * xlenp,	/* (in/out) */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2159) 	     s64 * xaddrp,	/* (in/out) */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2160) 	     int flag)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2161) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2162) 	int rc = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2163) 	struct metapage *mp;	/* meta-page buffer */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2164) 	xtpage_t *p;		/* base B+-tree index page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2165) 	s64 bn, xaddr;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2166) 	int index, nextindex;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2167) 	struct btstack btstack;	/* traverse stack */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2168) 	struct xtsplit split;	/* split information */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2169) 	xad_t *xad;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2170) 	int cmp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2171) 	struct tlock *tlck;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2172) 	struct xtlock *xtlck;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2173) 	int nsplit, nblocks, xlen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2174) 	struct pxdlist pxdlist;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2175) 	pxd_t *pxd;
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600 2176) 	s64 next;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2177) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2178) 	xaddr = *xaddrp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2179) 	xlen = *xlenp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2180) 	jfs_info("xtAppend: xoff:0x%lx maxblocks:%d xlen:%d xaddr:0x%lx",
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2181) 		 (ulong) xoff, maxblocks, xlen, (ulong) xaddr);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2182) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2183) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2184) 	 *	search for the entry location at which to insert:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2185) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2186) 	 * xtFastSearch() and xtSearch() both returns (leaf page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2187) 	 * pinned, index at which to insert).
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2188) 	 * n.b. xtSearch() may return index of maxentry of
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2189) 	 * the full page.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2190) 	 */
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600 2191) 	if ((rc = xtSearch(ip, xoff, &next, &cmp, &btstack, XT_INSERT)))
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2192) 		return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2193) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2194) 	/* retrieve search result */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2195) 	XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2196) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2197) 	if (cmp == 0) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2198) 		rc = -EEXIST;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2199) 		goto out;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2200) 	}
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600 2201) 
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600 2202) 	if (next)
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600 2203) 		xlen = min(xlen, (int)(next - xoff));
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2204) //insert:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2205) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2206) 	 *	insert entry for new extent
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2207) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2208) 	xflag |= XAD_NEW;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2209) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2210) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2211) 	 *	if the leaf page is full, split the page and
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2212) 	 *	propagate up the router entry for the new page from split
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2213) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2214) 	 * The xtSplitUp() will insert the entry and unpin the leaf page.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2215) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2216) 	nextindex = le16_to_cpu(p->header.nextindex);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2217) 	if (nextindex < le16_to_cpu(p->header.maxentry))
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2218) 		goto insertLeaf;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2219) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2220) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2221) 	 * allocate new index blocks to cover index page split(s)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2222) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2223) 	nsplit = btstack.nsplit;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2224) 	split.pxdlist = &pxdlist;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2225) 	pxdlist.maxnpxd = pxdlist.npxd = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2226) 	pxd = &pxdlist.pxd[0];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2227) 	nblocks = JFS_SBI(ip->i_sb)->nbperpage;
63f83c9fcf40a (Dave Kleikamp     2006-10-02 09:55:27 -0500 2228) 	for (; nsplit > 0; nsplit--, pxd++, xaddr += nblocks, maxblocks -= nblocks) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2229) 		if ((rc = dbAllocBottomUp(ip, xaddr, (s64) nblocks)) == 0) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2230) 			PXDaddress(pxd, xaddr);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2231) 			PXDlength(pxd, nblocks);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2232) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2233) 			pxdlist.maxnpxd++;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2234) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2235) 			continue;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2236) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2237) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2238) 		/* undo allocation */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2239) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2240) 		goto out;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2241) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2242) 
63f83c9fcf40a (Dave Kleikamp     2006-10-02 09:55:27 -0500 2243) 	xlen = min(xlen, maxblocks);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2244) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2245) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2246) 	 * allocate data extent requested
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2247) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2248) 	if ((rc = dbAllocBottomUp(ip, xaddr, (s64) xlen)))
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2249) 		goto out;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2250) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2251) 	split.mp = mp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2252) 	split.index = index;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2253) 	split.flag = xflag;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2254) 	split.off = xoff;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2255) 	split.len = xlen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2256) 	split.addr = xaddr;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2257) 	if ((rc = xtSplitUp(tid, ip, &split, &btstack))) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2258) 		/* undo data extent allocation */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2259) 		dbFree(ip, *xaddrp, (s64) * xlenp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2260) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2261) 		return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2262) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2263) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2264) 	*xaddrp = xaddr;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2265) 	*xlenp = xlen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2266) 	return 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2267) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2268) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2269) 	 *	insert the new entry into the leaf page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2270) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2271)       insertLeaf:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2272) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2273) 	 * allocate data extent requested
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2274) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2275) 	if ((rc = dbAllocBottomUp(ip, xaddr, (s64) xlen)))
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2276) 		goto out;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2277) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2278) 	BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2279) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2280) 	 * acquire a transaction lock on the leaf page;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2281) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2282) 	 * action: xad insertion/extension;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2283) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2284) 	tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2285) 	xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2286) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2287) 	/* insert the new entry: mark the entry NEW */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2288) 	xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2289) 	XT_PUTENTRY(xad, xflag, xoff, xlen, xaddr);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2290) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2291) 	/* advance next available entry index */
891456227881d (Marcin Slusarz    2008-02-13 15:34:20 -0600 2292) 	le16_add_cpu(&p->header.nextindex, 1);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2293) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2294) 	xtlck->lwm.offset =
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2295) 	    (xtlck->lwm.offset) ? min(index,(int) xtlck->lwm.offset) : index;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2296) 	xtlck->lwm.length = le16_to_cpu(p->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2297) 	    xtlck->lwm.offset;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2298) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2299) 	*xaddrp = xaddr;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2300) 	*xlenp = xlen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2301) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2302)       out:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2303) 	/* unpin the leaf page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2304) 	XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2305) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2306) 	return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2307) }
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2308) #ifdef _STILL_TO_PORT
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2309) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2310) /* - TBD for defragmentaion/reorganization -
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2311)  *
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2312)  *	xtDelete()
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2313)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2314)  * function:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2315)  *	delete the entry with the specified key.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2316)  *
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2317)  *	N.B.: whole extent of the entry is assumed to be deleted.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2318)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2319)  * parameter:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2320)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2321)  * return:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2322)  *	ENOENT: if the entry is not found.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2323)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2324)  * exception:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2325)  */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2326) int xtDelete(tid_t tid, struct inode *ip, s64 xoff, s32 xlen, int flag)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2327) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2328) 	int rc = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2329) 	struct btstack btstack;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2330) 	int cmp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2331) 	s64 bn;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2332) 	struct metapage *mp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2333) 	xtpage_t *p;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2334) 	int index, nextindex;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2335) 	struct tlock *tlck;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2336) 	struct xtlock *xtlck;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2337) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2338) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2339) 	 * find the matching entry; xtSearch() pins the page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2340) 	 */
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600 2341) 	if ((rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0)))
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2342) 		return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2343) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2344) 	XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2345) 	if (cmp) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2346) 		/* unpin the leaf page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2347) 		XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2348) 		return -ENOENT;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2349) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2350) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2351) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2352) 	 * delete the entry from the leaf page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2353) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2354) 	nextindex = le16_to_cpu(p->header.nextindex);
891456227881d (Marcin Slusarz    2008-02-13 15:34:20 -0600 2355) 	le16_add_cpu(&p->header.nextindex, -1);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2356) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2357) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2358) 	 * if the leaf page bocome empty, free the page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2359) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2360) 	if (p->header.nextindex == cpu_to_le16(XTENTRYSTART))
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2361) 		return (xtDeleteUp(tid, ip, mp, p, &btstack));
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2362) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2363) 	BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2364) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2365) 	 * acquire a transaction lock on the leaf page;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2366) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2367) 	 * action:xad deletion;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2368) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2369) 	tlck = txLock(tid, ip, mp, tlckXTREE);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2370) 	xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2371) 	xtlck->lwm.offset =
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2372) 	    (xtlck->lwm.offset) ? min(index, xtlck->lwm.offset) : index;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2373) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2374) 	/* if delete from middle, shift left/compact the remaining entries */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2375) 	if (index < nextindex - 1)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2376) 		memmove(&p->xad[index], &p->xad[index + 1],
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2377) 			(nextindex - index - 1) * sizeof(xad_t));
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2378) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2379) 	XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2380) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2381) 	return 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2382) }
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2383) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2384) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2385) /* - TBD for defragmentaion/reorganization -
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2386)  *
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2387)  *	xtDeleteUp()
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2388)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2389)  * function:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2390)  *	free empty pages as propagating deletion up the tree
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2391)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2392)  * parameter:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2393)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2394)  * return:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2395)  */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2396) static int
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2397) xtDeleteUp(tid_t tid, struct inode *ip,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2398) 	   struct metapage * fmp, xtpage_t * fp, struct btstack * btstack)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2399) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2400) 	int rc = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2401) 	struct metapage *mp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2402) 	xtpage_t *p;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2403) 	int index, nextindex;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2404) 	s64 xaddr;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2405) 	int xlen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2406) 	struct btframe *parent;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2407) 	struct tlock *tlck;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2408) 	struct xtlock *xtlck;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2409) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2410) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2411) 	 * keep root leaf page which has become empty
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2412) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2413) 	if (fp->header.flag & BT_ROOT) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2414) 		/* keep the root page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2415) 		fp->header.flag &= ~BT_INTERNAL;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2416) 		fp->header.flag |= BT_LEAF;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2417) 		fp->header.nextindex = cpu_to_le16(XTENTRYSTART);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2418) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2419) 		/* XT_PUTPAGE(fmp); */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2420) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2421) 		return 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2422) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2423) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2424) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2425) 	 * free non-root leaf page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2426) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2427) 	if ((rc = xtRelink(tid, ip, fp))) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2428) 		XT_PUTPAGE(fmp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2429) 		return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2430) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2431) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2432) 	xaddr = addressPXD(&fp->header.self);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2433) 	xlen = lengthPXD(&fp->header.self);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2434) 	/* free the page extent */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2435) 	dbFree(ip, xaddr, (s64) xlen);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2436) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2437) 	/* free the buffer page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2438) 	discard_metapage(fmp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2439) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2440) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2441) 	 * propagate page deletion up the index tree
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2442) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2443) 	 * If the delete from the parent page makes it empty,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2444) 	 * continue all the way up the tree.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2445) 	 * stop if the root page is reached (which is never deleted) or
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2446) 	 * if the entry deletion does not empty the page.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2447) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2448) 	while ((parent = BT_POP(btstack)) != NULL) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2449) 		/* get/pin the parent page <sp> */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2450) 		XT_GETPAGE(ip, parent->bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2451) 		if (rc)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2452) 			return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2453) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2454) 		index = parent->index;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2455) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2456) 		/* delete the entry for the freed child page from parent.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2457) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2458) 		nextindex = le16_to_cpu(p->header.nextindex);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2459) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2460) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2461) 		 * the parent has the single entry being deleted:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2462) 		 * free the parent page which has become empty.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2463) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2464) 		if (nextindex == 1) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2465) 			if (p->header.flag & BT_ROOT) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2466) 				/* keep the root page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2467) 				p->header.flag &= ~BT_INTERNAL;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2468) 				p->header.flag |= BT_LEAF;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2469) 				p->header.nextindex =
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2470) 				    cpu_to_le16(XTENTRYSTART);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2471) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2472) 				/* XT_PUTPAGE(mp); */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2473) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2474) 				break;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2475) 			} else {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2476) 				/* free the parent page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2477) 				if ((rc = xtRelink(tid, ip, p)))
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2478) 					return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2479) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2480) 				xaddr = addressPXD(&p->header.self);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2481) 				/* free the page extent */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2482) 				dbFree(ip, xaddr,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2483) 				       (s64) JFS_SBI(ip->i_sb)->nbperpage);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2484) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2485) 				/* unpin/free the buffer page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2486) 				discard_metapage(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2487) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2488) 				/* propagate up */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2489) 				continue;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2490) 			}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2491) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2492) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2493) 		 * the parent has other entries remaining:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2494) 		 * delete the router entry from the parent page.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2495) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2496) 		else {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2497) 			BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2498) 			/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2499) 			 * acquire a transaction lock on the leaf page;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2500) 			 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2501) 			 * action:xad deletion;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2502) 			 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2503) 			tlck = txLock(tid, ip, mp, tlckXTREE);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2504) 			xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2505) 			xtlck->lwm.offset =
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2506) 			    (xtlck->lwm.offset) ? min(index,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2507) 						      xtlck->lwm.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2508) 						      offset) : index;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2509) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2510) 			/* if delete from middle,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2511) 			 * shift left/compact the remaining entries in the page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2512) 			 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2513) 			if (index < nextindex - 1)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2514) 				memmove(&p->xad[index], &p->xad[index + 1],
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2515) 					(nextindex - index -
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2516) 					 1) << L2XTSLOTSIZE);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2517) 
891456227881d (Marcin Slusarz    2008-02-13 15:34:20 -0600 2518) 			le16_add_cpu(&p->header.nextindex, -1);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2519) 			jfs_info("xtDeleteUp(entry): 0x%lx[%d]",
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2520) 				 (ulong) parent->bn, index);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2521) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2522) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2523) 		/* unpin the parent page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2524) 		XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2525) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2526) 		/* exit propagation up */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2527) 		break;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2528) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2529) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2530) 	return 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2531) }
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2532) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2533) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2534) /*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2535)  * NAME:	xtRelocate()
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2536)  *
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2537)  * FUNCTION:	relocate xtpage or data extent of regular file;
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2538)  *		This function is mainly used by defragfs utility.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2539)  *
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2540)  * NOTE:	This routine does not have the logic to handle
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2541)  *		uncommitted allocated extent. The caller should call
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2542)  *		txCommit() to commit all the allocation before call
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2543)  *		this routine.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2544)  */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2545) int
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2546) xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad,	/* old XAD */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2547) 	   s64 nxaddr,		/* new xaddr */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2548) 	   int xtype)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2549) {				/* extent type: XTPAGE or DATAEXT */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2550) 	int rc = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2551) 	struct tblock *tblk;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2552) 	struct tlock *tlck;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2553) 	struct xtlock *xtlck;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2554) 	struct metapage *mp, *pmp, *lmp, *rmp;	/* meta-page buffer */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2555) 	xtpage_t *p, *pp, *rp, *lp;	/* base B+-tree index page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2556) 	xad_t *xad;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2557) 	pxd_t *pxd;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2558) 	s64 xoff, xsize;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2559) 	int xlen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2560) 	s64 oxaddr, sxaddr, dxaddr, nextbn, prevbn;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2561) 	cbuf_t *cp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2562) 	s64 offset, nbytes, nbrd, pno;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2563) 	int nb, npages, nblks;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2564) 	s64 bn;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2565) 	int cmp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2566) 	int index;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2567) 	struct pxd_lock *pxdlock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2568) 	struct btstack btstack;	/* traverse stack */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2569) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2570) 	xtype = xtype & EXTENT_TYPE;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2571) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2572) 	xoff = offsetXAD(oxad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2573) 	oxaddr = addressXAD(oxad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2574) 	xlen = lengthXAD(oxad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2575) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2576) 	/* validate extent offset */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2577) 	offset = xoff << JFS_SBI(ip->i_sb)->l2bsize;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2578) 	if (offset >= ip->i_size)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2579) 		return -ESTALE;	/* stale extent */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2580) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2581) 	jfs_info("xtRelocate: xtype:%d xoff:0x%lx xlen:0x%x xaddr:0x%lx:0x%lx",
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2582) 		 xtype, (ulong) xoff, xlen, (ulong) oxaddr, (ulong) nxaddr);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2583) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2584) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2585) 	 *	1. get and validate the parent xtpage/xad entry
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2586) 	 *	covering the source extent to be relocated;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2587) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2588) 	if (xtype == DATAEXT) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2589) 		/* search in leaf entry */
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600 2590) 		rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2591) 		if (rc)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2592) 			return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2593) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2594) 		/* retrieve search result */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2595) 		XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2596) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2597) 		if (cmp) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2598) 			XT_PUTPAGE(pmp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2599) 			return -ESTALE;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2600) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2601) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2602) 		/* validate for exact match with a single entry */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2603) 		xad = &pp->xad[index];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2604) 		if (addressXAD(xad) != oxaddr || lengthXAD(xad) != xlen) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2605) 			XT_PUTPAGE(pmp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2606) 			return -ESTALE;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2607) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2608) 	} else {		/* (xtype == XTPAGE) */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2609) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2610) 		/* search in internal entry */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2611) 		rc = xtSearchNode(ip, oxad, &cmp, &btstack, 0);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2612) 		if (rc)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2613) 			return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2614) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2615) 		/* retrieve search result */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2616) 		XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2617) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2618) 		if (cmp) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2619) 			XT_PUTPAGE(pmp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2620) 			return -ESTALE;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2621) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2622) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2623) 		/* xtSearchNode() validated for exact match with a single entry
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2624) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2625) 		xad = &pp->xad[index];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2626) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2627) 	jfs_info("xtRelocate: parent xad entry validated.");
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2628) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2629) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2630) 	 *	2. relocate the extent
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2631) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2632) 	if (xtype == DATAEXT) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2633) 		/* if the extent is allocated-but-not-recorded
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2634) 		 * there is no real data to be moved in this extent,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2635) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2636) 		if (xad->flag & XAD_NOTRECORDED)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2637) 			goto out;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2638) 		else
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2639) 			/* release xtpage for cmRead()/xtLookup() */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2640) 			XT_PUTPAGE(pmp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2641) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2642) 		/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2643) 		 *	cmRelocate()
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2644) 		 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2645) 		 * copy target data pages to be relocated;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2646) 		 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2647) 		 * data extent must start at page boundary and
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2648) 		 * multiple of page size (except the last data extent);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2649) 		 * read in each page of the source data extent into cbuf,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2650) 		 * update the cbuf extent descriptor of the page to be
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2651) 		 * homeward bound to new dst data extent
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2652) 		 * copy the data from the old extent to new extent.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2653) 		 * copy is essential for compressed files to avoid problems
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2654) 		 * that can arise if there was a change in compression
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2655) 		 * algorithms.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2656) 		 * it is a good strategy because it may disrupt cache
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2657) 		 * policy to keep the pages in memory afterwards.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2658) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2659) 		offset = xoff << JFS_SBI(ip->i_sb)->l2bsize;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2660) 		assert((offset & CM_OFFSET) == 0);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2661) 		nbytes = xlen << JFS_SBI(ip->i_sb)->l2bsize;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2662) 		pno = offset >> CM_L2BSIZE;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2663) 		npages = (nbytes + (CM_BSIZE - 1)) >> CM_L2BSIZE;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2664) /*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2665) 		npages = ((offset + nbytes - 1) >> CM_L2BSIZE) -
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2666) 			  (offset >> CM_L2BSIZE) + 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2667) */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2668) 		sxaddr = oxaddr;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2669) 		dxaddr = nxaddr;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2670) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2671) 		/* process the request one cache buffer at a time */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2672) 		for (nbrd = 0; nbrd < nbytes; nbrd += nb,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2673) 		     offset += nb, pno++, npages--) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2674) 			/* compute page size */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2675) 			nb = min(nbytes - nbrd, CM_BSIZE);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2676) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2677) 			/* get the cache buffer of the page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2678) 			if (rc = cmRead(ip, offset, npages, &cp))
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2679) 				break;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2680) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2681) 			assert(addressPXD(&cp->cm_pxd) == sxaddr);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2682) 			assert(!cp->cm_modified);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2683) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2684) 			/* bind buffer with the new extent address */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2685) 			nblks = nb >> JFS_IP(ip->i_sb)->l2bsize;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2686) 			cmSetXD(ip, cp, pno, dxaddr, nblks);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2687) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2688) 			/* release the cbuf, mark it as modified */
4d81715fc5dfa (Richard Knutsson  2006-09-30 23:27:14 -0700 2689) 			cmPut(cp, true);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2690) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2691) 			dxaddr += nblks;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2692) 			sxaddr += nblks;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2693) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2694) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2695) 		/* get back parent page */
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600 2696) 		if ((rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0)))
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2697) 			return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2698) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2699) 		XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2700) 		jfs_info("xtRelocate: target data extent relocated.");
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2701) 	} else {		/* (xtype == XTPAGE) */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2702) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2703) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2704) 		 * read in the target xtpage from the source extent;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2705) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2706) 		XT_GETPAGE(ip, oxaddr, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2707) 		if (rc) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2708) 			XT_PUTPAGE(pmp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2709) 			return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2710) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2711) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2712) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2713) 		 * read in sibling pages if any to update sibling pointers;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2714) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2715) 		rmp = NULL;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2716) 		if (p->header.next) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2717) 			nextbn = le64_to_cpu(p->header.next);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2718) 			XT_GETPAGE(ip, nextbn, rmp, PSIZE, rp, rc);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2719) 			if (rc) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2720) 				XT_PUTPAGE(pmp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2721) 				XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2722) 				return (rc);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2723) 			}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2724) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2725) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2726) 		lmp = NULL;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2727) 		if (p->header.prev) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2728) 			prevbn = le64_to_cpu(p->header.prev);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2729) 			XT_GETPAGE(ip, prevbn, lmp, PSIZE, lp, rc);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2730) 			if (rc) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2731) 				XT_PUTPAGE(pmp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2732) 				XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2733) 				if (rmp)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2734) 					XT_PUTPAGE(rmp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2735) 				return (rc);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2736) 			}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2737) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2738) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2739) 		/* at this point, all xtpages to be updated are in memory */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2740) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2741) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2742) 		 * update sibling pointers of sibling xtpages if any;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2743) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2744) 		if (lmp) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2745) 			BT_MARK_DIRTY(lmp, ip);
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2746) 			tlck = txLock(tid, ip, lmp, tlckXTREE | tlckRELINK);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2747) 			lp->header.next = cpu_to_le64(nxaddr);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2748) 			XT_PUTPAGE(lmp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2749) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2750) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2751) 		if (rmp) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2752) 			BT_MARK_DIRTY(rmp, ip);
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2753) 			tlck = txLock(tid, ip, rmp, tlckXTREE | tlckRELINK);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2754) 			rp->header.prev = cpu_to_le64(nxaddr);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2755) 			XT_PUTPAGE(rmp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2756) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2757) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2758) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2759) 		 * update the target xtpage to be relocated
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2760) 		 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2761) 		 * update the self address of the target page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2762) 		 * and write to destination extent;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2763) 		 * redo image covers the whole xtpage since it is new page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2764) 		 * to the destination extent;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2765) 		 * update of bmap for the free of source extent
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2766) 		 * of the target xtpage itself:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2767) 		 * update of bmap for the allocation of destination extent
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2768) 		 * of the target xtpage itself:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2769) 		 * update of bmap for the extents covered by xad entries in
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2770) 		 * the target xtpage is not necessary since they are not
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2771) 		 * updated;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2772) 		 * if not committed before this relocation,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2773) 		 * target page may contain XAD_NEW entries which must
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2774) 		 * be scanned for bmap update (logredo() always
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2775) 		 * scan xtpage REDOPAGE image for bmap update);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2776) 		 * if committed before this relocation (tlckRELOCATE),
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2777) 		 * scan may be skipped by commit() and logredo();
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2778) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2779) 		BT_MARK_DIRTY(mp, ip);
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2780) 		/* tlckNEW init xtlck->lwm.offset = XTENTRYSTART; */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2781) 		tlck = txLock(tid, ip, mp, tlckXTREE | tlckNEW);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2782) 		xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2783) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2784) 		/* update the self address in the xtpage header */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2785) 		pxd = &p->header.self;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2786) 		PXDaddress(pxd, nxaddr);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2787) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2788) 		/* linelock for the after image of the whole page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2789) 		xtlck->lwm.length =
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2790) 		    le16_to_cpu(p->header.nextindex) - xtlck->lwm.offset;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2791) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2792) 		/* update the buffer extent descriptor of target xtpage */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2793) 		xsize = xlen << JFS_SBI(ip->i_sb)->l2bsize;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2794) 		bmSetXD(mp, nxaddr, xsize);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2795) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2796) 		/* unpin the target page to new homeward bound */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2797) 		XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2798) 		jfs_info("xtRelocate: target xtpage relocated.");
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2799) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2800) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2801) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2802) 	 *	3. acquire maplock for the source extent to be freed;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2803) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2804) 	 * acquire a maplock saving the src relocated extent address;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2805) 	 * to free of the extent at commit time;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2806) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2807)       out:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2808) 	/* if DATAEXT relocation, write a LOG_UPDATEMAP record for
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2809) 	 * free PXD of the source data extent (logredo() will update
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2810) 	 * bmap for free of source data extent), and update bmap for
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2811) 	 * free of the source data extent;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2812) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2813) 	if (xtype == DATAEXT)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2814) 		tlck = txMaplock(tid, ip, tlckMAP);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2815) 	/* if XTPAGE relocation, write a LOG_NOREDOPAGE record
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2816) 	 * for the source xtpage (logredo() will init NoRedoPage
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2817) 	 * filter and will also update bmap for free of the source
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2818) 	 * xtpage), and update bmap for free of the source xtpage;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2819) 	 * N.B. We use tlckMAP instead of tlkcXTREE because there
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2820) 	 *      is no buffer associated with this lock since the buffer
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2821) 	 *      has been redirected to the target location.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2822) 	 */
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2823) 	else			/* (xtype == XTPAGE) */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2824) 		tlck = txMaplock(tid, ip, tlckMAP | tlckRELOCATE);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2825) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2826) 	pxdlock = (struct pxd_lock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2827) 	pxdlock->flag = mlckFREEPXD;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2828) 	PXDaddress(&pxdlock->pxd, oxaddr);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2829) 	PXDlength(&pxdlock->pxd, xlen);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2830) 	pxdlock->index = 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2831) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2832) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2833) 	 *	4. update the parent xad entry for relocation;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2834) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2835) 	 * acquire tlck for the parent entry with XAD_NEW as entry
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2836) 	 * update which will write LOG_REDOPAGE and update bmap for
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2837) 	 * allocation of XAD_NEW destination extent;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2838) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2839) 	jfs_info("xtRelocate: update parent xad entry.");
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2840) 	BT_MARK_DIRTY(pmp, ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2841) 	tlck = txLock(tid, ip, pmp, tlckXTREE | tlckGROW);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2842) 	xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2843) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2844) 	/* update the XAD with the new destination extent; */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2845) 	xad = &pp->xad[index];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2846) 	xad->flag |= XAD_NEW;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2847) 	XADaddress(xad, nxaddr);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2848) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2849) 	xtlck->lwm.offset = min(index, xtlck->lwm.offset);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2850) 	xtlck->lwm.length = le16_to_cpu(pp->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2851) 	    xtlck->lwm.offset;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2852) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2853) 	/* unpin the parent xtpage */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2854) 	XT_PUTPAGE(pmp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2855) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2856) 	return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2857) }
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2858) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2859) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2860) /*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2861)  *	xtSearchNode()
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2862)  *
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2863)  * function:	search for the internal xad entry covering specified extent.
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2864)  *		This function is mainly used by defragfs utility.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2865)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2866)  * parameters:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2867)  *	ip	- file object;
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2868)  *	xad	- extent to find;
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2869)  *	cmpp	- comparison result:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2870)  *	btstack - traverse stack;
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2871)  *	flag	- search process flag;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2872)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2873)  * returns:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2874)  *	btstack contains (bn, index) of search path traversed to the entry.
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2875)  *	*cmpp is set to result of comparison with the entry returned.
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2876)  *	the page containing the entry is pinned at exit.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2877)  */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2878) static int xtSearchNode(struct inode *ip, xad_t * xad,	/* required XAD entry */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2879) 			int *cmpp, struct btstack * btstack, int flag)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2880) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2881) 	int rc = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2882) 	s64 xoff, xaddr;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2883) 	int xlen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2884) 	int cmp = 1;		/* init for empty page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2885) 	s64 bn;			/* block number */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2886) 	struct metapage *mp;	/* meta-page buffer */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2887) 	xtpage_t *p;		/* page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2888) 	int base, index, lim;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2889) 	struct btframe *btsp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2890) 	s64 t64;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2891) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2892) 	BT_CLR(btstack);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2893) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2894) 	xoff = offsetXAD(xad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2895) 	xlen = lengthXAD(xad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2896) 	xaddr = addressXAD(xad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2897) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2898) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2899) 	 *	search down tree from root:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2900) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2901) 	 * between two consecutive entries of <Ki, Pi> and <Kj, Pj> of
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2902) 	 * internal page, child page Pi contains entry with k, Ki <= K < Kj.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2903) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2904) 	 * if entry with search key K is not found
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2905) 	 * internal page search find the entry with largest key Ki
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2906) 	 * less than K which point to the child page to search;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2907) 	 * leaf page search find the entry with smallest key Kj
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2908) 	 * greater than K so that the returned index is the position of
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2909) 	 * the entry to be shifted right for insertion of new entry.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2910) 	 * for empty tree, search key is greater than any key of the tree.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2911) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2912) 	 * by convention, root bn = 0.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2913) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2914) 	for (bn = 0;;) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2915) 		/* get/pin the page to search */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2916) 		XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2917) 		if (rc)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2918) 			return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2919) 		if (p->header.flag & BT_LEAF) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2920) 			XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2921) 			return -ESTALE;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2922) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2923) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2924) 		lim = le16_to_cpu(p->header.nextindex) - XTENTRYSTART;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2925) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2926) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2927) 		 * binary search with search key K on the current page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2928) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2929) 		for (base = XTENTRYSTART; lim; lim >>= 1) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2930) 			index = base + (lim >> 1);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2931) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2932) 			XT_CMP(cmp, xoff, &p->xad[index], t64);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2933) 			if (cmp == 0) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2934) 				/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2935) 				 *	search hit
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2936) 				 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2937) 				 * verify for exact match;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2938) 				 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2939) 				if (xaddr == addressXAD(&p->xad[index]) &&
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2940) 				    xoff == offsetXAD(&p->xad[index])) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2941) 					*cmpp = cmp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2942) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2943) 					/* save search result */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2944) 					btsp = btstack->top;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2945) 					btsp->bn = bn;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2946) 					btsp->index = index;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2947) 					btsp->mp = mp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2948) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2949) 					return 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2950) 				}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2951) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2952) 				/* descend/search its child page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2953) 				goto next;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2954) 			}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2955) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2956) 			if (cmp > 0) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2957) 				base = index + 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2958) 				--lim;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2959) 			}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2960) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2961) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2962) 		/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2963) 		 *	search miss - non-leaf page:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2964) 		 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2965) 		 * base is the smallest index with key (Kj) greater than
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2966) 		 * search key (K) and may be zero or maxentry index.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2967) 		 * if base is non-zero, decrement base by one to get the parent
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2968) 		 * entry of the child page to search.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2969) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2970) 		index = base ? base - 1 : base;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2971) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2972) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2973) 		 * go down to child page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2974) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2975) 	      next:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2976) 		/* get the child page block number */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2977) 		bn = addressXAD(&p->xad[index]);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2978) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2979) 		/* unpin the parent page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2980) 		XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2981) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2982) }
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2983) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2984) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2985) /*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2986)  *	xtRelink()
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2987)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2988)  * function:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2989)  *	link around a freed page.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2990)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2991)  * Parameter:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2992)  *	int		tid,
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2993)  *	struct inode	*ip,
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 2994)  *	xtpage_t	*p)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2995)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2996)  * returns:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2997)  */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2998) static int xtRelink(tid_t tid, struct inode *ip, xtpage_t * p)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 2999) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3000) 	int rc = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3001) 	struct metapage *mp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3002) 	s64 nextbn, prevbn;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3003) 	struct tlock *tlck;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3004) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3005) 	nextbn = le64_to_cpu(p->header.next);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3006) 	prevbn = le64_to_cpu(p->header.prev);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3007) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3008) 	/* update prev pointer of the next page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3009) 	if (nextbn != 0) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3010) 		XT_GETPAGE(ip, nextbn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3011) 		if (rc)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3012) 			return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3013) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3014) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3015) 		 * acquire a transaction lock on the page;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3016) 		 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3017) 		 * action: update prev pointer;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3018) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3019) 		BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3020) 		tlck = txLock(tid, ip, mp, tlckXTREE | tlckRELINK);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3021) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3022) 		/* the page may already have been tlock'd */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3023) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3024) 		p->header.prev = cpu_to_le64(prevbn);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3025) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3026) 		XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3027) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3028) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3029) 	/* update next pointer of the previous page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3030) 	if (prevbn != 0) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3031) 		XT_GETPAGE(ip, prevbn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3032) 		if (rc)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3033) 			return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3034) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3035) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3036) 		 * acquire a transaction lock on the page;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3037) 		 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3038) 		 * action: update next pointer;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3039) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3040) 		BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3041) 		tlck = txLock(tid, ip, mp, tlckXTREE | tlckRELINK);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3042) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3043) 		/* the page may already have been tlock'd */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3044) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3045) 		p->header.next = le64_to_cpu(nextbn);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3046) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3047) 		XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3048) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3049) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3050) 	return 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3051) }
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3052) #endif				/*  _STILL_TO_PORT */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3053) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3054) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3055) /*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3056)  *	xtInitRoot()
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3057)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3058)  * initialize file root (inline in inode)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3059)  */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3060) void xtInitRoot(tid_t tid, struct inode *ip)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3061) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3062) 	xtpage_t *p;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3063) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3064) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3065) 	 * acquire a transaction lock on the root
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3066) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3067) 	 * action:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3068) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3069) 	txLock(tid, ip, (struct metapage *) &JFS_IP(ip)->bxflag,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3070) 		      tlckXTREE | tlckNEW);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3071) 	p = &JFS_IP(ip)->i_xtroot;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3072) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3073) 	p->header.flag = DXD_INDEX | BT_ROOT | BT_LEAF;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3074) 	p->header.nextindex = cpu_to_le16(XTENTRYSTART);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3075) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3076) 	if (S_ISDIR(ip->i_mode))
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3077) 		p->header.maxentry = cpu_to_le16(XTROOTINITSLOT_DIR);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3078) 	else {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3079) 		p->header.maxentry = cpu_to_le16(XTROOTINITSLOT);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3080) 		ip->i_size = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3081) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3082) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3083) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3084) 	return;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3085) }
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3086) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3087) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3088) /*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3089)  * We can run into a deadlock truncating a file with a large number of
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3090)  * xtree pages (large fragmented file).  A robust fix would entail a
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3091)  * reservation system where we would reserve a number of metadata pages
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3092)  * and tlocks which we would be guaranteed without a deadlock.  Without
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3093)  * this, a partial fix is to limit number of metadata pages we will lock
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3094)  * in a single transaction.  Currently we will truncate the file so that
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3095)  * no more than 50 leaf pages will be locked.  The caller of xtTruncate
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3096)  * will be responsible for ensuring that the current transaction gets
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3097)  * committed, and that subsequent transactions are created to truncate
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3098)  * the file further if needed.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3099)  */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3100) #define MAX_TRUNCATE_LEAVES 50
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3101) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3102) /*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3103)  *	xtTruncate()
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3104)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3105)  * function:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3106)  *	traverse for truncation logging backward bottom up;
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3107)  *	terminate at the last extent entry at the current subtree
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3108)  *	root page covering new down size.
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3109)  *	truncation may occur within the last extent entry.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3110)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3111)  * parameter:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3112)  *	int		tid,
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3113)  *	struct inode	*ip,
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3114)  *	s64		newsize,
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3115)  *	int		type)	{PWMAP, PMAP, WMAP; DELETE, TRUNCATE}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3116)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3117)  * return:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3118)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3119)  * note:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3120)  *	PWMAP:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3121)  *	 1. truncate (non-COMMIT_NOLINK file)
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3122)  *	    by jfs_truncate() or jfs_open(O_TRUNC):
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3123)  *	    xtree is updated;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3124)  *	 2. truncate index table of directory when last entry removed
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3125)  *	map update via tlock at commit time;
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3126)  *	PMAP:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3127)  *	 Call xtTruncate_pmap instead
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3128)  *	WMAP:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3129)  *	 1. remove (free zero link count) on last reference release
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3130)  *	    (pmap has been freed at commit zero link count);
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3131)  *	 2. truncate (COMMIT_NOLINK file, i.e., tmp file):
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3132)  *	    xtree is updated;
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3133)  *	 map update directly at truncation time;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3134)  *
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3135)  *	if (DELETE)
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3136)  *		no LOG_NOREDOPAGE is required (NOREDOFILE is sufficient);
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3137)  *	else if (TRUNCATE)
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3138)  *		must write LOG_NOREDOPAGE for deleted index page;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3139)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3140)  * pages may already have been tlocked by anonymous transactions
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3141)  * during file growth (i.e., write) before truncation;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3142)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3143)  * except last truncated entry, deleted entries remains as is
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3144)  * in the page (nextindex is updated) for other use
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3145)  * (e.g., log/update allocation map): this avoid copying the page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3146)  * info but delay free of pages;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3147)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3148)  */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3149) s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3150) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3151) 	int rc = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3152) 	s64 teof;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3153) 	struct metapage *mp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3154) 	xtpage_t *p;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3155) 	s64 bn;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3156) 	int index, nextindex;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3157) 	xad_t *xad;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3158) 	s64 xoff, xaddr;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3159) 	int xlen, len, freexlen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3160) 	struct btstack btstack;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3161) 	struct btframe *parent;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3162) 	struct tblock *tblk = NULL;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3163) 	struct tlock *tlck = NULL;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3164) 	struct xtlock *xtlck = NULL;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3165) 	struct xdlistlock xadlock;	/* maplock for COMMIT_WMAP */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3166) 	struct pxd_lock *pxdlock;		/* maplock for COMMIT_WMAP */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3167) 	s64 nfreed;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3168) 	int freed, log;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3169) 	int locked_leaves = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3170) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3171) 	/* save object truncation type */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3172) 	if (tid) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3173) 		tblk = tid_to_tblock(tid);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3174) 		tblk->xflag |= flag;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3175) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3176) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3177) 	nfreed = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3178) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3179) 	flag &= COMMIT_MAP;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3180) 	assert(flag != COMMIT_PMAP);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3181) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3182) 	if (flag == COMMIT_PWMAP)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3183) 		log = 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3184) 	else {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3185) 		log = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3186) 		xadlock.flag = mlckFREEXADLIST;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3187) 		xadlock.index = 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3188) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3189) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3190) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3191) 	 * if the newsize is not an integral number of pages,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3192) 	 * the file between newsize and next page boundary will
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3193) 	 * be cleared.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3194) 	 * if truncating into a file hole, it will cause
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3195) 	 * a full block to be allocated for the logical block.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3196) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3197) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3198) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3199) 	 * release page blocks of truncated region <teof, eof>
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3200) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3201) 	 * free the data blocks from the leaf index blocks.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3202) 	 * delete the parent index entries corresponding to
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3203) 	 * the freed child data/index blocks.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3204) 	 * free the index blocks themselves which aren't needed
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3205) 	 * in new sized file.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3206) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3207) 	 * index blocks are updated only if the blocks are to be
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3208) 	 * retained in the new sized file.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3209) 	 * if type is PMAP, the data and index pages are NOT
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3210) 	 * freed, and the data and index blocks are NOT freed
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3211) 	 * from working map.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3212) 	 * (this will allow continued access of data/index of
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3213) 	 * temporary file (zerolink count file truncated to zero-length)).
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3214) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3215) 	teof = (newsize + (JFS_SBI(ip->i_sb)->bsize - 1)) >>
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3216) 	    JFS_SBI(ip->i_sb)->l2bsize;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3217) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3218) 	/* clear stack */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3219) 	BT_CLR(&btstack);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3220) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3221) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3222) 	 * start with root
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3223) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3224) 	 * root resides in the inode
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3225) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3226) 	bn = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3227) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3228) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3229) 	 * first access of each page:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3230) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3231)       getPage:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3232) 	XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3233) 	if (rc)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3234) 		return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3235) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3236) 	/* process entries backward from last index */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3237) 	index = le16_to_cpu(p->header.nextindex) - 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3238) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3239) 
7038f1cbac899 (Dave Kleikamp     2005-10-28 13:27:40 -0500 3240) 	/* Since this is the rightmost page at this level, and we may have
7038f1cbac899 (Dave Kleikamp     2005-10-28 13:27:40 -0500 3241) 	 * already freed a page that was formerly to the right, let's make
7038f1cbac899 (Dave Kleikamp     2005-10-28 13:27:40 -0500 3242) 	 * sure that the next pointer is zero.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3243) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3244) 	if (p->header.next) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3245) 		if (log)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3246) 			/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3247) 			 * Make sure this change to the header is logged.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3248) 			 * If we really truncate this leaf, the flag
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3249) 			 * will be changed to tlckTRUNCATE
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3250) 			 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3251) 			tlck = txLock(tid, ip, mp, tlckXTREE|tlckGROW);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3252) 		BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3253) 		p->header.next = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3254) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3255) 
7038f1cbac899 (Dave Kleikamp     2005-10-28 13:27:40 -0500 3256) 	if (p->header.flag & BT_INTERNAL)
7038f1cbac899 (Dave Kleikamp     2005-10-28 13:27:40 -0500 3257) 		goto getChild;
7038f1cbac899 (Dave Kleikamp     2005-10-28 13:27:40 -0500 3258) 
7038f1cbac899 (Dave Kleikamp     2005-10-28 13:27:40 -0500 3259) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3260) 	 *	leaf page
7038f1cbac899 (Dave Kleikamp     2005-10-28 13:27:40 -0500 3261) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3262) 	freed = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3263) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3264) 	/* does region covered by leaf page precede Teof ? */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3265) 	xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3266) 	xoff = offsetXAD(xad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3267) 	xlen = lengthXAD(xad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3268) 	if (teof >= xoff + xlen) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3269) 		XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3270) 		goto getParent;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3271) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3272) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3273) 	/* (re)acquire tlock of the leaf page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3274) 	if (log) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3275) 		if (++locked_leaves > MAX_TRUNCATE_LEAVES) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3276) 			/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3277) 			 * We need to limit the size of the transaction
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3278) 			 * to avoid exhausting pagecache & tlocks
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3279) 			 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3280) 			XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3281) 			newsize = (xoff + xlen) << JFS_SBI(ip->i_sb)->l2bsize;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3282) 			goto getParent;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3283) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3284) 		tlck = txLock(tid, ip, mp, tlckXTREE);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3285) 		tlck->type = tlckXTREE | tlckTRUNCATE;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3286) 		xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3287) 		xtlck->hwm.offset = le16_to_cpu(p->header.nextindex) - 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3288) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3289) 	BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3290) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3291) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3292) 	 * scan backward leaf page entries
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3293) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3294) 	for (; index >= XTENTRYSTART; index--) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3295) 		xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3296) 		xoff = offsetXAD(xad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3297) 		xlen = lengthXAD(xad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3298) 		xaddr = addressXAD(xad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3299) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3300) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3301) 		 * The "data" for a directory is indexed by the block
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3302) 		 * device's address space.  This metadata must be invalidated
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3303) 		 * here
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3304) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3305) 		if (S_ISDIR(ip->i_mode) && (teof == 0))
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3306) 			invalidate_xad_metapages(ip, *xad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3307) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3308) 		 * entry beyond eof: continue scan of current page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3309) 		 *          xad
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3310) 		 * ---|---=======------->
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3311) 		 *   eof
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3312) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3313) 		if (teof < xoff) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3314) 			nfreed += xlen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3315) 			continue;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3316) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3317) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3318) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3319) 		 * (xoff <= teof): last entry to be deleted from page;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3320) 		 * If other entries remain in page: keep and update the page.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3321) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3322) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3323) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3324) 		 * eof == entry_start: delete the entry
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3325) 		 *           xad
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3326) 		 * -------|=======------->
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3327) 		 *       eof
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3328) 		 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3329) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3330) 		if (teof == xoff) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3331) 			nfreed += xlen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3332) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3333) 			if (index == XTENTRYSTART)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3334) 				break;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3335) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3336) 			nextindex = index;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3337) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3338) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3339) 		 * eof within the entry: truncate the entry.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3340) 		 *          xad
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3341) 		 * -------===|===------->
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3342) 		 *          eof
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3343) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3344) 		else if (teof < xoff + xlen) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3345) 			/* update truncated entry */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3346) 			len = teof - xoff;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3347) 			freexlen = xlen - len;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3348) 			XADlength(xad, len);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3349) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3350) 			/* save pxd of truncated extent in tlck */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3351) 			xaddr += len;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3352) 			if (log) {	/* COMMIT_PWMAP */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3353) 				xtlck->lwm.offset = (xtlck->lwm.offset) ?
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3354) 				    min(index, (int)xtlck->lwm.offset) : index;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3355) 				xtlck->lwm.length = index + 1 -
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3356) 				    xtlck->lwm.offset;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3357) 				xtlck->twm.offset = index;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3358) 				pxdlock = (struct pxd_lock *) & xtlck->pxdlock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3359) 				pxdlock->flag = mlckFREEPXD;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3360) 				PXDaddress(&pxdlock->pxd, xaddr);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3361) 				PXDlength(&pxdlock->pxd, freexlen);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3362) 			}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3363) 			/* free truncated extent */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3364) 			else {	/* COMMIT_WMAP */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3365) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3366) 				pxdlock = (struct pxd_lock *) & xadlock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3367) 				pxdlock->flag = mlckFREEPXD;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3368) 				PXDaddress(&pxdlock->pxd, xaddr);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3369) 				PXDlength(&pxdlock->pxd, freexlen);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3370) 				txFreeMap(ip, pxdlock, NULL, COMMIT_WMAP);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3371) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3372) 				/* reset map lock */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3373) 				xadlock.flag = mlckFREEXADLIST;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3374) 			}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3375) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3376) 			/* current entry is new last entry; */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3377) 			nextindex = index + 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3378) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3379) 			nfreed += freexlen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3380) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3381) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3382) 		 * eof beyond the entry:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3383) 		 *          xad
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3384) 		 * -------=======---|--->
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3385) 		 *                 eof
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3386) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3387) 		else {		/* (xoff + xlen < teof) */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3388) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3389) 			nextindex = index + 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3390) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3391) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3392) 		if (nextindex < le16_to_cpu(p->header.nextindex)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3393) 			if (!log) {	/* COMMIT_WAMP */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3394) 				xadlock.xdlist = &p->xad[nextindex];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3395) 				xadlock.count =
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3396) 				    le16_to_cpu(p->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3397) 				    nextindex;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3398) 				txFreeMap(ip, (struct maplock *) & xadlock,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3399) 					  NULL, COMMIT_WMAP);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3400) 			}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3401) 			p->header.nextindex = cpu_to_le16(nextindex);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3402) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3403) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3404) 		XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3405) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3406) 		/* assert(freed == 0); */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3407) 		goto getParent;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3408) 	}			/* end scan of leaf page entries */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3409) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3410) 	freed = 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3411) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3412) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3413) 	 * leaf page become empty: free the page if type != PMAP
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3414) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3415) 	if (log) {		/* COMMIT_PWMAP */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3416) 		/* txCommit() with tlckFREE:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3417) 		 * free data extents covered by leaf [XTENTRYSTART:hwm);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3418) 		 * invalidate leaf if COMMIT_PWMAP;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3419) 		 * if (TRUNCATE), will write LOG_NOREDOPAGE;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3420) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3421) 		tlck->type = tlckXTREE | tlckFREE;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3422) 	} else {		/* COMMIT_WAMP */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3423) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3424) 		/* free data extents covered by leaf */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3425) 		xadlock.xdlist = &p->xad[XTENTRYSTART];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3426) 		xadlock.count =
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3427) 		    le16_to_cpu(p->header.nextindex) - XTENTRYSTART;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3428) 		txFreeMap(ip, (struct maplock *) & xadlock, NULL, COMMIT_WMAP);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3429) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3430) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3431) 	if (p->header.flag & BT_ROOT) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3432) 		p->header.flag &= ~BT_INTERNAL;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3433) 		p->header.flag |= BT_LEAF;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3434) 		p->header.nextindex = cpu_to_le16(XTENTRYSTART);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3435) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3436) 		XT_PUTPAGE(mp);	/* debug */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3437) 		goto out;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3438) 	} else {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3439) 		if (log) {	/* COMMIT_PWMAP */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3440) 			/* page will be invalidated at tx completion
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3441) 			 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3442) 			XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3443) 		} else {	/* COMMIT_WMAP */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3444) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3445) 			if (mp->lid)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3446) 				lid_to_tlock(mp->lid)->flag |= tlckFREELOCK;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3447) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3448) 			/* invalidate empty leaf page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3449) 			discard_metapage(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3450) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3451) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3452) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3453) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3454) 	 * the leaf page become empty: delete the parent entry
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3455) 	 * for the leaf page if the parent page is to be kept
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3456) 	 * in the new sized file.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3457) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3458) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3459) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3460) 	 * go back up to the parent page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3461) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3462)       getParent:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3463) 	/* pop/restore parent entry for the current child page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3464) 	if ((parent = BT_POP(&btstack)) == NULL)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3465) 		/* current page must have been root */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3466) 		goto out;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3467) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3468) 	/* get back the parent page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3469) 	bn = parent->bn;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3470) 	XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3471) 	if (rc)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3472) 		return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3473) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3474) 	index = parent->index;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3475) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3476) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3477) 	 * child page was not empty:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3478) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3479) 	if (freed == 0) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3480) 		/* has any entry deleted from parent ? */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3481) 		if (index < le16_to_cpu(p->header.nextindex) - 1) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3482) 			/* (re)acquire tlock on the parent page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3483) 			if (log) {	/* COMMIT_PWMAP */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3484) 				/* txCommit() with tlckTRUNCATE:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3485) 				 * free child extents covered by parent [);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3486) 				 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3487) 				tlck = txLock(tid, ip, mp, tlckXTREE);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3488) 				xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3489) 				if (!(tlck->type & tlckTRUNCATE)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3490) 					xtlck->hwm.offset =
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3491) 					    le16_to_cpu(p->header.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3492) 							nextindex) - 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3493) 					tlck->type =
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3494) 					    tlckXTREE | tlckTRUNCATE;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3495) 				}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3496) 			} else {	/* COMMIT_WMAP */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3497) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3498) 				/* free child extents covered by parent */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3499) 				xadlock.xdlist = &p->xad[index + 1];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3500) 				xadlock.count =
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3501) 				    le16_to_cpu(p->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3502) 				    index - 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3503) 				txFreeMap(ip, (struct maplock *) & xadlock,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3504) 					  NULL, COMMIT_WMAP);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3505) 			}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3506) 			BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3507) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3508) 			p->header.nextindex = cpu_to_le16(index + 1);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3509) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3510) 		XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3511) 		goto getParent;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3512) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3513) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3514) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3515) 	 * child page was empty:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3516) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3517) 	nfreed += lengthXAD(&p->xad[index]);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3518) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3519) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3520) 	 * During working map update, child page's tlock must be handled
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3521) 	 * before parent's.  This is because the parent's tlock will cause
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3522) 	 * the child's disk space to be marked available in the wmap, so
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3523) 	 * it's important that the child page be released by that time.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3524) 	 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3525) 	 * ToDo:  tlocks should be on doubly-linked list, so we can
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3526) 	 * quickly remove it and add it to the end.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3527) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3528) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3529) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3530) 	 * Move parent page's tlock to the end of the tid's tlock list
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3531) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3532) 	if (log && mp->lid && (tblk->last != mp->lid) &&
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3533) 	    lid_to_tlock(mp->lid)->tid) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3534) 		lid_t lid = mp->lid;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3535) 		struct tlock *prev;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3536) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3537) 		tlck = lid_to_tlock(lid);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3538) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3539) 		if (tblk->next == lid)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3540) 			tblk->next = tlck->next;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3541) 		else {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3542) 			for (prev = lid_to_tlock(tblk->next);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3543) 			     prev->next != lid;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3544) 			     prev = lid_to_tlock(prev->next)) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3545) 				assert(prev->next);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3546) 			}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3547) 			prev->next = tlck->next;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3548) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3549) 		lid_to_tlock(tblk->last)->next = lid;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3550) 		tlck->next = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3551) 		tblk->last = lid;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3552) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3553) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3554) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3555) 	 * parent page become empty: free the page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3556) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3557) 	if (index == XTENTRYSTART) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3558) 		if (log) {	/* COMMIT_PWMAP */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3559) 			/* txCommit() with tlckFREE:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3560) 			 * free child extents covered by parent;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3561) 			 * invalidate parent if COMMIT_PWMAP;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3562) 			 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3563) 			tlck = txLock(tid, ip, mp, tlckXTREE);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3564) 			xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3565) 			xtlck->hwm.offset =
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3566) 			    le16_to_cpu(p->header.nextindex) - 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3567) 			tlck->type = tlckXTREE | tlckFREE;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3568) 		} else {	/* COMMIT_WMAP */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3569) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3570) 			/* free child extents covered by parent */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3571) 			xadlock.xdlist = &p->xad[XTENTRYSTART];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3572) 			xadlock.count =
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3573) 			    le16_to_cpu(p->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3574) 			    XTENTRYSTART;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3575) 			txFreeMap(ip, (struct maplock *) & xadlock, NULL,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3576) 				  COMMIT_WMAP);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3577) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3578) 		BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3579) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3580) 		if (p->header.flag & BT_ROOT) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3581) 			p->header.flag &= ~BT_INTERNAL;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3582) 			p->header.flag |= BT_LEAF;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3583) 			p->header.nextindex = cpu_to_le16(XTENTRYSTART);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3584) 			if (le16_to_cpu(p->header.maxentry) == XTROOTMAXSLOT) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3585) 				/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3586) 				 * Shrink root down to allow inline
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3587) 				 * EA (otherwise fsck complains)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3588) 				 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3589) 				p->header.maxentry =
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3590) 				    cpu_to_le16(XTROOTINITSLOT);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3591) 				JFS_IP(ip)->mode2 |= INLINEEA;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3592) 			}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3593) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3594) 			XT_PUTPAGE(mp);	/* debug */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3595) 			goto out;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3596) 		} else {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3597) 			if (log) {	/* COMMIT_PWMAP */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3598) 				/* page will be invalidated at tx completion
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3599) 				 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3600) 				XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3601) 			} else {	/* COMMIT_WMAP */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3602) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3603) 				if (mp->lid)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3604) 					lid_to_tlock(mp->lid)->flag |=
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3605) 						tlckFREELOCK;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3606) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3607) 				/* invalidate parent page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3608) 				discard_metapage(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3609) 			}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3610) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3611) 			/* parent has become empty and freed:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3612) 			 * go back up to its parent page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3613) 			 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3614) 			/* freed = 1; */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3615) 			goto getParent;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3616) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3617) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3618) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3619) 	 * parent page still has entries for front region;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3620) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3621) 	else {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3622) 		/* try truncate region covered by preceding entry
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3623) 		 * (process backward)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3624) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3625) 		index--;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3626) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3627) 		/* go back down to the child page corresponding
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3628) 		 * to the entry
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3629) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3630) 		goto getChild;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3631) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3632) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3633) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3634) 	 *	internal page: go down to child page of current entry
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3635) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3636)       getChild:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3637) 	/* save current parent entry for the child page */
17e6afc75ad01 (Dave Kleikamp     2007-01-09 08:57:34 -0600 3638) 	if (BT_STACK_FULL(&btstack)) {
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700 3639) 		jfs_error(ip->i_sb, "stack overrun!\n");
17e6afc75ad01 (Dave Kleikamp     2007-01-09 08:57:34 -0600 3640) 		XT_PUTPAGE(mp);
17e6afc75ad01 (Dave Kleikamp     2007-01-09 08:57:34 -0600 3641) 		return -EIO;
17e6afc75ad01 (Dave Kleikamp     2007-01-09 08:57:34 -0600 3642) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3643) 	BT_PUSH(&btstack, bn, index);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3644) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3645) 	/* get child page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3646) 	xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3647) 	bn = addressXAD(xad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3648) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3649) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3650) 	 * first access of each internal entry:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3651) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3652) 	/* release parent page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3653) 	XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3654) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3655) 	/* process the child page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3656) 	goto getPage;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3657) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3658)       out:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3659) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3660) 	 * update file resource stat
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3661) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3662) 	/* set size
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3663) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3664) 	if (S_ISDIR(ip->i_mode) && !newsize)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3665) 		ip->i_size = 1;	/* fsck hates zero-length directories */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3666) 	else
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3667) 		ip->i_size = newsize;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3668) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3669) 	/* update quota allocation to reflect freed blocks */
5dd4056db8438 (Christoph Hellwig 2010-03-03 09:05:00 -0500 3670) 	dquot_free_block(ip, nfreed);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3671) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3672) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3673) 	 * free tlock of invalidated pages
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3674) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3675) 	if (flag == COMMIT_WMAP)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3676) 		txFreelock(ip);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3677) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3678) 	return newsize;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3679) }
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3680) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3681) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3682) /*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3683)  *	xtTruncate_pmap()
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3684)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3685)  * function:
efad798b9f013 (Paulius Zaleckas  2008-02-03 15:42:53 +0200 3686)  *	Perform truncate to zero length for deleted file, leaving the
ed1c9a7a8517f (Randy Dunlap      2020-08-04 19:49:01 -0700 3687)  *	xtree and working map untouched.  This allows the file to
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3688)  *	be accessed via open file handles, while the delete of the file
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3689)  *	is committed to disk.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3690)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3691)  * parameter:
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3692)  *	tid_t		tid,
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3693)  *	struct inode	*ip,
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3694)  *	s64		committed_size)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3695)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3696)  * return: new committed size
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3697)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3698)  * note:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3699)  *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3700)  *	To avoid deadlock by holding too many transaction locks, the
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3701)  *	truncation may be broken up into multiple transactions.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3702)  *	The committed_size keeps track of part of the file has been
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3703)  *	freed from the pmaps.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3704)  */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3705) s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3706) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3707) 	s64 bn;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3708) 	struct btstack btstack;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3709) 	int cmp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3710) 	int index;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3711) 	int locked_leaves = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3712) 	struct metapage *mp;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3713) 	xtpage_t *p;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3714) 	struct btframe *parent;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3715) 	int rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3716) 	struct tblock *tblk;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3717) 	struct tlock *tlck = NULL;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3718) 	xad_t *xad;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3719) 	int xlen;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3720) 	s64 xoff;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3721) 	struct xtlock *xtlck = NULL;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3722) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3723) 	/* save object truncation type */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3724) 	tblk = tid_to_tblock(tid);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3725) 	tblk->xflag |= COMMIT_PMAP;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3726) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3727) 	/* clear stack */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3728) 	BT_CLR(&btstack);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3729) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3730) 	if (committed_size) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3731) 		xoff = (committed_size >> JFS_SBI(ip->i_sb)->l2bsize) - 1;
6628465e33ca6 (Dave Kleikamp     2005-05-02 12:25:13 -0600 3732) 		rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3733) 		if (rc)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3734) 			return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3735) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3736) 		XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3737) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3738) 		if (cmp != 0) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3739) 			XT_PUTPAGE(mp);
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700 3740) 			jfs_error(ip->i_sb, "did not find extent\n");
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3741) 			return -EIO;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3742) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3743) 	} else {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3744) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3745) 		 * start with root
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3746) 		 *
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3747) 		 * root resides in the inode
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3748) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3749) 		bn = 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3750) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3751) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3752) 		 * first access of each page:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3753) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3754)       getPage:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3755) 		XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3756) 		if (rc)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3757) 			return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3758) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3759) 		/* process entries backward from last index */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3760) 		index = le16_to_cpu(p->header.nextindex) - 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3761) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3762) 		if (p->header.flag & BT_INTERNAL)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3763) 			goto getChild;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3764) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3765) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3766) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3767) 	 *	leaf page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3768) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3769) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3770) 	if (++locked_leaves > MAX_TRUNCATE_LEAVES) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3771) 		/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3772) 		 * We need to limit the size of the transaction
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3773) 		 * to avoid exhausting pagecache & tlocks
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3774) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3775) 		xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3776) 		xoff = offsetXAD(xad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3777) 		xlen = lengthXAD(xad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3778) 		XT_PUTPAGE(mp);
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3779) 		return (xoff + xlen) << JFS_SBI(ip->i_sb)->l2bsize;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3780) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3781) 	tlck = txLock(tid, ip, mp, tlckXTREE);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3782) 	tlck->type = tlckXTREE | tlckFREE;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3783) 	xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3784) 	xtlck->hwm.offset = index;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3785) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3786) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3787) 	XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3788) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3789) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3790) 	 * go back up to the parent page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3791) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3792)       getParent:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3793) 	/* pop/restore parent entry for the current child page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3794) 	if ((parent = BT_POP(&btstack)) == NULL)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3795) 		/* current page must have been root */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3796) 		goto out;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3797) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3798) 	/* get back the parent page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3799) 	bn = parent->bn;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3800) 	XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3801) 	if (rc)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3802) 		return rc;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3803) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3804) 	index = parent->index;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3805) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3806) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3807) 	 * parent page become empty: free the page
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3808) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3809) 	if (index == XTENTRYSTART) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3810) 		/* txCommit() with tlckFREE:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3811) 		 * free child extents covered by parent;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3812) 		 * invalidate parent if COMMIT_PWMAP;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3813) 		 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3814) 		tlck = txLock(tid, ip, mp, tlckXTREE);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3815) 		xtlck = (struct xtlock *) & tlck->lock;
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3816) 		xtlck->hwm.offset = le16_to_cpu(p->header.nextindex) - 1;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3817) 		tlck->type = tlckXTREE | tlckFREE;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3818) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3819) 		XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3820) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3821) 		if (p->header.flag & BT_ROOT) {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3822) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3823) 			goto out;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3824) 		} else {
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3825) 			goto getParent;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3826) 		}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3827) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3828) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3829) 	 * parent page still has entries for front region;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3830) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3831) 	else
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3832) 		index--;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3833) 	/*
f720e3ba55868 (Dave Kleikamp     2007-06-06 15:28:35 -0500 3834) 	 *	internal page: go down to child page of current entry
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3835) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3836)       getChild:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3837) 	/* save current parent entry for the child page */
17e6afc75ad01 (Dave Kleikamp     2007-01-09 08:57:34 -0600 3838) 	if (BT_STACK_FULL(&btstack)) {
eb8630d7d2fd1 (Joe Perches       2013-06-04 16:39:15 -0700 3839) 		jfs_error(ip->i_sb, "stack overrun!\n");
17e6afc75ad01 (Dave Kleikamp     2007-01-09 08:57:34 -0600 3840) 		XT_PUTPAGE(mp);
17e6afc75ad01 (Dave Kleikamp     2007-01-09 08:57:34 -0600 3841) 		return -EIO;
17e6afc75ad01 (Dave Kleikamp     2007-01-09 08:57:34 -0600 3842) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3843) 	BT_PUSH(&btstack, bn, index);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3844) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3845) 	/* get child page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3846) 	xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3847) 	bn = addressXAD(xad);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3848) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3849) 	/*
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3850) 	 * first access of each internal entry:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3851) 	 */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3852) 	/* release parent page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3853) 	XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3854) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3855) 	/* process the child page */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3856) 	goto getPage;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3857) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3858)       out:
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3859) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3860) 	return 0;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3861) }
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3862) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3863) #ifdef CONFIG_JFS_STATISTICS
07a3b8ed48557 (Christoph Hellwig 2018-04-11 16:51:18 +0200 3864) int jfs_xtstat_proc_show(struct seq_file *m, void *v)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3865) {
b2e03ca7485ca (Alexey Dobriyan   2008-05-13 08:22:10 -0500 3866) 	seq_printf(m,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3867) 		       "JFS Xtree statistics\n"
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3868) 		       "====================\n"
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3869) 		       "searches = %d\n"
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3870) 		       "fast searches = %d\n"
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3871) 		       "splits = %d\n",
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3872) 		       xtStat.search,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3873) 		       xtStat.fastSearch,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3874) 		       xtStat.split);
b2e03ca7485ca (Alexey Dobriyan   2008-05-13 08:22:10 -0500 3875) 	return 0;
b2e03ca7485ca (Alexey Dobriyan   2008-05-13 08:22:10 -0500 3876) }
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 3877) #endif