|
@@ -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;
|
|
|
|