xfs: rename xfs_bmapi to xfs_bmapi_write
[pandora-kernel.git] / fs / xfs / xfs_bmap.c
index c2e49fd..595cc63 100644 (file)
@@ -4211,9 +4211,8 @@ xfs_bmap_validate_ret(
                ASSERT(i == 0 ||
                       mval[i - 1].br_startoff + mval[i - 1].br_blockcount ==
                       mval[i].br_startoff);
-               if (flags & XFS_BMAPI_WRITE)
-                       ASSERT(mval[i].br_startblock != DELAYSTARTBLOCK &&
-                              mval[i].br_startblock != HOLESTARTBLOCK);
+               ASSERT(mval[i].br_startblock != DELAYSTARTBLOCK &&
+                      mval[i].br_startblock != HOLESTARTBLOCK);
                ASSERT(mval[i].br_state == XFS_EXT_NORM ||
                       mval[i].br_state == XFS_EXT_UNWRITTEN);
        }
@@ -4809,60 +4808,57 @@ xfs_bmapi_convert_unwritten(
 }
 
 /*
- * Map file blocks to filesystem blocks.
- * File range is given by the bno/len pair.
- * Adds blocks to file if a write ("flags & XFS_BMAPI_WRITE" set)
- * into a hole or past eof.
- * Only allocates blocks from a single allocation group,
- * to avoid locking problems.
+ * Map file blocks to filesystem blocks, and allocate blocks or convert the
+ * extent state if necessary.  Details behaviour is controlled by the flags
+ * parameter.  Only allocates blocks from a single allocation group, to avoid
+ * locking problems.
+ *
  * The returned value in "firstblock" from the first call in a transaction
  * must be remembered and presented to subsequent calls in "firstblock".
  * An upper bound for the number of blocks to be allocated is supplied to
  * the first call in "total"; if no allocation group has that many free
  * blocks then the call will fail (return NULLFSBLOCK in "firstblock").
  */
