1a59d1b8e05ea (Thomas Gleixner 2019-05-27 08:55:05 +0200 1) // SPDX-License-Identifier: GPL-2.0-or-later
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2) /*
6b6bf51081a27 (Dave Kleikamp 2005-05-04 09:11:49 -0500 3) * Copyright (C) International Business Machines Corp., 2000-2005
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 4) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 5) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 6) * jfs_xtree.c: extent allocation descriptor B+-tree manager
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 7) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 8)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 9) #include <linux/fs.h>
b2e03ca7485ca (Alexey Dobriyan 2008-05-13 08:22:10 -0500 10) #include <linux/module.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 11) #include <linux/quotaops.h>
b2e03ca7485ca (Alexey Dobriyan 2008-05-13 08:22:10 -0500 12) #include <linux/seq_file.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 13) #include "jfs_incore.h"
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 14) #include "jfs_filsys.h"
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 15) #include "jfs_metapage.h"
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 16) #include "jfs_dmap.h"
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 17) #include "jfs_dinode.h"
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 18) #include "jfs_superblock.h"
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 19) #include "jfs_debug.h"
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 20)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 21) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 22) * xtree local flag
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 23) */
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 24) #define XT_INSERT 0x00000001
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 25)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 26) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 27) * xtree key/entry comparison: extent offset
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 28) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 29) * return:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 30) * -1: k < start of extent
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 31) * 0: start_of_extent <= k <= end_of_extent
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 32) * 1: k > end_of_extent
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 33) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 34) #define XT_CMP(CMP, K, X, OFFSET64)\
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 35) {\
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 36) OFFSET64 = offsetXAD(X);\
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 37) (CMP) = ((K) >= OFFSET64 + lengthXAD(X)) ? 1 :\
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 38) ((K) < OFFSET64) ? -1 : 0;\
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 39) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 40)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 41) /* write a xad entry */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 42) #define XT_PUTENTRY(XAD, FLAG, OFF, LEN, ADDR)\
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 43) {\
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 44) (XAD)->flag = (FLAG);\
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 45) XADoffset((XAD), (OFF));\
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 46) XADlength((XAD), (LEN));\
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 47) XADaddress((XAD), (ADDR));\
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 48) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 49)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 50) #define XT_PAGE(IP, MP) BT_PAGE(IP, MP, xtpage_t, i_xtroot)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 51)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 52) /* get page buffer for specified block address */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 53) /* ToDo: Replace this ugly macro with a function */
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 54) #define XT_GETPAGE(IP, BN, MP, SIZE, P, RC) \
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 55) do { \
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 56) BT_GETPAGE(IP, BN, MP, xtpage_t, SIZE, P, RC, i_xtroot); \
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 57) if (!(RC)) { \
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 58) if ((le16_to_cpu((P)->header.nextindex) < XTENTRYSTART) || \
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 59) (le16_to_cpu((P)->header.nextindex) > \
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 60) le16_to_cpu((P)->header.maxentry)) || \
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 61) (le16_to_cpu((P)->header.maxentry) > \
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 62) (((BN) == 0) ? XTROOTMAXSLOT : PSIZE >> L2XTSLOTSIZE))) { \
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 63) jfs_error((IP)->i_sb, \
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 64) "XT_GETPAGE: xtree page corrupt\n"); \
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 65) BT_PUTPAGE(MP); \
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 66) MP = NULL; \
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 67) RC = -EIO; \
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 68) } \
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 69) } \
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 70) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 71)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 72) /* for consistency */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 73) #define XT_PUTPAGE(MP) BT_PUTPAGE(MP)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 74)
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 75) #define XT_GETSEARCH(IP, LEAF, BN, MP, P, INDEX) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 76) BT_GETSEARCH(IP, LEAF, BN, MP, xtpage_t, P, INDEX, i_xtroot)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 77) /* xtree entry parameter descriptor */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 78) struct xtsplit {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 79) struct metapage *mp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 80) s16 index;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 81) u8 flag;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 82) s64 off;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 83) s64 addr;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 84) int len;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 85) struct pxdlist *pxdlist;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 86) };
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 87)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 88)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 89) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 90) * statistics
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 91) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 92) #ifdef CONFIG_JFS_STATISTICS
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 93) static struct {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 94) uint search;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 95) uint fastSearch;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 96) uint split;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 97) } xtStat;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 98) #endif
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 99)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 100)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 101) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 102) * forward references
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 103) */
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 104) static int xtSearch(struct inode *ip, s64 xoff, s64 *next, int *cmpp,
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 105) struct btstack * btstack, int flag);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 106)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 107) static int xtSplitUp(tid_t tid,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 108) struct inode *ip,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 109) struct xtsplit * split, struct btstack * btstack);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 110)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 111) static int xtSplitPage(tid_t tid, struct inode *ip, struct xtsplit * split,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 112) struct metapage ** rmpp, s64 * rbnp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 113)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 114) static int xtSplitRoot(tid_t tid, struct inode *ip,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 115) struct xtsplit * split, struct metapage ** rmpp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 116)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 117) #ifdef _STILL_TO_PORT
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 118) static int xtDeleteUp(tid_t tid, struct inode *ip, struct metapage * fmp,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 119) xtpage_t * fp, struct btstack * btstack);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 120)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 121) static int xtSearchNode(struct inode *ip,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 122) xad_t * xad,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 123) int *cmpp, struct btstack * btstack, int flag);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 124)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 125) static int xtRelink(tid_t tid, struct inode *ip, xtpage_t * fp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 126) #endif /* _STILL_TO_PORT */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 127)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 128) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 129) * xtLookup()
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 130) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 131) * function: map a single page into a physical extent;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 132) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 133) int xtLookup(struct inode *ip, s64 lstart,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 134) s64 llen, int *pflag, s64 * paddr, s32 * plen, int no_check)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 135) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 136) int rc = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 137) struct btstack btstack;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 138) int cmp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 139) s64 bn;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 140) struct metapage *mp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 141) xtpage_t *p;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 142) int index;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 143) xad_t *xad;
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 144) s64 next, size, xoff, xend;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 145) int xlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 146) s64 xaddr;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 147)
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 148) *paddr = 0;
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 149) *plen = llen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 150)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 151) if (!no_check) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 152) /* is lookup offset beyond eof ? */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 153) size = ((u64) ip->i_size + (JFS_SBI(ip->i_sb)->bsize - 1)) >>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 154) JFS_SBI(ip->i_sb)->l2bsize;
fec1878fe952b (Dave Kleikamp 2009-01-09 15:42:04 -0600 155) if (lstart >= size)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 156) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 157) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 158)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 159) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 160) * search for the xad entry covering the logical extent
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 161) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 162) //search:
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 163) if ((rc = xtSearch(ip, lstart, &next, &cmp, &btstack, 0))) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 164) jfs_err("xtLookup: xtSearch returned %d", rc);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 165) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 166) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 167)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 168) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 169) * compute the physical extent covering logical extent
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 170) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 171) * N.B. search may have failed (e.g., hole in sparse file),
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 172) * and returned the index of the next entry.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 173) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 174) /* retrieve search result */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 175) XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 176)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 177) /* is xad found covering start of logical extent ?
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 178) * lstart is a page start address,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 179) * i.e., lstart cannot start in a hole;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 180) */
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 181) if (cmp) {
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 182) if (next)
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 183) *plen = min(next - lstart, llen);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 184) goto out;
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 185) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 186)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 187) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 188) * lxd covered by xad
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 189) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 190) xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 191) xoff = offsetXAD(xad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 192) xlen = lengthXAD(xad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 193) xend = xoff + xlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 194) xaddr = addressXAD(xad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 195)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 196) /* initialize new pxd */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 197) *pflag = xad->flag;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 198) *paddr = xaddr + (lstart - xoff);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 199) /* a page must be fully covered by an xad */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 200) *plen = min(xend - lstart, llen);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 201)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 202) out:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 203) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 204)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 205) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 206) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 207)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 208) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 209) * xtSearch()
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 210) *
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 211) * function: search for the xad entry covering specified offset.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 212) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 213) * parameters:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 214) * ip - file object;
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 215) * xoff - extent offset;
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 216) * nextp - address of next extent (if any) for search miss
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 217) * cmpp - comparison result:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 218) * btstack - traverse stack;
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 219) * flag - search process flag (XT_INSERT);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 220) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 221) * returns:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 222) * btstack contains (bn, index) of search path traversed to the entry.
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 223) * *cmpp is set to result of comparison with the entry returned.
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 224) * the page containing the entry is pinned at exit.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 225) */
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 226) static int xtSearch(struct inode *ip, s64 xoff, s64 *nextp,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 227) int *cmpp, struct btstack * btstack, int flag)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 228) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 229) struct jfs_inode_info *jfs_ip = JFS_IP(ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 230) int rc = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 231) int cmp = 1; /* init for empty page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 232) s64 bn; /* block number */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 233) struct metapage *mp; /* page buffer */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 234) xtpage_t *p; /* page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 235) xad_t *xad;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 236) int base, index, lim, btindex;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 237) struct btframe *btsp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 238) int nsplit = 0; /* number of pages to split */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 239) s64 t64;
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 240) s64 next = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 241)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 242) INCREMENT(xtStat.search);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 243)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 244) BT_CLR(btstack);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 245)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 246) btstack->nsplit = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 247)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 248) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 249) * search down tree from root:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 250) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 251) * between two consecutive entries of <Ki, Pi> and <Kj, Pj> of
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 252) * internal page, child page Pi contains entry with k, Ki <= K < Kj.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 253) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 254) * if entry with search key K is not found
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 255) * internal page search find the entry with largest key Ki
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 256) * less than K which point to the child page to search;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 257) * leaf page search find the entry with smallest key Kj
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 258) * greater than K so that the returned index is the position of
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 259) * the entry to be shifted right for insertion of new entry.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 260) * for empty tree, search key is greater than any key of the tree.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 261) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 262) * by convention, root bn = 0.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 263) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 264) for (bn = 0;;) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 265) /* get/pin the page to search */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 266) XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 267) if (rc)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 268) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 269)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 270) /* try sequential access heuristics with the previous
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 271) * access entry in target leaf page:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 272) * once search narrowed down into the target leaf,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 273) * key must either match an entry in the leaf or
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 274) * key entry does not exist in the tree;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 275) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 276) //fastSearch:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 277) if ((jfs_ip->btorder & BT_SEQUENTIAL) &&
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 278) (p->header.flag & BT_LEAF) &&
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 279) (index = jfs_ip->btindex) <
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 280) le16_to_cpu(p->header.nextindex)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 281) xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 282) t64 = offsetXAD(xad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 283) if (xoff < t64 + lengthXAD(xad)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 284) if (xoff >= t64) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 285) *cmpp = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 286) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 287) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 288)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 289) /* stop sequential access heuristics */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 290) goto binarySearch;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 291) } else { /* (t64 + lengthXAD(xad)) <= xoff */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 292)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 293) /* try next sequential entry */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 294) index++;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 295) if (index <
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 296) le16_to_cpu(p->header.nextindex)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 297) xad++;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 298) t64 = offsetXAD(xad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 299) if (xoff < t64 + lengthXAD(xad)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 300) if (xoff >= t64) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 301) *cmpp = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 302) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 303) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 304)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 305) /* miss: key falls between
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 306) * previous and this entry
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 307) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 308) *cmpp = 1;
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 309) next = t64;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 310) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 311) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 312)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 313) /* (xoff >= t64 + lengthXAD(xad));
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 314) * matching entry may be further out:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 315) * stop heuristic search
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 316) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 317) /* stop sequential access heuristics */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 318) goto binarySearch;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 319) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 320)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 321) /* (index == p->header.nextindex);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 322) * miss: key entry does not exist in
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 323) * the target leaf/tree
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 324) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 325) *cmpp = 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 326) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 327) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 328)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 329) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 330) * if hit, return index of the entry found, and
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 331) * if miss, where new entry with search key is
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 332) * to be inserted;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 333) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 334) out:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 335) /* compute number of pages to split */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 336) if (flag & XT_INSERT) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 337) if (p->header.nextindex == /* little-endian */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 338) p->header.maxentry)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 339) nsplit++;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 340) else
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 341) nsplit = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 342) btstack->nsplit = nsplit;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 343) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 344)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 345) /* save search result */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 346) btsp = btstack->top;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 347) btsp->bn = bn;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 348) btsp->index = index;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 349) btsp->mp = mp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 350)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 351) /* update sequential access heuristics */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 352) jfs_ip->btindex = index;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 353)
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 354) if (nextp)
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 355) *nextp = next;
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 356)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 357) INCREMENT(xtStat.fastSearch);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 358) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 359) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 360)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 361) /* well, ... full search now */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 362) binarySearch:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 363) lim = le16_to_cpu(p->header.nextindex) - XTENTRYSTART;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 364)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 365) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 366) * binary search with search key K on the current page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 367) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 368) for (base = XTENTRYSTART; lim; lim >>= 1) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 369) index = base + (lim >> 1);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 370)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 371) XT_CMP(cmp, xoff, &p->xad[index], t64);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 372) if (cmp == 0) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 373) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 374) * search hit
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 375) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 376) /* search hit - leaf page:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 377) * return the entry found
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 378) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 379) if (p->header.flag & BT_LEAF) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 380) *cmpp = cmp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 381)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 382) /* compute number of pages to split */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 383) if (flag & XT_INSERT) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 384) if (p->header.nextindex ==
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 385) p->header.maxentry)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 386) nsplit++;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 387) else
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 388) nsplit = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 389) btstack->nsplit = nsplit;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 390) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 391)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 392) /* save search result */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 393) btsp = btstack->top;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 394) btsp->bn = bn;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 395) btsp->index = index;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 396) btsp->mp = mp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 397)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 398) /* init sequential access heuristics */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 399) btindex = jfs_ip->btindex;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 400) if (index == btindex ||
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 401) index == btindex + 1)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 402) jfs_ip->btorder = BT_SEQUENTIAL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 403) else
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 404) jfs_ip->btorder = BT_RANDOM;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 405) jfs_ip->btindex = index;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 406)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 407) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 408) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 409) /* search hit - internal page:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 410) * descend/search its child page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 411) */
6b6bf51081a27 (Dave Kleikamp 2005-05-04 09:11:49 -0500 412) if (index < le16_to_cpu(p->header.nextindex)-1)
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 413) next = offsetXAD(&p->xad[index + 1]);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 414) goto next;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 415) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 416)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 417) if (cmp > 0) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 418) base = index + 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 419) --lim;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 420) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 421) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 422)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 423) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 424) * search miss
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 425) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 426) * base is the smallest index with key (Kj) greater than
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 427) * search key (K) and may be zero or maxentry index.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 428) */
6b6bf51081a27 (Dave Kleikamp 2005-05-04 09:11:49 -0500 429) if (base < le16_to_cpu(p->header.nextindex))
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 430) next = offsetXAD(&p->xad[base]);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 431) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 432) * search miss - leaf page:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 433) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 434) * return location of entry (base) where new entry with
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 435) * search key K is to be inserted.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 436) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 437) if (p->header.flag & BT_LEAF) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 438) *cmpp = cmp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 439)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 440) /* compute number of pages to split */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 441) if (flag & XT_INSERT) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 442) if (p->header.nextindex ==
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 443) p->header.maxentry)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 444) nsplit++;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 445) else
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 446) nsplit = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 447) btstack->nsplit = nsplit;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 448) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 449)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 450) /* save search result */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 451) btsp = btstack->top;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 452) btsp->bn = bn;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 453) btsp->index = base;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 454) btsp->mp = mp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 455)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 456) /* init sequential access heuristics */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 457) btindex = jfs_ip->btindex;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 458) if (base == btindex || base == btindex + 1)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 459) jfs_ip->btorder = BT_SEQUENTIAL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 460) else
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 461) jfs_ip->btorder = BT_RANDOM;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 462) jfs_ip->btindex = base;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 463)
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 464) if (nextp)
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 465) *nextp = next;
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 466)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 467) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 468) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 469)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 470) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 471) * search miss - non-leaf page:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 472) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 473) * if base is non-zero, decrement base by one to get the parent
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 474) * entry of the child page to search.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 475) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 476) index = base ? base - 1 : base;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 477)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 478) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 479) * go down to child page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 480) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 481) next:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 482) /* update number of pages to split */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 483) if (p->header.nextindex == p->header.maxentry)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 484) nsplit++;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 485) else
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 486) nsplit = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 487)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 488) /* push (bn, index) of the parent page/entry */
17e6afc75ad01 (Dave Kleikamp 2007-01-09 08:57:34 -0600 489) if (BT_STACK_FULL(btstack)) {
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 490) jfs_error(ip->i_sb, "stack overrun!\n");
17e6afc75ad01 (Dave Kleikamp 2007-01-09 08:57:34 -0600 491) XT_PUTPAGE(mp);
17e6afc75ad01 (Dave Kleikamp 2007-01-09 08:57:34 -0600 492) return -EIO;
17e6afc75ad01 (Dave Kleikamp 2007-01-09 08:57:34 -0600 493) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 494) BT_PUSH(btstack, bn, index);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 495)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 496) /* get the child page block number */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 497) bn = addressXAD(&p->xad[index]);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 498)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 499) /* unpin the parent page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 500) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 501) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 502) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 503)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 504) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 505) * xtInsert()
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 506) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 507) * function:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 508) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 509) * parameter:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 510) * tid - transaction id;
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 511) * ip - file object;
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 512) * xflag - extent flag (XAD_NOTRECORDED):
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 513) * xoff - extent offset;
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 514) * xlen - extent length;
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 515) * xaddrp - extent address pointer (in/out):
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 516) * if (*xaddrp)
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 517) * caller allocated data extent at *xaddrp;
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 518) * else
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 519) * allocate data extent and return its xaddr;
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 520) * flag -
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 521) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 522) * return:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 523) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 524) int xtInsert(tid_t tid, /* transaction id */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 525) struct inode *ip, int xflag, s64 xoff, s32 xlen, s64 * xaddrp,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 526) int flag)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 527) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 528) int rc = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 529) s64 xaddr, hint;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 530) struct metapage *mp; /* meta-page buffer */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 531) xtpage_t *p; /* base B+-tree index page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 532) s64 bn;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 533) int index, nextindex;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 534) struct btstack btstack; /* traverse stack */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 535) struct xtsplit split; /* split information */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 536) xad_t *xad;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 537) int cmp;
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 538) s64 next;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 539) struct tlock *tlck;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 540) struct xtlock *xtlck;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 541)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 542) jfs_info("xtInsert: nxoff:0x%lx nxlen:0x%x", (ulong) xoff, xlen);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 543)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 544) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 545) * search for the entry location at which to insert:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 546) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 547) * xtFastSearch() and xtSearch() both returns (leaf page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 548) * pinned, index at which to insert).
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 549) * n.b. xtSearch() may return index of maxentry of
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 550) * the full page.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 551) */
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 552) if ((rc = xtSearch(ip, xoff, &next, &cmp, &btstack, XT_INSERT)))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 553) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 554)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 555) /* retrieve search result */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 556) XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 557)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 558) /* This test must follow XT_GETSEARCH since mp must be valid if
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 559) * we branch to out: */
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 560) if ((cmp == 0) || (next && (xlen > next - xoff))) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 561) rc = -EEXIST;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 562) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 563) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 564)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 565) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 566) * allocate data extent requested
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 567) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 568) * allocation hint: last xad
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 569) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 570) if ((xaddr = *xaddrp) == 0) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 571) if (index > XTENTRYSTART) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 572) xad = &p->xad[index - 1];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 573) hint = addressXAD(xad) + lengthXAD(xad) - 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 574) } else
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 575) hint = 0;
5dd4056db8438 (Christoph Hellwig 2010-03-03 09:05:00 -0500 576) if ((rc = dquot_alloc_block(ip, xlen)))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 577) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 578) if ((rc = dbAlloc(ip, hint, (s64) xlen, &xaddr))) {
5dd4056db8438 (Christoph Hellwig 2010-03-03 09:05:00 -0500 579) dquot_free_block(ip, xlen);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 580) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 581) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 582) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 583)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 584) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 585) * insert entry for new extent
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 586) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 587) xflag |= XAD_NEW;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 588)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 589) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 590) * if the leaf page is full, split the page and
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 591) * propagate up the router entry for the new page from split
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 592) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 593) * The xtSplitUp() will insert the entry and unpin the leaf page.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 594) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 595) nextindex = le16_to_cpu(p->header.nextindex);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 596) if (nextindex == le16_to_cpu(p->header.maxentry)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 597) split.mp = mp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 598) split.index = index;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 599) split.flag = xflag;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 600) split.off = xoff;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 601) split.len = xlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 602) split.addr = xaddr;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 603) split.pxdlist = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 604) if ((rc = xtSplitUp(tid, ip, &split, &btstack))) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 605) /* undo data extent allocation */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 606) if (*xaddrp == 0) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 607) dbFree(ip, xaddr, (s64) xlen);
5dd4056db8438 (Christoph Hellwig 2010-03-03 09:05:00 -0500 608) dquot_free_block(ip, xlen);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 609) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 610) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 611) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 612)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 613) *xaddrp = xaddr;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 614) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 615) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 616)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 617) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 618) * insert the new entry into the leaf page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 619) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 620) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 621) * acquire a transaction lock on the leaf page;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 622) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 623) * action: xad insertion/extension;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 624) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 625) BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 626)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 627) /* if insert into middle, shift right remaining entries. */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 628) if (index < nextindex)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 629) memmove(&p->xad[index + 1], &p->xad[index],
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 630) (nextindex - index) * sizeof(xad_t));
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 631)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 632) /* insert the new entry: mark the entry NEW */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 633) xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 634) XT_PUTENTRY(xad, xflag, xoff, xlen, xaddr);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 635)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 636) /* advance next available entry index */
891456227881d (Marcin Slusarz 2008-02-13 15:34:20 -0600 637) le16_add_cpu(&p->header.nextindex, 1);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 638)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 639) /* Don't log it if there are no links to the file */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 640) if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 641) tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 642) xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 643) xtlck->lwm.offset =
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 644) (xtlck->lwm.offset) ? min(index,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 645) (int)xtlck->lwm.offset) : index;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 646) xtlck->lwm.length =
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 647) le16_to_cpu(p->header.nextindex) - xtlck->lwm.offset;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 648) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 649)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 650) *xaddrp = xaddr;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 651)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 652) out:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 653) /* unpin the leaf page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 654) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 655)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 656) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 657) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 658)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 659)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 660) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 661) * xtSplitUp()
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 662) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 663) * function:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 664) * split full pages as propagating insertion up the tree
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 665) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 666) * parameter:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 667) * tid - transaction id;
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 668) * ip - file object;
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 669) * split - entry parameter descriptor;
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 670) * btstack - traverse stack from xtSearch()
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 671) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 672) * return:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 673) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 674) static int
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 675) xtSplitUp(tid_t tid,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 676) struct inode *ip, struct xtsplit * split, struct btstack * btstack)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 677) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 678) int rc = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 679) struct metapage *smp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 680) xtpage_t *sp; /* split page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 681) struct metapage *rmp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 682) s64 rbn; /* new right page block number */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 683) struct metapage *rcmp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 684) xtpage_t *rcp; /* right child page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 685) s64 rcbn; /* right child page block number */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 686) int skip; /* index of entry of insertion */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 687) int nextindex; /* next available entry index of p */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 688) struct btframe *parent; /* parent page entry on traverse stack */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 689) xad_t *xad;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 690) s64 xaddr;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 691) int xlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 692) int nsplit; /* number of pages split */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 693) struct pxdlist pxdlist;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 694) pxd_t *pxd;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 695) struct tlock *tlck;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 696) struct xtlock *xtlck;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 697)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 698) smp = split->mp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 699) sp = XT_PAGE(ip, smp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 700)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 701) /* is inode xtree root extension/inline EA area free ? */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 702) if ((sp->header.flag & BT_ROOT) && (!S_ISDIR(ip->i_mode)) &&
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 703) (le16_to_cpu(sp->header.maxentry) < XTROOTMAXSLOT) &&
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 704) (JFS_IP(ip)->mode2 & INLINEEA)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 705) sp->header.maxentry = cpu_to_le16(XTROOTMAXSLOT);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 706) JFS_IP(ip)->mode2 &= ~INLINEEA;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 707)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 708) BT_MARK_DIRTY(smp, ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 709) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 710) * acquire a transaction lock on the leaf page;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 711) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 712) * action: xad insertion/extension;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 713) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 714)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 715) /* if insert into middle, shift right remaining entries. */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 716) skip = split->index;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 717) nextindex = le16_to_cpu(sp->header.nextindex);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 718) if (skip < nextindex)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 719) memmove(&sp->xad[skip + 1], &sp->xad[skip],
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 720) (nextindex - skip) * sizeof(xad_t));
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 721)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 722) /* insert the new entry: mark the entry NEW */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 723) xad = &sp->xad[skip];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 724) XT_PUTENTRY(xad, split->flag, split->off, split->len,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 725) split->addr);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 726)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 727) /* advance next available entry index */
891456227881d (Marcin Slusarz 2008-02-13 15:34:20 -0600 728) le16_add_cpu(&sp->header.nextindex, 1);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 729)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 730) /* Don't log it if there are no links to the file */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 731) if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 732) tlck = txLock(tid, ip, smp, tlckXTREE | tlckGROW);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 733) xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 734) xtlck->lwm.offset = (xtlck->lwm.offset) ?
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 735) min(skip, (int)xtlck->lwm.offset) : skip;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 736) xtlck->lwm.length =
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 737) le16_to_cpu(sp->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 738) xtlck->lwm.offset;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 739) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 740)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 741) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 742) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 743)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 744) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 745) * allocate new index blocks to cover index page split(s)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 746) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 747) * allocation hint: ?
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 748) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 749) if (split->pxdlist == NULL) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 750) nsplit = btstack->nsplit;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 751) split->pxdlist = &pxdlist;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 752) pxdlist.maxnpxd = pxdlist.npxd = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 753) pxd = &pxdlist.pxd[0];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 754) xlen = JFS_SBI(ip->i_sb)->nbperpage;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 755) for (; nsplit > 0; nsplit--, pxd++) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 756) if ((rc = dbAlloc(ip, (s64) 0, (s64) xlen, &xaddr))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 757) == 0) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 758) PXDaddress(pxd, xaddr);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 759) PXDlength(pxd, xlen);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 760)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 761) pxdlist.maxnpxd++;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 762)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 763) continue;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 764) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 765)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 766) /* undo allocation */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 767)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 768) XT_PUTPAGE(smp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 769) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 770) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 771) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 772)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 773) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 774) * Split leaf page <sp> into <sp> and a new right page <rp>.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 775) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 776) * The split routines insert the new entry into the leaf page,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 777) * and acquire txLock as appropriate.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 778) * return <rp> pinned and its block number <rpbn>.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 779) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 780) rc = (sp->header.flag & BT_ROOT) ?
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 781) xtSplitRoot(tid, ip, split, &rmp) :
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 782) xtSplitPage(tid, ip, split, &rmp, &rbn);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 783)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 784) XT_PUTPAGE(smp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 785)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 786) if (rc)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 787) return -EIO;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 788) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 789) * propagate up the router entry for the leaf page just split
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 790) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 791) * insert a router entry for the new page into the parent page,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 792) * propagate the insert/split up the tree by walking back the stack
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 793) * of (bn of parent page, index of child page entry in parent page)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 794) * that were traversed during the search for the page that split.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 795) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 796) * the propagation of insert/split up the tree stops if the root
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 797) * splits or the page inserted into doesn't have to split to hold
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 798) * the new entry.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 799) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 800) * the parent entry for the split page remains the same, and
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 801) * a new entry is inserted at its right with the first key and
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 802) * block number of the new right page.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 803) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 804) * There are a maximum of 3 pages pinned at any time:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 805) * right child, left parent and right parent (when the parent splits)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 806) * to keep the child page pinned while working on the parent.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 807) * make sure that all pins are released at exit.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 808) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 809) while ((parent = BT_POP(btstack)) != NULL) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 810) /* parent page specified by stack frame <parent> */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 811)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 812) /* keep current child pages <rcp> pinned */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 813) rcmp = rmp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 814) rcbn = rbn;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 815) rcp = XT_PAGE(ip, rcmp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 816)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 817) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 818) * insert router entry in parent for new right child page <rp>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 819) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 820) /* get/pin the parent page <sp> */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 821) XT_GETPAGE(ip, parent->bn, smp, PSIZE, sp, rc);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 822) if (rc) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 823) XT_PUTPAGE(rcmp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 824) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 825) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 826)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 827) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 828) * The new key entry goes ONE AFTER the index of parent entry,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 829) * because the split was to the right.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 830) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 831) skip = parent->index + 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 832)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 833) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 834) * split or shift right remaining entries of the parent page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 835) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 836) nextindex = le16_to_cpu(sp->header.nextindex);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 837) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 838) * parent page is full - split the parent page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 839) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 840) if (nextindex == le16_to_cpu(sp->header.maxentry)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 841) /* init for parent page split */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 842) split->mp = smp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 843) split->index = skip; /* index at insert */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 844) split->flag = XAD_NEW;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 845) split->off = offsetXAD(&rcp->xad[XTENTRYSTART]);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 846) split->len = JFS_SBI(ip->i_sb)->nbperpage;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 847) split->addr = rcbn;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 848)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 849) /* unpin previous right child page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 850) XT_PUTPAGE(rcmp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 851)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 852) /* The split routines insert the new entry,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 853) * and acquire txLock as appropriate.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 854) * return <rp> pinned and its block number <rpbn>.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 855) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 856) rc = (sp->header.flag & BT_ROOT) ?
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 857) xtSplitRoot(tid, ip, split, &rmp) :
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 858) xtSplitPage(tid, ip, split, &rmp, &rbn);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 859) if (rc) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 860) XT_PUTPAGE(smp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 861) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 862) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 863)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 864) XT_PUTPAGE(smp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 865) /* keep new child page <rp> pinned */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 866) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 867) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 868) * parent page is not full - insert in parent page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 869) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 870) else {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 871) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 872) * insert router entry in parent for the right child
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 873) * page from the first entry of the right child page:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 874) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 875) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 876) * acquire a transaction lock on the parent page;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 877) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 878) * action: router xad insertion;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 879) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 880) BT_MARK_DIRTY(smp, ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 881)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 882) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 883) * if insert into middle, shift right remaining entries
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 884) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 885) if (skip < nextindex)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 886) memmove(&sp->xad[skip + 1], &sp->xad[skip],
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 887) (nextindex -
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 888) skip) << L2XTSLOTSIZE);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 889)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 890) /* insert the router entry */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 891) xad = &sp->xad[skip];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 892) XT_PUTENTRY(xad, XAD_NEW,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 893) offsetXAD(&rcp->xad[XTENTRYSTART]),
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 894) JFS_SBI(ip->i_sb)->nbperpage, rcbn);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 895)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 896) /* advance next available entry index. */
891456227881d (Marcin Slusarz 2008-02-13 15:34:20 -0600 897) le16_add_cpu(&sp->header.nextindex, 1);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 898)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 899) /* Don't log it if there are no links to the file */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 900) if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 901) tlck = txLock(tid, ip, smp,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 902) tlckXTREE | tlckGROW);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 903) xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 904) xtlck->lwm.offset = (xtlck->lwm.offset) ?
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 905) min(skip, (int)xtlck->lwm.offset) : skip;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 906) xtlck->lwm.length =
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 907) le16_to_cpu(sp->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 908) xtlck->lwm.offset;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 909) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 910)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 911) /* unpin parent page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 912) XT_PUTPAGE(smp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 913)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 914) /* exit propagate up */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 915) break;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 916) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 917) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 918)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 919) /* unpin current right page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 920) XT_PUTPAGE(rmp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 921)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 922) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 923) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 924)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 925)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 926) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 927) * xtSplitPage()
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 928) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 929) * function:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 930) * split a full non-root page into
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 931) * original/split/left page and new right page
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 932) * i.e., the original/split page remains as left page.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 933) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 934) * parameter:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 935) * int tid,
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 936) * struct inode *ip,
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 937) * struct xtsplit *split,
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 938) * struct metapage **rmpp,
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 939) * u64 *rbnp,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 940) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 941) * return:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 942) * Pointer to page in which to insert or NULL on error.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 943) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 944) static int
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 945) xtSplitPage(tid_t tid, struct inode *ip,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 946) struct xtsplit * split, struct metapage ** rmpp, s64 * rbnp)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 947) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 948) int rc = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 949) struct metapage *smp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 950) xtpage_t *sp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 951) struct metapage *rmp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 952) xtpage_t *rp; /* new right page allocated */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 953) s64 rbn; /* new right page block number */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 954) struct metapage *mp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 955) xtpage_t *p;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 956) s64 nextbn;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 957) int skip, maxentry, middle, righthalf, n;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 958) xad_t *xad;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 959) struct pxdlist *pxdlist;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 960) pxd_t *pxd;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 961) struct tlock *tlck;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 962) struct xtlock *sxtlck = NULL, *rxtlck = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 963) int quota_allocation = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 964)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 965) smp = split->mp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 966) sp = XT_PAGE(ip, smp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 967)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 968) INCREMENT(xtStat.split);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 969)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 970) pxdlist = split->pxdlist;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 971) pxd = &pxdlist->pxd[pxdlist->npxd];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 972) pxdlist->npxd++;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 973) rbn = addressPXD(pxd);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 974)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 975) /* Allocate blocks to quota. */
5dd4056db8438 (Christoph Hellwig 2010-03-03 09:05:00 -0500 976) rc = dquot_alloc_block(ip, lengthPXD(pxd));
5dd4056db8438 (Christoph Hellwig 2010-03-03 09:05:00 -0500 977) if (rc)
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 978) goto clean_up;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 979)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 980) quota_allocation += lengthPXD(pxd);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 981)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 982) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 983) * allocate the new right page for the split
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 984) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 985) rmp = get_metapage(ip, rbn, PSIZE, 1);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 986) if (rmp == NULL) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 987) rc = -EIO;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 988) goto clean_up;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 989) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 990)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 991) jfs_info("xtSplitPage: ip:0x%p smp:0x%p rmp:0x%p", ip, smp, rmp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 992)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 993) BT_MARK_DIRTY(rmp, ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 994) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 995) * action: new page;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 996) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 997)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 998) rp = (xtpage_t *) rmp->data;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 999) rp->header.self = *pxd;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1000) rp->header.flag = sp->header.flag & BT_TYPE;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1001) rp->header.maxentry = sp->header.maxentry; /* little-endian */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1002) rp->header.nextindex = cpu_to_le16(XTENTRYSTART);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1003)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1004) BT_MARK_DIRTY(smp, ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1005) /* Don't log it if there are no links to the file */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1006) if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1007) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1008) * acquire a transaction lock on the new right page;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1009) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1010) tlck = txLock(tid, ip, rmp, tlckXTREE | tlckNEW);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1011) rxtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1012) rxtlck->lwm.offset = XTENTRYSTART;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1013) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1014) * acquire a transaction lock on the split page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1015) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1016) tlck = txLock(tid, ip, smp, tlckXTREE | tlckGROW);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1017) sxtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1018) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1019)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1020) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1021) * initialize/update sibling pointers of <sp> and <rp>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1022) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1023) nextbn = le64_to_cpu(sp->header.next);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1024) rp->header.next = cpu_to_le64(nextbn);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1025) rp->header.prev = cpu_to_le64(addressPXD(&sp->header.self));
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1026) sp->header.next = cpu_to_le64(rbn);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1027)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1028) skip = split->index;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1029)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1030) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1031) * sequential append at tail (after last entry of last page)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1032) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1033) * if splitting the last page on a level because of appending
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1034) * a entry to it (skip is maxentry), it's likely that the access is
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1035) * sequential. adding an empty page on the side of the level is less
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1036) * work and can push the fill factor much higher than normal.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1037) * if we're wrong it's no big deal - we will do the split the right
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1038) * way next time.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1039) * (it may look like it's equally easy to do a similar hack for
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1040) * reverse sorted data, that is, split the tree left, but it's not.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1041) * Be my guest.)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1042) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1043) if (nextbn == 0 && skip == le16_to_cpu(sp->header.maxentry)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1044) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1045) * acquire a transaction lock on the new/right page;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1046) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1047) * action: xad insertion;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1048) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1049) /* insert entry at the first entry of the new right page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1050) xad = &rp->xad[XTENTRYSTART];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1051) XT_PUTENTRY(xad, split->flag, split->off, split->len,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1052) split->addr);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1053)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1054) rp->header.nextindex = cpu_to_le16(XTENTRYSTART + 1);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1055)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1056) if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1057) /* rxtlck->lwm.offset = XTENTRYSTART; */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1058) rxtlck->lwm.length = 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1059) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1060)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1061) *rmpp = rmp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1062) *rbnp = rbn;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1063)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1064) jfs_info("xtSplitPage: sp:0x%p rp:0x%p", sp, rp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1065) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1066) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1067)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1068) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1069) * non-sequential insert (at possibly middle page)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1070) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1071)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1072) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1073) * update previous pointer of old next/right page of <sp>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1074) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1075) if (nextbn != 0) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1076) XT_GETPAGE(ip, nextbn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1077) if (rc) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1078) XT_PUTPAGE(rmp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1079) goto clean_up;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1080) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1081)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1082) BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1083) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1084) * acquire a transaction lock on the next page;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1085) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1086) * action:sibling pointer update;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1087) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1088) if (!test_cflag(COMMIT_Nolink, ip))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1089) tlck = txLock(tid, ip, mp, tlckXTREE | tlckRELINK);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1090)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1091) p->header.prev = cpu_to_le64(rbn);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1092)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1093) /* sibling page may have been updated previously, or
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1094) * it may be updated later;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1095) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1096)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1097) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1098) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1099)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1100) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1101) * split the data between the split and new/right pages
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1102) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1103) maxentry = le16_to_cpu(sp->header.maxentry);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1104) middle = maxentry >> 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1105) righthalf = maxentry - middle;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1106)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1107) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1108) * skip index in old split/left page - insert into left page:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1109) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1110) if (skip <= middle) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1111) /* move right half of split page to the new right page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1112) memmove(&rp->xad[XTENTRYSTART], &sp->xad[middle],
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1113) righthalf << L2XTSLOTSIZE);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1114)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1115) /* shift right tail of left half to make room for new entry */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1116) if (skip < middle)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1117) memmove(&sp->xad[skip + 1], &sp->xad[skip],
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1118) (middle - skip) << L2XTSLOTSIZE);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1119)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1120) /* insert new entry */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1121) xad = &sp->xad[skip];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1122) XT_PUTENTRY(xad, split->flag, split->off, split->len,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1123) split->addr);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1124)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1125) /* update page header */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1126) sp->header.nextindex = cpu_to_le16(middle + 1);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1127) if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1128) sxtlck->lwm.offset = (sxtlck->lwm.offset) ?
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1129) min(skip, (int)sxtlck->lwm.offset) : skip;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1130) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1131)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1132) rp->header.nextindex =
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1133) cpu_to_le16(XTENTRYSTART + righthalf);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1134) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1135) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1136) * skip index in new right page - insert into right page:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1137) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1138) else {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1139) /* move left head of right half to right page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1140) n = skip - middle;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1141) memmove(&rp->xad[XTENTRYSTART], &sp->xad[middle],
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1142) n << L2XTSLOTSIZE);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1143)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1144) /* insert new entry */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1145) n += XTENTRYSTART;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1146) xad = &rp->xad[n];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1147) XT_PUTENTRY(xad, split->flag, split->off, split->len,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1148) split->addr);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1149)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1150) /* move right tail of right half to right page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1151) if (skip < maxentry)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1152) memmove(&rp->xad[n + 1], &sp->xad[skip],
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1153) (maxentry - skip) << L2XTSLOTSIZE);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1154)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1155) /* update page header */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1156) sp->header.nextindex = cpu_to_le16(middle);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1157) if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1158) sxtlck->lwm.offset = (sxtlck->lwm.offset) ?
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1159) min(middle, (int)sxtlck->lwm.offset) : middle;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1160) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1161)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1162) rp->header.nextindex = cpu_to_le16(XTENTRYSTART +
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1163) righthalf + 1);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1164) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1165)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1166) if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1167) sxtlck->lwm.length = le16_to_cpu(sp->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1168) sxtlck->lwm.offset;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1169)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1170) /* rxtlck->lwm.offset = XTENTRYSTART; */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1171) rxtlck->lwm.length = le16_to_cpu(rp->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1172) XTENTRYSTART;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1173) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1174)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1175) *rmpp = rmp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1176) *rbnp = rbn;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1177)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1178) jfs_info("xtSplitPage: sp:0x%p rp:0x%p", sp, rp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1179) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1180)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1181) clean_up:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1182)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1183) /* Rollback quota allocation. */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1184) if (quota_allocation)
5dd4056db8438 (Christoph Hellwig 2010-03-03 09:05:00 -0500 1185) dquot_free_block(ip, quota_allocation);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1186)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1187) return (rc);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1188) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1189)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1190)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1191) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1192) * xtSplitRoot()
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1193) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1194) * function:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1195) * split the full root page into original/root/split page and new
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1196) * right page
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1197) * i.e., root remains fixed in tree anchor (inode) and the root is
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1198) * copied to a single new right child page since root page <<
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1199) * non-root page, and the split root page contains a single entry
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1200) * for the new right child page.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1201) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1202) * parameter:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1203) * int tid,
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1204) * struct inode *ip,
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1205) * struct xtsplit *split,
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1206) * struct metapage **rmpp)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1207) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1208) * return:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1209) * Pointer to page in which to insert or NULL on error.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1210) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1211) static int
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1212) xtSplitRoot(tid_t tid,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1213) struct inode *ip, struct xtsplit * split, struct metapage ** rmpp)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1214) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1215) xtpage_t *sp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1216) struct metapage *rmp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1217) xtpage_t *rp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1218) s64 rbn;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1219) int skip, nextindex;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1220) xad_t *xad;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1221) pxd_t *pxd;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1222) struct pxdlist *pxdlist;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1223) struct tlock *tlck;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1224) struct xtlock *xtlck;
5dd4056db8438 (Christoph Hellwig 2010-03-03 09:05:00 -0500 1225) int rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1226)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1227) sp = &JFS_IP(ip)->i_xtroot;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1228)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1229) INCREMENT(xtStat.split);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1230)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1231) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1232) * allocate a single (right) child page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1233) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1234) pxdlist = split->pxdlist;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1235) pxd = &pxdlist->pxd[pxdlist->npxd];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1236) pxdlist->npxd++;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1237) rbn = addressPXD(pxd);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1238) rmp = get_metapage(ip, rbn, PSIZE, 1);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1239) if (rmp == NULL)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1240) return -EIO;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1241)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1242) /* Allocate blocks to quota. */
5dd4056db8438 (Christoph Hellwig 2010-03-03 09:05:00 -0500 1243) rc = dquot_alloc_block(ip, lengthPXD(pxd));
5dd4056db8438 (Christoph Hellwig 2010-03-03 09:05:00 -0500 1244) if (rc) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1245) release_metapage(rmp);
5dd4056db8438 (Christoph Hellwig 2010-03-03 09:05:00 -0500 1246) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1247) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1248)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1249) jfs_info("xtSplitRoot: ip:0x%p rmp:0x%p", ip, rmp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1250)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1251) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1252) * acquire a transaction lock on the new right page;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1253) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1254) * action: new page;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1255) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1256) BT_MARK_DIRTY(rmp, ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1257)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1258) rp = (xtpage_t *) rmp->data;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1259) rp->header.flag =
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1260) (sp->header.flag & BT_LEAF) ? BT_LEAF : BT_INTERNAL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1261) rp->header.self = *pxd;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1262) rp->header.nextindex = cpu_to_le16(XTENTRYSTART);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1263) rp->header.maxentry = cpu_to_le16(PSIZE >> L2XTSLOTSIZE);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1264)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1265) /* initialize sibling pointers */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1266) rp->header.next = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1267) rp->header.prev = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1268)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1269) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1270) * copy the in-line root page into new right page extent
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1271) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1272) nextindex = le16_to_cpu(sp->header.maxentry);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1273) memmove(&rp->xad[XTENTRYSTART], &sp->xad[XTENTRYSTART],
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1274) (nextindex - XTENTRYSTART) << L2XTSLOTSIZE);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1275)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1276) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1277) * insert the new entry into the new right/child page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1278) * (skip index in the new right page will not change)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1279) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1280) skip = split->index;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1281) /* if insert into middle, shift right remaining entries */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1282) if (skip != nextindex)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1283) memmove(&rp->xad[skip + 1], &rp->xad[skip],
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1284) (nextindex - skip) * sizeof(xad_t));
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1285)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1286) xad = &rp->xad[skip];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1287) XT_PUTENTRY(xad, split->flag, split->off, split->len, split->addr);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1288)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1289) /* update page header */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1290) rp->header.nextindex = cpu_to_le16(nextindex + 1);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1291)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1292) if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1293) tlck = txLock(tid, ip, rmp, tlckXTREE | tlckNEW);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1294) xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1295) xtlck->lwm.offset = XTENTRYSTART;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1296) xtlck->lwm.length = le16_to_cpu(rp->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1297) XTENTRYSTART;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1298) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1299)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1300) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1301) * reset the root
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1302) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1303) * init root with the single entry for the new right page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1304) * set the 1st entry offset to 0, which force the left-most key
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1305) * at any level of the tree to be less than any search key.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1306) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1307) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1308) * acquire a transaction lock on the root page (in-memory inode);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1309) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1310) * action: root split;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1311) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1312) BT_MARK_DIRTY(split->mp, ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1313)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1314) xad = &sp->xad[XTENTRYSTART];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1315) XT_PUTENTRY(xad, XAD_NEW, 0, JFS_SBI(ip->i_sb)->nbperpage, rbn);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1316)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1317) /* update page header of root */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1318) sp->header.flag &= ~BT_LEAF;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1319) sp->header.flag |= BT_INTERNAL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1320)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1321) sp->header.nextindex = cpu_to_le16(XTENTRYSTART + 1);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1322)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1323) if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1324) tlck = txLock(tid, ip, split->mp, tlckXTREE | tlckGROW);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1325) xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1326) xtlck->lwm.offset = XTENTRYSTART;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1327) xtlck->lwm.length = 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1328) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1329)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1330) *rmpp = rmp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1331)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1332) jfs_info("xtSplitRoot: sp:0x%p rp:0x%p", sp, rp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1333) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1334) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1335)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1336)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1337) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1338) * xtExtend()
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1339) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1340) * function: extend in-place;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1341) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1342) * note: existing extent may or may not have been committed.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1343) * caller is responsible for pager buffer cache update, and
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1344) * working block allocation map update;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1345) * update pmap: alloc whole extended extent;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1346) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1347) int xtExtend(tid_t tid, /* transaction id */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1348) struct inode *ip, s64 xoff, /* delta extent offset */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1349) s32 xlen, /* delta extent length */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1350) int flag)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1351) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1352) int rc = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1353) int cmp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1354) struct metapage *mp; /* meta-page buffer */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1355) xtpage_t *p; /* base B+-tree index page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1356) s64 bn;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1357) int index, nextindex, len;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1358) struct btstack btstack; /* traverse stack */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1359) struct xtsplit split; /* split information */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1360) xad_t *xad;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1361) s64 xaddr;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1362) struct tlock *tlck;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1363) struct xtlock *xtlck = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1364)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1365) jfs_info("xtExtend: nxoff:0x%lx nxlen:0x%x", (ulong) xoff, xlen);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1366)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1367) /* there must exist extent to be extended */
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 1368) if ((rc = xtSearch(ip, xoff - 1, NULL, &cmp, &btstack, XT_INSERT)))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1369) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1370)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1371) /* retrieve search result */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1372) XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1373)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1374) if (cmp != 0) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1375) XT_PUTPAGE(mp);
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 1376) jfs_error(ip->i_sb, "xtSearch did not find extent\n");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1377) return -EIO;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1378) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1379)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1380) /* extension must be contiguous */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1381) xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1382) if ((offsetXAD(xad) + lengthXAD(xad)) != xoff) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1383) XT_PUTPAGE(mp);
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 1384) jfs_error(ip->i_sb, "extension is not contiguous\n");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1385) return -EIO;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1386) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1387)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1388) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1389) * acquire a transaction lock on the leaf page;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1390) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1391) * action: xad insertion/extension;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1392) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1393) BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1394) if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1395) tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1396) xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1397) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1398)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1399) /* extend will overflow extent ? */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1400) xlen = lengthXAD(xad) + xlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1401) if ((len = xlen - MAXXLEN) <= 0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1402) goto extendOld;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1403)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1404) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1405) * extent overflow: insert entry for new extent
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1406) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1407) //insertNew:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1408) xoff = offsetXAD(xad) + MAXXLEN;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1409) xaddr = addressXAD(xad) + MAXXLEN;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1410) nextindex = le16_to_cpu(p->header.nextindex);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1411)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1412) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1413) * if the leaf page is full, insert the new entry and
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1414) * propagate up the router entry for the new page from split
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1415) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1416) * The xtSplitUp() will insert the entry and unpin the leaf page.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1417) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1418) if (nextindex == le16_to_cpu(p->header.maxentry)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1419) /* xtSpliUp() unpins leaf pages */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1420) split.mp = mp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1421) split.index = index + 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1422) split.flag = XAD_NEW;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1423) split.off = xoff; /* split offset */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1424) split.len = len;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1425) split.addr = xaddr;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1426) split.pxdlist = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1427) if ((rc = xtSplitUp(tid, ip, &split, &btstack)))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1428) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1429)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1430) /* get back old page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1431) XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1432) if (rc)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1433) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1434) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1435) * if leaf root has been split, original root has been
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1436) * copied to new child page, i.e., original entry now
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1437) * resides on the new child page;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1438) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1439) if (p->header.flag & BT_INTERNAL) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1440) ASSERT(p->header.nextindex ==
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1441) cpu_to_le16(XTENTRYSTART + 1));
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1442) xad = &p->xad[XTENTRYSTART];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1443) bn = addressXAD(xad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1444) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1445)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1446) /* get new child page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1447) XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1448) if (rc)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1449) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1450)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1451) BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1452) if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1453) tlck = txLock(tid, ip, mp, tlckXTREE|tlckGROW);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1454) xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1455) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1456) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1457) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1458) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1459) * insert the new entry into the leaf page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1460) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1461) else {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1462) /* insert the new entry: mark the entry NEW */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1463) xad = &p->xad[index + 1];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1464) XT_PUTENTRY(xad, XAD_NEW, xoff, len, xaddr);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1465)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1466) /* advance next available entry index */
891456227881d (Marcin Slusarz 2008-02-13 15:34:20 -0600 1467) le16_add_cpu(&p->header.nextindex, 1);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1468) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1469)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1470) /* get back old entry */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1471) xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1472) xlen = MAXXLEN;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1473)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1474) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1475) * extend old extent
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1476) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1477) extendOld:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1478) XADlength(xad, xlen);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1479) if (!(xad->flag & XAD_NEW))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1480) xad->flag |= XAD_EXTENDED;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1481)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1482) if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1483) xtlck->lwm.offset =
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1484) (xtlck->lwm.offset) ? min(index,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1485) (int)xtlck->lwm.offset) : index;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1486) xtlck->lwm.length =
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1487) le16_to_cpu(p->header.nextindex) - xtlck->lwm.offset;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1488) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1489)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1490) /* unpin the leaf page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1491) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1492)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1493) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1494) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1495)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1496) #ifdef _NOTYET
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1497) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1498) * xtTailgate()
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1499) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1500) * function: split existing 'tail' extent
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1501) * (split offset >= start offset of tail extent), and
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1502) * relocate and extend the split tail half;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1503) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1504) * note: existing extent may or may not have been committed.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1505) * caller is responsible for pager buffer cache update, and
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1506) * working block allocation map update;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1507) * update pmap: free old split tail extent, alloc new extent;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1508) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1509) int xtTailgate(tid_t tid, /* transaction id */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1510) struct inode *ip, s64 xoff, /* split/new extent offset */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1511) s32 xlen, /* new extent length */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1512) s64 xaddr, /* new extent address */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1513) int flag)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1514) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1515) int rc = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1516) int cmp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1517) struct metapage *mp; /* meta-page buffer */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1518) xtpage_t *p; /* base B+-tree index page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1519) s64 bn;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1520) int index, nextindex, llen, rlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1521) struct btstack btstack; /* traverse stack */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1522) struct xtsplit split; /* split information */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1523) xad_t *xad;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1524) struct tlock *tlck;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1525) struct xtlock *xtlck = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1526) struct tlock *mtlck;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1527) struct maplock *pxdlock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1528)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1529) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1530) printf("xtTailgate: nxoff:0x%lx nxlen:0x%x nxaddr:0x%lx\n",
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1531) (ulong)xoff, xlen, (ulong)xaddr);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1532) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1533)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1534) /* there must exist extent to be tailgated */
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 1535) if ((rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, XT_INSERT)))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1536) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1537)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1538) /* retrieve search result */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1539) XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1540)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1541) if (cmp != 0) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1542) XT_PUTPAGE(mp);
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 1543) jfs_error(ip->i_sb, "couldn't find extent\n");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1544) return -EIO;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1545) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1546)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1547) /* entry found must be last entry */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1548) nextindex = le16_to_cpu(p->header.nextindex);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1549) if (index != nextindex - 1) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1550) XT_PUTPAGE(mp);
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 1551) jfs_error(ip->i_sb, "the entry found is not the last entry\n");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1552) return -EIO;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1553) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1554)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1555) BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1556) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1557) * acquire tlock of the leaf page containing original entry
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1558) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1559) if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1560) tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1561) xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1562) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1563)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1564) /* completely replace extent ? */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1565) xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1566) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1567) printf("xtTailgate: xoff:0x%lx xlen:0x%x xaddr:0x%lx\n",
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1568) (ulong)offsetXAD(xad), lengthXAD(xad), (ulong)addressXAD(xad));
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1569) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1570) if ((llen = xoff - offsetXAD(xad)) == 0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1571) goto updateOld;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1572)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1573) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1574) * partially replace extent: insert entry for new extent
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1575) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1576) //insertNew:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1577) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1578) * if the leaf page is full, insert the new entry and
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1579) * propagate up the router entry for the new page from split
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1580) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1581) * The xtSplitUp() will insert the entry and unpin the leaf page.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1582) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1583) if (nextindex == le16_to_cpu(p->header.maxentry)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1584) /* xtSpliUp() unpins leaf pages */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1585) split.mp = mp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1586) split.index = index + 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1587) split.flag = XAD_NEW;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1588) split.off = xoff; /* split offset */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1589) split.len = xlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1590) split.addr = xaddr;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1591) split.pxdlist = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1592) if ((rc = xtSplitUp(tid, ip, &split, &btstack)))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1593) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1594)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1595) /* get back old page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1596) XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1597) if (rc)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1598) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1599) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1600) * if leaf root has been split, original root has been
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1601) * copied to new child page, i.e., original entry now
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1602) * resides on the new child page;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1603) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1604) if (p->header.flag & BT_INTERNAL) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1605) ASSERT(p->header.nextindex ==
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1606) cpu_to_le16(XTENTRYSTART + 1));
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1607) xad = &p->xad[XTENTRYSTART];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1608) bn = addressXAD(xad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1609) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1610)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1611) /* get new child page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1612) XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1613) if (rc)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1614) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1615)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1616) BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1617) if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1618) tlck = txLock(tid, ip, mp, tlckXTREE|tlckGROW);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1619) xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1620) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1621) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1622) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1623) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1624) * insert the new entry into the leaf page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1625) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1626) else {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1627) /* insert the new entry: mark the entry NEW */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1628) xad = &p->xad[index + 1];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1629) XT_PUTENTRY(xad, XAD_NEW, xoff, xlen, xaddr);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1630)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1631) /* advance next available entry index */
891456227881d (Marcin Slusarz 2008-02-13 15:34:20 -0600 1632) le16_add_cpu(&p->header.nextindex, 1);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1633) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1634)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1635) /* get back old XAD */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1636) xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1637)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1638) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1639) * truncate/relocate old extent at split offset
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1640) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1641) updateOld:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1642) /* update dmap for old/committed/truncated extent */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1643) rlen = lengthXAD(xad) - llen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1644) if (!(xad->flag & XAD_NEW)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1645) /* free from PWMAP at commit */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1646) if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1647) mtlck = txMaplock(tid, ip, tlckMAP);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1648) pxdlock = (struct maplock *) & mtlck->lock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1649) pxdlock->flag = mlckFREEPXD;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1650) PXDaddress(&pxdlock->pxd, addressXAD(xad) + llen);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1651) PXDlength(&pxdlock->pxd, rlen);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1652) pxdlock->index = 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1653) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1654) } else
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1655) /* free from WMAP */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1656) dbFree(ip, addressXAD(xad) + llen, (s64) rlen);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1657)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1658) if (llen)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1659) /* truncate */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1660) XADlength(xad, llen);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1661) else
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1662) /* replace */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1663) XT_PUTENTRY(xad, XAD_NEW, xoff, xlen, xaddr);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1664)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1665) if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1666) xtlck->lwm.offset = (xtlck->lwm.offset) ?
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1667) min(index, (int)xtlck->lwm.offset) : index;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1668) xtlck->lwm.length = le16_to_cpu(p->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1669) xtlck->lwm.offset;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1670) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1671)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1672) /* unpin the leaf page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1673) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1674)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1675) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1676) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1677) #endif /* _NOTYET */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1678)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1679) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1680) * xtUpdate()
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1681) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1682) * function: update XAD;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1683) *
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1684) * update extent for allocated_but_not_recorded or
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1685) * compressed extent;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1686) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1687) * parameter:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1688) * nxad - new XAD;
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1689) * logical extent of the specified XAD must be completely
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 1690) * contained by an existing XAD;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1691) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1692) int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1693) { /* new XAD */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1694) int rc = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1695) int cmp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1696) struct metapage *mp; /* meta-page buffer */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1697) xtpage_t *p; /* base B+-tree index page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1698) s64 bn;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1699) int index0, index, newindex, nextindex;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1700) struct btstack btstack; /* traverse stack */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1701) struct xtsplit split; /* split information */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1702) xad_t *xad, *lxad, *rxad;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1703) int xflag;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1704) s64 nxoff, xoff;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1705) int nxlen, xlen, lxlen, rxlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1706) s64 nxaddr, xaddr;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1707) struct tlock *tlck;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1708) struct xtlock *xtlck = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1709) int newpage = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1710)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1711) /* there must exist extent to be tailgated */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1712) nxoff = offsetXAD(nxad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1713) nxlen = lengthXAD(nxad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1714) nxaddr = addressXAD(nxad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1715)
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 1716) if ((rc = xtSearch(ip, nxoff, NULL, &cmp, &btstack, XT_INSERT)))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1717) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1718)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1719) /* retrieve search result */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1720) XT_GETSEARCH(ip, btstack.top, bn, mp, p, index0);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1721)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1722) if (cmp != 0) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1723) XT_PUTPAGE(mp);
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 1724) jfs_error(ip->i_sb, "Could not find extent\n");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1725) return -EIO;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1726) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1727)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1728) BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1729) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1730) * acquire tlock of the leaf page containing original entry
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1731) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1732) if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1733) tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1734) xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1735) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1736)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1737) xad = &p->xad[index0];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1738) xflag = xad->flag;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1739) xoff = offsetXAD(xad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1740) xlen = lengthXAD(xad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1741) xaddr = addressXAD(xad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1742)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1743) /* nXAD must be completely contained within XAD */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1744) if ((xoff > nxoff) ||
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1745) (nxoff + nxlen > xoff + xlen)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1746) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1747) jfs_error(ip->i_sb,
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 1748) "nXAD in not completely contained within XAD\n");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1749) return -EIO;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1750) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1751)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1752) index = index0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1753) newindex = index + 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1754) nextindex = le16_to_cpu(p->header.nextindex);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1755)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1756) #ifdef _JFS_WIP_NOCOALESCE
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1757) if (xoff < nxoff)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1758) goto updateRight;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1759)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1760) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1761) * replace XAD with nXAD
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1762) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1763) replace: /* (nxoff == xoff) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1764) if (nxlen == xlen) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1765) /* replace XAD with nXAD:recorded */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1766) *xad = *nxad;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1767) xad->flag = xflag & ~XAD_NOTRECORDED;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1768)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1769) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1770) } else /* (nxlen < xlen) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1771) goto updateLeft;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1772) #endif /* _JFS_WIP_NOCOALESCE */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1773)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1774) /* #ifdef _JFS_WIP_COALESCE */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1775) if (xoff < nxoff)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1776) goto coalesceRight;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1777)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1778) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1779) * coalesce with left XAD
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1780) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1781) //coalesceLeft: /* (xoff == nxoff) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1782) /* is XAD first entry of page ? */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1783) if (index == XTENTRYSTART)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1784) goto replace;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1785)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1786) /* is nXAD logically and physically contiguous with lXAD ? */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1787) lxad = &p->xad[index - 1];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1788) lxlen = lengthXAD(lxad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1789) if (!(lxad->flag & XAD_NOTRECORDED) &&
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1790) (nxoff == offsetXAD(lxad) + lxlen) &&
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1791) (nxaddr == addressXAD(lxad) + lxlen) &&
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1792) (lxlen + nxlen < MAXXLEN)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1793) /* extend right lXAD */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1794) index0 = index - 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1795) XADlength(lxad, lxlen + nxlen);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1796)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1797) /* If we just merged two extents together, need to make sure the
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1798) * right extent gets logged. If the left one is marked XAD_NEW,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1799) * then we know it will be logged. Otherwise, mark as
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1800) * XAD_EXTENDED
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1801) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1802) if (!(lxad->flag & XAD_NEW))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1803) lxad->flag |= XAD_EXTENDED;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1804)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1805) if (xlen > nxlen) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1806) /* truncate XAD */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1807) XADoffset(xad, xoff + nxlen);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1808) XADlength(xad, xlen - nxlen);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1809) XADaddress(xad, xaddr + nxlen);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1810) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1811) } else { /* (xlen == nxlen) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1812)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1813) /* remove XAD */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1814) if (index < nextindex - 1)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1815) memmove(&p->xad[index], &p->xad[index + 1],
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1816) (nextindex - index -
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1817) 1) << L2XTSLOTSIZE);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1818)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1819) p->header.nextindex =
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1820) cpu_to_le16(le16_to_cpu(p->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1821) 1);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1822)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1823) index = index0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1824) newindex = index + 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1825) nextindex = le16_to_cpu(p->header.nextindex);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1826) xoff = nxoff = offsetXAD(lxad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1827) xlen = nxlen = lxlen + nxlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1828) xaddr = nxaddr = addressXAD(lxad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1829) goto coalesceRight;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1830) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1831) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1832)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1833) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1834) * replace XAD with nXAD
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1835) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1836) replace: /* (nxoff == xoff) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1837) if (nxlen == xlen) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1838) /* replace XAD with nXAD:recorded */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1839) *xad = *nxad;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1840) xad->flag = xflag & ~XAD_NOTRECORDED;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1841)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1842) goto coalesceRight;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1843) } else /* (nxlen < xlen) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1844) goto updateLeft;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1845)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1846) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1847) * coalesce with right XAD
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1848) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1849) coalesceRight: /* (xoff <= nxoff) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1850) /* is XAD last entry of page ? */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1851) if (newindex == nextindex) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1852) if (xoff == nxoff)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1853) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1854) goto updateRight;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1855) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1856)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1857) /* is nXAD logically and physically contiguous with rXAD ? */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1858) rxad = &p->xad[index + 1];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1859) rxlen = lengthXAD(rxad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1860) if (!(rxad->flag & XAD_NOTRECORDED) &&
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1861) (nxoff + nxlen == offsetXAD(rxad)) &&
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1862) (nxaddr + nxlen == addressXAD(rxad)) &&
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1863) (rxlen + nxlen < MAXXLEN)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1864) /* extend left rXAD */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1865) XADoffset(rxad, nxoff);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1866) XADlength(rxad, rxlen + nxlen);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1867) XADaddress(rxad, nxaddr);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1868)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1869) /* If we just merged two extents together, need to make sure
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1870) * the left extent gets logged. If the right one is marked
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1871) * XAD_NEW, then we know it will be logged. Otherwise, mark as
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1872) * XAD_EXTENDED
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1873) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1874) if (!(rxad->flag & XAD_NEW))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1875) rxad->flag |= XAD_EXTENDED;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1876)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1877) if (xlen > nxlen)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1878) /* truncate XAD */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1879) XADlength(xad, xlen - nxlen);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1880) else { /* (xlen == nxlen) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1881)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1882) /* remove XAD */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1883) memmove(&p->xad[index], &p->xad[index + 1],
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1884) (nextindex - index - 1) << L2XTSLOTSIZE);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1885)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1886) p->header.nextindex =
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1887) cpu_to_le16(le16_to_cpu(p->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1888) 1);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1889) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1890)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1891) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1892) } else if (xoff == nxoff)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1893) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1894)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1895) if (xoff >= nxoff) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1896) XT_PUTPAGE(mp);
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 1897) jfs_error(ip->i_sb, "xoff >= nxoff\n");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1898) return -EIO;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1899) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1900) /* #endif _JFS_WIP_COALESCE */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1901)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1902) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1903) * split XAD into (lXAD, nXAD):
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1904) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1905) * |---nXAD--->
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1906) * --|----------XAD----------|--
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1907) * |-lXAD-|
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1908) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1909) updateRight: /* (xoff < nxoff) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1910) /* truncate old XAD as lXAD:not_recorded */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1911) xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1912) XADlength(xad, nxoff - xoff);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1913)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1914) /* insert nXAD:recorded */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1915) if (nextindex == le16_to_cpu(p->header.maxentry)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1916)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1917) /* xtSpliUp() unpins leaf pages */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1918) split.mp = mp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1919) split.index = newindex;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1920) split.flag = xflag & ~XAD_NOTRECORDED;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1921) split.off = nxoff;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1922) split.len = nxlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1923) split.addr = nxaddr;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1924) split.pxdlist = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1925) if ((rc = xtSplitUp(tid, ip, &split, &btstack)))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1926) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1927)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1928) /* get back old page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1929) XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1930) if (rc)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1931) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1932) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1933) * if leaf root has been split, original root has been
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1934) * copied to new child page, i.e., original entry now
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1935) * resides on the new child page;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1936) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1937) if (p->header.flag & BT_INTERNAL) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1938) ASSERT(p->header.nextindex ==
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1939) cpu_to_le16(XTENTRYSTART + 1));
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1940) xad = &p->xad[XTENTRYSTART];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1941) bn = addressXAD(xad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1942) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1943)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1944) /* get new child page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1945) XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1946) if (rc)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1947) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1948)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1949) BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1950) if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1951) tlck = txLock(tid, ip, mp, tlckXTREE|tlckGROW);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1952) xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1953) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1954) } else {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1955) /* is nXAD on new page ? */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1956) if (newindex >
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1957) (le16_to_cpu(p->header.maxentry) >> 1)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1958) newindex =
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1959) newindex -
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1960) le16_to_cpu(p->header.nextindex) +
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1961) XTENTRYSTART;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1962) newpage = 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1963) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1964) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1965) } else {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1966) /* if insert into middle, shift right remaining entries */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1967) if (newindex < nextindex)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1968) memmove(&p->xad[newindex + 1], &p->xad[newindex],
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1969) (nextindex - newindex) << L2XTSLOTSIZE);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1970)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1971) /* insert the entry */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1972) xad = &p->xad[newindex];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1973) *xad = *nxad;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1974) xad->flag = xflag & ~XAD_NOTRECORDED;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1975)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1976) /* advance next available entry index. */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1977) p->header.nextindex =
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1978) cpu_to_le16(le16_to_cpu(p->header.nextindex) + 1);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1979) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1980)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1981) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1982) * does nXAD force 3-way split ?
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1983) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1984) * |---nXAD--->|
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1985) * --|----------XAD-------------|--
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1986) * |-lXAD-| |-rXAD -|
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1987) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1988) if (nxoff + nxlen == xoff + xlen)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1989) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1990)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1991) /* reorient nXAD as XAD for further split XAD into (nXAD, rXAD) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1992) if (newpage) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1993) /* close out old page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1994) if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1995) xtlck->lwm.offset = (xtlck->lwm.offset) ?
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1996) min(index0, (int)xtlck->lwm.offset) : index0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1997) xtlck->lwm.length =
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1998) le16_to_cpu(p->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1999) xtlck->lwm.offset;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2000) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2001)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2002) bn = le64_to_cpu(p->header.next);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2003) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2004)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2005) /* get new right page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2006) XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2007) if (rc)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2008) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2009)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2010) BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2011) if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2012) tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2013) xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2014) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2015)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2016) index0 = index = newindex;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2017) } else
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2018) index++;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2019)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2020) newindex = index + 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2021) nextindex = le16_to_cpu(p->header.nextindex);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2022) xlen = xlen - (nxoff - xoff);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2023) xoff = nxoff;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2024) xaddr = nxaddr;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2025)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2026) /* recompute split pages */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2027) if (nextindex == le16_to_cpu(p->header.maxentry)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2028) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2029)
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 2030) if ((rc = xtSearch(ip, nxoff, NULL, &cmp, &btstack, XT_INSERT)))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2031) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2032)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2033) /* retrieve search result */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2034) XT_GETSEARCH(ip, btstack.top, bn, mp, p, index0);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2035)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2036) if (cmp != 0) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2037) XT_PUTPAGE(mp);
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 2038) jfs_error(ip->i_sb, "xtSearch failed\n");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2039) return -EIO;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2040) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2041)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2042) if (index0 != index) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2043) XT_PUTPAGE(mp);
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 2044) jfs_error(ip->i_sb, "unexpected value of index\n");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2045) return -EIO;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2046) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2047) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2048)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2049) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2050) * split XAD into (nXAD, rXAD)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2051) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2052) * ---nXAD---|
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2053) * --|----------XAD----------|--
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2054) * |-rXAD-|
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2055) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2056) updateLeft: /* (nxoff == xoff) && (nxlen < xlen) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2057) /* update old XAD with nXAD:recorded */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2058) xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2059) *xad = *nxad;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2060) xad->flag = xflag & ~XAD_NOTRECORDED;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2061)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2062) /* insert rXAD:not_recorded */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2063) xoff = xoff + nxlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2064) xlen = xlen - nxlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2065) xaddr = xaddr + nxlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2066) if (nextindex == le16_to_cpu(p->header.maxentry)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2067) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2068) printf("xtUpdate.updateLeft.split p:0x%p\n", p);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2069) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2070) /* xtSpliUp() unpins leaf pages */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2071) split.mp = mp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2072) split.index = newindex;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2073) split.flag = xflag;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2074) split.off = xoff;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2075) split.len = xlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2076) split.addr = xaddr;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2077) split.pxdlist = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2078) if ((rc = xtSplitUp(tid, ip, &split, &btstack)))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2079) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2080)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2081) /* get back old page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2082) XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2083) if (rc)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2084) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2085)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2086) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2087) * if leaf root has been split, original root has been
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2088) * copied to new child page, i.e., original entry now
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2089) * resides on the new child page;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2090) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2091) if (p->header.flag & BT_INTERNAL) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2092) ASSERT(p->header.nextindex ==
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2093) cpu_to_le16(XTENTRYSTART + 1));
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2094) xad = &p->xad[XTENTRYSTART];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2095) bn = addressXAD(xad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2096) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2097)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2098) /* get new child page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2099) XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2100) if (rc)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2101) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2102)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2103) BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2104) if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2105) tlck = txLock(tid, ip, mp, tlckXTREE|tlckGROW);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2106) xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2107) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2108) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2109) } else {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2110) /* if insert into middle, shift right remaining entries */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2111) if (newindex < nextindex)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2112) memmove(&p->xad[newindex + 1], &p->xad[newindex],
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2113) (nextindex - newindex) << L2XTSLOTSIZE);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2114)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2115) /* insert the entry */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2116) xad = &p->xad[newindex];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2117) XT_PUTENTRY(xad, xflag, xoff, xlen, xaddr);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2118)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2119) /* advance next available entry index. */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2120) p->header.nextindex =
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2121) cpu_to_le16(le16_to_cpu(p->header.nextindex) + 1);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2122) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2123)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2124) out:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2125) if (!test_cflag(COMMIT_Nolink, ip)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2126) xtlck->lwm.offset = (xtlck->lwm.offset) ?
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2127) min(index0, (int)xtlck->lwm.offset) : index0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2128) xtlck->lwm.length = le16_to_cpu(p->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2129) xtlck->lwm.offset;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2130) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2131)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2132) /* unpin the leaf page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2133) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2134)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2135) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2136) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2137)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2138)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2139) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2140) * xtAppend()
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2141) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2142) * function: grow in append mode from contiguous region specified ;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2143) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2144) * parameter:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2145) * tid - transaction id;
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2146) * ip - file object;
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2147) * xflag - extent flag:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2148) * xoff - extent offset;
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2149) * maxblocks - max extent length;
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2150) * xlen - extent length (in/out);
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2151) * xaddrp - extent address pointer (in/out):
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2152) * flag -
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2153) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2154) * return:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2155) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2156) int xtAppend(tid_t tid, /* transaction id */
63f83c9fcf40a (Dave Kleikamp 2006-10-02 09:55:27 -0500 2157) struct inode *ip, int xflag, s64 xoff, s32 maxblocks,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2158) s32 * xlenp, /* (in/out) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2159) s64 * xaddrp, /* (in/out) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2160) int flag)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2161) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2162) int rc = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2163) struct metapage *mp; /* meta-page buffer */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2164) xtpage_t *p; /* base B+-tree index page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2165) s64 bn, xaddr;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2166) int index, nextindex;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2167) struct btstack btstack; /* traverse stack */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2168) struct xtsplit split; /* split information */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2169) xad_t *xad;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2170) int cmp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2171) struct tlock *tlck;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2172) struct xtlock *xtlck;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2173) int nsplit, nblocks, xlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2174) struct pxdlist pxdlist;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2175) pxd_t *pxd;
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 2176) s64 next;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2177)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2178) xaddr = *xaddrp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2179) xlen = *xlenp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2180) jfs_info("xtAppend: xoff:0x%lx maxblocks:%d xlen:%d xaddr:0x%lx",
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2181) (ulong) xoff, maxblocks, xlen, (ulong) xaddr);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2182)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2183) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2184) * search for the entry location at which to insert:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2185) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2186) * xtFastSearch() and xtSearch() both returns (leaf page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2187) * pinned, index at which to insert).
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2188) * n.b. xtSearch() may return index of maxentry of
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2189) * the full page.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2190) */
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 2191) if ((rc = xtSearch(ip, xoff, &next, &cmp, &btstack, XT_INSERT)))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2192) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2193)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2194) /* retrieve search result */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2195) XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2196)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2197) if (cmp == 0) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2198) rc = -EEXIST;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2199) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2200) }
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 2201)
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 2202) if (next)
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 2203) xlen = min(xlen, (int)(next - xoff));
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2204) //insert:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2205) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2206) * insert entry for new extent
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2207) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2208) xflag |= XAD_NEW;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2209)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2210) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2211) * if the leaf page is full, split the page and
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2212) * propagate up the router entry for the new page from split
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2213) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2214) * The xtSplitUp() will insert the entry and unpin the leaf page.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2215) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2216) nextindex = le16_to_cpu(p->header.nextindex);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2217) if (nextindex < le16_to_cpu(p->header.maxentry))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2218) goto insertLeaf;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2219)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2220) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2221) * allocate new index blocks to cover index page split(s)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2222) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2223) nsplit = btstack.nsplit;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2224) split.pxdlist = &pxdlist;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2225) pxdlist.maxnpxd = pxdlist.npxd = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2226) pxd = &pxdlist.pxd[0];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2227) nblocks = JFS_SBI(ip->i_sb)->nbperpage;
63f83c9fcf40a (Dave Kleikamp 2006-10-02 09:55:27 -0500 2228) for (; nsplit > 0; nsplit--, pxd++, xaddr += nblocks, maxblocks -= nblocks) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2229) if ((rc = dbAllocBottomUp(ip, xaddr, (s64) nblocks)) == 0) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2230) PXDaddress(pxd, xaddr);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2231) PXDlength(pxd, nblocks);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2232)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2233) pxdlist.maxnpxd++;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2234)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2235) continue;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2236) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2237)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2238) /* undo allocation */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2239)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2240) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2241) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2242)
63f83c9fcf40a (Dave Kleikamp 2006-10-02 09:55:27 -0500 2243) xlen = min(xlen, maxblocks);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2244)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2245) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2246) * allocate data extent requested
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2247) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2248) if ((rc = dbAllocBottomUp(ip, xaddr, (s64) xlen)))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2249) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2250)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2251) split.mp = mp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2252) split.index = index;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2253) split.flag = xflag;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2254) split.off = xoff;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2255) split.len = xlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2256) split.addr = xaddr;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2257) if ((rc = xtSplitUp(tid, ip, &split, &btstack))) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2258) /* undo data extent allocation */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2259) dbFree(ip, *xaddrp, (s64) * xlenp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2260)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2261) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2262) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2263)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2264) *xaddrp = xaddr;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2265) *xlenp = xlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2266) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2267)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2268) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2269) * insert the new entry into the leaf page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2270) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2271) insertLeaf:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2272) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2273) * allocate data extent requested
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2274) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2275) if ((rc = dbAllocBottomUp(ip, xaddr, (s64) xlen)))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2276) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2277)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2278) BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2279) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2280) * acquire a transaction lock on the leaf page;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2281) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2282) * action: xad insertion/extension;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2283) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2284) tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2285) xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2286)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2287) /* insert the new entry: mark the entry NEW */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2288) xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2289) XT_PUTENTRY(xad, xflag, xoff, xlen, xaddr);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2290)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2291) /* advance next available entry index */
891456227881d (Marcin Slusarz 2008-02-13 15:34:20 -0600 2292) le16_add_cpu(&p->header.nextindex, 1);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2293)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2294) xtlck->lwm.offset =
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2295) (xtlck->lwm.offset) ? min(index,(int) xtlck->lwm.offset) : index;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2296) xtlck->lwm.length = le16_to_cpu(p->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2297) xtlck->lwm.offset;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2298)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2299) *xaddrp = xaddr;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2300) *xlenp = xlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2301)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2302) out:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2303) /* unpin the leaf page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2304) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2305)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2306) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2307) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2308) #ifdef _STILL_TO_PORT
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2309)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2310) /* - TBD for defragmentaion/reorganization -
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2311) *
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2312) * xtDelete()
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2313) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2314) * function:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2315) * delete the entry with the specified key.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2316) *
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2317) * N.B.: whole extent of the entry is assumed to be deleted.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2318) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2319) * parameter:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2320) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2321) * return:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2322) * ENOENT: if the entry is not found.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2323) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2324) * exception:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2325) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2326) int xtDelete(tid_t tid, struct inode *ip, s64 xoff, s32 xlen, int flag)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2327) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2328) int rc = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2329) struct btstack btstack;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2330) int cmp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2331) s64 bn;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2332) struct metapage *mp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2333) xtpage_t *p;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2334) int index, nextindex;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2335) struct tlock *tlck;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2336) struct xtlock *xtlck;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2337)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2338) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2339) * find the matching entry; xtSearch() pins the page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2340) */
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 2341) if ((rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0)))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2342) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2343)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2344) XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2345) if (cmp) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2346) /* unpin the leaf page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2347) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2348) return -ENOENT;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2349) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2350)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2351) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2352) * delete the entry from the leaf page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2353) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2354) nextindex = le16_to_cpu(p->header.nextindex);
891456227881d (Marcin Slusarz 2008-02-13 15:34:20 -0600 2355) le16_add_cpu(&p->header.nextindex, -1);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2356)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2357) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2358) * if the leaf page bocome empty, free the page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2359) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2360) if (p->header.nextindex == cpu_to_le16(XTENTRYSTART))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2361) return (xtDeleteUp(tid, ip, mp, p, &btstack));
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2362)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2363) BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2364) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2365) * acquire a transaction lock on the leaf page;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2366) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2367) * action:xad deletion;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2368) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2369) tlck = txLock(tid, ip, mp, tlckXTREE);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2370) xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2371) xtlck->lwm.offset =
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2372) (xtlck->lwm.offset) ? min(index, xtlck->lwm.offset) : index;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2373)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2374) /* if delete from middle, shift left/compact the remaining entries */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2375) if (index < nextindex - 1)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2376) memmove(&p->xad[index], &p->xad[index + 1],
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2377) (nextindex - index - 1) * sizeof(xad_t));
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2378)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2379) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2380)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2381) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2382) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2383)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2384)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2385) /* - TBD for defragmentaion/reorganization -
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2386) *
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2387) * xtDeleteUp()
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2388) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2389) * function:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2390) * free empty pages as propagating deletion up the tree
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2391) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2392) * parameter:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2393) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2394) * return:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2395) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2396) static int
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2397) xtDeleteUp(tid_t tid, struct inode *ip,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2398) struct metapage * fmp, xtpage_t * fp, struct btstack * btstack)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2399) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2400) int rc = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2401) struct metapage *mp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2402) xtpage_t *p;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2403) int index, nextindex;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2404) s64 xaddr;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2405) int xlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2406) struct btframe *parent;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2407) struct tlock *tlck;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2408) struct xtlock *xtlck;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2409)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2410) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2411) * keep root leaf page which has become empty
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2412) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2413) if (fp->header.flag & BT_ROOT) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2414) /* keep the root page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2415) fp->header.flag &= ~BT_INTERNAL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2416) fp->header.flag |= BT_LEAF;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2417) fp->header.nextindex = cpu_to_le16(XTENTRYSTART);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2418)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2419) /* XT_PUTPAGE(fmp); */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2420)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2421) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2422) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2423)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2424) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2425) * free non-root leaf page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2426) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2427) if ((rc = xtRelink(tid, ip, fp))) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2428) XT_PUTPAGE(fmp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2429) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2430) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2431)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2432) xaddr = addressPXD(&fp->header.self);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2433) xlen = lengthPXD(&fp->header.self);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2434) /* free the page extent */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2435) dbFree(ip, xaddr, (s64) xlen);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2436)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2437) /* free the buffer page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2438) discard_metapage(fmp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2439)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2440) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2441) * propagate page deletion up the index tree
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2442) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2443) * If the delete from the parent page makes it empty,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2444) * continue all the way up the tree.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2445) * stop if the root page is reached (which is never deleted) or
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2446) * if the entry deletion does not empty the page.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2447) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2448) while ((parent = BT_POP(btstack)) != NULL) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2449) /* get/pin the parent page <sp> */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2450) XT_GETPAGE(ip, parent->bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2451) if (rc)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2452) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2453)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2454) index = parent->index;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2455)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2456) /* delete the entry for the freed child page from parent.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2457) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2458) nextindex = le16_to_cpu(p->header.nextindex);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2459)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2460) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2461) * the parent has the single entry being deleted:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2462) * free the parent page which has become empty.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2463) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2464) if (nextindex == 1) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2465) if (p->header.flag & BT_ROOT) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2466) /* keep the root page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2467) p->header.flag &= ~BT_INTERNAL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2468) p->header.flag |= BT_LEAF;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2469) p->header.nextindex =
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2470) cpu_to_le16(XTENTRYSTART);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2471)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2472) /* XT_PUTPAGE(mp); */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2473)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2474) break;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2475) } else {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2476) /* free the parent page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2477) if ((rc = xtRelink(tid, ip, p)))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2478) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2479)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2480) xaddr = addressPXD(&p->header.self);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2481) /* free the page extent */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2482) dbFree(ip, xaddr,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2483) (s64) JFS_SBI(ip->i_sb)->nbperpage);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2484)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2485) /* unpin/free the buffer page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2486) discard_metapage(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2487)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2488) /* propagate up */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2489) continue;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2490) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2491) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2492) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2493) * the parent has other entries remaining:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2494) * delete the router entry from the parent page.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2495) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2496) else {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2497) BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2498) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2499) * acquire a transaction lock on the leaf page;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2500) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2501) * action:xad deletion;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2502) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2503) tlck = txLock(tid, ip, mp, tlckXTREE);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2504) xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2505) xtlck->lwm.offset =
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2506) (xtlck->lwm.offset) ? min(index,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2507) xtlck->lwm.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2508) offset) : index;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2509)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2510) /* if delete from middle,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2511) * shift left/compact the remaining entries in the page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2512) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2513) if (index < nextindex - 1)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2514) memmove(&p->xad[index], &p->xad[index + 1],
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2515) (nextindex - index -
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2516) 1) << L2XTSLOTSIZE);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2517)
891456227881d (Marcin Slusarz 2008-02-13 15:34:20 -0600 2518) le16_add_cpu(&p->header.nextindex, -1);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2519) jfs_info("xtDeleteUp(entry): 0x%lx[%d]",
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2520) (ulong) parent->bn, index);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2521) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2522)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2523) /* unpin the parent page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2524) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2525)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2526) /* exit propagation up */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2527) break;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2528) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2529)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2530) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2531) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2532)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2533)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2534) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2535) * NAME: xtRelocate()
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2536) *
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2537) * FUNCTION: relocate xtpage or data extent of regular file;
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2538) * This function is mainly used by defragfs utility.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2539) *
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2540) * NOTE: This routine does not have the logic to handle
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2541) * uncommitted allocated extent. The caller should call
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2542) * txCommit() to commit all the allocation before call
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2543) * this routine.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2544) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2545) int
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2546) xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2547) s64 nxaddr, /* new xaddr */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2548) int xtype)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2549) { /* extent type: XTPAGE or DATAEXT */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2550) int rc = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2551) struct tblock *tblk;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2552) struct tlock *tlck;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2553) struct xtlock *xtlck;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2554) struct metapage *mp, *pmp, *lmp, *rmp; /* meta-page buffer */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2555) xtpage_t *p, *pp, *rp, *lp; /* base B+-tree index page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2556) xad_t *xad;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2557) pxd_t *pxd;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2558) s64 xoff, xsize;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2559) int xlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2560) s64 oxaddr, sxaddr, dxaddr, nextbn, prevbn;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2561) cbuf_t *cp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2562) s64 offset, nbytes, nbrd, pno;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2563) int nb, npages, nblks;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2564) s64 bn;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2565) int cmp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2566) int index;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2567) struct pxd_lock *pxdlock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2568) struct btstack btstack; /* traverse stack */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2569)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2570) xtype = xtype & EXTENT_TYPE;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2571)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2572) xoff = offsetXAD(oxad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2573) oxaddr = addressXAD(oxad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2574) xlen = lengthXAD(oxad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2575)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2576) /* validate extent offset */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2577) offset = xoff << JFS_SBI(ip->i_sb)->l2bsize;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2578) if (offset >= ip->i_size)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2579) return -ESTALE; /* stale extent */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2580)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2581) jfs_info("xtRelocate: xtype:%d xoff:0x%lx xlen:0x%x xaddr:0x%lx:0x%lx",
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2582) xtype, (ulong) xoff, xlen, (ulong) oxaddr, (ulong) nxaddr);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2583)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2584) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2585) * 1. get and validate the parent xtpage/xad entry
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2586) * covering the source extent to be relocated;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2587) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2588) if (xtype == DATAEXT) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2589) /* search in leaf entry */
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 2590) rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2591) if (rc)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2592) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2593)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2594) /* retrieve search result */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2595) XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2596)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2597) if (cmp) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2598) XT_PUTPAGE(pmp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2599) return -ESTALE;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2600) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2601)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2602) /* validate for exact match with a single entry */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2603) xad = &pp->xad[index];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2604) if (addressXAD(xad) != oxaddr || lengthXAD(xad) != xlen) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2605) XT_PUTPAGE(pmp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2606) return -ESTALE;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2607) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2608) } else { /* (xtype == XTPAGE) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2609)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2610) /* search in internal entry */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2611) rc = xtSearchNode(ip, oxad, &cmp, &btstack, 0);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2612) if (rc)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2613) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2614)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2615) /* retrieve search result */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2616) XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2617)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2618) if (cmp) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2619) XT_PUTPAGE(pmp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2620) return -ESTALE;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2621) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2622)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2623) /* xtSearchNode() validated for exact match with a single entry
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2624) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2625) xad = &pp->xad[index];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2626) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2627) jfs_info("xtRelocate: parent xad entry validated.");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2628)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2629) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2630) * 2. relocate the extent
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2631) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2632) if (xtype == DATAEXT) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2633) /* if the extent is allocated-but-not-recorded
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2634) * there is no real data to be moved in this extent,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2635) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2636) if (xad->flag & XAD_NOTRECORDED)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2637) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2638) else
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2639) /* release xtpage for cmRead()/xtLookup() */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2640) XT_PUTPAGE(pmp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2641)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2642) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2643) * cmRelocate()
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2644) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2645) * copy target data pages to be relocated;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2646) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2647) * data extent must start at page boundary and
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2648) * multiple of page size (except the last data extent);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2649) * read in each page of the source data extent into cbuf,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2650) * update the cbuf extent descriptor of the page to be
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2651) * homeward bound to new dst data extent
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2652) * copy the data from the old extent to new extent.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2653) * copy is essential for compressed files to avoid problems
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2654) * that can arise if there was a change in compression
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2655) * algorithms.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2656) * it is a good strategy because it may disrupt cache
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2657) * policy to keep the pages in memory afterwards.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2658) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2659) offset = xoff << JFS_SBI(ip->i_sb)->l2bsize;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2660) assert((offset & CM_OFFSET) == 0);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2661) nbytes = xlen << JFS_SBI(ip->i_sb)->l2bsize;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2662) pno = offset >> CM_L2BSIZE;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2663) npages = (nbytes + (CM_BSIZE - 1)) >> CM_L2BSIZE;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2664) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2665) npages = ((offset + nbytes - 1) >> CM_L2BSIZE) -
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2666) (offset >> CM_L2BSIZE) + 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2667) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2668) sxaddr = oxaddr;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2669) dxaddr = nxaddr;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2670)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2671) /* process the request one cache buffer at a time */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2672) for (nbrd = 0; nbrd < nbytes; nbrd += nb,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2673) offset += nb, pno++, npages--) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2674) /* compute page size */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2675) nb = min(nbytes - nbrd, CM_BSIZE);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2676)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2677) /* get the cache buffer of the page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2678) if (rc = cmRead(ip, offset, npages, &cp))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2679) break;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2680)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2681) assert(addressPXD(&cp->cm_pxd) == sxaddr);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2682) assert(!cp->cm_modified);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2683)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2684) /* bind buffer with the new extent address */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2685) nblks = nb >> JFS_IP(ip->i_sb)->l2bsize;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2686) cmSetXD(ip, cp, pno, dxaddr, nblks);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2687)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2688) /* release the cbuf, mark it as modified */
4d81715fc5dfa (Richard Knutsson 2006-09-30 23:27:14 -0700 2689) cmPut(cp, true);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2690)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2691) dxaddr += nblks;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2692) sxaddr += nblks;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2693) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2694)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2695) /* get back parent page */
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 2696) if ((rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0)))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2697) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2698)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2699) XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2700) jfs_info("xtRelocate: target data extent relocated.");
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2701) } else { /* (xtype == XTPAGE) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2702)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2703) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2704) * read in the target xtpage from the source extent;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2705) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2706) XT_GETPAGE(ip, oxaddr, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2707) if (rc) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2708) XT_PUTPAGE(pmp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2709) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2710) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2711)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2712) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2713) * read in sibling pages if any to update sibling pointers;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2714) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2715) rmp = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2716) if (p->header.next) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2717) nextbn = le64_to_cpu(p->header.next);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2718) XT_GETPAGE(ip, nextbn, rmp, PSIZE, rp, rc);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2719) if (rc) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2720) XT_PUTPAGE(pmp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2721) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2722) return (rc);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2723) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2724) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2725)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2726) lmp = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2727) if (p->header.prev) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2728) prevbn = le64_to_cpu(p->header.prev);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2729) XT_GETPAGE(ip, prevbn, lmp, PSIZE, lp, rc);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2730) if (rc) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2731) XT_PUTPAGE(pmp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2732) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2733) if (rmp)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2734) XT_PUTPAGE(rmp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2735) return (rc);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2736) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2737) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2738)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2739) /* at this point, all xtpages to be updated are in memory */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2740)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2741) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2742) * update sibling pointers of sibling xtpages if any;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2743) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2744) if (lmp) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2745) BT_MARK_DIRTY(lmp, ip);
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2746) tlck = txLock(tid, ip, lmp, tlckXTREE | tlckRELINK);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2747) lp->header.next = cpu_to_le64(nxaddr);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2748) XT_PUTPAGE(lmp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2749) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2750)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2751) if (rmp) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2752) BT_MARK_DIRTY(rmp, ip);
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2753) tlck = txLock(tid, ip, rmp, tlckXTREE | tlckRELINK);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2754) rp->header.prev = cpu_to_le64(nxaddr);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2755) XT_PUTPAGE(rmp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2756) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2757)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2758) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2759) * update the target xtpage to be relocated
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2760) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2761) * update the self address of the target page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2762) * and write to destination extent;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2763) * redo image covers the whole xtpage since it is new page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2764) * to the destination extent;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2765) * update of bmap for the free of source extent
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2766) * of the target xtpage itself:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2767) * update of bmap for the allocation of destination extent
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2768) * of the target xtpage itself:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2769) * update of bmap for the extents covered by xad entries in
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2770) * the target xtpage is not necessary since they are not
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2771) * updated;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2772) * if not committed before this relocation,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2773) * target page may contain XAD_NEW entries which must
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2774) * be scanned for bmap update (logredo() always
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2775) * scan xtpage REDOPAGE image for bmap update);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2776) * if committed before this relocation (tlckRELOCATE),
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2777) * scan may be skipped by commit() and logredo();
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2778) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2779) BT_MARK_DIRTY(mp, ip);
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2780) /* tlckNEW init xtlck->lwm.offset = XTENTRYSTART; */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2781) tlck = txLock(tid, ip, mp, tlckXTREE | tlckNEW);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2782) xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2783)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2784) /* update the self address in the xtpage header */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2785) pxd = &p->header.self;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2786) PXDaddress(pxd, nxaddr);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2787)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2788) /* linelock for the after image of the whole page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2789) xtlck->lwm.length =
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2790) le16_to_cpu(p->header.nextindex) - xtlck->lwm.offset;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2791)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2792) /* update the buffer extent descriptor of target xtpage */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2793) xsize = xlen << JFS_SBI(ip->i_sb)->l2bsize;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2794) bmSetXD(mp, nxaddr, xsize);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2795)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2796) /* unpin the target page to new homeward bound */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2797) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2798) jfs_info("xtRelocate: target xtpage relocated.");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2799) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2800)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2801) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2802) * 3. acquire maplock for the source extent to be freed;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2803) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2804) * acquire a maplock saving the src relocated extent address;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2805) * to free of the extent at commit time;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2806) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2807) out:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2808) /* if DATAEXT relocation, write a LOG_UPDATEMAP record for
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2809) * free PXD of the source data extent (logredo() will update
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2810) * bmap for free of source data extent), and update bmap for
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2811) * free of the source data extent;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2812) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2813) if (xtype == DATAEXT)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2814) tlck = txMaplock(tid, ip, tlckMAP);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2815) /* if XTPAGE relocation, write a LOG_NOREDOPAGE record
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2816) * for the source xtpage (logredo() will init NoRedoPage
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2817) * filter and will also update bmap for free of the source
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2818) * xtpage), and update bmap for free of the source xtpage;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2819) * N.B. We use tlckMAP instead of tlkcXTREE because there
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2820) * is no buffer associated with this lock since the buffer
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2821) * has been redirected to the target location.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2822) */
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2823) else /* (xtype == XTPAGE) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2824) tlck = txMaplock(tid, ip, tlckMAP | tlckRELOCATE);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2825)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2826) pxdlock = (struct pxd_lock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2827) pxdlock->flag = mlckFREEPXD;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2828) PXDaddress(&pxdlock->pxd, oxaddr);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2829) PXDlength(&pxdlock->pxd, xlen);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2830) pxdlock->index = 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2831)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2832) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2833) * 4. update the parent xad entry for relocation;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2834) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2835) * acquire tlck for the parent entry with XAD_NEW as entry
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2836) * update which will write LOG_REDOPAGE and update bmap for
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2837) * allocation of XAD_NEW destination extent;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2838) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2839) jfs_info("xtRelocate: update parent xad entry.");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2840) BT_MARK_DIRTY(pmp, ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2841) tlck = txLock(tid, ip, pmp, tlckXTREE | tlckGROW);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2842) xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2843)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2844) /* update the XAD with the new destination extent; */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2845) xad = &pp->xad[index];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2846) xad->flag |= XAD_NEW;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2847) XADaddress(xad, nxaddr);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2848)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2849) xtlck->lwm.offset = min(index, xtlck->lwm.offset);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2850) xtlck->lwm.length = le16_to_cpu(pp->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2851) xtlck->lwm.offset;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2852)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2853) /* unpin the parent xtpage */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2854) XT_PUTPAGE(pmp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2855)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2856) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2857) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2858)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2859)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2860) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2861) * xtSearchNode()
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2862) *
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2863) * function: search for the internal xad entry covering specified extent.
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2864) * This function is mainly used by defragfs utility.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2865) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2866) * parameters:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2867) * ip - file object;
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2868) * xad - extent to find;
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2869) * cmpp - comparison result:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2870) * btstack - traverse stack;
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2871) * flag - search process flag;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2872) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2873) * returns:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2874) * btstack contains (bn, index) of search path traversed to the entry.
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2875) * *cmpp is set to result of comparison with the entry returned.
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2876) * the page containing the entry is pinned at exit.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2877) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2878) static int xtSearchNode(struct inode *ip, xad_t * xad, /* required XAD entry */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2879) int *cmpp, struct btstack * btstack, int flag)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2880) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2881) int rc = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2882) s64 xoff, xaddr;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2883) int xlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2884) int cmp = 1; /* init for empty page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2885) s64 bn; /* block number */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2886) struct metapage *mp; /* meta-page buffer */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2887) xtpage_t *p; /* page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2888) int base, index, lim;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2889) struct btframe *btsp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2890) s64 t64;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2891)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2892) BT_CLR(btstack);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2893)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2894) xoff = offsetXAD(xad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2895) xlen = lengthXAD(xad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2896) xaddr = addressXAD(xad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2897)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2898) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2899) * search down tree from root:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2900) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2901) * between two consecutive entries of <Ki, Pi> and <Kj, Pj> of
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2902) * internal page, child page Pi contains entry with k, Ki <= K < Kj.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2903) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2904) * if entry with search key K is not found
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2905) * internal page search find the entry with largest key Ki
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2906) * less than K which point to the child page to search;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2907) * leaf page search find the entry with smallest key Kj
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2908) * greater than K so that the returned index is the position of
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2909) * the entry to be shifted right for insertion of new entry.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2910) * for empty tree, search key is greater than any key of the tree.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2911) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2912) * by convention, root bn = 0.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2913) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2914) for (bn = 0;;) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2915) /* get/pin the page to search */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2916) XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2917) if (rc)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2918) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2919) if (p->header.flag & BT_LEAF) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2920) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2921) return -ESTALE;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2922) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2923)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2924) lim = le16_to_cpu(p->header.nextindex) - XTENTRYSTART;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2925)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2926) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2927) * binary search with search key K on the current page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2928) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2929) for (base = XTENTRYSTART; lim; lim >>= 1) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2930) index = base + (lim >> 1);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2931)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2932) XT_CMP(cmp, xoff, &p->xad[index], t64);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2933) if (cmp == 0) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2934) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2935) * search hit
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2936) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2937) * verify for exact match;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2938) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2939) if (xaddr == addressXAD(&p->xad[index]) &&
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2940) xoff == offsetXAD(&p->xad[index])) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2941) *cmpp = cmp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2942)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2943) /* save search result */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2944) btsp = btstack->top;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2945) btsp->bn = bn;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2946) btsp->index = index;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2947) btsp->mp = mp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2948)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2949) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2950) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2951)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2952) /* descend/search its child page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2953) goto next;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2954) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2955)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2956) if (cmp > 0) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2957) base = index + 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2958) --lim;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2959) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2960) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2961)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2962) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2963) * search miss - non-leaf page:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2964) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2965) * base is the smallest index with key (Kj) greater than
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2966) * search key (K) and may be zero or maxentry index.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2967) * if base is non-zero, decrement base by one to get the parent
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2968) * entry of the child page to search.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2969) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2970) index = base ? base - 1 : base;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2971)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2972) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2973) * go down to child page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2974) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2975) next:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2976) /* get the child page block number */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2977) bn = addressXAD(&p->xad[index]);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2978)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2979) /* unpin the parent page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2980) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2981) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2982) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2983)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2984)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2985) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2986) * xtRelink()
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2987) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2988) * function:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2989) * link around a freed page.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2990) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2991) * Parameter:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2992) * int tid,
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2993) * struct inode *ip,
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 2994) * xtpage_t *p)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2995) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2996) * returns:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2997) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2998) static int xtRelink(tid_t tid, struct inode *ip, xtpage_t * p)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2999) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3000) int rc = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3001) struct metapage *mp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3002) s64 nextbn, prevbn;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3003) struct tlock *tlck;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3004)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3005) nextbn = le64_to_cpu(p->header.next);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3006) prevbn = le64_to_cpu(p->header.prev);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3007)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3008) /* update prev pointer of the next page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3009) if (nextbn != 0) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3010) XT_GETPAGE(ip, nextbn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3011) if (rc)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3012) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3013)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3014) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3015) * acquire a transaction lock on the page;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3016) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3017) * action: update prev pointer;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3018) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3019) BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3020) tlck = txLock(tid, ip, mp, tlckXTREE | tlckRELINK);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3021)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3022) /* the page may already have been tlock'd */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3023)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3024) p->header.prev = cpu_to_le64(prevbn);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3025)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3026) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3027) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3028)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3029) /* update next pointer of the previous page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3030) if (prevbn != 0) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3031) XT_GETPAGE(ip, prevbn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3032) if (rc)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3033) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3034)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3035) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3036) * acquire a transaction lock on the page;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3037) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3038) * action: update next pointer;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3039) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3040) BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3041) tlck = txLock(tid, ip, mp, tlckXTREE | tlckRELINK);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3042)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3043) /* the page may already have been tlock'd */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3044)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3045) p->header.next = le64_to_cpu(nextbn);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3046)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3047) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3048) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3049)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3050) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3051) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3052) #endif /* _STILL_TO_PORT */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3053)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3054)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3055) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3056) * xtInitRoot()
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3057) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3058) * initialize file root (inline in inode)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3059) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3060) void xtInitRoot(tid_t tid, struct inode *ip)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3061) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3062) xtpage_t *p;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3063)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3064) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3065) * acquire a transaction lock on the root
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3066) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3067) * action:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3068) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3069) txLock(tid, ip, (struct metapage *) &JFS_IP(ip)->bxflag,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3070) tlckXTREE | tlckNEW);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3071) p = &JFS_IP(ip)->i_xtroot;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3072)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3073) p->header.flag = DXD_INDEX | BT_ROOT | BT_LEAF;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3074) p->header.nextindex = cpu_to_le16(XTENTRYSTART);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3075)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3076) if (S_ISDIR(ip->i_mode))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3077) p->header.maxentry = cpu_to_le16(XTROOTINITSLOT_DIR);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3078) else {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3079) p->header.maxentry = cpu_to_le16(XTROOTINITSLOT);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3080) ip->i_size = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3081) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3082)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3083)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3084) return;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3085) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3086)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3087)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3088) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3089) * We can run into a deadlock truncating a file with a large number of
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3090) * xtree pages (large fragmented file). A robust fix would entail a
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3091) * reservation system where we would reserve a number of metadata pages
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3092) * and tlocks which we would be guaranteed without a deadlock. Without
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3093) * this, a partial fix is to limit number of metadata pages we will lock
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3094) * in a single transaction. Currently we will truncate the file so that
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3095) * no more than 50 leaf pages will be locked. The caller of xtTruncate
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3096) * will be responsible for ensuring that the current transaction gets
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3097) * committed, and that subsequent transactions are created to truncate
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3098) * the file further if needed.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3099) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3100) #define MAX_TRUNCATE_LEAVES 50
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3101)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3102) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3103) * xtTruncate()
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3104) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3105) * function:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3106) * traverse for truncation logging backward bottom up;
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3107) * terminate at the last extent entry at the current subtree
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3108) * root page covering new down size.
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3109) * truncation may occur within the last extent entry.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3110) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3111) * parameter:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3112) * int tid,
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3113) * struct inode *ip,
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3114) * s64 newsize,
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3115) * int type) {PWMAP, PMAP, WMAP; DELETE, TRUNCATE}
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3116) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3117) * return:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3118) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3119) * note:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3120) * PWMAP:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3121) * 1. truncate (non-COMMIT_NOLINK file)
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3122) * by jfs_truncate() or jfs_open(O_TRUNC):
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3123) * xtree is updated;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3124) * 2. truncate index table of directory when last entry removed
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3125) * map update via tlock at commit time;
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3126) * PMAP:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3127) * Call xtTruncate_pmap instead
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3128) * WMAP:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3129) * 1. remove (free zero link count) on last reference release
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3130) * (pmap has been freed at commit zero link count);
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3131) * 2. truncate (COMMIT_NOLINK file, i.e., tmp file):
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3132) * xtree is updated;
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3133) * map update directly at truncation time;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3134) *
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3135) * if (DELETE)
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3136) * no LOG_NOREDOPAGE is required (NOREDOFILE is sufficient);
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3137) * else if (TRUNCATE)
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3138) * must write LOG_NOREDOPAGE for deleted index page;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3139) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3140) * pages may already have been tlocked by anonymous transactions
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3141) * during file growth (i.e., write) before truncation;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3142) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3143) * except last truncated entry, deleted entries remains as is
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3144) * in the page (nextindex is updated) for other use
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3145) * (e.g., log/update allocation map): this avoid copying the page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3146) * info but delay free of pages;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3147) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3148) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3149) s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3150) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3151) int rc = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3152) s64 teof;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3153) struct metapage *mp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3154) xtpage_t *p;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3155) s64 bn;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3156) int index, nextindex;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3157) xad_t *xad;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3158) s64 xoff, xaddr;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3159) int xlen, len, freexlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3160) struct btstack btstack;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3161) struct btframe *parent;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3162) struct tblock *tblk = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3163) struct tlock *tlck = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3164) struct xtlock *xtlck = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3165) struct xdlistlock xadlock; /* maplock for COMMIT_WMAP */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3166) struct pxd_lock *pxdlock; /* maplock for COMMIT_WMAP */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3167) s64 nfreed;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3168) int freed, log;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3169) int locked_leaves = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3170)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3171) /* save object truncation type */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3172) if (tid) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3173) tblk = tid_to_tblock(tid);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3174) tblk->xflag |= flag;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3175) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3176)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3177) nfreed = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3178)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3179) flag &= COMMIT_MAP;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3180) assert(flag != COMMIT_PMAP);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3181)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3182) if (flag == COMMIT_PWMAP)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3183) log = 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3184) else {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3185) log = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3186) xadlock.flag = mlckFREEXADLIST;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3187) xadlock.index = 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3188) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3189)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3190) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3191) * if the newsize is not an integral number of pages,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3192) * the file between newsize and next page boundary will
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3193) * be cleared.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3194) * if truncating into a file hole, it will cause
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3195) * a full block to be allocated for the logical block.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3196) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3197)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3198) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3199) * release page blocks of truncated region <teof, eof>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3200) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3201) * free the data blocks from the leaf index blocks.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3202) * delete the parent index entries corresponding to
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3203) * the freed child data/index blocks.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3204) * free the index blocks themselves which aren't needed
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3205) * in new sized file.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3206) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3207) * index blocks are updated only if the blocks are to be
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3208) * retained in the new sized file.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3209) * if type is PMAP, the data and index pages are NOT
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3210) * freed, and the data and index blocks are NOT freed
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3211) * from working map.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3212) * (this will allow continued access of data/index of
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3213) * temporary file (zerolink count file truncated to zero-length)).
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3214) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3215) teof = (newsize + (JFS_SBI(ip->i_sb)->bsize - 1)) >>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3216) JFS_SBI(ip->i_sb)->l2bsize;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3217)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3218) /* clear stack */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3219) BT_CLR(&btstack);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3220)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3221) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3222) * start with root
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3223) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3224) * root resides in the inode
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3225) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3226) bn = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3227)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3228) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3229) * first access of each page:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3230) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3231) getPage:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3232) XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3233) if (rc)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3234) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3235)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3236) /* process entries backward from last index */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3237) index = le16_to_cpu(p->header.nextindex) - 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3238)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3239)
7038f1cbac899 (Dave Kleikamp 2005-10-28 13:27:40 -0500 3240) /* Since this is the rightmost page at this level, and we may have
7038f1cbac899 (Dave Kleikamp 2005-10-28 13:27:40 -0500 3241) * already freed a page that was formerly to the right, let's make
7038f1cbac899 (Dave Kleikamp 2005-10-28 13:27:40 -0500 3242) * sure that the next pointer is zero.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3243) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3244) if (p->header.next) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3245) if (log)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3246) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3247) * Make sure this change to the header is logged.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3248) * If we really truncate this leaf, the flag
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3249) * will be changed to tlckTRUNCATE
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3250) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3251) tlck = txLock(tid, ip, mp, tlckXTREE|tlckGROW);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3252) BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3253) p->header.next = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3254) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3255)
7038f1cbac899 (Dave Kleikamp 2005-10-28 13:27:40 -0500 3256) if (p->header.flag & BT_INTERNAL)
7038f1cbac899 (Dave Kleikamp 2005-10-28 13:27:40 -0500 3257) goto getChild;
7038f1cbac899 (Dave Kleikamp 2005-10-28 13:27:40 -0500 3258)
7038f1cbac899 (Dave Kleikamp 2005-10-28 13:27:40 -0500 3259) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3260) * leaf page
7038f1cbac899 (Dave Kleikamp 2005-10-28 13:27:40 -0500 3261) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3262) freed = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3263)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3264) /* does region covered by leaf page precede Teof ? */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3265) xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3266) xoff = offsetXAD(xad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3267) xlen = lengthXAD(xad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3268) if (teof >= xoff + xlen) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3269) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3270) goto getParent;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3271) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3272)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3273) /* (re)acquire tlock of the leaf page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3274) if (log) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3275) if (++locked_leaves > MAX_TRUNCATE_LEAVES) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3276) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3277) * We need to limit the size of the transaction
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3278) * to avoid exhausting pagecache & tlocks
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3279) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3280) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3281) newsize = (xoff + xlen) << JFS_SBI(ip->i_sb)->l2bsize;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3282) goto getParent;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3283) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3284) tlck = txLock(tid, ip, mp, tlckXTREE);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3285) tlck->type = tlckXTREE | tlckTRUNCATE;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3286) xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3287) xtlck->hwm.offset = le16_to_cpu(p->header.nextindex) - 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3288) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3289) BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3290)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3291) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3292) * scan backward leaf page entries
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3293) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3294) for (; index >= XTENTRYSTART; index--) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3295) xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3296) xoff = offsetXAD(xad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3297) xlen = lengthXAD(xad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3298) xaddr = addressXAD(xad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3299)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3300) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3301) * The "data" for a directory is indexed by the block
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3302) * device's address space. This metadata must be invalidated
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3303) * here
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3304) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3305) if (S_ISDIR(ip->i_mode) && (teof == 0))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3306) invalidate_xad_metapages(ip, *xad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3307) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3308) * entry beyond eof: continue scan of current page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3309) * xad
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3310) * ---|---=======------->
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3311) * eof
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3312) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3313) if (teof < xoff) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3314) nfreed += xlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3315) continue;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3316) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3317)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3318) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3319) * (xoff <= teof): last entry to be deleted from page;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3320) * If other entries remain in page: keep and update the page.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3321) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3322)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3323) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3324) * eof == entry_start: delete the entry
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3325) * xad
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3326) * -------|=======------->
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3327) * eof
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3328) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3329) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3330) if (teof == xoff) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3331) nfreed += xlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3332)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3333) if (index == XTENTRYSTART)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3334) break;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3335)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3336) nextindex = index;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3337) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3338) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3339) * eof within the entry: truncate the entry.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3340) * xad
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3341) * -------===|===------->
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3342) * eof
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3343) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3344) else if (teof < xoff + xlen) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3345) /* update truncated entry */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3346) len = teof - xoff;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3347) freexlen = xlen - len;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3348) XADlength(xad, len);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3349)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3350) /* save pxd of truncated extent in tlck */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3351) xaddr += len;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3352) if (log) { /* COMMIT_PWMAP */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3353) xtlck->lwm.offset = (xtlck->lwm.offset) ?
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3354) min(index, (int)xtlck->lwm.offset) : index;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3355) xtlck->lwm.length = index + 1 -
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3356) xtlck->lwm.offset;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3357) xtlck->twm.offset = index;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3358) pxdlock = (struct pxd_lock *) & xtlck->pxdlock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3359) pxdlock->flag = mlckFREEPXD;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3360) PXDaddress(&pxdlock->pxd, xaddr);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3361) PXDlength(&pxdlock->pxd, freexlen);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3362) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3363) /* free truncated extent */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3364) else { /* COMMIT_WMAP */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3365)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3366) pxdlock = (struct pxd_lock *) & xadlock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3367) pxdlock->flag = mlckFREEPXD;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3368) PXDaddress(&pxdlock->pxd, xaddr);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3369) PXDlength(&pxdlock->pxd, freexlen);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3370) txFreeMap(ip, pxdlock, NULL, COMMIT_WMAP);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3371)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3372) /* reset map lock */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3373) xadlock.flag = mlckFREEXADLIST;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3374) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3375)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3376) /* current entry is new last entry; */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3377) nextindex = index + 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3378)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3379) nfreed += freexlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3380) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3381) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3382) * eof beyond the entry:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3383) * xad
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3384) * -------=======---|--->
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3385) * eof
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3386) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3387) else { /* (xoff + xlen < teof) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3388)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3389) nextindex = index + 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3390) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3391)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3392) if (nextindex < le16_to_cpu(p->header.nextindex)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3393) if (!log) { /* COMMIT_WAMP */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3394) xadlock.xdlist = &p->xad[nextindex];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3395) xadlock.count =
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3396) le16_to_cpu(p->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3397) nextindex;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3398) txFreeMap(ip, (struct maplock *) & xadlock,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3399) NULL, COMMIT_WMAP);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3400) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3401) p->header.nextindex = cpu_to_le16(nextindex);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3402) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3403)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3404) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3405)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3406) /* assert(freed == 0); */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3407) goto getParent;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3408) } /* end scan of leaf page entries */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3409)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3410) freed = 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3411)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3412) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3413) * leaf page become empty: free the page if type != PMAP
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3414) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3415) if (log) { /* COMMIT_PWMAP */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3416) /* txCommit() with tlckFREE:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3417) * free data extents covered by leaf [XTENTRYSTART:hwm);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3418) * invalidate leaf if COMMIT_PWMAP;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3419) * if (TRUNCATE), will write LOG_NOREDOPAGE;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3420) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3421) tlck->type = tlckXTREE | tlckFREE;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3422) } else { /* COMMIT_WAMP */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3423)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3424) /* free data extents covered by leaf */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3425) xadlock.xdlist = &p->xad[XTENTRYSTART];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3426) xadlock.count =
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3427) le16_to_cpu(p->header.nextindex) - XTENTRYSTART;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3428) txFreeMap(ip, (struct maplock *) & xadlock, NULL, COMMIT_WMAP);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3429) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3430)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3431) if (p->header.flag & BT_ROOT) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3432) p->header.flag &= ~BT_INTERNAL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3433) p->header.flag |= BT_LEAF;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3434) p->header.nextindex = cpu_to_le16(XTENTRYSTART);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3435)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3436) XT_PUTPAGE(mp); /* debug */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3437) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3438) } else {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3439) if (log) { /* COMMIT_PWMAP */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3440) /* page will be invalidated at tx completion
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3441) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3442) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3443) } else { /* COMMIT_WMAP */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3444)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3445) if (mp->lid)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3446) lid_to_tlock(mp->lid)->flag |= tlckFREELOCK;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3447)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3448) /* invalidate empty leaf page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3449) discard_metapage(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3450) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3451) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3452)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3453) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3454) * the leaf page become empty: delete the parent entry
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3455) * for the leaf page if the parent page is to be kept
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3456) * in the new sized file.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3457) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3458)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3459) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3460) * go back up to the parent page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3461) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3462) getParent:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3463) /* pop/restore parent entry for the current child page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3464) if ((parent = BT_POP(&btstack)) == NULL)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3465) /* current page must have been root */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3466) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3467)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3468) /* get back the parent page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3469) bn = parent->bn;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3470) XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3471) if (rc)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3472) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3473)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3474) index = parent->index;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3475)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3476) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3477) * child page was not empty:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3478) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3479) if (freed == 0) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3480) /* has any entry deleted from parent ? */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3481) if (index < le16_to_cpu(p->header.nextindex) - 1) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3482) /* (re)acquire tlock on the parent page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3483) if (log) { /* COMMIT_PWMAP */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3484) /* txCommit() with tlckTRUNCATE:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3485) * free child extents covered by parent [);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3486) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3487) tlck = txLock(tid, ip, mp, tlckXTREE);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3488) xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3489) if (!(tlck->type & tlckTRUNCATE)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3490) xtlck->hwm.offset =
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3491) le16_to_cpu(p->header.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3492) nextindex) - 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3493) tlck->type =
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3494) tlckXTREE | tlckTRUNCATE;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3495) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3496) } else { /* COMMIT_WMAP */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3497)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3498) /* free child extents covered by parent */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3499) xadlock.xdlist = &p->xad[index + 1];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3500) xadlock.count =
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3501) le16_to_cpu(p->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3502) index - 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3503) txFreeMap(ip, (struct maplock *) & xadlock,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3504) NULL, COMMIT_WMAP);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3505) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3506) BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3507)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3508) p->header.nextindex = cpu_to_le16(index + 1);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3509) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3510) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3511) goto getParent;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3512) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3513)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3514) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3515) * child page was empty:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3516) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3517) nfreed += lengthXAD(&p->xad[index]);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3518)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3519) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3520) * During working map update, child page's tlock must be handled
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3521) * before parent's. This is because the parent's tlock will cause
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3522) * the child's disk space to be marked available in the wmap, so
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3523) * it's important that the child page be released by that time.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3524) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3525) * ToDo: tlocks should be on doubly-linked list, so we can
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3526) * quickly remove it and add it to the end.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3527) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3528)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3529) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3530) * Move parent page's tlock to the end of the tid's tlock list
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3531) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3532) if (log && mp->lid && (tblk->last != mp->lid) &&
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3533) lid_to_tlock(mp->lid)->tid) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3534) lid_t lid = mp->lid;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3535) struct tlock *prev;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3536)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3537) tlck = lid_to_tlock(lid);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3538)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3539) if (tblk->next == lid)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3540) tblk->next = tlck->next;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3541) else {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3542) for (prev = lid_to_tlock(tblk->next);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3543) prev->next != lid;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3544) prev = lid_to_tlock(prev->next)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3545) assert(prev->next);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3546) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3547) prev->next = tlck->next;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3548) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3549) lid_to_tlock(tblk->last)->next = lid;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3550) tlck->next = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3551) tblk->last = lid;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3552) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3553)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3554) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3555) * parent page become empty: free the page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3556) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3557) if (index == XTENTRYSTART) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3558) if (log) { /* COMMIT_PWMAP */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3559) /* txCommit() with tlckFREE:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3560) * free child extents covered by parent;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3561) * invalidate parent if COMMIT_PWMAP;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3562) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3563) tlck = txLock(tid, ip, mp, tlckXTREE);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3564) xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3565) xtlck->hwm.offset =
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3566) le16_to_cpu(p->header.nextindex) - 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3567) tlck->type = tlckXTREE | tlckFREE;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3568) } else { /* COMMIT_WMAP */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3569)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3570) /* free child extents covered by parent */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3571) xadlock.xdlist = &p->xad[XTENTRYSTART];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3572) xadlock.count =
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3573) le16_to_cpu(p->header.nextindex) -
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3574) XTENTRYSTART;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3575) txFreeMap(ip, (struct maplock *) & xadlock, NULL,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3576) COMMIT_WMAP);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3577) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3578) BT_MARK_DIRTY(mp, ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3579)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3580) if (p->header.flag & BT_ROOT) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3581) p->header.flag &= ~BT_INTERNAL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3582) p->header.flag |= BT_LEAF;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3583) p->header.nextindex = cpu_to_le16(XTENTRYSTART);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3584) if (le16_to_cpu(p->header.maxentry) == XTROOTMAXSLOT) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3585) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3586) * Shrink root down to allow inline
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3587) * EA (otherwise fsck complains)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3588) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3589) p->header.maxentry =
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3590) cpu_to_le16(XTROOTINITSLOT);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3591) JFS_IP(ip)->mode2 |= INLINEEA;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3592) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3593)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3594) XT_PUTPAGE(mp); /* debug */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3595) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3596) } else {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3597) if (log) { /* COMMIT_PWMAP */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3598) /* page will be invalidated at tx completion
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3599) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3600) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3601) } else { /* COMMIT_WMAP */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3602)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3603) if (mp->lid)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3604) lid_to_tlock(mp->lid)->flag |=
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3605) tlckFREELOCK;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3606)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3607) /* invalidate parent page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3608) discard_metapage(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3609) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3610)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3611) /* parent has become empty and freed:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3612) * go back up to its parent page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3613) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3614) /* freed = 1; */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3615) goto getParent;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3616) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3617) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3618) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3619) * parent page still has entries for front region;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3620) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3621) else {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3622) /* try truncate region covered by preceding entry
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3623) * (process backward)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3624) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3625) index--;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3626)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3627) /* go back down to the child page corresponding
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3628) * to the entry
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3629) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3630) goto getChild;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3631) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3632)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3633) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3634) * internal page: go down to child page of current entry
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3635) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3636) getChild:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3637) /* save current parent entry for the child page */
17e6afc75ad01 (Dave Kleikamp 2007-01-09 08:57:34 -0600 3638) if (BT_STACK_FULL(&btstack)) {
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 3639) jfs_error(ip->i_sb, "stack overrun!\n");
17e6afc75ad01 (Dave Kleikamp 2007-01-09 08:57:34 -0600 3640) XT_PUTPAGE(mp);
17e6afc75ad01 (Dave Kleikamp 2007-01-09 08:57:34 -0600 3641) return -EIO;
17e6afc75ad01 (Dave Kleikamp 2007-01-09 08:57:34 -0600 3642) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3643) BT_PUSH(&btstack, bn, index);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3644)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3645) /* get child page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3646) xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3647) bn = addressXAD(xad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3648)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3649) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3650) * first access of each internal entry:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3651) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3652) /* release parent page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3653) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3654)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3655) /* process the child page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3656) goto getPage;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3657)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3658) out:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3659) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3660) * update file resource stat
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3661) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3662) /* set size
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3663) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3664) if (S_ISDIR(ip->i_mode) && !newsize)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3665) ip->i_size = 1; /* fsck hates zero-length directories */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3666) else
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3667) ip->i_size = newsize;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3668)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3669) /* update quota allocation to reflect freed blocks */
5dd4056db8438 (Christoph Hellwig 2010-03-03 09:05:00 -0500 3670) dquot_free_block(ip, nfreed);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3671)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3672) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3673) * free tlock of invalidated pages
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3674) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3675) if (flag == COMMIT_WMAP)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3676) txFreelock(ip);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3677)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3678) return newsize;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3679) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3680)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3681)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3682) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3683) * xtTruncate_pmap()
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3684) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3685) * function:
efad798b9f013 (Paulius Zaleckas 2008-02-03 15:42:53 +0200 3686) * Perform truncate to zero length for deleted file, leaving the
ed1c9a7a8517f (Randy Dunlap 2020-08-04 19:49:01 -0700 3687) * xtree and working map untouched. This allows the file to
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3688) * be accessed via open file handles, while the delete of the file
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3689) * is committed to disk.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3690) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3691) * parameter:
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3692) * tid_t tid,
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3693) * struct inode *ip,
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3694) * s64 committed_size)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3695) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3696) * return: new committed size
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3697) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3698) * note:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3699) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3700) * To avoid deadlock by holding too many transaction locks, the
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3701) * truncation may be broken up into multiple transactions.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3702) * The committed_size keeps track of part of the file has been
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3703) * freed from the pmaps.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3704) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3705) s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3706) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3707) s64 bn;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3708) struct btstack btstack;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3709) int cmp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3710) int index;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3711) int locked_leaves = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3712) struct metapage *mp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3713) xtpage_t *p;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3714) struct btframe *parent;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3715) int rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3716) struct tblock *tblk;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3717) struct tlock *tlck = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3718) xad_t *xad;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3719) int xlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3720) s64 xoff;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3721) struct xtlock *xtlck = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3722)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3723) /* save object truncation type */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3724) tblk = tid_to_tblock(tid);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3725) tblk->xflag |= COMMIT_PMAP;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3726)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3727) /* clear stack */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3728) BT_CLR(&btstack);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3729)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3730) if (committed_size) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3731) xoff = (committed_size >> JFS_SBI(ip->i_sb)->l2bsize) - 1;
6628465e33ca6 (Dave Kleikamp 2005-05-02 12:25:13 -0600 3732) rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3733) if (rc)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3734) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3735)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3736) XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3737)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3738) if (cmp != 0) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3739) XT_PUTPAGE(mp);
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 3740) jfs_error(ip->i_sb, "did not find extent\n");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3741) return -EIO;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3742) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3743) } else {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3744) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3745) * start with root
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3746) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3747) * root resides in the inode
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3748) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3749) bn = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3750)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3751) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3752) * first access of each page:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3753) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3754) getPage:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3755) XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3756) if (rc)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3757) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3758)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3759) /* process entries backward from last index */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3760) index = le16_to_cpu(p->header.nextindex) - 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3761)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3762) if (p->header.flag & BT_INTERNAL)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3763) goto getChild;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3764) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3765)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3766) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3767) * leaf page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3768) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3769)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3770) if (++locked_leaves > MAX_TRUNCATE_LEAVES) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3771) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3772) * We need to limit the size of the transaction
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3773) * to avoid exhausting pagecache & tlocks
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3774) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3775) xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3776) xoff = offsetXAD(xad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3777) xlen = lengthXAD(xad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3778) XT_PUTPAGE(mp);
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3779) return (xoff + xlen) << JFS_SBI(ip->i_sb)->l2bsize;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3780) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3781) tlck = txLock(tid, ip, mp, tlckXTREE);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3782) tlck->type = tlckXTREE | tlckFREE;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3783) xtlck = (struct xtlock *) & tlck->lock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3784) xtlck->hwm.offset = index;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3785)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3786)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3787) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3788)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3789) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3790) * go back up to the parent page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3791) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3792) getParent:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3793) /* pop/restore parent entry for the current child page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3794) if ((parent = BT_POP(&btstack)) == NULL)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3795) /* current page must have been root */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3796) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3797)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3798) /* get back the parent page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3799) bn = parent->bn;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3800) XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3801) if (rc)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3802) return rc;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3803)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3804) index = parent->index;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3805)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3806) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3807) * parent page become empty: free the page
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3808) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3809) if (index == XTENTRYSTART) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3810) /* txCommit() with tlckFREE:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3811) * free child extents covered by parent;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3812) * invalidate parent if COMMIT_PWMAP;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3813) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3814) tlck = txLock(tid, ip, mp, tlckXTREE);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3815) xtlck = (struct xtlock *) & tlck->lock;
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3816) xtlck->hwm.offset = le16_to_cpu(p->header.nextindex) - 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3817) tlck->type = tlckXTREE | tlckFREE;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3818)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3819) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3820)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3821) if (p->header.flag & BT_ROOT) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3822)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3823) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3824) } else {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3825) goto getParent;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3826) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3827) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3828) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3829) * parent page still has entries for front region;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3830) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3831) else
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3832) index--;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3833) /*
f720e3ba55868 (Dave Kleikamp 2007-06-06 15:28:35 -0500 3834) * internal page: go down to child page of current entry
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3835) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3836) getChild:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3837) /* save current parent entry for the child page */
17e6afc75ad01 (Dave Kleikamp 2007-01-09 08:57:34 -0600 3838) if (BT_STACK_FULL(&btstack)) {
eb8630d7d2fd1 (Joe Perches 2013-06-04 16:39:15 -0700 3839) jfs_error(ip->i_sb, "stack overrun!\n");
17e6afc75ad01 (Dave Kleikamp 2007-01-09 08:57:34 -0600 3840) XT_PUTPAGE(mp);
17e6afc75ad01 (Dave Kleikamp 2007-01-09 08:57:34 -0600 3841) return -EIO;
17e6afc75ad01 (Dave Kleikamp 2007-01-09 08:57:34 -0600 3842) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3843) BT_PUSH(&btstack, bn, index);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3844)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3845) /* get child page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3846) xad = &p->xad[index];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3847) bn = addressXAD(xad);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3848)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3849) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3850) * first access of each internal entry:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3851) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3852) /* release parent page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3853) XT_PUTPAGE(mp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3854)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3855) /* process the child page */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3856) goto getPage;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3857)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3858) out:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3859)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3860) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3861) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3862)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3863) #ifdef CONFIG_JFS_STATISTICS
07a3b8ed48557 (Christoph Hellwig 2018-04-11 16:51:18 +0200 3864) int jfs_xtstat_proc_show(struct seq_file *m, void *v)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3865) {
b2e03ca7485ca (Alexey Dobriyan 2008-05-13 08:22:10 -0500 3866) seq_printf(m,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3867) "JFS Xtree statistics\n"
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3868) "====================\n"
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3869) "searches = %d\n"
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3870) "fast searches = %d\n"
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3871) "splits = %d\n",
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3872) xtStat.search,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3873) xtStat.fastSearch,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3874) xtStat.split);
b2e03ca7485ca (Alexey Dobriyan 2008-05-13 08:22:10 -0500 3875) return 0;
b2e03ca7485ca (Alexey Dobriyan 2008-05-13 08:22:10 -0500 3876) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3877) #endif