Orange Pi5 kernel

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

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  *   Copyright (C) International Business Machines Corp., 2000-2004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *	jfs_dtree.c: directory B+-tree manager
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  * B+-tree with variable length key directory:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  * each directory page is structured as an array of 32-byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  * directory entry slots initialized as a freelist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  * to avoid search/compaction of free space at insertion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  * when an entry is inserted, a number of slots are allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  * from the freelist as required to store variable length data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  * of the entry; when the entry is deleted, slots of the entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  * are returned to freelist.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19)  * leaf entry stores full name as key and file serial number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20)  * (aka inode number) as data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21)  * internal/router entry stores sufffix compressed name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22)  * as key and simple extent descriptor as data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24)  * each directory page maintains a sorted entry index table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25)  * which stores the start slot index of sorted entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26)  * to allow binary search on the table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28)  * directory starts as a root/leaf page in on-disk inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29)  * inline data area.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30)  * when it becomes full, it starts a leaf of a external extent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31)  * of length of 1 block. each time the first leaf becomes full,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32)  * it is extended rather than split (its size is doubled),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33)  * until its length becoms 4 KBytes, from then the extent is split
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34)  * with new 4 Kbyte extent when it becomes full
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35)  * to reduce external fragmentation of small directories.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37)  * blah, blah, blah, for linear scan of directory in pieces by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38)  * readdir().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41)  *	case-insensitive directory file system
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43)  * names are stored in case-sensitive way in leaf entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44)  * but stored, searched and compared in case-insensitive (uppercase) order
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45)  * (i.e., both search key and entry key are folded for search/compare):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46)  * (note that case-sensitive order is BROKEN in storage, e.g.,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47)  *  sensitive: Ad, aB, aC, aD -> insensitive: aB, aC, aD, Ad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49)  *  entries which folds to the same key makes up a equivalent class
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50)  *  whose members are stored as contiguous cluster (may cross page boundary)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51)  *  but whose order is arbitrary and acts as duplicate, e.g.,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52)  *  abc, Abc, aBc, abC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54)  * once match is found at leaf, requires scan forward/backward
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55)  * either for, in case-insensitive search, duplicate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56)  * or for, in case-sensitive search, for exact match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58)  * router entry must be created/stored in case-insensitive way
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59)  * in internal entry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60)  * (right most key of left page and left most key of right page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61)  * are folded, and its suffix compression is propagated as router
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62)  * key in parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63)  * (e.g., if split occurs <abc> and <aBd>, <ABD> trather than <aB>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64)  * should be made the router key for the split)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66)  * case-insensitive search:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68)  *	fold search key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70)  *	case-insensitive search of B-tree:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71)  *	for internal entry, router key is already folded;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72)  *	for leaf entry, fold the entry key before comparison.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74)  *	if (leaf entry case-insensitive match found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75)  *		if (next entry satisfies case-insensitive match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76)  *			return EDUPLICATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77)  *		if (prev entry satisfies case-insensitive match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78)  *			return EDUPLICATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79)  *		return match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80)  *	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81)  *		return no match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83)  *	serialization:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84)  * target directory inode lock is being held on entry/exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85)  * of all main directory service routines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87)  *	log based recovery:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) #include <linux/quotaops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) #include "jfs_incore.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) #include "jfs_superblock.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) #include "jfs_filsys.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) #include "jfs_metapage.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) #include "jfs_dmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) #include "jfs_unicode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) #include "jfs_debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) /* dtree split parameter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) struct dtsplit {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	struct metapage *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	s16 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	s16 nslot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	struct component_name *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	ddata_t *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	struct pxdlist *pxdlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) #define DT_PAGE(IP, MP) BT_PAGE(IP, MP, dtpage_t, i_dtroot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) /* get page buffer for specified block address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) #define DT_GETPAGE(IP, BN, MP, SIZE, P, RC)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) do {									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	BT_GETPAGE(IP, BN, MP, dtpage_t, SIZE, P, RC, i_dtroot);	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	if (!(RC)) {							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 		if (((P)->header.nextindex >				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 		     (((BN) == 0) ? DTROOTMAXSLOT : (P)->header.maxslot)) || \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 		    ((BN) && ((P)->header.maxslot > DTPAGEMAXSLOT))) {	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 			BT_PUTPAGE(MP);					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 			jfs_error((IP)->i_sb,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 				  "DT_GETPAGE: dtree page corrupt\n");	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 			MP = NULL;					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 			RC = -EIO;					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 		}							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	}								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) /* for consistency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) #define DT_PUTPAGE(MP) BT_PUTPAGE(MP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) #define DT_GETSEARCH(IP, LEAF, BN, MP, P, INDEX) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	BT_GETSEARCH(IP, LEAF, BN, MP, dtpage_t, P, INDEX, i_dtroot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137)  * forward references
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) static int dtSplitUp(tid_t tid, struct inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 		     struct dtsplit * split, struct btstack * btstack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 		       struct metapage ** rmpp, dtpage_t ** rpp, pxd_t * rxdp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) static int dtExtendPage(tid_t tid, struct inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 			struct dtsplit * split, struct btstack * btstack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) static int dtSplitRoot(tid_t tid, struct inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 		       struct dtsplit * split, struct metapage ** rmpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) static int dtDeleteUp(tid_t tid, struct inode *ip, struct metapage * fmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 		      dtpage_t * fp, struct btstack * btstack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) static int dtRelink(tid_t tid, struct inode *ip, dtpage_t * p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) static int dtReadFirst(struct inode *ip, struct btstack * btstack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) static int dtReadNext(struct inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 		      loff_t * offset, struct btstack * btstack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) static int dtCompare(struct component_name * key, dtpage_t * p, int si);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) static int ciCompare(struct component_name * key, dtpage_t * p, int si,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 		     int flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) static void dtGetKey(dtpage_t * p, int i, struct component_name * key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 		     int flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) static int ciGetLeafPrefixKey(dtpage_t * lp, int li, dtpage_t * rp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 			      int ri, struct component_name * key, int flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) static void dtInsertEntry(dtpage_t * p, int index, struct component_name * key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 			  ddata_t * data, struct dt_lock **);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) static void dtMoveEntry(dtpage_t * sp, int si, dtpage_t * dp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 			struct dt_lock ** sdtlock, struct dt_lock ** ddtlock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 			int do_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) static void dtDeleteEntry(dtpage_t * p, int fi, struct dt_lock ** dtlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) static void dtTruncateEntry(dtpage_t * p, int ti, struct dt_lock ** dtlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) static void dtLinelockFreelist(dtpage_t * p, int m, struct dt_lock ** dtlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) #define ciToUpper(c)	UniStrupr((c)->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188)  *	read_index_page()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190)  *	Reads a page of a directory's index table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191)  *	Having metadata mapped into the directory inode's address space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192)  *	presents a multitude of problems.  We avoid this by mapping to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193)  *	the absolute address space outside of the *_metapage routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) static struct metapage *read_index_page(struct inode *inode, s64 blkno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	s64 xaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	int xflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	s32 xlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	rc = xtLookup(inode, blkno, 1, &xflag, &xaddr, &xlen, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	if (rc || (xaddr == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	return read_metapage(inode, xaddr, PSIZE, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210)  *	get_index_page()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212)  *	Same as get_index_page(), but get's a new page without reading
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) static struct metapage *get_index_page(struct inode *inode, s64 blkno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	s64 xaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	int xflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	s32 xlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	rc = xtLookup(inode, blkno, 1, &xflag, &xaddr, &xlen, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	if (rc || (xaddr == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	return get_metapage(inode, xaddr, PSIZE, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229)  *	find_index()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231)  *	Returns dtree page containing directory table entry for specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232)  *	index and pointer to its entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234)  *	mp must be released by caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) static struct dir_table_slot *find_index(struct inode *ip, u32 index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 					 struct metapage ** mp, s64 *lblock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	struct jfs_inode_info *jfs_ip = JFS_IP(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	s64 blkno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	s64 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	int page_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	struct dir_table_slot *slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	static int maxWarnings = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	if (index < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 		if (maxWarnings) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 			jfs_warn("find_entry called with index = %d", index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 			maxWarnings--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	if (index >= jfs_ip->next_index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 		jfs_warn("find_entry called with index >= next_index");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	if (jfs_dirtable_inline(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 		 * Inline directory table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 		*mp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 		slot = &jfs_ip->i_dirtable[index - 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 		offset = (index - 2) * sizeof(struct dir_table_slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 		page_offset = offset & (PSIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 		blkno = ((offset + 1) >> L2PSIZE) <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 		    JFS_SBI(ip->i_sb)->l2nbperpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 		if (*mp && (*lblock != blkno)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 			release_metapage(*mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 			*mp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 		if (!(*mp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 			*lblock = blkno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 			*mp = read_index_page(ip, blkno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 		if (!(*mp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 			jfs_err("free_index: error reading directory table");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 			return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 		slot =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 		    (struct dir_table_slot *) ((char *) (*mp)->data +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 					       page_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	return slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) static inline void lock_index(tid_t tid, struct inode *ip, struct metapage * mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 			      u32 index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	struct tlock *tlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	struct linelock *llck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	struct lv *lv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	tlck = txLock(tid, ip, mp, tlckDATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	llck = (struct linelock *) tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	if (llck->index >= llck->maxcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 		llck = txLinelock(llck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	lv = &llck->lv[llck->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	 *	Linelock slot size is twice the size of directory table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	 *	slot size.  512 entries per page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	lv->offset = ((index - 2) & 511) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	lv->length = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	llck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315)  *	add_index()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317)  *	Adds an entry to the directory index table.  This is used to provide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318)  *	each directory entry with a persistent index in which to resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319)  *	directory traversals
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	struct super_block *sb = ip->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	struct jfs_sb_info *sbi = JFS_SBI(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	struct jfs_inode_info *jfs_ip = JFS_IP(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	u64 blkno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	struct dir_table_slot *dirtab_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	u32 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	struct linelock *llck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	struct lv *lv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	struct metapage *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	s64 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	uint page_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	struct tlock *tlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	s64 xaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	ASSERT(DO_INDEX(ip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	if (jfs_ip->next_index < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 		jfs_warn("add_index: next_index = %d.  Resetting!",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 			   jfs_ip->next_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 		jfs_ip->next_index = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 	index = jfs_ip->next_index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	if (index <= MAX_INLINE_DIRTABLE_ENTRY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 		 * i_size reflects size of index table, or 8 bytes per entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 		ip->i_size = (loff_t) (index - 1) << 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 		 * dir table fits inline within inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 		dirtab_slot = &jfs_ip->i_dirtable[index-2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 		dirtab_slot->flag = DIR_INDEX_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 		dirtab_slot->slot = slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 		DTSaddress(dirtab_slot, bn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 		set_cflag(COMMIT_Dirtable, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 		return index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	if (index == (MAX_INLINE_DIRTABLE_ENTRY + 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 		struct dir_table_slot temp_table[12];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 		 * It's time to move the inline table to an external
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 		 * page and begin to build the xtree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 		if (dquot_alloc_block(ip, sbi->nbperpage))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 			goto clean_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 		if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 			dquot_free_block(ip, sbi->nbperpage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 			goto clean_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 		 * Save the table, we're going to overwrite it with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 		 * xtree root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 		memcpy(temp_table, &jfs_ip->i_dirtable, sizeof(temp_table));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 		 * Initialize empty x-tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 		xtInitRoot(tid, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 		 * Add the first block to the xtree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 		if (xtInsert(tid, ip, 0, 0, sbi->nbperpage, &xaddr, 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 			/* This really shouldn't fail */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 			jfs_warn("add_index: xtInsert failed!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 			memcpy(&jfs_ip->i_dirtable, temp_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 			       sizeof (temp_table));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 			dbFree(ip, xaddr, sbi->nbperpage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 			dquot_free_block(ip, sbi->nbperpage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 			goto clean_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 		ip->i_size = PSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 		mp = get_index_page(ip, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 		if (!mp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 			jfs_err("add_index: get_metapage failed!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 			xtTruncate(tid, ip, 0, COMMIT_PWMAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 			memcpy(&jfs_ip->i_dirtable, temp_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 			       sizeof (temp_table));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 			goto clean_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 		tlck = txLock(tid, ip, mp, tlckDATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 		llck = (struct linelock *) & tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 		ASSERT(llck->index == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 		lv = &llck->lv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 		lv->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 		lv->length = 6;	/* tlckDATA slot size is 16 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 		llck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 		memcpy(mp->data, temp_table, sizeof(temp_table));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 		mark_metapage_dirty(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 		release_metapage(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 		 * Logging is now directed by xtree tlocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 		clear_cflag(COMMIT_Dirtable, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	offset = (index - 2) * sizeof(struct dir_table_slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	page_offset = offset & (PSIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	blkno = ((offset + 1) >> L2PSIZE) << sbi->l2nbperpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	if (page_offset == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 		 * This will be the beginning of a new page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 		xaddr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 		if (xtInsert(tid, ip, 0, blkno, sbi->nbperpage, &xaddr, 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 			jfs_warn("add_index: xtInsert failed!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 			goto clean_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 		ip->i_size += PSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 		if ((mp = get_index_page(ip, blkno)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 			memset(mp->data, 0, PSIZE);	/* Just looks better */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 			xtTruncate(tid, ip, offset, COMMIT_PWMAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 		mp = read_index_page(ip, blkno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	if (!mp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 		jfs_err("add_index: get/read_metapage failed!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 		goto clean_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	lock_index(tid, ip, mp, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	dirtab_slot =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	    (struct dir_table_slot *) ((char *) mp->data + page_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	dirtab_slot->flag = DIR_INDEX_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 	dirtab_slot->slot = slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	DTSaddress(dirtab_slot, bn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	mark_metapage_dirty(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	release_metapage(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	return index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471)       clean_up:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	jfs_ip->next_index--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479)  *	free_index()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481)  *	Marks an entry to the directory index table as free.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) static void free_index(tid_t tid, struct inode *ip, u32 index, u32 next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	struct dir_table_slot *dirtab_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 	s64 lblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	struct metapage *mp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	dirtab_slot = find_index(ip, index, &mp, &lblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	if (!dirtab_slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	dirtab_slot->flag = DIR_INDEX_FREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	dirtab_slot->slot = dirtab_slot->addr1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	dirtab_slot->addr2 = cpu_to_le32(next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	if (mp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 		lock_index(tid, ip, mp, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 		mark_metapage_dirty(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 		release_metapage(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 		set_cflag(COMMIT_Dirtable, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507)  *	modify_index()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509)  *	Changes an entry in the directory index table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) static void modify_index(tid_t tid, struct inode *ip, u32 index, s64 bn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 			 int slot, struct metapage ** mp, s64 *lblock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	struct dir_table_slot *dirtab_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	dirtab_slot = find_index(ip, index, mp, lblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	if (!dirtab_slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	DTSaddress(dirtab_slot, bn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	dirtab_slot->slot = slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	if (*mp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 		lock_index(tid, ip, *mp, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 		mark_metapage_dirty(*mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 		set_cflag(COMMIT_Dirtable, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532)  *	read_index()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534)  *	reads a directory table slot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) static int read_index(struct inode *ip, u32 index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 		     struct dir_table_slot * dirtab_slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	s64 lblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	struct metapage *mp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	struct dir_table_slot *slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	slot = find_index(ip, index, &mp, &lblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	if (!slot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	memcpy(dirtab_slot, slot, sizeof(struct dir_table_slot));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	if (mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 		release_metapage(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557)  *	dtSearch()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559)  * function:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560)  *	Search for the entry with specified key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562)  * parameter:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564)  * return: 0 - search result on stack, leaf page pinned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565)  *	   errno - I/O error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) int dtSearch(struct inode *ip, struct component_name * key, ino_t * data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	     struct btstack * btstack, int flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	int cmp = 1;		/* init for empty page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	s64 bn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	struct metapage *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	dtpage_t *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	s8 *stbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	int base, index, lim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	struct btframe *btsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	pxd_t *pxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	int psize = 288;	/* initial in-line directory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	ino_t inumber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	struct component_name ciKey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	struct super_block *sb = ip->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	ciKey.name = kmalloc_array(JFS_NAME_MAX + 1, sizeof(wchar_t),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 				   GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	if (!ciKey.name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 		rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 		goto dtSearch_Exit2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	/* uppercase search key for c-i directory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	UniStrcpy(ciKey.name, key->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	ciKey.namlen = key->namlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	/* only uppercase if case-insensitive support is on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	if ((JFS_SBI(sb)->mntflag & JFS_OS2) == JFS_OS2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 		ciToUpper(&ciKey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	BT_CLR(btstack);	/* reset stack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	/* init level count for max pages to split */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	btstack->nsplit = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	 *	search down tree from root:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	 * between two consecutive entries of <Ki, Pi> and <Kj, Pj> of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	 * internal page, child page Pi contains entry with k, Ki <= K < Kj.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	 * if entry with search key K is not found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	 * internal page search find the entry with largest key Ki
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	 * less than K which point to the child page to search;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	 * leaf page search find the entry with smallest key Kj
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	 * greater than K so that the returned index is the position of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	 * the entry to be shifted right for insertion of new entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	 * for empty tree, search key is greater than any key of the tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	 * by convention, root bn = 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	for (bn = 0;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 		/* get/pin the page to search */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 		DT_GETPAGE(ip, bn, mp, psize, p, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 			goto dtSearch_Exit1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 		/* get sorted entry table of the page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 		stbl = DT_GETSTBL(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 		 * binary search with search key K on the current page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 		for (base = 0, lim = p->header.nextindex; lim; lim >>= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 			index = base + (lim >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 			if (p->header.flag & BT_LEAF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 				/* uppercase leaf name to compare */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 				cmp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 				    ciCompare(&ciKey, p, stbl[index],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 					      JFS_SBI(sb)->mntflag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 				/* router key is in uppercase */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 				cmp = dtCompare(&ciKey, p, stbl[index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 			if (cmp == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 				 *	search hit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 				/* search hit - leaf page:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 				 * return the entry found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 				if (p->header.flag & BT_LEAF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 					inumber = le32_to_cpu(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 			((struct ldtentry *) & p->slot[stbl[index]])->inumber);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 					/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 					 * search for JFS_LOOKUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 					 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 					if (flag == JFS_LOOKUP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 						*data = inumber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 						rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 						goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 					/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 					 * search for JFS_CREATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 					 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 					if (flag == JFS_CREATE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 						*data = inumber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 						rc = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 						goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 					/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 					 * search for JFS_REMOVE or JFS_RENAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 					 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 					if ((flag == JFS_REMOVE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 					     flag == JFS_RENAME) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 					    *data != inumber) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 						rc = -ESTALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 						goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 					/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 					 * JFS_REMOVE|JFS_FINDDIR|JFS_RENAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 					 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 					/* save search result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 					*data = inumber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 					btsp = btstack->top;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 					btsp->bn = bn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 					btsp->index = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 					btsp->mp = mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 					rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 					goto dtSearch_Exit1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 				/* search hit - internal page:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 				 * descend/search its child page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 				goto getChild;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 			if (cmp > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 				base = index + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 				--lim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 		 *	search miss
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 		 * base is the smallest index with key (Kj) greater than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 		 * search key (K) and may be zero or (maxindex + 1) index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 		 * search miss - leaf page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 		 * return location of entry (base) where new entry with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 		 * search key K is to be inserted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 		if (p->header.flag & BT_LEAF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 			 * search for JFS_LOOKUP, JFS_REMOVE, or JFS_RENAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 			if (flag == JFS_LOOKUP || flag == JFS_REMOVE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 			    flag == JFS_RENAME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 				rc = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 			 * search for JFS_CREATE|JFS_FINDDIR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 			 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 			 * save search result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 			*data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 			btsp = btstack->top;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 			btsp->bn = bn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 			btsp->index = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 			btsp->mp = mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 			rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 			goto dtSearch_Exit1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 		 * search miss - internal page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		 * if base is non-zero, decrement base by one to get the parent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 		 * entry of the child page to search.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 		index = base ? base - 1 : base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 		 * go down to child page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	      getChild:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 		/* update max. number of pages to split */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 		if (BT_STACK_FULL(btstack)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 			/* Something's corrupted, mark filesystem dirty so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 			 * chkdsk will fix it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 			jfs_error(sb, "stack overrun!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 			BT_STACK_DUMP(btstack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 			rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 		btstack->nsplit++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 		/* push (bn, index) of the parent page/entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 		BT_PUSH(btstack, bn, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 		/* get the child page block number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 		pxd = (pxd_t *) & p->slot[stbl[index]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 		bn = addressPXD(pxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 		psize = lengthPXD(pxd) << JFS_SBI(ip->i_sb)->l2bsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 		/* unpin the parent page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 		DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786)       out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789)       dtSearch_Exit1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	kfree(ciKey.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793)       dtSearch_Exit2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800)  *	dtInsert()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802)  * function: insert an entry to directory tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804)  * parameter:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806)  * return: 0 - success;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807)  *	   errno - failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) int dtInsert(tid_t tid, struct inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	 struct component_name * name, ino_t * fsn, struct btstack * btstack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	struct metapage *mp;	/* meta-page buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	dtpage_t *p;		/* base B+-tree index page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	s64 bn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 	int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	struct dtsplit split;	/* split information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	ddata_t data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	struct dt_lock *dtlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 	int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	struct tlock *tlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 	struct lv *lv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	 *	retrieve search result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	 * dtSearch() returns (leaf page pinned, index at which to insert).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	 * n.b. dtSearch() may return index of (maxindex + 1) of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	 * the full page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	DT_GETSEARCH(ip, btstack->top, bn, mp, p, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	 *	insert entry for new key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	if (DO_INDEX(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 		if (JFS_IP(ip)->next_index == DIREND) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 			DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 			return -EMLINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 		n = NDTLEAF(name->namlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 		data.leaf.tid = tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 		data.leaf.ip = ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 		n = NDTLEAF_LEGACY(name->namlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 		data.leaf.ip = NULL;	/* signifies legacy directory format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	data.leaf.ino = *fsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	 *	leaf page does not have enough room for new entry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	 *	extend/split the leaf page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	 * dtSplitUp() will insert the entry and unpin the leaf page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	if (n > p->header.freecnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 		split.mp = mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 		split.index = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 		split.nslot = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 		split.key = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 		split.data = &data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 		rc = dtSplitUp(tid, ip, &split, btstack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	 *	leaf page does have enough room for new entry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	 *	insert the new data entry into the leaf page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	BT_MARK_DIRTY(mp, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	 * acquire a transaction lock on the leaf page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	tlck = txLock(tid, ip, mp, tlckDTREE | tlckENTRY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	dtlck = (struct dt_lock *) & tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	ASSERT(dtlck->index == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	lv = & dtlck->lv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	/* linelock header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	lv->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	lv->length = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	dtInsertEntry(p, index, name, &data, &dtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	/* linelock stbl of non-root leaf page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 	if (!(p->header.flag & BT_ROOT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 		if (dtlck->index >= dtlck->maxcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 			dtlck = (struct dt_lock *) txLinelock(dtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 		lv = & dtlck->lv[dtlck->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 		n = index >> L2DTSLOTSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 		lv->offset = p->header.stblindex + n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 		lv->length =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 		    ((p->header.nextindex - 1) >> L2DTSLOTSIZE) - n + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 		dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	/* unpin the leaf page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908)  *	dtSplitUp()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910)  * function: propagate insertion bottom up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912)  * parameter:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914)  * return: 0 - success;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915)  *	   errno - failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916)  *	leaf page unpinned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) static int dtSplitUp(tid_t tid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	  struct inode *ip, struct dtsplit * split, struct btstack * btstack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	struct metapage *smp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	dtpage_t *sp;		/* split page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	struct metapage *rmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	dtpage_t *rp;		/* new right page split from sp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	pxd_t rpxd;		/* new right page extent descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	struct metapage *lmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	dtpage_t *lp;		/* left child page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	int skip;		/* index of entry of insertion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	struct btframe *parent;	/* parent page entry on traverse stack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	s64 xaddr, nxaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	int xlen, xsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	struct pxdlist pxdlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	pxd_t *pxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	struct component_name key = { 0, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	ddata_t *data = split->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	struct dt_lock *dtlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	struct tlock *tlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	struct lv *lv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	int quota_allocation = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	/* get split page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	smp = split->mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	sp = DT_PAGE(ip, smp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	key.name = kmalloc_array(JFS_NAME_MAX + 2, sizeof(wchar_t), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	if (!key.name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 		DT_PUTPAGE(smp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 		rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 		goto dtSplitUp_Exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	 *	split leaf page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	 * The split routines insert the new entry, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	 * acquire txLock as appropriate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	 *	split root leaf page:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	if (sp->header.flag & BT_ROOT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 		 * allocate a single extent child page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 		xlen = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 		n = sbi->bsize >> L2DTSLOTSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 		n -= (n + 31) >> L2DTSLOTSIZE;	/* stbl size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 		n -= DTROOTMAXSLOT - sp->header.freecnt; /* header + entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 		if (n <= split->nslot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 			xlen++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 		if ((rc = dbAlloc(ip, 0, (s64) xlen, &xaddr))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 			DT_PUTPAGE(smp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 			goto freeKeyName;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 		pxdlist.maxnpxd = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 		pxdlist.npxd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 		pxd = &pxdlist.pxd[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 		PXDaddress(pxd, xaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 		PXDlength(pxd, xlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 		split->pxdlist = &pxdlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 		rc = dtSplitRoot(tid, ip, split, &rmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 			dbFree(ip, xaddr, xlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 			DT_PUTPAGE(rmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 		DT_PUTPAGE(smp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 		if (!DO_INDEX(ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 			ip->i_size = xlen << sbi->l2bsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 		goto freeKeyName;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	 *	extend first leaf page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	 * extend the 1st extent if less than buffer page size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	 * (dtExtendPage() reurns leaf page unpinned)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	pxd = &sp->header.self;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	xlen = lengthPXD(pxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	xsize = xlen << sbi->l2bsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	if (xsize < PSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 		xaddr = addressPXD(pxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 		n = xsize >> L2DTSLOTSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 		n -= (n + 31) >> L2DTSLOTSIZE;	/* stbl size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 		if ((n + sp->header.freecnt) <= split->nslot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 			n = xlen + (xlen << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 			n = xlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 		/* Allocate blocks to quota. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 		rc = dquot_alloc_block(ip, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 			goto extendOut;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 		quota_allocation += n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 		if ((rc = dbReAlloc(sbi->ipbmap, xaddr, (s64) xlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 				    (s64) n, &nxaddr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 			goto extendOut;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 		pxdlist.maxnpxd = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 		pxdlist.npxd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 		pxd = &pxdlist.pxd[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 		PXDaddress(pxd, nxaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 		PXDlength(pxd, xlen + n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 		split->pxdlist = &pxdlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 		if ((rc = dtExtendPage(tid, ip, split, btstack))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 			nxaddr = addressPXD(pxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 			if (xaddr != nxaddr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 				/* free relocated extent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 				xlen = lengthPXD(pxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 				dbFree(ip, nxaddr, (s64) xlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 				/* free extended delta */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 				xlen = lengthPXD(pxd) - n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 				xaddr = addressPXD(pxd) + xlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 				dbFree(ip, xaddr, (s64) n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 		} else if (!DO_INDEX(ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 			ip->i_size = lengthPXD(pxd) << sbi->l2bsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	      extendOut:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 		DT_PUTPAGE(smp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 		goto freeKeyName;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	 *	split leaf page <sp> into <sp> and a new right page <rp>.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	 * return <rp> pinned and its extent descriptor <rpxd>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	 * allocate new directory page extent and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	 * new index page(s) to cover page split(s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	 * allocation hint: ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	n = btstack->nsplit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	pxdlist.maxnpxd = pxdlist.npxd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	xlen = sbi->nbperpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	for (pxd = pxdlist.pxd; n > 0; n--, pxd++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 		if ((rc = dbAlloc(ip, 0, (s64) xlen, &xaddr)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 			PXDaddress(pxd, xaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 			PXDlength(pxd, xlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 			pxdlist.maxnpxd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 		DT_PUTPAGE(smp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 		/* undo allocation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 		goto splitOut;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	split->pxdlist = &pxdlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	if ((rc = dtSplitPage(tid, ip, split, &rmp, &rp, &rpxd))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 		DT_PUTPAGE(smp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 		/* undo allocation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 		goto splitOut;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	if (!DO_INDEX(ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 		ip->i_size += PSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	 * propagate up the router entry for the leaf page just split
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	 * insert a router entry for the new page into the parent page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	 * propagate the insert/split up the tree by walking back the stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	 * of (bn of parent page, index of child page entry in parent page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	 * that were traversed during the search for the page that split.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	 * the propagation of insert/split up the tree stops if the root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	 * splits or the page inserted into doesn't have to split to hold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	 * the new entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	 * the parent entry for the split page remains the same, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	 * a new entry is inserted at its right with the first key and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	 * block number of the new right page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	 * There are a maximum of 4 pages pinned at any time:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	 * two children, left parent and right parent (when the parent splits).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	 * keep the child pages pinned while working on the parent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	 * make sure that all pins are released at exit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	while ((parent = BT_POP(btstack)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 		/* parent page specified by stack frame <parent> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 		/* keep current child pages (<lp>, <rp>) pinned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 		lmp = smp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 		lp = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 		 * insert router entry in parent for new right child page <rp>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 		/* get the parent page <sp> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 		DT_GETPAGE(ip, parent->bn, smp, PSIZE, sp, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 		if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 			DT_PUTPAGE(lmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 			DT_PUTPAGE(rmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 			goto splitOut;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 		 * The new key entry goes ONE AFTER the index of parent entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 		 * because the split was to the right.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 		skip = parent->index + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 		 * compute the key for the router entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 		 * key suffix compression:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 		 * for internal pages that have leaf pages as children,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 		 * retain only what's needed to distinguish between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 		 * the new entry and the entry on the page to its left.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 		 * If the keys compare equal, retain the entire key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 		 * note that compression is performed only at computing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 		 * router key at the lowest internal level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 		 * further compression of the key between pairs of higher
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 		 * level internal pages loses too much information and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 		 * the search may fail.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 		 * (e.g., two adjacent leaf pages of {a, ..., x} {xx, ...,}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 		 * results in two adjacent parent entries (a)(xx).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 		 * if split occurs between these two entries, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 		 * if compression is applied, the router key of parent entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 		 * of right page (x) will divert search for x into right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 		 * subtree and miss x in the left subtree.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 		 * the entire key must be retained for the next-to-leftmost
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 		 * internal key at any level of the tree, or search may fail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 		 * (e.g., ?)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 		switch (rp->header.flag & BT_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 		case BT_LEAF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 			 * compute the length of prefix for suffix compression
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 			 * between last entry of left page and first entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 			 * of right page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 			if ((sp->header.flag & BT_ROOT && skip > 1) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 			    sp->header.prev != 0 || skip > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 				/* compute uppercase router prefix key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 				rc = ciGetLeafPrefixKey(lp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 							lp->header.nextindex-1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 							rp, 0, &key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 							sbi->mntflag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 				if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 					DT_PUTPAGE(lmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 					DT_PUTPAGE(rmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 					DT_PUTPAGE(smp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 					goto splitOut;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 				/* next to leftmost entry of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 				   lowest internal level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 				/* compute uppercase router key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 				dtGetKey(rp, 0, &key, sbi->mntflag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 				key.name[key.namlen] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 				if ((sbi->mntflag & JFS_OS2) == JFS_OS2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 					ciToUpper(&key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 			n = NDTINTERNAL(key.namlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 		case BT_INTERNAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 			dtGetKey(rp, 0, &key, sbi->mntflag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 			n = NDTINTERNAL(key.namlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 			jfs_err("dtSplitUp(): UFO!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 		/* unpin left child page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 		DT_PUTPAGE(lmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 		 * compute the data for the router entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 		data->xd = rpxd;	/* child page xd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 		 * parent page is full - split the parent page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 		if (n > sp->header.freecnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 			/* init for parent page split */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 			split->mp = smp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 			split->index = skip;	/* index at insert */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 			split->nslot = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 			split->key = &key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 			/* split->data = data; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 			/* unpin right child page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 			DT_PUTPAGE(rmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 			/* The split routines insert the new entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 			 * acquire txLock as appropriate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 			 * return <rp> pinned and its block number <rbn>.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 			rc = (sp->header.flag & BT_ROOT) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 			    dtSplitRoot(tid, ip, split, &rmp) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 			    dtSplitPage(tid, ip, split, &rmp, &rp, &rpxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 			if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 				DT_PUTPAGE(smp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 				goto splitOut;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 			/* smp and rmp are pinned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 		 * parent page is not full - insert router entry in parent page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 			BT_MARK_DIRTY(smp, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 			 * acquire a transaction lock on the parent page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 			tlck = txLock(tid, ip, smp, tlckDTREE | tlckENTRY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 			dtlck = (struct dt_lock *) & tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 			ASSERT(dtlck->index == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 			lv = & dtlck->lv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 			/* linelock header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 			lv->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 			lv->length = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 			dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 			/* linelock stbl of non-root parent page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 			if (!(sp->header.flag & BT_ROOT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 				lv++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 				n = skip >> L2DTSLOTSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 				lv->offset = sp->header.stblindex + n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 				lv->length =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 				    ((sp->header.nextindex -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 				      1) >> L2DTSLOTSIZE) - n + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 				dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 			dtInsertEntry(sp, skip, &key, data, &dtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 			/* exit propagate up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 	/* unpin current split and its right page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	DT_PUTPAGE(smp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	DT_PUTPAGE(rmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 	 * free remaining extents allocated for split
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)       splitOut:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	n = pxdlist.npxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 	pxd = &pxdlist.pxd[n];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 	for (; n < pxdlist.maxnpxd; n++, pxd++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 		dbFree(ip, addressPXD(pxd), (s64) lengthPXD(pxd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294)       freeKeyName:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	kfree(key.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 	/* Rollback quota allocation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 	if (rc && quota_allocation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 		dquot_free_block(ip, quota_allocation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)       dtSplitUp_Exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)  *	dtSplitPage()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)  * function: Split a non-root page of a btree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)  * parameter:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)  * return: 0 - success;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)  *	   errno - failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)  *	return split and new page pinned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 	    struct metapage ** rmpp, dtpage_t ** rpp, pxd_t * rpxdp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	struct metapage *smp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 	dtpage_t *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	struct metapage *rmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	dtpage_t *rp;		/* new right page allocated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 	s64 rbn;		/* new right page block number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	struct metapage *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 	dtpage_t *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 	s64 nextbn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 	struct pxdlist *pxdlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 	pxd_t *pxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 	int skip, nextindex, half, left, nxt, off, si;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 	struct ldtentry *ldtentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 	struct idtentry *idtentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 	u8 *stbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 	struct dtslot *f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 	int fsi, stblsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 	struct dt_lock *sdtlck, *rdtlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 	struct tlock *tlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	struct dt_lock *dtlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	struct lv *slv, *rlv, *lv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 	/* get split page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 	smp = split->mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	sp = DT_PAGE(ip, smp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 	 * allocate the new right page for the split
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	pxdlist = split->pxdlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 	pxd = &pxdlist->pxd[pxdlist->npxd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	pxdlist->npxd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	rbn = addressPXD(pxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	rmp = get_metapage(ip, rbn, PSIZE, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	if (rmp == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	/* Allocate blocks to quota. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 	rc = dquot_alloc_block(ip, lengthPXD(pxd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 	if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 		release_metapage(rmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 	jfs_info("dtSplitPage: ip:0x%p smp:0x%p rmp:0x%p", ip, smp, rmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 	BT_MARK_DIRTY(rmp, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 	 * acquire a transaction lock on the new right page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 	tlck = txLock(tid, ip, rmp, tlckDTREE | tlckNEW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 	rdtlck = (struct dt_lock *) & tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 	rp = (dtpage_t *) rmp->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 	*rpp = rp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 	rp->header.self = *pxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 	BT_MARK_DIRTY(smp, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 	 * acquire a transaction lock on the split page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 	 * action:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 	tlck = txLock(tid, ip, smp, tlckDTREE | tlckENTRY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 	sdtlck = (struct dt_lock *) & tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 	/* linelock header of split page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 	ASSERT(sdtlck->index == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 	slv = & sdtlck->lv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 	slv->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 	slv->length = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 	sdtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 	 * initialize/update sibling pointers between sp and rp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 	nextbn = le64_to_cpu(sp->header.next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 	rp->header.next = cpu_to_le64(nextbn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 	rp->header.prev = cpu_to_le64(addressPXD(&sp->header.self));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 	sp->header.next = cpu_to_le64(rbn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 	 * initialize new right page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 	rp->header.flag = sp->header.flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 	/* compute sorted entry table at start of extent data area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 	rp->header.nextindex = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 	rp->header.stblindex = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 	n = PSIZE >> L2DTSLOTSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 	rp->header.maxslot = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 	stblsize = (n + 31) >> L2DTSLOTSIZE;	/* in unit of slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 	/* init freelist */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 	fsi = rp->header.stblindex + stblsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	rp->header.freelist = fsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	rp->header.freecnt = rp->header.maxslot - fsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 	 *	sequential append at tail: append without split
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	 * If splitting the last page on a level because of appending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 	 * a entry to it (skip is maxentry), it's likely that the access is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 	 * sequential. Adding an empty page on the side of the level is less
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 	 * work and can push the fill factor much higher than normal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 	 * If we're wrong it's no big deal, we'll just do the split the right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 	 * way next time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 	 * (It may look like it's equally easy to do a similar hack for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 	 * reverse sorted data, that is, split the tree left,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 	 * but it's not. Be my guest.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 	if (nextbn == 0 && split->index == sp->header.nextindex) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 		/* linelock header + stbl (first slot) of new page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 		rlv = & rdtlck->lv[rdtlck->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 		rlv->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 		rlv->length = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 		rdtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 		 * initialize freelist of new right page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 		f = &rp->slot[fsi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 		for (fsi++; fsi < rp->header.maxslot; f++, fsi++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 			f->next = fsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 		f->next = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 		/* insert entry at the first entry of the new right page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 		dtInsertEntry(rp, 0, split->key, split->data, &rdtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 	 *	non-sequential insert (at possibly middle page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 	 * update prev pointer of previous right sibling page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 	if (nextbn != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 		DT_GETPAGE(ip, nextbn, mp, PSIZE, p, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 		if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 			discard_metapage(rmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 		BT_MARK_DIRTY(mp, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 		 * acquire a transaction lock on the next page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 		tlck = txLock(tid, ip, mp, tlckDTREE | tlckRELINK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 		jfs_info("dtSplitPage: tlck = 0x%p, ip = 0x%p, mp=0x%p",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 			tlck, ip, mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 		dtlck = (struct dt_lock *) & tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 		/* linelock header of previous right sibling page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 		lv = & dtlck->lv[dtlck->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 		lv->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 		lv->length = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 		dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 		p->header.prev = cpu_to_le64(rbn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 		DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 	 * split the data between the split and right pages.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 	skip = split->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 	half = (PSIZE >> L2DTSLOTSIZE) >> 1;	/* swag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 	left = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 	 *	compute fill factor for split pages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 	 * <nxt> traces the next entry to move to rp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 	 * <off> traces the next entry to stay in sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 	stbl = (u8 *) & sp->slot[sp->header.stblindex];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 	nextindex = sp->header.nextindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 	for (nxt = off = 0; nxt < nextindex; ++off) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 		if (off == skip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 			/* check for fill factor with new entry size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 			n = split->nslot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 			si = stbl[nxt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 			switch (sp->header.flag & BT_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 			case BT_LEAF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 				ldtentry = (struct ldtentry *) & sp->slot[si];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 				if (DO_INDEX(ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 					n = NDTLEAF(ldtentry->namlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 					n = NDTLEAF_LEGACY(ldtentry->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 							   namlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 			case BT_INTERNAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 				idtentry = (struct idtentry *) & sp->slot[si];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 				n = NDTINTERNAL(idtentry->namlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 			default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 			++nxt;	/* advance to next entry to move in sp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 		left += n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 		if (left >= half)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 	/* <nxt> poins to the 1st entry to move */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 	 *	move entries to right page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 	 * dtMoveEntry() initializes rp and reserves entry for insertion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 	 * split page moved out entries are linelocked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 	 * new/right page moved in entries are linelocked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 	/* linelock header + stbl of new right page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 	rlv = & rdtlck->lv[rdtlck->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 	rlv->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 	rlv->length = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 	rdtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 	dtMoveEntry(sp, nxt, rp, &sdtlck, &rdtlck, DO_INDEX(ip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 	sp->header.nextindex = nxt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 	 * finalize freelist of new right page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 	fsi = rp->header.freelist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 	f = &rp->slot[fsi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 	for (fsi++; fsi < rp->header.maxslot; f++, fsi++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 		f->next = fsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 	f->next = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 	 * Update directory index table for entries now in right page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 	if ((rp->header.flag & BT_LEAF) && DO_INDEX(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 		s64 lblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 		mp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 		stbl = DT_GETSTBL(rp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 		for (n = 0; n < rp->header.nextindex; n++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 			ldtentry = (struct ldtentry *) & rp->slot[stbl[n]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 			modify_index(tid, ip, le32_to_cpu(ldtentry->index),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 				     rbn, n, &mp, &lblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 		if (mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 			release_metapage(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 	 * the skipped index was on the left page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 	if (skip <= off) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 		/* insert the new entry in the split page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 		dtInsertEntry(sp, skip, split->key, split->data, &sdtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 		/* linelock stbl of split page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 		if (sdtlck->index >= sdtlck->maxcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 			sdtlck = (struct dt_lock *) txLinelock(sdtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 		slv = & sdtlck->lv[sdtlck->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 		n = skip >> L2DTSLOTSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 		slv->offset = sp->header.stblindex + n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 		slv->length =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 		    ((sp->header.nextindex - 1) >> L2DTSLOTSIZE) - n + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 		sdtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 	 * the skipped index was on the right page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 		/* adjust the skip index to reflect the new position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 		skip -= nxt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 		/* insert the new entry in the right page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 		dtInsertEntry(rp, skip, split->key, split->data, &rdtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611)       out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 	*rmpp = rmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 	*rpxdp = *pxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)  *	dtExtendPage()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622)  * function: extend 1st/only directory leaf page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624)  * parameter:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626)  * return: 0 - success;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627)  *	   errno - failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628)  *	return extended page pinned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) static int dtExtendPage(tid_t tid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 	     struct inode *ip, struct dtsplit * split, struct btstack * btstack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 	struct super_block *sb = ip->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 	struct metapage *smp, *pmp, *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 	dtpage_t *sp, *pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 	struct pxdlist *pxdlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 	pxd_t *pxd, *tpxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 	int xlen, xsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 	int newstblindex, newstblsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 	int oldstblindex, oldstblsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 	int fsi, last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 	struct dtslot *f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 	struct btframe *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 	int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 	struct dt_lock *dtlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 	s64 xaddr, txaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 	struct tlock *tlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 	struct pxd_lock *pxdlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 	struct lv *lv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 	uint type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 	struct ldtentry *ldtentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 	u8 *stbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 	/* get page to extend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 	smp = split->mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 	sp = DT_PAGE(ip, smp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 	/* get parent/root page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 	parent = BT_POP(btstack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 	DT_GETPAGE(ip, parent->bn, pmp, PSIZE, pp, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 		return (rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 	 *	extend the extent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 	pxdlist = split->pxdlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 	pxd = &pxdlist->pxd[pxdlist->npxd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 	pxdlist->npxd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 	xaddr = addressPXD(pxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 	tpxd = &sp->header.self;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 	txaddr = addressPXD(tpxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 	/* in-place extension */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 	if (xaddr == txaddr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 		type = tlckEXTEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 	/* relocation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 		type = tlckNEW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 		/* save moved extent descriptor for later free */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 		tlck = txMaplock(tid, ip, tlckDTREE | tlckRELOCATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 		pxdlock = (struct pxd_lock *) & tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 		pxdlock->flag = mlckFREEPXD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 		pxdlock->pxd = sp->header.self;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 		pxdlock->index = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 		 * Update directory index table to reflect new page address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 		if (DO_INDEX(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 			s64 lblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 			mp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 			stbl = DT_GETSTBL(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 			for (n = 0; n < sp->header.nextindex; n++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 				ldtentry =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 				    (struct ldtentry *) & sp->slot[stbl[n]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 				modify_index(tid, ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 					     le32_to_cpu(ldtentry->index),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 					     xaddr, n, &mp, &lblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 			if (mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 				release_metapage(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 	 *	extend the page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 	sp->header.self = *pxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 	jfs_info("dtExtendPage: ip:0x%p smp:0x%p sp:0x%p", ip, smp, sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 	BT_MARK_DIRTY(smp, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 	 * acquire a transaction lock on the extended/leaf page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 	tlck = txLock(tid, ip, smp, tlckDTREE | type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 	dtlck = (struct dt_lock *) & tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 	lv = & dtlck->lv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 	/* update buffer extent descriptor of extended page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 	xlen = lengthPXD(pxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 	xsize = xlen << JFS_SBI(sb)->l2bsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 	 * copy old stbl to new stbl at start of extended area
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 	oldstblindex = sp->header.stblindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 	oldstblsize = (sp->header.maxslot + 31) >> L2DTSLOTSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 	newstblindex = sp->header.maxslot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 	n = xsize >> L2DTSLOTSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 	newstblsize = (n + 31) >> L2DTSLOTSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 	memcpy(&sp->slot[newstblindex], &sp->slot[oldstblindex],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 	       sp->header.nextindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 	 * in-line extension: linelock old area of extended page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 	if (type == tlckEXTEND) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 		/* linelock header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 		lv->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 		lv->length = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 		dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 		lv++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 		/* linelock new stbl of extended page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 		lv->offset = newstblindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 		lv->length = newstblsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 	 * relocation: linelock whole relocated area
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 		lv->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 		lv->length = sp->header.maxslot + newstblsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 	dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 	sp->header.maxslot = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 	sp->header.stblindex = newstblindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 	/* sp->header.nextindex remains the same */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 	 * add old stbl region at head of freelist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 	fsi = oldstblindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 	f = &sp->slot[fsi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 	last = sp->header.freelist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 	for (n = 0; n < oldstblsize; n++, fsi++, f++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 		f->next = last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 		last = fsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 	sp->header.freelist = last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 	sp->header.freecnt += oldstblsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 	 * append free region of newly extended area at tail of freelist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 	/* init free region of newly extended area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 	fsi = n = newstblindex + newstblsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 	f = &sp->slot[fsi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 	for (fsi++; fsi < sp->header.maxslot; f++, fsi++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 		f->next = fsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 	f->next = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 	/* append new free region at tail of old freelist */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 	fsi = sp->header.freelist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 	if (fsi == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 		sp->header.freelist = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 		do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 			f = &sp->slot[fsi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 			fsi = f->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 		} while (fsi != -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 		f->next = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 	sp->header.freecnt += sp->header.maxslot - n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 	 * insert the new entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 	dtInsertEntry(sp, split->index, split->key, split->data, &dtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 	BT_MARK_DIRTY(pmp, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 	 * linelock any freeslots residing in old extent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 	if (type == tlckEXTEND) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 		n = sp->header.maxslot >> 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 		if (sp->header.freelist < n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 			dtLinelockFreelist(sp, n, &dtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 	 *	update parent entry on the parent/root page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 	 * acquire a transaction lock on the parent/root page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 	tlck = txLock(tid, ip, pmp, tlckDTREE | tlckENTRY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 	dtlck = (struct dt_lock *) & tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 	lv = & dtlck->lv[dtlck->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 	/* linelock parent entry - 1st slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 	lv->offset = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 	lv->length = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 	dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 	/* update the parent pxd for page extension */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 	tpxd = (pxd_t *) & pp->slot[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 	*tpxd = *pxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 	DT_PUTPAGE(pmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846)  *	dtSplitRoot()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848)  * function:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849)  *	split the full root page into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850)  *	original/root/split page and new right page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851)  *	i.e., root remains fixed in tree anchor (inode) and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852)  *	the root is copied to a single new right child page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853)  *	since root page << non-root page, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854)  *	the split root page contains a single entry for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855)  *	new right child page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857)  * parameter:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859)  * return: 0 - success;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860)  *	   errno - failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861)  *	return new page pinned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) static int dtSplitRoot(tid_t tid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 	    struct inode *ip, struct dtsplit * split, struct metapage ** rmpp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 	struct super_block *sb = ip->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 	struct metapage *smp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 	dtroot_t *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 	struct metapage *rmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 	dtpage_t *rp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 	s64 rbn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 	int xlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 	int xsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 	struct dtslot *f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 	s8 *stbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 	int fsi, stblsize, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 	struct idtentry *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 	pxd_t *ppxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 	struct pxdlist *pxdlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 	pxd_t *pxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) 	struct dt_lock *dtlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) 	struct tlock *tlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) 	struct lv *lv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) 	/* get split root page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) 	smp = split->mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 	sp = &JFS_IP(ip)->i_dtroot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 	 *	allocate/initialize a single (right) child page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 	 * N.B. at first split, a one (or two) block to fit new entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 	 * is allocated; at subsequent split, a full page is allocated;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 	pxdlist = split->pxdlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 	pxd = &pxdlist->pxd[pxdlist->npxd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 	pxdlist->npxd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 	rbn = addressPXD(pxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 	xlen = lengthPXD(pxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 	xsize = xlen << JFS_SBI(sb)->l2bsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 	rmp = get_metapage(ip, rbn, xsize, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 	if (!rmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 	rp = rmp->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 	/* Allocate blocks to quota. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 	rc = dquot_alloc_block(ip, lengthPXD(pxd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 	if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 		release_metapage(rmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 	BT_MARK_DIRTY(rmp, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 	 * acquire a transaction lock on the new right page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 	tlck = txLock(tid, ip, rmp, tlckDTREE | tlckNEW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 	dtlck = (struct dt_lock *) & tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 	rp->header.flag =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 	    (sp->header.flag & BT_LEAF) ? BT_LEAF : BT_INTERNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 	rp->header.self = *pxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 	/* initialize sibling pointers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 	rp->header.next = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 	rp->header.prev = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) 	 *	move in-line root page into new right page extent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 	/* linelock header + copied entries + new stbl (1st slot) in new page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 	ASSERT(dtlck->index == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 	lv = & dtlck->lv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 	lv->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 	lv->length = 10;	/* 1 + 8 + 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 	dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 	n = xsize >> L2DTSLOTSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 	rp->header.maxslot = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 	stblsize = (n + 31) >> L2DTSLOTSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 	/* copy old stbl to new stbl at start of extended area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 	rp->header.stblindex = DTROOTMAXSLOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 	stbl = (s8 *) & rp->slot[DTROOTMAXSLOT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 	memcpy(stbl, sp->header.stbl, sp->header.nextindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 	rp->header.nextindex = sp->header.nextindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 	/* copy old data area to start of new data area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 	memcpy(&rp->slot[1], &sp->slot[1], IDATASIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 	 * append free region of newly extended area at tail of freelist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 	/* init free region of newly extended area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 	fsi = n = DTROOTMAXSLOT + stblsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 	f = &rp->slot[fsi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 	for (fsi++; fsi < rp->header.maxslot; f++, fsi++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 		f->next = fsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 	f->next = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 	/* append new free region at tail of old freelist */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 	fsi = sp->header.freelist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 	if (fsi == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 		rp->header.freelist = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 		rp->header.freelist = fsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 		do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 			f = &rp->slot[fsi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 			fsi = f->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 		} while (fsi != -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) 		f->next = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 	rp->header.freecnt = sp->header.freecnt + rp->header.maxslot - n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 	 * Update directory index table for entries now in right page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 	if ((rp->header.flag & BT_LEAF) && DO_INDEX(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 		s64 lblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 		struct metapage *mp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 		struct ldtentry *ldtentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 		stbl = DT_GETSTBL(rp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 		for (n = 0; n < rp->header.nextindex; n++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 			ldtentry = (struct ldtentry *) & rp->slot[stbl[n]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 			modify_index(tid, ip, le32_to_cpu(ldtentry->index),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 				     rbn, n, &mp, &lblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 		if (mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 			release_metapage(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 	 * insert the new entry into the new right/child page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 	 * (skip index in the new right page will not change)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 	dtInsertEntry(rp, split->index, split->key, split->data, &dtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 	 *	reset parent/root page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 	 * set the 1st entry offset to 0, which force the left-most key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 	 * at any level of the tree to be less than any search key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 	 * The btree comparison code guarantees that the left-most key on any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 	 * level of the tree is never used, so it doesn't need to be filled in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) 	BT_MARK_DIRTY(smp, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) 	 * acquire a transaction lock on the root page (in-memory inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 	tlck = txLock(tid, ip, smp, tlckDTREE | tlckNEW | tlckBTROOT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) 	dtlck = (struct dt_lock *) & tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 	/* linelock root */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) 	ASSERT(dtlck->index == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 	lv = & dtlck->lv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 	lv->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 	lv->length = DTROOTMAXSLOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 	dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 	/* update page header of root */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 	if (sp->header.flag & BT_LEAF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 		sp->header.flag &= ~BT_LEAF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 		sp->header.flag |= BT_INTERNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 	/* init the first entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 	s = (struct idtentry *) & sp->slot[DTENTRYSTART];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 	ppxd = (pxd_t *) s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 	*ppxd = *pxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 	s->next = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 	s->namlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 	stbl = sp->header.stbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) 	stbl[0] = DTENTRYSTART;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 	sp->header.nextindex = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 	/* init freelist */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 	fsi = DTENTRYSTART + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) 	f = &sp->slot[fsi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) 	/* init free region of remaining area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) 	for (fsi++; fsi < DTROOTMAXSLOT; f++, fsi++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 		f->next = fsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) 	f->next = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 	sp->header.freelist = DTENTRYSTART + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) 	sp->header.freecnt = DTROOTMAXSLOT - (DTENTRYSTART + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) 	*rmpp = rmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062)  *	dtDelete()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064)  * function: delete the entry(s) referenced by a key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066)  * parameter:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068)  * return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) int dtDelete(tid_t tid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 	 struct inode *ip, struct component_name * key, ino_t * ino, int flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 	s64 bn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 	struct metapage *mp, *imp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 	dtpage_t *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 	int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 	struct btstack btstack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 	struct dt_lock *dtlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 	struct tlock *tlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 	struct lv *lv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 	struct ldtentry *ldtentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) 	u8 *stbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 	u32 table_index, next_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 	struct metapage *nmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) 	dtpage_t *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) 	 *	search for the entry to delete:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 	 * dtSearch() returns (leaf page pinned, index at which to delete).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 	if ((rc = dtSearch(ip, key, ino, &btstack, flag)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 	/* retrieve search result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 	DT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 	 * We need to find put the index of the next entry into the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 	 * directory index table in order to resume a readdir from this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 	 * entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 	if (DO_INDEX(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 		stbl = DT_GETSTBL(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 		ldtentry = (struct ldtentry *) & p->slot[stbl[index]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) 		table_index = le32_to_cpu(ldtentry->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 		if (index == (p->header.nextindex - 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) 			 * Last entry in this leaf page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) 			if ((p->header.flag & BT_ROOT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 			    || (p->header.next == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) 				next_index = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) 				/* Read next leaf page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) 				DT_GETPAGE(ip, le64_to_cpu(p->header.next),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) 					   nmp, PSIZE, np, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) 				if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) 					next_index = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) 				else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) 					stbl = DT_GETSTBL(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) 					ldtentry =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) 					    (struct ldtentry *) & np->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 					    slot[stbl[0]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 					next_index =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) 					    le32_to_cpu(ldtentry->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) 					DT_PUTPAGE(nmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) 			ldtentry =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 			    (struct ldtentry *) & p->slot[stbl[index + 1]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) 			next_index = le32_to_cpu(ldtentry->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 		free_index(tid, ip, table_index, next_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 	 * the leaf page becomes empty, delete the page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 	if (p->header.nextindex == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) 		/* delete empty page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 		rc = dtDeleteUp(tid, ip, mp, p, &btstack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) 	 * the leaf page has other entries remaining:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 	 * delete the entry from the leaf page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 		BT_MARK_DIRTY(mp, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 		 * acquire a transaction lock on the leaf page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) 		tlck = txLock(tid, ip, mp, tlckDTREE | tlckENTRY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 		dtlck = (struct dt_lock *) & tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) 		 * Do not assume that dtlck->index will be zero.  During a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 		 * rename within a directory, this transaction may have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) 		 * modified this page already when adding the new entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) 		/* linelock header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 		if (dtlck->index >= dtlck->maxcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 			dtlck = (struct dt_lock *) txLinelock(dtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 		lv = & dtlck->lv[dtlck->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 		lv->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) 		lv->length = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) 		dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) 		/* linelock stbl of non-root leaf page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 		if (!(p->header.flag & BT_ROOT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 			if (dtlck->index >= dtlck->maxcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 				dtlck = (struct dt_lock *) txLinelock(dtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 			lv = & dtlck->lv[dtlck->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) 			i = index >> L2DTSLOTSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) 			lv->offset = p->header.stblindex + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 			lv->length =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) 			    ((p->header.nextindex - 1) >> L2DTSLOTSIZE) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) 			    i + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) 			dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) 		/* free the leaf entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) 		dtDeleteEntry(p, index, &dtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) 		 * Update directory index table for entries moved in stbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 		if (DO_INDEX(ip) && index < p->header.nextindex) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 			s64 lblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 			imp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 			stbl = DT_GETSTBL(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 			for (i = index; i < p->header.nextindex; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) 				ldtentry =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) 				    (struct ldtentry *) & p->slot[stbl[i]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) 				modify_index(tid, ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) 					     le32_to_cpu(ldtentry->index),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) 					     bn, i, &imp, &lblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 			if (imp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 				release_metapage(imp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) 		DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216)  *	dtDeleteUp()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218)  * function:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219)  *	free empty pages as propagating deletion up the tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221)  * parameter:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223)  * return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) static int dtDeleteUp(tid_t tid, struct inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) 	   struct metapage * fmp, dtpage_t * fp, struct btstack * btstack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) 	struct metapage *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) 	dtpage_t *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 	int index, nextindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) 	int xlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 	struct btframe *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) 	struct dt_lock *dtlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 	struct tlock *tlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 	struct lv *lv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 	struct pxd_lock *pxdlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 	 *	keep the root leaf page which has become empty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 	if (BT_IS_ROOT(fmp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 		 * reset the root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) 		 * dtInitRoot() acquires txlock on the root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 		dtInitRoot(tid, ip, PARENT(ip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 		DT_PUTPAGE(fmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 	 *	free the non-root leaf page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 	 * acquire a transaction lock on the page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 	 * write FREEXTENT|NOREDOPAGE log record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 	 * N.B. linelock is overlaid as freed extent descriptor, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 	 * the buffer page is freed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 	tlck = txMaplock(tid, ip, tlckDTREE | tlckFREE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 	pxdlock = (struct pxd_lock *) & tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 	pxdlock->flag = mlckFREEPXD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) 	pxdlock->pxd = fp->header.self;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) 	pxdlock->index = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) 	/* update sibling pointers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) 	if ((rc = dtRelink(tid, ip, fp))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) 		BT_PUTPAGE(fmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) 	xlen = lengthPXD(&fp->header.self);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) 	/* Free quota allocation. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 	dquot_free_block(ip, xlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) 	/* free/invalidate its buffer page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) 	discard_metapage(fmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 	 *	propagate page deletion up the directory tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 	 * If the delete from the parent page makes it empty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 	 * continue all the way up the tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 	 * stop if the root page is reached (which is never deleted) or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 	 * if the entry deletion does not empty the page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 	while ((parent = BT_POP(btstack)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 		/* pin the parent page <sp> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 		DT_GETPAGE(ip, parent->bn, mp, PSIZE, p, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 		 * free the extent of the child page deleted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 		index = parent->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 		 * delete the entry for the child page from parent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) 		nextindex = p->header.nextindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) 		 * the parent has the single entry being deleted:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 		 * free the parent page which has become empty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 		if (nextindex == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 			 * keep the root internal page which has become empty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 			if (p->header.flag & BT_ROOT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 				 * reset the root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 				 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 				 * dtInitRoot() acquires txlock on the root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 				dtInitRoot(tid, ip, PARENT(ip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 				DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 			 * free the parent page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) 				 * acquire a transaction lock on the page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 				 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 				 * write FREEXTENT|NOREDOPAGE log record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 				tlck =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 				    txMaplock(tid, ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 					      tlckDTREE | tlckFREE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 				pxdlock = (struct pxd_lock *) & tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 				pxdlock->flag = mlckFREEPXD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 				pxdlock->pxd = p->header.self;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 				pxdlock->index = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 				/* update sibling pointers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 				if ((rc = dtRelink(tid, ip, p))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 					DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) 					return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 				xlen = lengthPXD(&p->header.self);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 				/* Free quota allocation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 				dquot_free_block(ip, xlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 				/* free/invalidate its buffer page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 				discard_metapage(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 				/* propagate up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 		 * the parent has other entries remaining:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 		 * delete the router entry from the parent page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 		BT_MARK_DIRTY(mp, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 		 * acquire a transaction lock on the page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 		 * action: router entry deletion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 		tlck = txLock(tid, ip, mp, tlckDTREE | tlckENTRY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 		dtlck = (struct dt_lock *) & tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 		/* linelock header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 		if (dtlck->index >= dtlck->maxcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 			dtlck = (struct dt_lock *) txLinelock(dtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 		lv = & dtlck->lv[dtlck->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 		lv->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) 		lv->length = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 		dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 		/* linelock stbl of non-root leaf page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) 		if (!(p->header.flag & BT_ROOT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 			if (dtlck->index < dtlck->maxcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 				lv++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 				dtlck = (struct dt_lock *) txLinelock(dtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) 				lv = & dtlck->lv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) 			i = index >> L2DTSLOTSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) 			lv->offset = p->header.stblindex + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) 			lv->length =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) 			    ((p->header.nextindex - 1) >> L2DTSLOTSIZE) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 			    i + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) 			dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) 		/* free the router entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) 		dtDeleteEntry(p, index, &dtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 		/* reset key of new leftmost entry of level (for consistency) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 		if (index == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 		    ((p->header.flag & BT_ROOT) || p->header.prev == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 			dtTruncateEntry(p, 0, &dtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) 		/* unpin the parent page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 		DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 		/* exit propagation up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 	if (!DO_INDEX(ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 		ip->i_size -= PSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) #ifdef _NOTYET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428)  * NAME:	dtRelocate()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430)  * FUNCTION:	relocate dtpage (internal or leaf) of directory;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431)  *		This function is mainly used by defragfs utility.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) 	       s64 nxaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 	struct metapage *mp, *pmp, *lmp, *rmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 	dtpage_t *p, *pp, *rp = 0, *lp= 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 	s64 bn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 	int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 	struct btstack btstack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) 	pxd_t *pxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 	s64 oxaddr, nextbn, prevbn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) 	int xlen, xsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) 	struct tlock *tlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) 	struct dt_lock *dtlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) 	struct pxd_lock *pxdlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) 	s8 *stbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) 	struct lv *lv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) 	oxaddr = addressPXD(opxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) 	xlen = lengthPXD(opxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 	jfs_info("dtRelocate: lmxaddr:%Ld xaddr:%Ld:%Ld xlen:%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 		   (long long)lmxaddr, (long long)oxaddr, (long long)nxaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 		   xlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) 	 *	1. get the internal parent dtpage covering
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 	 *	router entry for the tartget page to be relocated;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) 	rc = dtSearchNode(ip, lmxaddr, opxd, &btstack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 	/* retrieve search result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 	DT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 	jfs_info("dtRelocate: parent router entry validated.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) 	 *	2. relocate the target dtpage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) 	/* read in the target page from src extent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 	DT_GETPAGE(ip, oxaddr, mp, PSIZE, p, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 	if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 		/* release the pinned parent page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) 		DT_PUTPAGE(pmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 	 * read in sibling pages if any to update sibling pointers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 	rmp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) 	if (p->header.next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 		nextbn = le64_to_cpu(p->header.next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) 		DT_GETPAGE(ip, nextbn, rmp, PSIZE, rp, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) 		if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) 			DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) 			DT_PUTPAGE(pmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) 			return (rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 	lmp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 	if (p->header.prev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) 		prevbn = le64_to_cpu(p->header.prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) 		DT_GETPAGE(ip, prevbn, lmp, PSIZE, lp, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) 		if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) 			DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 			DT_PUTPAGE(pmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) 			if (rmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 				DT_PUTPAGE(rmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 			return (rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 	/* at this point, all xtpages to be updated are in memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) 	 * update sibling pointers of sibling dtpages if any;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 	if (lmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) 		tlck = txLock(tid, ip, lmp, tlckDTREE | tlckRELINK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 		dtlck = (struct dt_lock *) & tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) 		/* linelock header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 		ASSERT(dtlck->index == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) 		lv = & dtlck->lv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) 		lv->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) 		lv->length = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 		dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 		lp->header.next = cpu_to_le64(nxaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 		DT_PUTPAGE(lmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) 	if (rmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 		tlck = txLock(tid, ip, rmp, tlckDTREE | tlckRELINK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 		dtlck = (struct dt_lock *) & tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 		/* linelock header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 		ASSERT(dtlck->index == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 		lv = & dtlck->lv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 		lv->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) 		lv->length = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 		dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 		rp->header.prev = cpu_to_le64(nxaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 		DT_PUTPAGE(rmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) 	 * update the target dtpage to be relocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 	 * write LOG_REDOPAGE of LOG_NEW type for dst page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) 	 * for the whole target page (logredo() will apply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) 	 * after image and update bmap for allocation of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) 	 * dst extent), and update bmap for allocation of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 	 * the dst extent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 	tlck = txLock(tid, ip, mp, tlckDTREE | tlckNEW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) 	dtlck = (struct dt_lock *) & tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 	/* linelock header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 	ASSERT(dtlck->index == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) 	lv = & dtlck->lv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 	/* update the self address in the dtpage header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 	pxd = &p->header.self;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) 	PXDaddress(pxd, nxaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 	/* the dst page is the same as the src page, i.e.,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) 	 * linelock for afterimage of the whole page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) 	lv->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 	lv->length = p->header.maxslot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 	dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 	/* update the buffer extent descriptor of the dtpage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) 	xsize = xlen << JFS_SBI(ip->i_sb)->l2bsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) 	/* unpin the relocated page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) 	DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) 	jfs_info("dtRelocate: target dtpage relocated.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) 	/* the moved extent is dtpage, then a LOG_NOREDOPAGE log rec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) 	 * needs to be written (in logredo(), the LOG_NOREDOPAGE log rec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) 	 * will also force a bmap update ).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) 	 *	3. acquire maplock for the source extent to be freed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) 	/* for dtpage relocation, write a LOG_NOREDOPAGE record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) 	 * for the source dtpage (logredo() will init NoRedoPage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 	 * filter and will also update bmap for free of the source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) 	 * dtpage), and upadte bmap for free of the source dtpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) 	tlck = txMaplock(tid, ip, tlckDTREE | tlckFREE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) 	pxdlock = (struct pxd_lock *) & tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) 	pxdlock->flag = mlckFREEPXD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) 	PXDaddress(&pxdlock->pxd, oxaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) 	PXDlength(&pxdlock->pxd, xlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) 	pxdlock->index = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) 	 *	4. update the parent router entry for relocation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) 	 * acquire tlck for the parent entry covering the target dtpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) 	 * write LOG_REDOPAGE to apply after image only;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) 	jfs_info("dtRelocate: update parent router entry.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 	tlck = txLock(tid, ip, pmp, tlckDTREE | tlckENTRY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) 	dtlck = (struct dt_lock *) & tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 	lv = & dtlck->lv[dtlck->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) 	/* update the PXD with the new address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) 	stbl = DT_GETSTBL(pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) 	pxd = (pxd_t *) & pp->slot[stbl[index]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) 	PXDaddress(pxd, nxaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) 	lv->offset = stbl[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) 	lv->length = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) 	dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) 	/* unpin the parent dtpage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) 	DT_PUTPAGE(pmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620)  * NAME:	dtSearchNode()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622)  * FUNCTION:	Search for an dtpage containing a specified address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623)  *		This function is mainly used by defragfs utility.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625)  * NOTE:	Search result on stack, the found page is pinned at exit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626)  *		The result page must be an internal dtpage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627)  *		lmxaddr give the address of the left most page of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628)  *		dtree level, in which the required dtpage resides.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) static int dtSearchNode(struct inode *ip, s64 lmxaddr, pxd_t * kpxd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) 			struct btstack * btstack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) 	s64 bn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 	struct metapage *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) 	dtpage_t *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) 	int psize = 288;	/* initial in-line directory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) 	s8 *stbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) 	pxd_t *pxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) 	struct btframe *btsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) 	BT_CLR(btstack);	/* reset stack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) 	 *	descend tree to the level with specified leftmost page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) 	 *  by convention, root bn = 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) 	for (bn = 0;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) 		/* get/pin the page to search */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) 		DT_GETPAGE(ip, bn, mp, psize, p, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) 		/* does the xaddr of leftmost page of the levevl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) 		 * matches levevl search key ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) 		if (p->header.flag & BT_ROOT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) 			if (lmxaddr == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) 		} else if (addressPXD(&p->header.self) == lmxaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) 		 * descend down to leftmost child page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) 		if (p->header.flag & BT_LEAF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) 			DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) 			return -ESTALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 		/* get the leftmost entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 		stbl = DT_GETSTBL(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) 		pxd = (pxd_t *) & p->slot[stbl[0]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 		/* get the child page block address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 		bn = addressPXD(pxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 		psize = lengthPXD(pxd) << JFS_SBI(ip->i_sb)->l2bsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) 		/* unpin the parent page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) 		DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) 	 *	search each page at the current levevl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687)       loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) 	stbl = DT_GETSTBL(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) 	for (i = 0; i < p->header.nextindex; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) 		pxd = (pxd_t *) & p->slot[stbl[i]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 		/* found the specified router entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) 		if (addressPXD(pxd) == addressPXD(kpxd) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) 		    lengthPXD(pxd) == lengthPXD(kpxd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 			btsp = btstack->top;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) 			btsp->bn = bn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) 			btsp->index = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) 			btsp->mp = mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) 	/* get the right sibling page if any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) 	if (p->header.next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) 		bn = le64_to_cpu(p->header.next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) 		DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) 		return -ESTALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) 	/* unpin current page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) 	DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) 	/* get the right sibling page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) 	DT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) 	goto loop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) #endif /* _NOTYET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725)  *	dtRelink()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727)  * function:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728)  *	link around a freed page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730)  * parameter:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731)  *	fp:	page to be freed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733)  * return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) static int dtRelink(tid_t tid, struct inode *ip, dtpage_t * p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) 	struct metapage *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) 	s64 nextbn, prevbn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) 	struct tlock *tlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) 	struct dt_lock *dtlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) 	struct lv *lv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) 	nextbn = le64_to_cpu(p->header.next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) 	prevbn = le64_to_cpu(p->header.prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) 	/* update prev pointer of the next page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) 	if (nextbn != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) 		DT_GETPAGE(ip, nextbn, mp, PSIZE, p, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) 		BT_MARK_DIRTY(mp, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) 		 * acquire a transaction lock on the next page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) 		 * action: update prev pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) 		tlck = txLock(tid, ip, mp, tlckDTREE | tlckRELINK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) 		jfs_info("dtRelink nextbn: tlck = 0x%p, ip = 0x%p, mp=0x%p",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) 			tlck, ip, mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) 		dtlck = (struct dt_lock *) & tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) 		/* linelock header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) 		if (dtlck->index >= dtlck->maxcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) 			dtlck = (struct dt_lock *) txLinelock(dtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) 		lv = & dtlck->lv[dtlck->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) 		lv->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) 		lv->length = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) 		dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) 		p->header.prev = cpu_to_le64(prevbn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) 		DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) 	/* update next pointer of the previous page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) 	if (prevbn != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) 		DT_GETPAGE(ip, prevbn, mp, PSIZE, p, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 		BT_MARK_DIRTY(mp, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 		 * acquire a transaction lock on the prev page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) 		 * action: update next pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) 		tlck = txLock(tid, ip, mp, tlckDTREE | tlckRELINK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) 		jfs_info("dtRelink prevbn: tlck = 0x%p, ip = 0x%p, mp=0x%p",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) 			tlck, ip, mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) 		dtlck = (struct dt_lock *) & tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) 		/* linelock header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) 		if (dtlck->index >= dtlck->maxcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) 			dtlck = (struct dt_lock *) txLinelock(dtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) 		lv = & dtlck->lv[dtlck->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) 		lv->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) 		lv->length = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) 		dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) 		p->header.next = cpu_to_le64(nextbn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) 		DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810)  *	dtInitRoot()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812)  * initialize directory root (inline in inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) void dtInitRoot(tid_t tid, struct inode *ip, u32 idotdot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) 	struct jfs_inode_info *jfs_ip = JFS_IP(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) 	dtroot_t *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) 	int fsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) 	struct dtslot *f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) 	struct tlock *tlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) 	struct dt_lock *dtlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) 	struct lv *lv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) 	u16 xflag_save;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) 	 * If this was previously an non-empty directory, we need to remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) 	 * the old directory table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) 	if (DO_INDEX(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) 		if (!jfs_dirtable_inline(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) 			struct tblock *tblk = tid_to_tblock(tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) 			 * We're playing games with the tid's xflag.  If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) 			 * we're removing a regular file, the file's xtree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) 			 * is committed with COMMIT_PMAP, but we always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) 			 * commit the directories xtree with COMMIT_PWMAP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) 			xflag_save = tblk->xflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) 			tblk->xflag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) 			 * xtTruncate isn't guaranteed to fully truncate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) 			 * the xtree.  The caller needs to check i_size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) 			 * after committing the transaction to see if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) 			 * additional truncation is needed.  The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) 			 * COMMIT_Stale flag tells caller that we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) 			 * initiated the truncation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 			xtTruncate(tid, ip, 0, COMMIT_PWMAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) 			set_cflag(COMMIT_Stale, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) 			tblk->xflag = xflag_save;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) 			ip->i_size = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) 		jfs_ip->next_index = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) 		ip->i_size = IDATASIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) 	 * acquire a transaction lock on the root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) 	 * action: directory initialization;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) 	tlck = txLock(tid, ip, (struct metapage *) & jfs_ip->bxflag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) 		      tlckDTREE | tlckENTRY | tlckBTROOT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) 	dtlck = (struct dt_lock *) & tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) 	/* linelock root */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) 	ASSERT(dtlck->index == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) 	lv = & dtlck->lv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) 	lv->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) 	lv->length = DTROOTMAXSLOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) 	dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) 	p = &jfs_ip->i_dtroot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) 	p->header.flag = DXD_INDEX | BT_ROOT | BT_LEAF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) 	p->header.nextindex = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) 	/* init freelist */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) 	fsi = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) 	f = &p->slot[fsi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) 	/* init data area of root */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) 	for (fsi++; fsi < DTROOTMAXSLOT; f++, fsi++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) 		f->next = fsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 	f->next = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) 	p->header.freelist = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) 	p->header.freecnt = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) 	/* init '..' entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) 	p->header.idotdot = cpu_to_le32(idotdot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900)  *	add_missing_indices()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902)  * function: Fix dtree page in which one or more entries has an invalid index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903)  *	     fsck.jfs should really fix this, but it currently does not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904)  *	     Called from jfs_readdir when bad index is detected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) static void add_missing_indices(struct inode *inode, s64 bn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) 	struct ldtentry *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) 	struct dt_lock *dtlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) 	uint index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) 	struct lv *lv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) 	struct metapage *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) 	dtpage_t *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) 	s8 *stbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) 	tid_t tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) 	struct tlock *tlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) 	tid = txBegin(inode->i_sb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) 	DT_GETPAGE(inode, bn, mp, PSIZE, p, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) 	if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) 		printk(KERN_ERR "DT_GETPAGE failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) 		goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) 	BT_MARK_DIRTY(mp, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) 	ASSERT(p->header.flag & BT_LEAF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) 	tlck = txLock(tid, inode, mp, tlckDTREE | tlckENTRY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) 	if (BT_IS_ROOT(mp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) 		tlck->type |= tlckBTROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) 	dtlck = (struct dt_lock *) &tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) 	stbl = DT_GETSTBL(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) 	for (i = 0; i < p->header.nextindex; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) 		d = (struct ldtentry *) &p->slot[stbl[i]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) 		index = le32_to_cpu(d->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) 		if ((index < 2) || (index >= JFS_IP(inode)->next_index)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) 			d->index = cpu_to_le32(add_index(tid, inode, bn, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) 			if (dtlck->index >= dtlck->maxcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) 				dtlck = (struct dt_lock *) txLinelock(dtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) 			lv = &dtlck->lv[dtlck->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) 			lv->offset = stbl[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) 			lv->length = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) 			dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) 	DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) 	(void) txCommit(tid, 1, &inode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) 	txEnd(tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960)  * Buffer to hold directory entry info while traversing a dtree page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961)  * before being fed to the filldir function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) struct jfs_dirent {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) 	loff_t position;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) 	int ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) 	u16 name_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) 	char name[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971)  * function to determine next variable-sized jfs_dirent in buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) static inline struct jfs_dirent *next_jfs_dirent(struct jfs_dirent *dirent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) 	return (struct jfs_dirent *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) 		((char *)dirent +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) 		 ((sizeof (struct jfs_dirent) + dirent->name_len + 1 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) 		   sizeof (loff_t) - 1) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) 		  ~(sizeof (loff_t) - 1)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983)  *	jfs_readdir()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985)  * function: read directory entries sequentially
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986)  *	from the specified entry offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988)  * parameter:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990)  * return: offset = (pn, index) of start entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991)  *	of next jfs_readdir()/dtRead()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) int jfs_readdir(struct file *file, struct dir_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) 	struct inode *ip = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) 	struct nls_table *codepage = JFS_SBI(ip->i_sb)->nls_tab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) 	loff_t dtpos;	/* legacy OS/2 style position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) 	struct dtoffset {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) 		s16 pn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) 		s16 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) 		s32 unused;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) 	} *dtoffset = (struct dtoffset *) &dtpos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) 	s64 bn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) 	struct metapage *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) 	dtpage_t *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) 	int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) 	s8 *stbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) 	struct btstack btstack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) 	int i, next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) 	struct ldtentry *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) 	struct dtslot *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) 	int d_namleft, len, outlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) 	unsigned long dirent_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) 	char *name_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) 	u32 dir_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) 	int do_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) 	uint loop_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) 	struct jfs_dirent *jfs_dirent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) 	int jfs_dirents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) 	int overflow, fix_page, page_fixed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) 	static int unique_pos = 2;	/* If we can't fix broken index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) 	if (ctx->pos == DIREND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) 	if (DO_INDEX(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) 		 * persistent index is stored in directory entries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) 		 * Special cases:	 0 = .
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) 		 *			 1 = ..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) 		 *			-1 = End of directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) 		do_index = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) 		dir_index = (u32) ctx->pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) 		 * NFSv4 reserves cookies 1 and 2 for . and .. so the value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) 		 * we return to the vfs is one greater than the one we use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) 		 * internally.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) 		if (dir_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) 			dir_index--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) 		if (dir_index > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) 			struct dir_table_slot dirtab_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) 			if (dtEmpty(ip) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) 			    (dir_index >= JFS_IP(ip)->next_index)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) 				/* Stale position.  Directory has shrunk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) 				ctx->pos = DIREND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) 		      repeat:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) 			rc = read_index(ip, dir_index, &dirtab_slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) 			if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) 				ctx->pos = DIREND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) 				return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) 			if (dirtab_slot.flag == DIR_INDEX_FREE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) 				if (loop_count++ > JFS_IP(ip)->next_index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) 					jfs_err("jfs_readdir detected infinite loop!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) 					ctx->pos = DIREND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) 					return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) 				dir_index = le32_to_cpu(dirtab_slot.addr2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) 				if (dir_index == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) 					ctx->pos = DIREND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) 					return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) 				goto repeat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) 			bn = addressDTS(&dirtab_slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) 			index = dirtab_slot.slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) 			DT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) 			if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) 				ctx->pos = DIREND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) 			if (p->header.flag & BT_INTERNAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) 				jfs_err("jfs_readdir: bad index table");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) 				DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) 				ctx->pos = DIREND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) 			if (dir_index == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) 				 * self "."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) 				ctx->pos = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) 				if (!dir_emit(ctx, ".", 1, ip->i_ino, DT_DIR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) 					return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) 			 * parent ".."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) 			ctx->pos = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) 			if (!dir_emit(ctx, "..", 2, PARENT(ip), DT_DIR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) 			 * Find first entry of left-most leaf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) 			if (dtEmpty(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) 				ctx->pos = DIREND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) 			if ((rc = dtReadFirst(ip, &btstack)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) 				return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) 			DT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) 		 * Legacy filesystem - OS/2 & Linux JFS < 0.3.6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) 		 * pn = 0; index = 1:	First entry "."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) 		 * pn = 0; index = 2:	Second entry ".."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) 		 * pn > 0:		Real entries, pn=1 -> leftmost page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) 		 * pn = index = -1:	No more entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) 		dtpos = ctx->pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) 		if (dtpos < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) 			/* build "." entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) 			ctx->pos = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) 			if (!dir_emit(ctx, ".", 1, ip->i_ino, DT_DIR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) 			dtoffset->index = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) 			ctx->pos = dtpos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) 		if (dtoffset->pn == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) 			if (dtoffset->index == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) 				/* build ".." entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) 				if (!dir_emit(ctx, "..", 2, PARENT(ip), DT_DIR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) 					return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) 				jfs_err("jfs_readdir called with invalid offset!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) 			dtoffset->pn = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) 			dtoffset->index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) 			ctx->pos = dtpos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) 		if (dtEmpty(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) 			ctx->pos = DIREND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) 		if ((rc = dtReadNext(ip, &ctx->pos, &btstack))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) 			jfs_err("jfs_readdir: unexpected rc = %d from dtReadNext",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) 				rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) 			ctx->pos = DIREND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) 		/* get start leaf page and index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) 		DT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) 		/* offset beyond directory eof ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) 		if (bn < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) 			ctx->pos = DIREND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) 	dirent_buf = __get_free_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) 	if (dirent_buf == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) 		DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) 		jfs_warn("jfs_readdir: __get_free_page failed!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) 		ctx->pos = DIREND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) 		jfs_dirent = (struct jfs_dirent *) dirent_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) 		jfs_dirents = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) 		overflow = fix_page = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) 		stbl = DT_GETSTBL(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) 		for (i = index; i < p->header.nextindex; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) 			d = (struct ldtentry *) & p->slot[stbl[i]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) 			if (((long) jfs_dirent + d->namlen + 1) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) 			    (dirent_buf + PAGE_SIZE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) 				/* DBCS codepages could overrun dirent_buf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) 				index = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) 				overflow = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) 			d_namleft = d->namlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) 			name_ptr = jfs_dirent->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) 			jfs_dirent->ino = le32_to_cpu(d->inumber);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) 			if (do_index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) 				len = min(d_namleft, DTLHDRDATALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) 				jfs_dirent->position = le32_to_cpu(d->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) 				 * d->index should always be valid, but it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) 				 * isn't.  fsck.jfs doesn't create the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) 				 * directory index for the lost+found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) 				 * directory.  Rather than let it go,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) 				 * we can try to fix it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) 				if ((jfs_dirent->position < 2) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) 				    (jfs_dirent->position >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) 				     JFS_IP(ip)->next_index)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) 					if (!page_fixed && !isReadOnly(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) 						fix_page = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) 						/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) 						 * setting overflow and setting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) 						 * index to i will cause the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) 						 * same page to be processed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) 						 * again starting here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) 						 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) 						overflow = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) 						index = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) 						break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) 					jfs_dirent->position = unique_pos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) 				 * We add 1 to the index because we may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) 				 * use a value of 2 internally, and NFSv4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) 				 * doesn't like that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) 				jfs_dirent->position++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) 				jfs_dirent->position = dtpos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) 				len = min(d_namleft, DTLHDRDATALEN_LEGACY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) 			/* copy the name of head/only segment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) 			outlen = jfs_strfromUCS_le(name_ptr, d->name, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) 						   codepage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) 			jfs_dirent->name_len = outlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) 			/* copy name in the additional segment(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) 			next = d->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) 			while (next >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) 				t = (struct dtslot *) & p->slot[next];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) 				name_ptr += outlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) 				d_namleft -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) 				/* Sanity Check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) 				if (d_namleft == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) 					jfs_error(ip->i_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) 						  "JFS:Dtree error: ino = %ld, bn=%lld, index = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) 						  (long)ip->i_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) 						  (long long)bn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) 						  i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) 					goto skip_one;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) 				len = min(d_namleft, DTSLOTDATALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) 				outlen = jfs_strfromUCS_le(name_ptr, t->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) 							   len, codepage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) 				jfs_dirent->name_len += outlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) 				next = t->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) 			jfs_dirents++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) 			jfs_dirent = next_jfs_dirent(jfs_dirent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) skip_one:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) 			if (!do_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) 				dtoffset->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) 		if (!overflow) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) 			/* Point to next leaf page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) 			if (p->header.flag & BT_ROOT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) 				bn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) 				bn = le64_to_cpu(p->header.next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) 				index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) 				/* update offset (pn:index) for new page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) 				if (!do_index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) 					dtoffset->pn++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) 					dtoffset->index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) 			page_fixed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) 		/* unpin previous leaf page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) 		DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) 		jfs_dirent = (struct jfs_dirent *) dirent_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) 		while (jfs_dirents--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) 			ctx->pos = jfs_dirent->position;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) 			if (!dir_emit(ctx, jfs_dirent->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) 				    jfs_dirent->name_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) 				    jfs_dirent->ino, DT_UNKNOWN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) 			jfs_dirent = next_jfs_dirent(jfs_dirent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) 		if (fix_page) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) 			add_missing_indices(ip, bn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) 			page_fixed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) 		if (!overflow && (bn == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) 			ctx->pos = DIREND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) 		DT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) 		if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) 			free_page(dirent_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318)       out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) 	free_page(dirent_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326)  *	dtReadFirst()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328)  * function: get the leftmost page of the directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) static int dtReadFirst(struct inode *ip, struct btstack * btstack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) 	s64 bn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) 	int psize = 288;	/* initial in-line directory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) 	struct metapage *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) 	dtpage_t *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) 	s8 *stbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) 	struct btframe *btsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) 	pxd_t *xd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) 	BT_CLR(btstack);	/* reset stack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) 	 *	descend leftmost path of the tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) 	 * by convention, root bn = 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) 	for (bn = 0;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) 		DT_GETPAGE(ip, bn, mp, psize, p, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) 		 * leftmost leaf page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) 		if (p->header.flag & BT_LEAF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) 			/* return leftmost entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) 			btsp = btstack->top;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) 			btsp->bn = bn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) 			btsp->index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) 			btsp->mp = mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) 		 * descend down to leftmost child page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) 		if (BT_STACK_FULL(btstack)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) 			DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) 			jfs_error(ip->i_sb, "btstack overrun\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) 			BT_STACK_DUMP(btstack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) 			return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) 		/* push (bn, index) of the parent page/entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) 		BT_PUSH(btstack, bn, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) 		/* get the leftmost entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) 		stbl = DT_GETSTBL(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) 		xd = (pxd_t *) & p->slot[stbl[0]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) 		/* get the child page block address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) 		bn = addressPXD(xd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) 		psize = lengthPXD(xd) << JFS_SBI(ip->i_sb)->l2bsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) 		/* unpin the parent page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) 		DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393)  *	dtReadNext()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395)  * function: get the page of the specified offset (pn:index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397)  * return: if (offset > eof), bn = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399)  * note: if index > nextindex of the target leaf page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400)  * start with 1st entry of next leaf page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) static int dtReadNext(struct inode *ip, loff_t * offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) 		      struct btstack * btstack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) 	struct dtoffset {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) 		s16 pn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) 		s16 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) 		s32 unused;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) 	} *dtoffset = (struct dtoffset *) offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) 	s64 bn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) 	struct metapage *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) 	dtpage_t *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) 	int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) 	int pn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) 	s8 *stbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) 	struct btframe *btsp, *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) 	pxd_t *xd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) 	 * get leftmost leaf page pinned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) 	if ((rc = dtReadFirst(ip, btstack)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) 	/* get leaf page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) 	DT_GETSEARCH(ip, btstack->top, bn, mp, p, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) 	/* get the start offset (pn:index) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) 	pn = dtoffset->pn - 1;	/* Now pn = 0 represents leftmost leaf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) 	index = dtoffset->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) 	/* start at leftmost page ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) 	if (pn == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) 		/* offset beyond eof ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) 		if (index < p->header.nextindex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) 		if (p->header.flag & BT_ROOT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) 			bn = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) 		/* start with 1st entry of next leaf page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) 		dtoffset->pn++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) 		dtoffset->index = index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) 		goto a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) 	/* start at non-leftmost page: scan parent pages for large pn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) 	if (p->header.flag & BT_ROOT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) 		bn = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) 	/* start after next leaf page ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) 	if (pn > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) 		goto b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) 	/* get leaf page pn = 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461)       a:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) 	bn = le64_to_cpu(p->header.next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) 	/* unpin leaf page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) 	DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) 	/* offset beyond eof ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) 	if (bn == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) 		bn = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) 	goto c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) 	 * scan last internal page level to get target leaf page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478)       b:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) 	/* unpin leftmost leaf page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) 	DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) 	/* get left most parent page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) 	btsp = btstack->top;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) 	parent = btsp - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) 	bn = parent->bn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) 	DT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) 	/* scan parent pages at last internal page level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) 	while (pn >= p->header.nextindex) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) 		pn -= p->header.nextindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) 		/* get next parent page address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) 		bn = le64_to_cpu(p->header.next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) 		/* unpin current parent page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) 		DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) 		/* offset beyond eof ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) 		if (bn == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) 			bn = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) 		/* get next parent page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) 		DT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) 		/* update parent page stack frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) 		parent->bn = bn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) 	/* get leaf page address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) 	stbl = DT_GETSTBL(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) 	xd = (pxd_t *) & p->slot[stbl[pn]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) 	bn = addressPXD(xd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) 	/* unpin parent page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) 	DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) 	 * get target leaf page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526)       c:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) 	DT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) 	 * leaf page has been completed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) 	 * start with 1st entry of next leaf page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) 	if (index >= p->header.nextindex) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) 		bn = le64_to_cpu(p->header.next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) 		/* unpin leaf page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) 		DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) 		/* offset beyond eof ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) 		if (bn == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) 			bn = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) 		/* get next leaf page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) 		DT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) 		/* start with 1st entry of next leaf page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) 		dtoffset->pn++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) 		dtoffset->index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557)       out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) 	/* return target leaf page pinned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) 	btsp = btstack->top;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) 	btsp->bn = bn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) 	btsp->index = dtoffset->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) 	btsp->mp = mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569)  *	dtCompare()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571)  * function: compare search key with an internal entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573)  * return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574)  *	< 0 if k is < record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575)  *	= 0 if k is = record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576)  *	> 0 if k is > record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) static int dtCompare(struct component_name * key,	/* search key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) 		     dtpage_t * p,	/* directory page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) 		     int si)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) {				/* entry slot index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) 	wchar_t *kname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) 	__le16 *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) 	int klen, namlen, len, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) 	struct idtentry *ih;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) 	struct dtslot *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) 	 * force the left-most key on internal pages, at any level of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) 	 * the tree, to be less than any search key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) 	 * this obviates having to update the leftmost key on an internal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) 	 * page when the user inserts a new key in the tree smaller than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) 	 * anything that has been stored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) 	 * (? if/when dtSearch() narrows down to 1st entry (index = 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) 	 * at any internal page at any level of the tree,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) 	 * it descends to child of the entry anyway -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) 	 * ? make the entry as min size dummy entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) 	 * if (e->index == 0 && h->prevpg == P_INVALID && !(h->flags & BT_LEAF))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) 	 * return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) 	kname = key->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) 	klen = key->namlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) 	ih = (struct idtentry *) & p->slot[si];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) 	si = ih->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) 	name = ih->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) 	namlen = ih->namlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) 	len = min(namlen, DTIHDRDATALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) 	/* compare with head/only segment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) 	len = min(klen, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) 	if ((rc = UniStrncmp_le(kname, name, len)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) 	klen -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) 	namlen -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) 	/* compare with additional segment(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) 	kname += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) 	while (klen > 0 && namlen > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) 		/* compare with next name segment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) 		t = (struct dtslot *) & p->slot[si];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) 		len = min(namlen, DTSLOTDATALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) 		len = min(klen, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) 		name = t->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) 		if ((rc = UniStrncmp_le(kname, name, len)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) 		klen -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) 		namlen -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) 		kname += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) 		si = t->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) 	return (klen - namlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645)  *	ciCompare()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647)  * function: compare search key with an (leaf/internal) entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649)  * return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650)  *	< 0 if k is < record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651)  *	= 0 if k is = record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652)  *	> 0 if k is > record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) static int ciCompare(struct component_name * key,	/* search key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) 		     dtpage_t * p,	/* directory page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) 		     int si,	/* entry slot index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) 		     int flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) 	wchar_t *kname, x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) 	__le16 *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) 	int klen, namlen, len, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) 	struct ldtentry *lh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) 	struct idtentry *ih;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) 	struct dtslot *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) 	 * force the left-most key on internal pages, at any level of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) 	 * the tree, to be less than any search key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) 	 * this obviates having to update the leftmost key on an internal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) 	 * page when the user inserts a new key in the tree smaller than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) 	 * anything that has been stored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) 	 * (? if/when dtSearch() narrows down to 1st entry (index = 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) 	 * at any internal page at any level of the tree,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) 	 * it descends to child of the entry anyway -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) 	 * ? make the entry as min size dummy entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) 	 * if (e->index == 0 && h->prevpg == P_INVALID && !(h->flags & BT_LEAF))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) 	 * return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) 	kname = key->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) 	klen = key->namlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) 	 * leaf page entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) 	if (p->header.flag & BT_LEAF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) 		lh = (struct ldtentry *) & p->slot[si];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) 		si = lh->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) 		name = lh->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) 		namlen = lh->namlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) 		if (flag & JFS_DIR_INDEX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) 			len = min(namlen, DTLHDRDATALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) 			len = min(namlen, DTLHDRDATALEN_LEGACY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) 	 * internal page entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) 		ih = (struct idtentry *) & p->slot[si];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) 		si = ih->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) 		name = ih->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) 		namlen = ih->namlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) 		len = min(namlen, DTIHDRDATALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) 	/* compare with head/only segment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) 	len = min(klen, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) 	for (i = 0; i < len; i++, kname++, name++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) 		/* only uppercase if case-insensitive support is on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) 		if ((flag & JFS_OS2) == JFS_OS2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) 			x = UniToupper(le16_to_cpu(*name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) 			x = le16_to_cpu(*name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) 		if ((rc = *kname - x))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) 	klen -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) 	namlen -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) 	/* compare with additional segment(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) 	while (klen > 0 && namlen > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) 		/* compare with next name segment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) 		t = (struct dtslot *) & p->slot[si];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) 		len = min(namlen, DTSLOTDATALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) 		len = min(klen, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) 		name = t->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) 		for (i = 0; i < len; i++, kname++, name++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) 			/* only uppercase if case-insensitive support is on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) 			if ((flag & JFS_OS2) == JFS_OS2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) 				x = UniToupper(le16_to_cpu(*name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) 				x = le16_to_cpu(*name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) 			if ((rc = *kname - x))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) 				return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) 		klen -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) 		namlen -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) 		si = t->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) 	return (klen - namlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753)  *	ciGetLeafPrefixKey()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755)  * function: compute prefix of suffix compression
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756)  *	     from two adjacent leaf entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757)  *	     across page boundary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759)  * return: non-zero on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) static int ciGetLeafPrefixKey(dtpage_t * lp, int li, dtpage_t * rp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) 			       int ri, struct component_name * key, int flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) 	int klen, namlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) 	wchar_t *pl, *pr, *kname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) 	struct component_name lkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) 	struct component_name rkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) 	lkey.name = kmalloc_array(JFS_NAME_MAX + 1, sizeof(wchar_t),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) 					GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) 	if (lkey.name == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) 	rkey.name = kmalloc_array(JFS_NAME_MAX + 1, sizeof(wchar_t),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) 					GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) 	if (rkey.name == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) 		kfree(lkey.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) 	/* get left and right key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) 	dtGetKey(lp, li, &lkey, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) 	lkey.name[lkey.namlen] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) 	if ((flag & JFS_OS2) == JFS_OS2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) 		ciToUpper(&lkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) 	dtGetKey(rp, ri, &rkey, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) 	rkey.name[rkey.namlen] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) 	if ((flag & JFS_OS2) == JFS_OS2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) 		ciToUpper(&rkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) 	/* compute prefix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) 	klen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) 	kname = key->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) 	namlen = min(lkey.namlen, rkey.namlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) 	for (pl = lkey.name, pr = rkey.name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) 	     namlen; pl++, pr++, namlen--, klen++, kname++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) 		*kname = *pr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) 		if (*pl != *pr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) 			key->namlen = klen + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) 			goto free_names;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) 	/* l->namlen <= r->namlen since l <= r */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) 	if (lkey.namlen < rkey.namlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) 		*kname = *pr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) 		key->namlen = klen + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) 	} else			/* l->namelen == r->namelen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) 		key->namlen = klen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) free_names:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) 	kfree(lkey.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) 	kfree(rkey.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825)  *	dtGetKey()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827)  * function: get key of the entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) static void dtGetKey(dtpage_t * p, int i,	/* entry index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) 		     struct component_name * key, int flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) 	int si;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) 	s8 *stbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) 	struct ldtentry *lh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) 	struct idtentry *ih;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) 	struct dtslot *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) 	int namlen, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) 	wchar_t *kname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) 	__le16 *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) 	/* get entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) 	stbl = DT_GETSTBL(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) 	si = stbl[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) 	if (p->header.flag & BT_LEAF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) 		lh = (struct ldtentry *) & p->slot[si];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) 		si = lh->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) 		namlen = lh->namlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) 		name = lh->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) 		if (flag & JFS_DIR_INDEX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) 			len = min(namlen, DTLHDRDATALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) 			len = min(namlen, DTLHDRDATALEN_LEGACY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) 		ih = (struct idtentry *) & p->slot[si];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) 		si = ih->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) 		namlen = ih->namlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) 		name = ih->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) 		len = min(namlen, DTIHDRDATALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) 	key->namlen = namlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) 	kname = key->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) 	 * move head/only segment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) 	UniStrncpy_from_le(kname, name, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) 	 * move additional segment(s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) 	while (si >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) 		/* get next segment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) 		t = &p->slot[si];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) 		kname += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) 		namlen -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) 		len = min(namlen, DTSLOTDATALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) 		UniStrncpy_from_le(kname, t->name, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) 		si = t->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886)  *	dtInsertEntry()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888)  * function: allocate free slot(s) and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889)  *	     write a leaf/internal entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891)  * return: entry slot index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) static void dtInsertEntry(dtpage_t * p, int index, struct component_name * key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) 			  ddata_t * data, struct dt_lock ** dtlock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) 	struct dtslot *h, *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) 	struct ldtentry *lh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) 	struct idtentry *ih = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) 	int hsi, fsi, klen, len, nextindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) 	wchar_t *kname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) 	__le16 *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) 	s8 *stbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) 	pxd_t *xd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) 	struct dt_lock *dtlck = *dtlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) 	struct lv *lv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) 	int xsi, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) 	s64 bn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) 	struct metapage *mp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) 	klen = key->namlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) 	kname = key->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) 	/* allocate a free slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) 	hsi = fsi = p->header.freelist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) 	h = &p->slot[fsi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) 	p->header.freelist = h->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) 	--p->header.freecnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) 	/* open new linelock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) 	if (dtlck->index >= dtlck->maxcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) 		dtlck = (struct dt_lock *) txLinelock(dtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) 	lv = & dtlck->lv[dtlck->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) 	lv->offset = hsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) 	/* write head/only segment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) 	if (p->header.flag & BT_LEAF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) 		lh = (struct ldtentry *) h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) 		lh->next = h->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) 		lh->inumber = cpu_to_le32(data->leaf.ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) 		lh->namlen = klen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) 		name = lh->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) 		if (data->leaf.ip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) 			len = min(klen, DTLHDRDATALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) 			if (!(p->header.flag & BT_ROOT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) 				bn = addressPXD(&p->header.self);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) 			lh->index = cpu_to_le32(add_index(data->leaf.tid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) 							  data->leaf.ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) 							  bn, index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) 			len = min(klen, DTLHDRDATALEN_LEGACY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) 		ih = (struct idtentry *) h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) 		ih->next = h->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) 		xd = (pxd_t *) ih;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) 		*xd = data->xd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) 		ih->namlen = klen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) 		name = ih->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) 		len = min(klen, DTIHDRDATALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) 	UniStrncpy_to_le(name, kname, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) 	n = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) 	xsi = hsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) 	/* write additional segment(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) 	t = h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) 	klen -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) 	while (klen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) 		/* get free slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) 		fsi = p->header.freelist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) 		t = &p->slot[fsi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) 		p->header.freelist = t->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) 		--p->header.freecnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) 		/* is next slot contiguous ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) 		if (fsi != xsi + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) 			/* close current linelock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) 			lv->length = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) 			dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) 			/* open new linelock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) 			if (dtlck->index < dtlck->maxcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) 				lv++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) 				dtlck = (struct dt_lock *) txLinelock(dtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) 				lv = & dtlck->lv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) 			lv->offset = fsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) 			n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) 		kname += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) 		len = min(klen, DTSLOTDATALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) 		UniStrncpy_to_le(t->name, kname, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) 		n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) 		xsi = fsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) 		klen -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) 	/* close current linelock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) 	lv->length = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) 	dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) 	*dtlock = dtlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) 	/* terminate last/only segment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) 	if (h == t) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) 		/* single segment entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) 		if (p->header.flag & BT_LEAF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) 			lh->next = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) 			ih->next = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) 		/* multi-segment entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) 		t->next = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) 	/* if insert into middle, shift right succeeding entries in stbl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) 	stbl = DT_GETSTBL(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) 	nextindex = p->header.nextindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) 	if (index < nextindex) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) 		memmove(stbl + index + 1, stbl + index, nextindex - index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) 		if ((p->header.flag & BT_LEAF) && data->leaf.ip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) 			s64 lblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) 			 * Need to update slot number for entries that moved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) 			 * in the stbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) 			mp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) 			for (n = index + 1; n <= nextindex; n++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) 				lh = (struct ldtentry *) & (p->slot[stbl[n]]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) 				modify_index(data->leaf.tid, data->leaf.ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) 					     le32_to_cpu(lh->index), bn, n,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) 					     &mp, &lblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) 			if (mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) 				release_metapage(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) 	stbl[index] = hsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) 	/* advance next available entry index of stbl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) 	++p->header.nextindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044)  *	dtMoveEntry()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046)  * function: move entries from split/left page to new/right page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048)  *	nextindex of dst page and freelist/freecnt of both pages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049)  *	are updated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) static void dtMoveEntry(dtpage_t * sp, int si, dtpage_t * dp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) 			struct dt_lock ** sdtlock, struct dt_lock ** ddtlock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) 			int do_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) 	int ssi, next;		/* src slot index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) 	int di;			/* dst entry index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) 	int dsi;		/* dst slot index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) 	s8 *sstbl, *dstbl;	/* sorted entry table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) 	int snamlen, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) 	struct ldtentry *slh, *dlh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) 	struct idtentry *sih, *dih = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) 	struct dtslot *h, *s, *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) 	struct dt_lock *sdtlck = *sdtlock, *ddtlck = *ddtlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) 	struct lv *slv, *dlv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) 	int xssi, ns, nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) 	int sfsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) 	sstbl = (s8 *) & sp->slot[sp->header.stblindex];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) 	dstbl = (s8 *) & dp->slot[dp->header.stblindex];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) 	dsi = dp->header.freelist;	/* first (whole page) free slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) 	sfsi = sp->header.freelist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) 	/* linelock destination entry slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) 	dlv = & ddtlck->lv[ddtlck->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) 	dlv->offset = dsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) 	/* linelock source entry slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) 	slv = & sdtlck->lv[sdtlck->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) 	slv->offset = sstbl[si];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) 	xssi = slv->offset - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) 	 * move entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) 	ns = nd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) 	for (di = 0; si < sp->header.nextindex; si++, di++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) 		ssi = sstbl[si];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) 		dstbl[di] = dsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) 		/* is next slot contiguous ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) 		if (ssi != xssi + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) 			/* close current linelock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) 			slv->length = ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) 			sdtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) 			/* open new linelock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) 			if (sdtlck->index < sdtlck->maxcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) 				slv++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) 				sdtlck = (struct dt_lock *) txLinelock(sdtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) 				slv = & sdtlck->lv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) 			slv->offset = ssi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) 			ns = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) 		 * move head/only segment of an entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) 		/* get dst slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) 		h = d = &dp->slot[dsi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) 		/* get src slot and move */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) 		s = &sp->slot[ssi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) 		if (sp->header.flag & BT_LEAF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) 			/* get source entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) 			slh = (struct ldtentry *) s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) 			dlh = (struct ldtentry *) h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) 			snamlen = slh->namlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) 			if (do_index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) 				len = min(snamlen, DTLHDRDATALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) 				dlh->index = slh->index; /* little-endian */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) 			} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) 				len = min(snamlen, DTLHDRDATALEN_LEGACY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) 			memcpy(dlh, slh, 6 + len * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) 			next = slh->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) 			/* update dst head/only segment next field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) 			dsi++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) 			dlh->next = dsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) 			sih = (struct idtentry *) s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) 			snamlen = sih->namlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) 			len = min(snamlen, DTIHDRDATALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) 			dih = (struct idtentry *) h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) 			memcpy(dih, sih, 10 + len * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) 			next = sih->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) 			dsi++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) 			dih->next = dsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) 		/* free src head/only segment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) 		s->next = sfsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) 		s->cnt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) 		sfsi = ssi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) 		ns++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) 		nd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) 		xssi = ssi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) 		 * move additional segment(s) of the entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) 		snamlen -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) 		while ((ssi = next) >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) 			/* is next slot contiguous ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) 			if (ssi != xssi + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) 				/* close current linelock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) 				slv->length = ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) 				sdtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) 				/* open new linelock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) 				if (sdtlck->index < sdtlck->maxcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) 					slv++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) 				else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) 					sdtlck =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) 					    (struct dt_lock *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) 					    txLinelock(sdtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) 					slv = & sdtlck->lv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) 				slv->offset = ssi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) 				ns = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) 			/* get next source segment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) 			s = &sp->slot[ssi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) 			/* get next destination free slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) 			d++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) 			len = min(snamlen, DTSLOTDATALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) 			UniStrncpy_le(d->name, s->name, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) 			ns++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) 			nd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) 			xssi = ssi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) 			dsi++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) 			d->next = dsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) 			/* free source segment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) 			next = s->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) 			s->next = sfsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) 			s->cnt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) 			sfsi = ssi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) 			snamlen -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) 		}		/* end while */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) 		/* terminate dst last/only segment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) 		if (h == d) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) 			/* single segment entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) 			if (dp->header.flag & BT_LEAF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) 				dlh->next = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) 				dih->next = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) 			/* multi-segment entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) 			d->next = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) 	}			/* end for */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) 	/* close current linelock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) 	slv->length = ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) 	sdtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) 	*sdtlock = sdtlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225) 	dlv->length = nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) 	ddtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) 	*ddtlock = ddtlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) 	/* update source header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) 	sp->header.freelist = sfsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) 	sp->header.freecnt += nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) 	/* update destination header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) 	dp->header.nextindex = di;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) 	dp->header.freelist = dsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) 	dp->header.freecnt -= nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242)  *	dtDeleteEntry()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244)  * function: free a (leaf/internal) entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246)  * log freelist header, stbl, and each segment slot of entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247)  * (even though last/only segment next field is modified,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248)  * physical image logging requires all segment slots of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249)  * the entry logged to avoid applying previous updates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250)  * to the same slots)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) static void dtDeleteEntry(dtpage_t * p, int fi, struct dt_lock ** dtlock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) 	int fsi;		/* free entry slot index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) 	s8 *stbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) 	struct dtslot *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) 	int si, freecnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) 	struct dt_lock *dtlck = *dtlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) 	struct lv *lv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) 	int xsi, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) 	/* get free entry slot index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) 	stbl = DT_GETSTBL(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) 	fsi = stbl[fi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) 	/* open new linelock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) 	if (dtlck->index >= dtlck->maxcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) 		dtlck = (struct dt_lock *) txLinelock(dtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) 	lv = & dtlck->lv[dtlck->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) 	lv->offset = fsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) 	/* get the head/only segment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) 	t = &p->slot[fsi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) 	if (p->header.flag & BT_LEAF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) 		si = ((struct ldtentry *) t)->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) 		si = ((struct idtentry *) t)->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) 	t->next = si;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) 	t->cnt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) 	n = freecnt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) 	xsi = fsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) 	/* find the last/only segment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) 	while (si >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) 		/* is next slot contiguous ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) 		if (si != xsi + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) 			/* close current linelock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) 			lv->length = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) 			dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) 			/* open new linelock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) 			if (dtlck->index < dtlck->maxcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) 				lv++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) 				dtlck = (struct dt_lock *) txLinelock(dtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) 				lv = & dtlck->lv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) 			lv->offset = si;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302) 			n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305) 		n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) 		xsi = si;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) 		freecnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) 		t = &p->slot[si];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) 		t->cnt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) 		si = t->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314) 	/* close current linelock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) 	lv->length = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) 	dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) 	*dtlock = dtlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) 	/* update freelist */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321) 	t->next = p->header.freelist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) 	p->header.freelist = fsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) 	p->header.freecnt += freecnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) 	/* if delete from middle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) 	 * shift left the succedding entries in the stbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) 	si = p->header.nextindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) 	if (fi < si - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330) 		memmove(&stbl[fi], &stbl[fi + 1], si - fi - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) 	p->header.nextindex--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337)  *	dtTruncateEntry()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339)  * function: truncate a (leaf/internal) entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341)  * log freelist header, stbl, and each segment slot of entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342)  * (even though last/only segment next field is modified,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343)  * physical image logging requires all segment slots of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344)  * the entry logged to avoid applying previous updates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345)  * to the same slots)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) static void dtTruncateEntry(dtpage_t * p, int ti, struct dt_lock ** dtlock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349) 	int tsi;		/* truncate entry slot index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) 	s8 *stbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) 	struct dtslot *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) 	int si, freecnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353) 	struct dt_lock *dtlck = *dtlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) 	struct lv *lv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) 	int fsi, xsi, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) 	/* get free entry slot index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) 	stbl = DT_GETSTBL(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) 	tsi = stbl[ti];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) 	/* open new linelock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) 	if (dtlck->index >= dtlck->maxcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363) 		dtlck = (struct dt_lock *) txLinelock(dtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) 	lv = & dtlck->lv[dtlck->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) 	lv->offset = tsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) 	/* get the head/only segment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) 	t = &p->slot[tsi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370) 	ASSERT(p->header.flag & BT_INTERNAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) 	((struct idtentry *) t)->namlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) 	si = ((struct idtentry *) t)->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373) 	((struct idtentry *) t)->next = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375) 	n = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) 	freecnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) 	fsi = si;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) 	xsi = tsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) 	/* find the last/only segment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381) 	while (si >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382) 		/* is next slot contiguous ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) 		if (si != xsi + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384) 			/* close current linelock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) 			lv->length = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) 			dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) 			/* open new linelock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) 			if (dtlck->index < dtlck->maxcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390) 				lv++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) 				dtlck = (struct dt_lock *) txLinelock(dtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393) 				lv = & dtlck->lv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396) 			lv->offset = si;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) 			n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) 		n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) 		xsi = si;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) 		freecnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404) 		t = &p->slot[si];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) 		t->cnt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) 		si = t->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409) 	/* close current linelock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) 	lv->length = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) 	dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) 	*dtlock = dtlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415) 	/* update freelist */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) 	if (freecnt == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418) 	t->next = p->header.freelist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419) 	p->header.freelist = fsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420) 	p->header.freecnt += freecnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425)  *	dtLinelockFreelist()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427) static void dtLinelockFreelist(dtpage_t * p,	/* directory page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428) 			       int m,	/* max slot index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) 			       struct dt_lock ** dtlock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431) 	int fsi;		/* free entry slot index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432) 	struct dtslot *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) 	int si;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) 	struct dt_lock *dtlck = *dtlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) 	struct lv *lv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436) 	int xsi, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) 	/* get free entry slot index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439) 	fsi = p->header.freelist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) 	/* open new linelock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) 	if (dtlck->index >= dtlck->maxcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443) 		dtlck = (struct dt_lock *) txLinelock(dtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444) 	lv = & dtlck->lv[dtlck->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) 	lv->offset = fsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448) 	n = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) 	xsi = fsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451) 	t = &p->slot[fsi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) 	si = t->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454) 	/* find the last/only segment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) 	while (si < m && si >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456) 		/* is next slot contiguous ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) 		if (si != xsi + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) 			/* close current linelock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) 			lv->length = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) 			dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) 			/* open new linelock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) 			if (dtlck->index < dtlck->maxcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) 				lv++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) 				dtlck = (struct dt_lock *) txLinelock(dtlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) 				lv = & dtlck->lv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) 			lv->offset = si;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) 			n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474) 		n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) 		xsi = si;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) 		t = &p->slot[si];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) 		si = t->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481) 	/* close current linelock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) 	lv->length = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483) 	dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) 	*dtlock = dtlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490)  * NAME: dtModify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492)  * FUNCTION: Modify the inode number part of a directory entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494)  * PARAMETERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495)  *	tid	- Transaction id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496)  *	ip	- Inode of parent directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497)  *	key	- Name of entry to be modified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498)  *	orig_ino	- Original inode number expected in entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499)  *	new_ino	- New inode number to put into entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500)  *	flag	- JFS_RENAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502)  * RETURNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503)  *	-ESTALE	- If entry found does not match orig_ino passed in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504)  *	-ENOENT	- If no entry can be found to match key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505)  *	0	- If successfully modified entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) int dtModify(tid_t tid, struct inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) 	 struct component_name * key, ino_t * orig_ino, ino_t new_ino, int flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511) 	s64 bn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) 	struct metapage *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513) 	dtpage_t *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) 	int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) 	struct btstack btstack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) 	struct tlock *tlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) 	struct dt_lock *dtlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) 	struct lv *lv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) 	s8 *stbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520) 	int entry_si;		/* entry slot index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521) 	struct ldtentry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524) 	 *	search for the entry to modify:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) 	 * dtSearch() returns (leaf page pinned, index at which to modify).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) 	if ((rc = dtSearch(ip, key, orig_ino, &btstack, flag)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531) 	/* retrieve search result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532) 	DT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) 	BT_MARK_DIRTY(mp, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) 	 * acquire a transaction lock on the leaf page of named entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) 	tlck = txLock(tid, ip, mp, tlckDTREE | tlckENTRY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) 	dtlck = (struct dt_lock *) & tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) 	/* get slot index of the entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542) 	stbl = DT_GETSTBL(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543) 	entry_si = stbl[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) 	/* linelock entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) 	ASSERT(dtlck->index == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547) 	lv = & dtlck->lv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548) 	lv->offset = entry_si;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) 	lv->length = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) 	dtlck->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552) 	/* get the head/only segment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553) 	entry = (struct ldtentry *) & p->slot[entry_si];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) 	/* substitute the inode number of the entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) 	entry->inumber = cpu_to_le32(new_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558) 	/* unpin the leaf page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) 	DT_PUTPAGE(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) }