summaryrefslogtreecommitdiffstats
path: root/fs/jfs/jfs_xtree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jfs/jfs_xtree.c')
-rw-r--r--fs/jfs/jfs_xtree.c61
1 files changed, 41 insertions, 20 deletions
diff --git a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c
index 11c58c5..2c1f311 100644
--- a/fs/jfs/jfs_xtree.c
+++ b/fs/jfs/jfs_xtree.c
@@ -111,8 +111,8 @@ static struct {
/*
* forward references
*/
-static int xtSearch(struct inode *ip,
- s64 xoff, int *cmpp, struct btstack * btstack, int flag);
+static int xtSearch(struct inode *ip, s64 xoff, s64 *next, int *cmpp,
+ struct btstack * btstack, int flag);
static int xtSplitUp(tid_t tid,
struct inode *ip,
@@ -159,11 +159,12 @@ int xtLookup(struct inode *ip, s64 lstart,
xtpage_t *p;
int index;
xad_t *xad;
- s64 size, xoff, xend;
+ s64 next, size, xoff, xend;
int xlen;
s64 xaddr;
- *plen = 0;
+ *paddr = 0;
+ *plen = llen;
if (!no_check) {
/* is lookup offset beyond eof ? */
@@ -180,7 +181,7 @@ int xtLookup(struct inode *ip, s64 lstart,
* search for the xad entry covering the logical extent
*/
//search:
- if ((rc = xtSearch(ip, lstart, &cmp, &btstack, 0))) {
+ if ((rc = xtSearch(ip, lstart, &next, &cmp, &btstack, 0))) {
jfs_err("xtLookup: xtSearch returned %d", rc);
return rc;
}
@@ -198,8 +199,11 @@ int xtLookup(struct inode *ip, s64 lstart,
* lstart is a page start address,
* i.e., lstart cannot start in a hole;
*/
- if (cmp)
+ if (cmp) {
+ if (next)
+ *plen = min(next - lstart, llen);
goto out;
+ }
/*
* lxd covered by xad
@@ -284,7 +288,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist,
if (lstart >= size)
return 0;
- if ((rc = xtSearch(ip, lstart, &cmp, &btstack, 0)))
+ if ((rc = xtSearch(ip, lstart, NULL, &cmp, &btstack, 0)))
return rc;
/*
@@ -488,6 +492,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist,
* parameters:
* ip - file object;
* xoff - extent offset;
+ * nextp - address of next extent (if any) for search miss
* cmpp - comparison result:
* btstack - traverse stack;
* flag - search process flag (XT_INSERT);
@@ -497,7 +502,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist,
* *cmpp is set to result of comparison with the entry returned.
* the page containing the entry is pinned at exit.
*/
-static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */
+static int xtSearch(struct inode *ip, s64 xoff, s64 *nextp,
int *cmpp, struct btstack * btstack, int flag)
{
struct jfs_inode_info *jfs_ip = JFS_IP(ip);
@@ -511,6 +516,7 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */
struct btframe *btsp;
int nsplit = 0; /* number of pages to split */
s64 t64;
+ s64 next = 0;
INCREMENT(xtStat.search);
@@ -579,6 +585,7 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */
* previous and this entry
*/
*cmpp = 1;
+ next = t64;
goto out;
}
@@ -623,6 +630,9 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */
/* update sequential access heuristics */
jfs_ip->btindex = index;
+ if (nextp)
+ *nextp = next;
+
INCREMENT(xtStat.fastSearch);
return 0;
}
@@ -675,10 +685,11 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */
return 0;
}
-
/* search hit - internal page:
* descend/search its child page
*/
+ if (index < p->header.nextindex - 1)
+ next = offsetXAD(&p->xad[index + 1]);
goto next;
}
@@ -694,6 +705,8 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */
* base is the smallest index with key (Kj) greater than
* search key (K) and may be zero or maxentry index.
*/
+ if (base < p->header.nextindex)
+ next = offsetXAD(&p->xad[base]);
/*
* search miss - leaf page:
*
@@ -727,6 +740,9 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */
jfs_ip->btorder = BT_RANDOM;
jfs_ip->btindex = base;
+ if (nextp)
+ *nextp = next;
+
return 0;
}
@@ -793,6 +809,7 @@ int xtInsert(tid_t tid, /* transaction id */
struct xtsplit split; /* split information */
xad_t *xad;
int cmp;
+ s64 next;
struct tlock *tlck;
struct xtlock *xtlck;
@@ -806,7 +823,7 @@ int xtInsert(tid_t tid, /* transaction id */
* n.b. xtSearch() may return index of maxentry of
* the full page.
*/
- if ((rc = xtSearch(ip, xoff, &cmp, &btstack, XT_INSERT)))
+ if ((rc = xtSearch(ip, xoff, &next, &cmp, &btstack, XT_INSERT)))
return rc;
/* retrieve search result */
@@ -814,7 +831,7 @@ int xtInsert(tid_t tid, /* transaction id */
/* This test must follow XT_GETSEARCH since mp must be valid if
* we branch to out: */
- if (cmp == 0) {
+ if ((cmp == 0) || (next && (xlen > next - xoff))) {
rc = -EEXIST;
goto out;
}
@@ -1626,7 +1643,7 @@ int xtExtend(tid_t tid, /* transaction id */
jfs_info("xtExtend: nxoff:0x%lx nxlen:0x%x", (ulong) xoff, xlen);
/* there must exist extent to be extended */
- if ((rc = xtSearch(ip, xoff - 1, &cmp, &btstack, XT_INSERT)))
+ if ((rc = xtSearch(ip, xoff - 1, NULL, &cmp, &btstack, XT_INSERT)))
return rc;
/* retrieve search result */
@@ -1794,7 +1811,7 @@ printf("xtTailgate: nxoff:0x%lx nxlen:0x%x nxaddr:0x%lx\n",
*/
/* there must exist extent to be tailgated */
- if ((rc = xtSearch(ip, xoff, &cmp, &btstack, XT_INSERT)))
+ if ((rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, XT_INSERT)))
return rc;
/* retrieve search result */
@@ -1977,7 +1994,7 @@ int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad)
nxlen = lengthXAD(nxad);
nxaddr = addressXAD(nxad);
- if ((rc = xtSearch(ip, nxoff, &cmp, &btstack, XT_INSERT)))
+ if ((rc = xtSearch(ip, nxoff, NULL, &cmp, &btstack, XT_INSERT)))
return rc;
/* retrieve search result */
@@ -2291,7 +2308,7 @@ int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad)
if (nextindex == le16_to_cpu(p->header.maxentry)) {
XT_PUTPAGE(mp);
- if ((rc = xtSearch(ip, nxoff, &cmp, &btstack, XT_INSERT)))
+ if ((rc = xtSearch(ip, nxoff, NULL, &cmp, &btstack, XT_INSERT)))
return rc;
/* retrieve search result */
@@ -2438,6 +2455,7 @@ int xtAppend(tid_t tid, /* transaction id */
int nsplit, nblocks, xlen;
struct pxdlist pxdlist;
pxd_t *pxd;
+ s64 next;
xaddr = *xaddrp;
xlen = *xlenp;
@@ -2452,7 +2470,7 @@ int xtAppend(tid_t tid, /* transaction id */
* n.b. xtSearch() may return index of maxentry of
* the full page.
*/
- if ((rc = xtSearch(ip, xoff, &cmp, &btstack, XT_INSERT)))
+ if ((rc = xtSearch(ip, xoff, &next, &cmp, &btstack, XT_INSERT)))
return rc;
/* retrieve search result */
@@ -2462,6 +2480,9 @@ int xtAppend(tid_t tid, /* transaction id */
rc = -EEXIST;
goto out;
}
+
+ if (next)
+ xlen = min(xlen, (int)(next - xoff));
//insert:
/*
* insert entry for new extent
@@ -2600,7 +2621,7 @@ int xtDelete(tid_t tid, struct inode *ip, s64 xoff, s32 xlen, int flag)
/*
* find the matching entry; xtSearch() pins the page
*/
- if ((rc = xtSearch(ip, xoff, &cmp, &btstack, 0)))
+ if ((rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0)))
return rc;
XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
@@ -2852,7 +2873,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */
*/
if (xtype == DATAEXT) {
/* search in leaf entry */
- rc = xtSearch(ip, xoff, &cmp, &btstack, 0);
+ rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0);
if (rc)
return rc;
@@ -2958,7 +2979,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */
}
/* get back parent page */
- if ((rc = xtSearch(ip, xoff, &cmp, &btstack, 0)))
+ if ((rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0)))
return rc;
XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index);
@@ -3991,7 +4012,7 @@ s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size)
if (committed_size) {
xoff = (committed_size >> JFS_SBI(ip->i_sb)->l2bsize) - 1;
- rc = xtSearch(ip, xoff, &cmp, &btstack, 0);
+ rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0);
if (rc)
return rc;
OpenPOWER on IntegriCloud