]> err.no Git - linux-2.6/blobdiff - fs/xfs/xfs_bmap.c
Merge master.kernel.org:/home/rmk/linux-2.6-arm
[linux-2.6] / fs / xfs / xfs_bmap.c
index 64a02eaf1dfedce1dd8731575750550fbedfc965..26939d364bc47bbcff7d52bce28d06ac988939d1 100644 (file)
@@ -3467,158 +3467,54 @@ done:
        return error;
 }
 
+/*
+ * Search the extent records for the entry containing block bno.
+ * If bno lies in a hole, point to the next entry.  If bno lies
+ * past eof, *eofp will be set, and *prevp will contain the last
+ * entry (null if none).  Else, *lastxp will be set to the index
+ * of the found entry; *gotp will contain the entry.
+ */
 xfs_bmbt_rec_t *                       /* pointer to found extent entry */
-xfs_bmap_do_search_extents(
-       xfs_bmbt_rec_t  *base,          /* base of extent list */
-       xfs_extnum_t    lastx,          /* last extent index used */
-       xfs_extnum_t    nextents,       /* number of file extents */
+xfs_bmap_search_multi_extents(
+       xfs_ifork_t     *ifp,           /* inode fork pointer */
        xfs_fileoff_t   bno,            /* block number searched for */
        int             *eofp,          /* out: end of file found */
        xfs_extnum_t    *lastxp,        /* out: last extent index */
        xfs_bmbt_irec_t *gotp,          /* out: extent entry found */
        xfs_bmbt_irec_t *prevp)         /* out: previous extent entry found */
 {
-       xfs_bmbt_rec_t  *ep;            /* extent list entry pointer */
-       xfs_bmbt_irec_t got;            /* extent list entry, decoded */
-       int             high;           /* high index of binary search */
-       int             low;            /* low index of binary search */
+       xfs_bmbt_rec_t  *ep;            /* extent record pointer */
+       xfs_extnum_t    lastx;          /* last extent index */
 
        /*
         * Initialize the extent entry structure to catch access to
         * uninitialized br_startblock field.
         */
-       got.br_startoff = 0xffa5a5a5a5a5a5a5LL;
-       got.br_blockcount = 0xa55a5a5a5a5a5a5aLL;
-       got.br_state = XFS_EXT_INVALID;
-
+       gotp->br_startoff = 0xffa5a5a5a5a5a5a5LL;
+       gotp->br_blockcount = 0xa55a5a5a5a5a5a5aLL;
+       gotp->br_state = XFS_EXT_INVALID;
 #if XFS_BIG_BLKNOS
-       got.br_startblock = 0xffffa5a5a5a5a5a5LL;
+       gotp->br_startblock = 0xffffa5a5a5a5a5a5LL;
 #else
-       got.br_startblock = 0xffffa5a5;
+       gotp->br_startblock = 0xffffa5a5;
 #endif
-
-       if (lastx != NULLEXTNUM && lastx < nextents)
-               ep = base + lastx;
-       else
-               ep = NULL;
        prevp->br_startoff = NULLFILEOFF;
-       if (ep && bno >= (got.br_startoff = xfs_bmbt_get_startoff(ep)) &&
-           bno < got.br_startoff +
-                 (got.br_blockcount = xfs_bmbt_get_blockcount(ep)))
-               *eofp = 0;
-       else if (ep && lastx < nextents - 1 &&
-                bno >= (got.br_startoff = xfs_bmbt_get_startoff(ep + 1)) &&
-                bno < got.br_startoff +
-                      (got.br_blockcount = xfs_bmbt_get_blockcount(ep + 1))) {
-               lastx++;
-               ep++;
-               *eofp = 0;
-       } else if (nextents == 0)
-               *eofp = 1;
-       else if (bno == 0 &&
-                (got.br_startoff = xfs_bmbt_get_startoff(base)) == 0) {
-               ep = base;
-               lastx = 0;
-               got.br_blockcount = xfs_bmbt_get_blockcount(ep);
+
+       ep = xfs_iext_bno_to_ext(ifp, bno, &lastx);
+       if (lastx > 0) {
+               xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx - 1), prevp);
+       }
+       if (lastx < (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))) {
+               xfs_bmbt_get_all(ep, gotp);
                *eofp = 0;
        } else {
-               low = 0;
-               high = nextents - 1;
-               /* binary search the extents array */
-               while (low <= high) {
-                       XFS_STATS_INC(xs_cmp_exlist);
-                       lastx = (low + high) >> 1;
-                       ep = base + lastx;
-                       got.br_startoff = xfs_bmbt_get_startoff(ep);
-                       got.br_blockcount = xfs_bmbt_get_blockcount(ep);
-                       if (bno < got.br_startoff)
-                               high = lastx - 1;
-                       else if (bno >= got.br_startoff + got.br_blockcount)
-                               low = lastx + 1;
-                       else {
-                               got.br_startblock = xfs_bmbt_get_startblock(ep);
-                               got.br_state = xfs_bmbt_get_state(ep);
-                               *eofp = 0;
-                               *lastxp = lastx;
-                               *gotp = got;
-                               return ep;
-                       }
-               }
-               if (bno >= got.br_startoff + got.br_blockcount) {
-                       lastx++;
-                       if (lastx == nextents) {
-                               *eofp = 1;
-                               got.br_startblock = xfs_bmbt_get_startblock(ep);
-                               got.br_state = xfs_bmbt_get_state(ep);
-                               *prevp = got;
-                               ep = NULL;
-                       } else {
-                               *eofp = 0;
-                               xfs_bmbt_get_all(ep, prevp);
-                               ep++;
-                               got.br_startoff = xfs_bmbt_get_startoff(ep);
-                               got.br_blockcount = xfs_bmbt_get_blockcount(ep);
-                       }
-               } else {
-                       *eofp = 0;
-                       if (ep > base)
-                               xfs_bmbt_get_all(ep - 1, prevp);
+               if (lastx > 0) {
+                       *gotp = *prevp;
                }
-       }
-       if (ep) {
-               got.br_startblock = xfs_bmbt_get_startblock(ep);
-               got.br_state = xfs_bmbt_get_state(ep);
+               *eofp = 1;
+               ep = NULL;
        }
        *lastxp = lastx;
-       *gotp = got;
-       return ep;
-}
-
-/*
- * Call xfs_bmap_do_search_extents() to search for the extent
- * record containing block bno. If in multi-level in-core extent
- * allocation mode, find and extract the target extent buffer,
- * otherwise just use the direct extent list.
- */
-xfs_bmbt_rec_t *                       /* pointer to found extent entry */
-xfs_bmap_search_multi_extents(
-       xfs_ifork_t     *ifp,           /* inode fork pointer */
-       xfs_fileoff_t   bno,            /* block number searched for */
-       int             *eofp,          /* out: end of file found */
-       xfs_extnum_t    *lastxp,        /* out: last extent index */
-       xfs_bmbt_irec_t *gotp,          /* out: extent entry found */
-       xfs_bmbt_irec_t *prevp)         /* out: previous extent entry found */
-{
-       xfs_bmbt_rec_t  *base;          /* base of extent records */
-       xfs_bmbt_rec_t  *ep;            /* extent record pointer */
-       xfs_ext_irec_t  *erp = NULL;    /* indirection array pointer */
-       xfs_extnum_t    lastx;          /* last extent index */
-       xfs_extnum_t    nextents;       /* number of file extents */
-
-       /*
-        * For multi-level extent allocation mode, find the
-        * target extent list and pass only the contiguous
-        * list to xfs_bmap_do_search_extents. Convert lastx
-        * from a file extent index to an index within the
-        * target extent list.
-        */
-       if (ifp->if_flags & XFS_IFEXTIREC) {
-               int     erp_idx = 0;
-               erp = xfs_iext_bno_to_irec(ifp, bno, &erp_idx);
-               base = erp->er_extbuf;
-               nextents = erp->er_extcount;
-               lastx = ifp->if_lastex - erp->er_extoff;
-       } else {
-               base = &ifp->if_u1.if_extents[0];
-               nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
-               lastx = ifp->if_lastex;
-       }
-       ep = xfs_bmap_do_search_extents(base, lastx, nextents, bno,
-                                       eofp, lastxp, gotp, prevp);
-       /* Convert lastx back to file-based index */
-       if (ifp->if_flags & XFS_IFEXTIREC) {
-               *lastxp += erp->er_extoff;
-       }
        return ep;
 }
 
@@ -4823,18 +4719,17 @@ xfs_bmapi(
                                /*
                                 * Make a transaction-less quota reservation for
                                 * delayed allocation blocks. This number gets
-                                * adjusted later.
-                                * We return EDQUOT if we haven't allocated
-                                * blks already inside this loop;
+                                * adjusted later.  We return if we haven't
+                                * allocated blocks already inside this loop.
                                 */
-                               if (XFS_TRANS_RESERVE_QUOTA_NBLKS(
+                               if ((error = XFS_TRANS_RESERVE_QUOTA_NBLKS(
                                                mp, NULL, ip, (long)alen, 0,
                                                rt ? XFS_QMOPT_RES_RTBLKS :
-                                                    XFS_QMOPT_RES_REGBLKS)) {
+                                                    XFS_QMOPT_RES_REGBLKS))) {
                                        if (n == 0) {
                                                *nmap = 0;
                                                ASSERT(cur == NULL);
-                                               return XFS_ERROR(EDQUOT);
+                                               return error;
                                        }
                                        break;
                                }