-int                                    /* error */
-xfs_bmapi(
-       xfs_trans_t     *tp,            /* transaction pointer */
-       xfs_inode_t     *ip,            /* incore inode */
-       xfs_fileoff_t   bno,            /* starting file offs. mapped */
-       xfs_filblks_t   len,            /* length to map in file */
-       int             flags,          /* XFS_BMAPI_... */
-       xfs_fsblock_t   *firstblock,    /* first allocated block
-                                          controls a.g. for allocs */
-       xfs_extlen_t    total,          /* total blocks needed */
-       xfs_bmbt_irec_t *mval,          /* output: map values */
-       int             *nmap,          /* i/o: mval size/count */
-       xfs_bmap_free_t *flist)         /* i/o: list extents to free */
+int
+xfs_bmapi_write(
+       struct xfs_trans        *tp,            /* transaction pointer */
+       struct xfs_inode        *ip,            /* incore inode */
+       xfs_fileoff_t           bno,            /* starting file offs. mapped */
+       xfs_filblks_t           len,            /* length to map in file */
+       int                     flags,          /* XFS_BMAPI_... */
+       xfs_fsblock_t           *firstblock,    /* first allocated block
+                                                  controls a.g. for allocs */
+       xfs_extlen_t            total,          /* total blocks needed */
+       struct xfs_bmbt_irec    *mval,          /* output: map values */
+       int                     *nmap,          /* i/o: mval size/count */
+       struct xfs_bmap_free    *flist)         /* i/o: list extents to free */
 {
-       xfs_bmalloca_t  bma = { 0 };    /* args for xfs_bmap_alloc */
-       xfs_btree_cur_t *cur;           /* bmap btree cursor */
-       xfs_fileoff_t   end;            /* end of mapped file region */
-       int             eof;            /* we've hit the end of extents */
-       xfs_bmbt_rec_host_t *ep;        /* extent record pointer */
-       int             error;          /* error return */
-       xfs_bmbt_irec_t got;            /* current file extent record */
-       xfs_ifork_t     *ifp;           /* inode fork pointer */
-       xfs_extnum_t    lastx;          /* last useful extent number */
-       int             logflags;       /* flags for transaction logging */
-       xfs_extlen_t    minleft;        /* min blocks left after allocation */
-       xfs_mount_t     *mp;            /* xfs mount structure */
-       int             n;              /* current extent index */
-       int             nallocs;        /* number of extents alloc'd */
-       xfs_fileoff_t   obno;           /* old block number (offset) */
-       xfs_bmbt_irec_t prev;           /* previous file extent record */
-       int             tmp_logflags;   /* temp flags holder */
-       int             whichfork;      /* data or attr fork */
-       char            inhole;         /* current location is hole in file */
-       char            wasdelay;       /* old extent was delayed */
-       char            wr;             /* this is a write request */
-       char            rt;             /* this is a realtime file */
+       struct xfs_mount        *mp = ip->i_mount;
+       struct xfs_ifork        *ifp;
+       struct xfs_bmalloca     bma = { 0 };    /* args for xfs_bmap_alloc */
+       struct xfs_btree_cur    *cur;           /* bmap btree cursor */
+       xfs_fileoff_t           end;            /* end of mapped file region */
+       int                     eof;            /* after the end of extents */
+       int                     error;          /* error return */
+       struct xfs_bmbt_irec    got;            /* current file extent record */
+       xfs_extnum_t            lastx;          /* last useful extent number */
+       int                     logflags;       /* flags for transaction logging */
+       xfs_extlen_t            minleft;        /* min blocks left after allocation */
+       int                     n;              /* current extent index */
+       int                     nallocs;        /* number of extents alloc'd */
+       xfs_fileoff_t           obno;           /* old block number (offset) */
+       struct xfs_bmbt_irec    prev;           /* previous file extent record */
+       int                     tmp_logflags;   /* temp flags holder */
+       int                     whichfork;      /* data or attr fork */
+       char                    inhole;         /* current location is hole in file */
+       char                    wasdelay;       /* old extent was delayed */
+
 #ifdef DEBUG
-       xfs_fileoff_t   orig_bno;       /* original block number value */
-       int             orig_flags;     /* original flags arg value */
-       xfs_filblks_t   orig_len;       /* original value of len arg */
-       xfs_bmbt_irec_t *orig_mval;     /* original value of mval */
-       int             orig_nmap;      /* original value of *nmap */
+       xfs_fileoff_t           orig_bno;       /* original block number value */
+       int                     orig_flags;     /* original flags arg value */
+       xfs_filblks_t           orig_len;       /* original value of len arg */
+       struct xfs_bmbt_irec    *orig_mval;     /* original value of mval */
+       int                     orig_nmap;      /* original value of *nmap */
 
        orig_bno = bno;
        orig_len = len;
@@ -4870,69 +4866,60 @@ xfs_bmapi(
        orig_mval = mval;
        orig_nmap = *nmap;
 #endif
+
        ASSERT(*nmap >= 1);
-       ASSERT(*nmap <= XFS_BMAP_MAX_NMAP || !(flags & XFS_BMAPI_WRITE));
+       ASSERT(*nmap <= XFS_BMAP_MAX_NMAP);
+       ASSERT(!(flags & XFS_BMAPI_IGSTATE));
+       ASSERT(tp != NULL);
+
        whichfork = (flags & XFS_BMAPI_ATTRFORK) ?
                XFS_ATTR_FORK : XFS_DATA_FORK;
-       mp = ip->i_mount;
+
        if (unlikely(XFS_TEST_ERROR(
            (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
             XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
             XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL),
             mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) {
-               XFS_ERROR_REPORT("xfs_bmapi", XFS_ERRLEVEL_LOW, mp);
+               XFS_ERROR_REPORT("xfs_bmapi_write", XFS_ERRLEVEL_LOW, mp);
                return XFS_ERROR(EFSCORRUPTED);
        }
+
        if (XFS_FORCED_SHUTDOWN(mp))
                return XFS_ERROR(EIO);
-       rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip);
+
        ifp = XFS_IFORK_PTR(ip, whichfork);
        ASSERT(ifp->if_ext_max ==
               XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
-       if ((wr = (flags & XFS_BMAPI_WRITE)) != 0)
-               XFS_STATS_INC(xs_blk_mapw);
-       else
-               XFS_STATS_INC(xs_blk_mapr);
-       /*
-        * IGSTATE flag is used to combine extents which
-        * differ only due to the state of the extents.
-        * This technique is used from xfs_getbmap()
-        * when the caller does not wish to see the
-        * separation (which is the default).
-        *
-        * This technique is also used when writing a
-        * buffer which has been partially written,
-        * (usually by being flushed during a chunkread),
-        * to ensure one write takes place. This also
-        * prevents a change in the xfs inode extents at
-        * this time, intentionally. This change occurs
-        * on completion of the write operation, in
-        * xfs_strat_comp(), where the xfs_bmapi() call
-        * is transactioned, and the extents combined.
-        */
-       if ((flags & XFS_BMAPI_IGSTATE) && wr)  /* if writing unwritten space */
-               wr = 0;                         /* no allocations are allowed */
+
+       XFS_STATS_INC(xs_blk_mapw);
+
        logflags = 0;
        nallocs = 0;
        cur = NULL;
+
        if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) {
-               ASSERT(wr && tp);
-               if ((error = xfs_bmap_local_to_extents(tp, ip,
-                               firstblock, total, &logflags, whichfork)))
+               error = xfs_bmap_local_to_extents(tp, ip, firstblock, total,
+                                                 &logflags, whichfork);
+               if (error)
                        goto error0;
        }
-       if (wr && *firstblock == NULLFSBLOCK) {
+
+       if (*firstblock == NULLFSBLOCK) {
                if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE)
                        minleft = be16_to_cpu(ifp->if_broot->bb_level) + 1;
                else
                        minleft = 1;
-       } else
+       } else {
                minleft = 0;
-       if (!(ifp->if_flags & XFS_IFEXTENTS) &&
-           (error = xfs_iread_extents(tp, ip, whichfork)))
-               goto error0;
-       ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got,
-               &prev);
+       }
+
+       if (!(ifp->if_flags & XFS_IFEXTENTS)) {
+               error = xfs_iread_extents(tp, ip, whichfork);
+               if (error)
+                       goto error0;
+       }
+
+       xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, &prev);
        n = 0;
        end = bno + len;
        obno = bno;
