int extHint(struct inode *ip, s64 offset, xad_t * xp)
{
struct super_block *sb = ip->i_sb;
- struct xadlist xadl;
- struct lxdlist lxdl;
- lxd_t lxd;
+ int nbperpage = JFS_SBI(sb)->nbperpage;
s64 prev;
- int rc, nbperpage = JFS_SBI(sb)->nbperpage;
+ int rc = 0;
+ s64 xaddr;
+ int xlen;
+ int xflag;
/* init the hint as "no hint provided" */
XADaddress(xp, 0);
*/
prev = ((offset & ~POFFSET) >> JFS_SBI(sb)->l2bsize) - nbperpage;
- /* if the offsets in the first page of the file,
- * no hint provided.
+ /* if the offset is in the first page of the file, no hint provided.
*/
if (prev < 0)
- return (0);
-
- /* prepare to lookup the previous page's extent info */
- lxdl.maxnlxd = 1;
- lxdl.nlxd = 1;
- lxdl.lxd = &lxd;
- LXDoffset(&lxd, prev)
- LXDlength(&lxd, nbperpage);
-
- xadl.maxnxad = 1;
- xadl.nxad = 0;
- xadl.xad = xp;
-
- /* perform the lookup */
- if ((rc = xtLookupList(ip, &lxdl, &xadl, 0)))
- return (rc);
-
- /* check if no extent exists for the previous page.
- * this is possible for sparse files.
- */
- if (xadl.nxad == 0) {
-// assert(ISSPARSE(ip));
- return (0);
- }
+ goto out;
- /* only preserve the abnr flag within the xad flags
- * of the returned hint.
- */
- xp->flag &= XAD_NOTRECORDED;
+ rc = xtLookup(ip, prev, nbperpage, &xflag, &xaddr, &xlen, 0);
- if(xadl.nxad != 1 || lengthXAD(xp) != nbperpage) {
- jfs_error(ip->i_sb, "extHint: corrupt xtree");
- return -EIO;
- }
+ if ((rc == 0) && xlen) {
+ if (xlen != nbperpage) {
+ jfs_error(ip->i_sb, "extHint: corrupt xtree");
+ rc = -EIO;
+ }
+ XADaddress(xp, xaddr);
+ XADlength(xp, xlen);
+ /*
+ * only preserve the abnr flag within the xad flags
+ * of the returned hint.
+ */
+ xp->flag = xflag & XAD_NOTRECORDED;
+ } else
+ rc = 0;
- return (0);
+out:
+ return (rc);
}
/* is lookup offset beyond eof ? */
size = ((u64) ip->i_size + (JFS_SBI(ip->i_sb)->bsize - 1)) >>
JFS_SBI(ip->i_sb)->l2bsize;
- if (lstart >= size) {
- jfs_err("xtLookup: lstart (0x%lx) >= size (0x%lx)",
- (ulong) lstart, (ulong) size);
+ if (lstart >= size)
return 0;
- }
}
/*
return rc;
}
-
-/*
- * xtLookupList()
- *
- * function: map a single logical extent into a list of physical extent;
- *
- * parameter:
- * struct inode *ip,
- * struct lxdlist *lxdlist, lxd list (in)
- * struct xadlist *xadlist, xad list (in/out)
- * int flag)
- *
- * coverage of lxd by xad under assumption of
- * . lxd's are ordered and disjoint.
- * . xad's are ordered and disjoint.
- *
- * return:
- * 0: success
- *
- * note: a page being written (even a single byte) is backed fully,
- * except the last page which is only backed with blocks
- * required to cover the last byte;
- * the extent backing a page is fully contained within an xad;
- */
-int xtLookupList(struct inode *ip, struct lxdlist * lxdlist,
- struct xadlist * xadlist, int flag)
-{
- int rc = 0;
- struct btstack btstack;
- int cmp;
- s64 bn;
- struct metapage *mp;
- xtpage_t *p;
- int index;
- lxd_t *lxd;
- xad_t *xad, *pxd;
- s64 size, lstart, lend, xstart, xend, pstart;
- s64 llen, xlen, plen;
- s64 xaddr, paddr;
- int nlxd, npxd, maxnpxd;
-
- npxd = xadlist->nxad = 0;
- maxnpxd = xadlist->maxnxad;
- pxd = xadlist->xad;
-
- nlxd = lxdlist->nlxd;
- lxd = lxdlist->lxd;
-
- lstart = offsetLXD(lxd);
- llen = lengthLXD(lxd);
- lend = lstart + llen;
-
- size = (ip->i_size + (JFS_SBI(ip->i_sb)->bsize - 1)) >>
- JFS_SBI(ip->i_sb)->l2bsize;
-
- /*
- * search for the xad entry covering the logical extent
- */
- search:
- if (lstart >= size)
- return 0;
-
- if ((rc = xtSearch(ip, lstart, NULL, &cmp, &btstack, 0)))
- return rc;
-
- /*
- * compute the physical extent covering logical extent
- *
- * N.B. search may have failed (e.g., hole in sparse file),
- * and returned the index of the next entry.
- */
-//map:
- /* retrieve search result */
- XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
-
- /* is xad on the next sibling page ? */
- if (index == le16_to_cpu(p->header.nextindex)) {
- if (p->header.flag & BT_ROOT)
- goto mapend;
-
- if ((bn = le64_to_cpu(p->header.next)) == 0)
- goto mapend;
-
- XT_PUTPAGE(mp);
-
- /* get next sibling page */
- XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
- if (rc)
- return rc;
-
- index = XTENTRYSTART;
- }
-
- xad = &p->xad[index];
-
- /*
- * is lxd covered by xad ?
- */
- compare:
- xstart = offsetXAD(xad);
- xlen = lengthXAD(xad);
- xend = xstart + xlen;
- xaddr = addressXAD(xad);
-
- compare1:
- if (xstart < lstart)
- goto compare2;
-
- /* (lstart <= xstart) */
-
- /* lxd is NOT covered by xad */
- if (lend <= xstart) {
- /*
- * get next lxd
- */
- if (--nlxd == 0)
- goto mapend;
- lxd++;
-
- lstart = offsetLXD(lxd);
- llen = lengthLXD(lxd);
- lend = lstart + llen;
- if (lstart >= size)
- goto mapend;
-
- /* compare with the current xad */
- goto compare1;
- }
- /* lxd is covered by xad */
- else { /* (xstart < lend) */
-
- /* initialize new pxd */
- pstart = xstart;
- plen = min(lend - xstart, xlen);
- paddr = xaddr;
-
- goto cover;
- }
-
- /* (xstart < lstart) */
- compare2:
- /* lxd is covered by xad */
- if (lstart < xend) {
- /* initialize new pxd */
- pstart = lstart;
- plen = min(xend - lstart, llen);
- paddr = xaddr + (lstart - xstart);
-
- goto cover;
- }
- /* lxd is NOT covered by xad */
- else { /* (xend <= lstart) */
-
- /*
- * get next xad
- *
- * linear search next xad covering lxd on
- * the current xad page, and then tree search
- */
- if (index == le16_to_cpu(p->header.nextindex) - 1) {
- if (p->header.flag & BT_ROOT)
- goto mapend;
-
- XT_PUTPAGE(mp);
- goto search;
- } else {
- index++;
- xad++;
-
- /* compare with new xad */
- goto compare;
- }
- }
-
- /*
- * lxd is covered by xad and a new pxd has been initialized
- * (lstart <= xstart < lend) or (xstart < lstart < xend)
- */
- cover:
- /* finalize pxd corresponding to current xad */
- XT_PUTENTRY(pxd, xad->flag, pstart, plen, paddr);
-
- if (++npxd >= maxnpxd)
- goto mapend;
- pxd++;
-
- /*
- * lxd is fully covered by xad
- */
- if (lend <= xend) {
- /*
- * get next lxd
- */
- if (--nlxd == 0)
- goto mapend;
- lxd++;
-
- lstart = offsetLXD(lxd);
- llen = lengthLXD(lxd);
- lend = lstart + llen;
- if (lstart >= size)
- goto mapend;
-
- /*
- * test for old xad covering new lxd
- * (old xstart < new lstart)
- */
- goto compare2;
- }
- /*
- * lxd is partially covered by xad
- */
- else { /* (xend < lend) */
-
- /*
- * get next xad
- *
- * linear search next xad covering lxd on
- * the current xad page, and then next xad page search
- */
- if (index == le16_to_cpu(p->header.nextindex) - 1) {
- if (p->header.flag & BT_ROOT)
- goto mapend;
-
- if ((bn = le64_to_cpu(p->header.next)) == 0)
- goto mapend;
-
- XT_PUTPAGE(mp);
-
- /* get next sibling page */
- XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
- if (rc)
- return rc;
-
- index = XTENTRYSTART;
- xad = &p->xad[index];
- } else {
- index++;
- xad++;
- }
-
- /*
- * test for new xad covering old lxd
- * (old lstart < new xstart)
- */
- goto compare;
- }
-
- mapend:
- xadlist->nxad = npxd;
-
-//out:
- XT_PUTPAGE(mp);
-
- return rc;
-}
-
-
/*
* xtSearch()
*