diff options
Diffstat (limited to 'fs/jfs/jfs_xtree.c')
-rw-r--r-- | fs/jfs/jfs_xtree.c | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c index 11c58c54b818..2c1f311914a1 100644 --- a/fs/jfs/jfs_xtree.c +++ b/fs/jfs/jfs_xtree.c | |||
@@ -111,8 +111,8 @@ static struct { | |||
111 | /* | 111 | /* |
112 | * forward references | 112 | * forward references |
113 | */ | 113 | */ |
114 | static int xtSearch(struct inode *ip, | 114 | static int xtSearch(struct inode *ip, s64 xoff, s64 *next, int *cmpp, |
115 | s64 xoff, int *cmpp, struct btstack * btstack, int flag); | 115 | struct btstack * btstack, int flag); |
116 | 116 | ||
117 | static int xtSplitUp(tid_t tid, | 117 | static int xtSplitUp(tid_t tid, |
118 | struct inode *ip, | 118 | struct inode *ip, |
@@ -159,11 +159,12 @@ int xtLookup(struct inode *ip, s64 lstart, | |||
159 | xtpage_t *p; | 159 | xtpage_t *p; |
160 | int index; | 160 | int index; |
161 | xad_t *xad; | 161 | xad_t *xad; |
162 | s64 size, xoff, xend; | 162 | s64 next, size, xoff, xend; |
163 | int xlen; | 163 | int xlen; |
164 | s64 xaddr; | 164 | s64 xaddr; |
165 | 165 | ||
166 | *plen = 0; | 166 | *paddr = 0; |
167 | *plen = llen; | ||
167 | 168 | ||
168 | if (!no_check) { | 169 | if (!no_check) { |
169 | /* is lookup offset beyond eof ? */ | 170 | /* is lookup offset beyond eof ? */ |
@@ -180,7 +181,7 @@ int xtLookup(struct inode *ip, s64 lstart, | |||
180 | * search for the xad entry covering the logical extent | 181 | * search for the xad entry covering the logical extent |
181 | */ | 182 | */ |
182 | //search: | 183 | //search: |
183 | if ((rc = xtSearch(ip, lstart, &cmp, &btstack, 0))) { | 184 | if ((rc = xtSearch(ip, lstart, &next, &cmp, &btstack, 0))) { |
184 | jfs_err("xtLookup: xtSearch returned %d", rc); | 185 | jfs_err("xtLookup: xtSearch returned %d", rc); |
185 | return rc; | 186 | return rc; |
186 | } | 187 | } |
@@ -198,8 +199,11 @@ int xtLookup(struct inode *ip, s64 lstart, | |||
198 | * lstart is a page start address, | 199 | * lstart is a page start address, |
199 | * i.e., lstart cannot start in a hole; | 200 | * i.e., lstart cannot start in a hole; |
200 | */ | 201 | */ |
201 | if (cmp) | 202 | if (cmp) { |
203 | if (next) | ||
204 | *plen = min(next - lstart, llen); | ||
202 | goto out; | 205 | goto out; |
206 | } | ||
203 | 207 | ||
204 | /* | 208 | /* |
205 | * lxd covered by xad | 209 | * lxd covered by xad |
@@ -284,7 +288,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist, | |||
284 | if (lstart >= size) | 288 | if (lstart >= size) |
285 | return 0; | 289 | return 0; |
286 | 290 | ||
287 | if ((rc = xtSearch(ip, lstart, &cmp, &btstack, 0))) | 291 | if ((rc = xtSearch(ip, lstart, NULL, &cmp, &btstack, 0))) |
288 | return rc; | 292 | return rc; |
289 | 293 | ||
290 | /* | 294 | /* |
@@ -488,6 +492,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist, | |||
488 | * parameters: | 492 | * parameters: |
489 | * ip - file object; | 493 | * ip - file object; |
490 | * xoff - extent offset; | 494 | * xoff - extent offset; |
495 | * nextp - address of next extent (if any) for search miss | ||
491 | * cmpp - comparison result: | 496 | * cmpp - comparison result: |
492 | * btstack - traverse stack; | 497 | * btstack - traverse stack; |
493 | * flag - search process flag (XT_INSERT); | 498 | * flag - search process flag (XT_INSERT); |
@@ -497,7 +502,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist, | |||
497 | * *cmpp is set to result of comparison with the entry returned. | 502 | * *cmpp is set to result of comparison with the entry returned. |
498 | * the page containing the entry is pinned at exit. | 503 | * the page containing the entry is pinned at exit. |
499 | */ | 504 | */ |
500 | static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */ | 505 | static int xtSearch(struct inode *ip, s64 xoff, s64 *nextp, |
501 | int *cmpp, struct btstack * btstack, int flag) | 506 | int *cmpp, struct btstack * btstack, int flag) |
502 | { | 507 | { |
503 | struct jfs_inode_info *jfs_ip = JFS_IP(ip); | 508 | struct jfs_inode_info *jfs_ip = JFS_IP(ip); |
@@ -511,6 +516,7 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */ | |||
511 | struct btframe *btsp; | 516 | struct btframe *btsp; |
512 | int nsplit = 0; /* number of pages to split */ | 517 | int nsplit = 0; /* number of pages to split */ |
513 | s64 t64; | 518 | s64 t64; |
519 | s64 next = 0; | ||
514 | 520 | ||
515 | INCREMENT(xtStat.search); | 521 | INCREMENT(xtStat.search); |
516 | 522 | ||
@@ -579,6 +585,7 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */ | |||
579 | * previous and this entry | 585 | * previous and this entry |
580 | */ | 586 | */ |
581 | *cmpp = 1; | 587 | *cmpp = 1; |
588 | next = t64; | ||
582 | goto out; | 589 | goto out; |
583 | } | 590 | } |
584 | 591 | ||
@@ -623,6 +630,9 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */ | |||
623 | /* update sequential access heuristics */ | 630 | /* update sequential access heuristics */ |
624 | jfs_ip->btindex = index; | 631 | jfs_ip->btindex = index; |
625 | 632 | ||
633 | if (nextp) | ||
634 | *nextp = next; | ||
635 | |||
626 | INCREMENT(xtStat.fastSearch); | 636 | INCREMENT(xtStat.fastSearch); |
627 | return 0; | 637 | return 0; |
628 | } | 638 | } |
@@ -675,10 +685,11 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */ | |||
675 | 685 | ||
676 | return 0; | 686 | return 0; |
677 | } | 687 | } |
678 | |||
679 | /* search hit - internal page: | 688 | /* search hit - internal page: |
680 | * descend/search its child page | 689 | * descend/search its child page |
681 | */ | 690 | */ |
691 | if (index < p->header.nextindex - 1) | ||
692 | next = offsetXAD(&p->xad[index + 1]); | ||
682 | goto next; | 693 | goto next; |
683 | } | 694 | } |
684 | 695 | ||
@@ -694,6 +705,8 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */ | |||
694 | * base is the smallest index with key (Kj) greater than | 705 | * base is the smallest index with key (Kj) greater than |
695 | * search key (K) and may be zero or maxentry index. | 706 | * search key (K) and may be zero or maxentry index. |
696 | */ | 707 | */ |
708 | if (base < p->header.nextindex) | ||
709 | next = offsetXAD(&p->xad[base]); | ||
697 | /* | 710 | /* |
698 | * search miss - leaf page: | 711 | * search miss - leaf page: |
699 | * | 712 | * |
@@ -727,6 +740,9 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */ | |||
727 | jfs_ip->btorder = BT_RANDOM; | 740 | jfs_ip->btorder = BT_RANDOM; |
728 | jfs_ip->btindex = base; | 741 | jfs_ip->btindex = base; |
729 | 742 | ||
743 | if (nextp) | ||
744 | *nextp = next; | ||
745 | |||
730 | return 0; | 746 | return 0; |
731 | } | 747 | } |
732 | 748 | ||
@@ -793,6 +809,7 @@ int xtInsert(tid_t tid, /* transaction id */ | |||
793 | struct xtsplit split; /* split information */ | 809 | struct xtsplit split; /* split information */ |
794 | xad_t *xad; | 810 | xad_t *xad; |
795 | int cmp; | 811 | int cmp; |
812 | s64 next; | ||
796 | struct tlock *tlck; | 813 | struct tlock *tlck; |
797 | struct xtlock *xtlck; | 814 | struct xtlock *xtlck; |
798 | 815 | ||
@@ -806,7 +823,7 @@ int xtInsert(tid_t tid, /* transaction id */ | |||
806 | * n.b. xtSearch() may return index of maxentry of | 823 | * n.b. xtSearch() may return index of maxentry of |
807 | * the full page. | 824 | * the full page. |
808 | */ | 825 | */ |
809 | if ((rc = xtSearch(ip, xoff, &cmp, &btstack, XT_INSERT))) | 826 | if ((rc = xtSearch(ip, xoff, &next, &cmp, &btstack, XT_INSERT))) |
810 | return rc; | 827 | return rc; |
811 | 828 | ||
812 | /* retrieve search result */ | 829 | /* retrieve search result */ |
@@ -814,7 +831,7 @@ int xtInsert(tid_t tid, /* transaction id */ | |||
814 | 831 | ||
815 | /* This test must follow XT_GETSEARCH since mp must be valid if | 832 | /* This test must follow XT_GETSEARCH since mp must be valid if |
816 | * we branch to out: */ | 833 | * we branch to out: */ |
817 | if (cmp == 0) { | 834 | if ((cmp == 0) || (next && (xlen > next - xoff))) { |
818 | rc = -EEXIST; | 835 | rc = -EEXIST; |
819 | goto out; | 836 | goto out; |
820 | } | 837 | } |
@@ -1626,7 +1643,7 @@ int xtExtend(tid_t tid, /* transaction id */ | |||
1626 | jfs_info("xtExtend: nxoff:0x%lx nxlen:0x%x", (ulong) xoff, xlen); | 1643 | jfs_info("xtExtend: nxoff:0x%lx nxlen:0x%x", (ulong) xoff, xlen); |
1627 | 1644 | ||
1628 | /* there must exist extent to be extended */ | 1645 | /* there must exist extent to be extended */ |
1629 | if ((rc = xtSearch(ip, xoff - 1, &cmp, &btstack, XT_INSERT))) | 1646 | if ((rc = xtSearch(ip, xoff - 1, NULL, &cmp, &btstack, XT_INSERT))) |
1630 | return rc; | 1647 | return rc; |
1631 | 1648 | ||
1632 | /* retrieve search result */ | 1649 | /* retrieve search result */ |
@@ -1794,7 +1811,7 @@ printf("xtTailgate: nxoff:0x%lx nxlen:0x%x nxaddr:0x%lx\n", | |||
1794 | */ | 1811 | */ |
1795 | 1812 | ||
1796 | /* there must exist extent to be tailgated */ | 1813 | /* there must exist extent to be tailgated */ |
1797 | if ((rc = xtSearch(ip, xoff, &cmp, &btstack, XT_INSERT))) | 1814 | if ((rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, XT_INSERT))) |
1798 | return rc; | 1815 | return rc; |
1799 | 1816 | ||
1800 | /* retrieve search result */ | 1817 | /* retrieve search result */ |
@@ -1977,7 +1994,7 @@ int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad) | |||
1977 | nxlen = lengthXAD(nxad); | 1994 | nxlen = lengthXAD(nxad); |
1978 | nxaddr = addressXAD(nxad); | 1995 | nxaddr = addressXAD(nxad); |
1979 | 1996 | ||
1980 | if ((rc = xtSearch(ip, nxoff, &cmp, &btstack, XT_INSERT))) | 1997 | if ((rc = xtSearch(ip, nxoff, NULL, &cmp, &btstack, XT_INSERT))) |
1981 | return rc; | 1998 | return rc; |
1982 | 1999 | ||
1983 | /* retrieve search result */ | 2000 | /* retrieve search result */ |
@@ -2291,7 +2308,7 @@ int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad) | |||
2291 | if (nextindex == le16_to_cpu(p->header.maxentry)) { | 2308 | if (nextindex == le16_to_cpu(p->header.maxentry)) { |
2292 | XT_PUTPAGE(mp); | 2309 | XT_PUTPAGE(mp); |
2293 | 2310 | ||
2294 | if ((rc = xtSearch(ip, nxoff, &cmp, &btstack, XT_INSERT))) | 2311 | if ((rc = xtSearch(ip, nxoff, NULL, &cmp, &btstack, XT_INSERT))) |
2295 | return rc; | 2312 | return rc; |
2296 | 2313 | ||
2297 | /* retrieve search result */ | 2314 | /* retrieve search result */ |
@@ -2438,6 +2455,7 @@ int xtAppend(tid_t tid, /* transaction id */ | |||
2438 | int nsplit, nblocks, xlen; | 2455 | int nsplit, nblocks, xlen; |
2439 | struct pxdlist pxdlist; | 2456 | struct pxdlist pxdlist; |
2440 | pxd_t *pxd; | 2457 | pxd_t *pxd; |
2458 | s64 next; | ||
2441 | 2459 | ||
2442 | xaddr = *xaddrp; | 2460 | xaddr = *xaddrp; |
2443 | xlen = *xlenp; | 2461 | xlen = *xlenp; |
@@ -2452,7 +2470,7 @@ int xtAppend(tid_t tid, /* transaction id */ | |||
2452 | * n.b. xtSearch() may return index of maxentry of | 2470 | * n.b. xtSearch() may return index of maxentry of |
2453 | * the full page. | 2471 | * the full page. |
2454 | */ | 2472 | */ |
2455 | if ((rc = xtSearch(ip, xoff, &cmp, &btstack, XT_INSERT))) | 2473 | if ((rc = xtSearch(ip, xoff, &next, &cmp, &btstack, XT_INSERT))) |
2456 | return rc; | 2474 | return rc; |
2457 | 2475 | ||
2458 | /* retrieve search result */ | 2476 | /* retrieve search result */ |
@@ -2462,6 +2480,9 @@ int xtAppend(tid_t tid, /* transaction id */ | |||
2462 | rc = -EEXIST; | 2480 | rc = -EEXIST; |
2463 | goto out; | 2481 | goto out; |
2464 | } | 2482 | } |
2483 | |||
2484 | if (next) | ||
2485 | xlen = min(xlen, (int)(next - xoff)); | ||
2465 | //insert: | 2486 | //insert: |
2466 | /* | 2487 | /* |
2467 | * insert entry for new extent | 2488 | * insert entry for new extent |
@@ -2600,7 +2621,7 @@ int xtDelete(tid_t tid, struct inode *ip, s64 xoff, s32 xlen, int flag) | |||
2600 | /* | 2621 | /* |
2601 | * find the matching entry; xtSearch() pins the page | 2622 | * find the matching entry; xtSearch() pins the page |
2602 | */ | 2623 | */ |
2603 | if ((rc = xtSearch(ip, xoff, &cmp, &btstack, 0))) | 2624 | if ((rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0))) |
2604 | return rc; | 2625 | return rc; |
2605 | 2626 | ||
2606 | XT_GETSEARCH(ip, btstack.top, bn, mp, p, index); | 2627 | 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 */ | |||
2852 | */ | 2873 | */ |
2853 | if (xtype == DATAEXT) { | 2874 | if (xtype == DATAEXT) { |
2854 | /* search in leaf entry */ | 2875 | /* search in leaf entry */ |
2855 | rc = xtSearch(ip, xoff, &cmp, &btstack, 0); | 2876 | rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0); |
2856 | if (rc) | 2877 | if (rc) |
2857 | return rc; | 2878 | return rc; |
2858 | 2879 | ||
@@ -2958,7 +2979,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */ | |||
2958 | } | 2979 | } |
2959 | 2980 | ||
2960 | /* get back parent page */ | 2981 | /* get back parent page */ |
2961 | if ((rc = xtSearch(ip, xoff, &cmp, &btstack, 0))) | 2982 | if ((rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0))) |
2962 | return rc; | 2983 | return rc; |
2963 | 2984 | ||
2964 | XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index); | 2985 | 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) | |||
3991 | 4012 | ||
3992 | if (committed_size) { | 4013 | if (committed_size) { |
3993 | xoff = (committed_size >> JFS_SBI(ip->i_sb)->l2bsize) - 1; | 4014 | xoff = (committed_size >> JFS_SBI(ip->i_sb)->l2bsize) - 1; |
3994 | rc = xtSearch(ip, xoff, &cmp, &btstack, 0); | 4015 | rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0); |
3995 | if (rc) | 4016 | if (rc) |
3996 | return rc; | 4017 | return rc; |
3997 | 4018 | ||