@@ -4945,19 +4932,14 @@ xfs_bmapi(
        bma.userdata = 0;
 
        while (bno < end && n < *nmap) {
-               /*
-                * Reading past eof, act as though there's a hole
-                * up to end.
-                */
-               if (eof && !wr)
-                       got.br_startoff = end;
                inhole = eof || got.br_startoff > bno;
-               wasdelay = wr && !inhole && isnullstartblock(got.br_startblock);
+               wasdelay = !inhole && isnullstartblock(got.br_startblock);
+
                /*
                 * First, deal with the hole before the allocated space
                 * that we found, if any.
                 */
-               if (wr && (inhole || wasdelay)) {
+               if (inhole || wasdelay) {
                        bma.eof = eof;
                        bma.conv = !!(flags & XFS_BMAPI_CONVERT);
                        bma.wasdel = wasdelay;
@@ -4975,36 +4957,20 @@ xfs_bmapi(
                                minleft = 0;
                        if (bma.rval == NULLFSBLOCK)
                                break;
-               } else if (inhole) {
-                       /*
-                        * Reading in a hole.
-                        */
-                       mval->br_startoff = bno;
-                       mval->br_startblock = HOLESTARTBLOCK;
-                       mval->br_blockcount =
-                               XFS_FILBLKS_MIN(len, got.br_startoff - bno);
-                       mval->br_state = XFS_EXT_NORM;
-                       bno += mval->br_blockcount;
-                       len -= mval->br_blockcount;
-                       mval++;
-                       n++;
-                       continue;
                }
 
                /* Deal with the allocated space we found.  */
                xfs_bmapi_trim_map(mval, &got, &bno, len, obno, end, n, flags);
 
                /* Execute unwritten extent conversion if necessary */
-               if (wr) {
-                       error = xfs_bmapi_convert_unwritten(&bma, mval, len,
-                                               &lastx, &cur, firstblock, flist, flags,
-                                               &tmp_logflags);
-                       logflags |= tmp_logflags;
-                       if (error == EAGAIN)
-                               continue;
-                       if (error)
-                               goto error0;
-               }
+               error = xfs_bmapi_convert_unwritten(&bma, mval, len, &lastx,
+                                                   &cur, firstblock, flist,
+                                                   flags, &tmp_logflags);
+               logflags |= tmp_logflags;
+               if (error == EAGAIN)
+                       continue;
+               if (error)
+                       goto error0;
 
                /* update the extent map to return */
                xfs_bmapi_update_map(&mval, &bno, &len, obno, end, &n, flags);
@@ -5016,24 +4982,22 @@ xfs_bmapi(
                 */
                if (bno >= end || n >= *nmap || nallocs >= *nmap)
                        break;
-               /*
-                * Else go on to the next record.
-                */
+
+               /* Else go on to the next record. */
                prev = got;
-               if (++lastx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t)) {
-                       ep = xfs_iext_get_ext(ifp, lastx);
-                       xfs_bmbt_get_all(ep, &got);
-               } else {
+               if (++lastx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t))
+                       xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx), &got);
+               else
                        eof = 1;
-               }
        }
        *nmap = n;
+
        /*
         * Transform from btree to extents, give it cur.
         */
-       if (tp && XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE &&
+       if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE &&
            XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max) {
-               ASSERT(wr && cur);
+               ASSERT(cur);
                error = xfs_bmap_btree_to_extents(tp, ip, cur,
                        &tmp_logflags, whichfork);
                logflags |= tmp_logflags;
@@ -5061,10 +5025,9 @@ error0:
         * detecting a case where the data is changed, there's an error,
         * and it's not logged so we don't shutdown when we should.
         */
-       if (logflags) {
-               ASSERT(tp && wr);
+       if (logflags)
                xfs_trans_log_inode(tp, ip, logflags);
-       }
+
        if (cur) {
                if (!error) {
                        ASSERT(*firstblock == NULLFSBLOCK ||