]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
xfs: introduce xfs_bmapi_delay()
authorChristoph Hellwig <hch@infradead.org>
Sun, 18 Sep 2011 20:40:48 +0000 (20:40 +0000)
committerAlex Elder <aelder@sgi.com>
Wed, 12 Oct 2011 02:15:04 +0000 (21:15 -0500)
Delalloc reservations are much simpler than allocations, so give
them a separate bmapi-level interface.  Using the previously added
xfs_bmapi_reserve_delalloc we get a function that is only minimally
more complicated than xfs_bmapi_read, which is far from the complexity
in xfs_bmapi.  Also remove the XFS_BMAPI_DELAY code after switching
over the only user to xfs_bmapi_delay.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Alex Elder <aelder@sgi.com>
fs/xfs/xfs_bmap.c
fs/xfs/xfs_bmap.h
fs/xfs/xfs_iomap.c

index cd01783a89d77d193d4de86b6330f6380f921a64..6f32769745553ca0b11ec9fd5db73dce77f1a3f6 100644 (file)
@@ -4238,7 +4238,7 @@ 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) && !(flags & XFS_BMAPI_DELAY))
+               if (flags & XFS_BMAPI_WRITE)
                        ASSERT(mval[i].br_startblock != DELAYSTARTBLOCK &&
                               mval[i].br_startblock != HOLESTARTBLOCK);
                ASSERT(mval[i].br_state == XFS_EXT_NORM ||
@@ -4555,6 +4555,90 @@ out_unreserve_quota:
        return error;
 }
 
+/*
+ * Map file blocks to filesystem blocks, adding delayed allocations as needed.
+ */
+int
+xfs_bmapi_delay(
+       struct xfs_inode        *ip,    /* incore inode */
+       xfs_fileoff_t           bno,    /* starting file offs. mapped */
+       xfs_filblks_t           len,    /* length to map in file */
+       struct xfs_bmbt_irec    *mval,  /* output: map values */
+       int                     *nmap,  /* i/o: mval size/count */
+       int                     flags)  /* XFS_BMAPI_... */
+{
+       struct xfs_mount        *mp = ip->i_mount;
+       struct xfs_ifork        *ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
+       struct xfs_bmbt_irec    got;    /* current file extent record */
+       struct xfs_bmbt_irec    prev;   /* previous file extent record */
+       xfs_fileoff_t           obno;   /* old block number (offset) */
+       xfs_fileoff_t           end;    /* end of mapped file region */
+       xfs_extnum_t            lastx;  /* last useful extent number */
+       int                     eof;    /* we've hit the end of extents */
+       int                     n = 0;  /* current extent index */
+       int                     error = 0;
+
+       ASSERT(*nmap >= 1);
+       ASSERT(*nmap <= XFS_BMAP_MAX_NMAP);
+       ASSERT(!(flags & ~XFS_BMAPI_ENTIRE));
+
+       if (unlikely(XFS_TEST_ERROR(
+           (XFS_IFORK_FORMAT(ip, XFS_DATA_FORK) != XFS_DINODE_FMT_EXTENTS &&
+            XFS_IFORK_FORMAT(ip, XFS_DATA_FORK) != XFS_DINODE_FMT_BTREE),
+            mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) {
+               XFS_ERROR_REPORT("xfs_bmapi_delay", XFS_ERRLEVEL_LOW, mp);
+               return XFS_ERROR(EFSCORRUPTED);
+       }
+
+       if (XFS_FORCED_SHUTDOWN(mp))
+               return XFS_ERROR(EIO);
+
+       XFS_STATS_INC(xs_blk_mapw);
+
+       if (!(ifp->if_flags & XFS_IFEXTENTS)) {
+               error = xfs_iread_extents(NULL, ip, XFS_DATA_FORK);
+               if (error)
+                       return error;
+       }
+
+       xfs_bmap_search_extents(ip, bno, XFS_DATA_FORK, &eof, &lastx, &got, &prev);
+       end = bno + len;
+       obno = bno;
+
+       while (bno < end && n < *nmap) {
+               if (eof || got.br_startoff > bno) {
+                       error = xfs_bmapi_reserve_delalloc(ip, bno, len, &got,
+                                                          &prev, &lastx, eof);
+                       if (error) {
+                               if (n == 0) {
+                                       *nmap = 0;
+                                       return error;
+                               }
+                               break;
+                       }
+               }
+
+               /* set up the extent map to return. */
+               xfs_bmapi_trim_map(mval, &got, &bno, len, obno, end, n, flags);
+               xfs_bmapi_update_map(&mval, &bno, &len, obno, end, &n, flags);
+
+               /* If we're done, stop now. */
+               if (bno >= end || n >= *nmap)
+                       break;
+
+               /* Else go on to the next record. */
+               prev = got;
+               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;
+       return 0;
+}
+
+
 /*
  * Map file blocks to filesystem blocks.
  * File range is given by the bno/len pair.
@@ -4663,7 +4747,6 @@ xfs_bmapi(
         */
        if ((flags & XFS_BMAPI_IGSTATE) && wr)  /* if writing unwritten space */
                wr = 0;                         /* no allocations are allowed */
-       ASSERT(wr || !(flags & XFS_BMAPI_DELAY));
        logflags = 0;
        nallocs = 0;
        cur = NULL;
@@ -4698,8 +4781,7 @@ xfs_bmapi(
                if (eof && !wr)
                        got.br_startoff = end;
                inhole = eof || got.br_startoff > bno;
-               wasdelay = wr && !inhole && !(flags & XFS_BMAPI_DELAY) &&
-                       isnullstartblock(got.br_startblock);
+               wasdelay = wr && !inhole && isnullstartblock(got.br_startblock);
                /*
                 * First, deal with the hole before the allocated space
                 * that we found, if any.
@@ -4727,20 +4809,7 @@ xfs_bmapi(
                                aoff = bno;
                        }
                        minlen = (flags & XFS_BMAPI_CONTIG) ? alen : 1;
-                       if (flags & XFS_BMAPI_DELAY) {
-                               error = xfs_bmapi_reserve_delalloc(ip, bno, len, &got,
-                                                                  &prev, &lastx, eof);
-                               if (error) {
-                                       if (n == 0) {
-                                               *nmap = 0;
-                                               ASSERT(cur == NULL);
-                                               return error;
-                                       }
-                                       break;
-                               }
-
-                               goto trim_extent;
-                       } else {
+                       {
                                /*
                                 * If first time, allocate and fill in
                                 * once-only bma fields.
@@ -4851,14 +4920,8 @@ xfs_bmapi(
                        ASSERT(got.br_startoff <= aoff);
                        ASSERT(got.br_startoff + got.br_blockcount >=
                                aoff + alen);
-#ifdef DEBUG
-                       if (flags & XFS_BMAPI_DELAY) {
-                               ASSERT(isnullstartblock(got.br_startblock));
-                               ASSERT(startblockval(got.br_startblock) > 0);
-                       }
                        ASSERT(got.br_state == XFS_EXT_NORM ||
                               got.br_state == XFS_EXT_UNWRITTEN);
-#endif
                        /*
                         * Fall down into the found allocated space case.
                         */
@@ -4877,7 +4940,7 @@ xfs_bmapi(
                        n++;
                        continue;
                }
-trim_extent:
+
                /* Deal with the allocated space we found.  */
                xfs_bmapi_trim_map(mval, &got, &bno, len, obno, end, n, flags);
 
@@ -4887,7 +4950,7 @@ trim_extent:
                 */
                if (wr &&
                    ((mval->br_state == XFS_EXT_UNWRITTEN &&
-                     ((flags & (XFS_BMAPI_PREALLOC|XFS_BMAPI_DELAY)) == 0)) ||
+                     ((flags & XFS_BMAPI_PREALLOC) == 0)) ||
                     (mval->br_state == XFS_EXT_NORM &&
                      ((flags & (XFS_BMAPI_PREALLOC|XFS_BMAPI_CONVERT)) ==
                                (XFS_BMAPI_PREALLOC|XFS_BMAPI_CONVERT))))) {
index 01693390df219c06420dc5850599b3745fb00a7d..c70c19c7f1fa6ec884340e0fe327e3d5dd0b7d53 100644 (file)
@@ -65,7 +65,6 @@ typedef       struct xfs_bmap_free
  * Flags for xfs_bmapi
  */
 #define        XFS_BMAPI_WRITE         0x001   /* write operation: allocate space */
-#define XFS_BMAPI_DELAY                0x002   /* delayed write operation */
 #define XFS_BMAPI_ENTIRE       0x004   /* return entire extent, not trimmed */
 #define XFS_BMAPI_METADATA     0x008   /* mapping metadata not user data */
 #define XFS_BMAPI_ATTRFORK     0x010   /* use attribute fork not data */
@@ -82,7 +81,6 @@ typedef       struct xfs_bmap_free
 
 #define XFS_BMAPI_FLAGS \
        { XFS_BMAPI_WRITE,      "WRITE" }, \
-       { XFS_BMAPI_DELAY,      "DELAY" }, \
        { XFS_BMAPI_ENTIRE,     "ENTIRE" }, \
        { XFS_BMAPI_METADATA,   "METADATA" }, \
        { XFS_BMAPI_ATTRFORK,   "ATTRFORK" }, \
@@ -297,6 +295,9 @@ xfs_bmapi(
 int    xfs_bmapi_read(struct xfs_inode *ip, xfs_fileoff_t bno,
                xfs_filblks_t len, struct xfs_bmbt_irec *mval,
                int *nmap, int flags);
+int    xfs_bmapi_delay(struct xfs_inode *ip, xfs_fileoff_t bno,
+               xfs_filblks_t len, struct xfs_bmbt_irec *mval,
+               int *nmap, int flags);
 
 /*
  * Unmap (remove) blocks from a file.
index 544f053860f15bff7d5730ee28970cb17f8080aa..681ba34c9233c55709bd0c9b03b7484ecf6524cc 100644 (file)
@@ -381,7 +381,6 @@ xfs_iomap_write_delay(
        xfs_fileoff_t   last_fsb;
        xfs_off_t       aligned_offset;
        xfs_fileoff_t   ioalign;
-       xfs_fsblock_t   firstblock;
        xfs_extlen_t    extsz;
        int             nimaps;
        xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS];
@@ -425,12 +424,8 @@ retry:
        }
 
        nimaps = XFS_WRITE_IMAPS;
-       firstblock = NULLFSBLOCK;
-       error = xfs_bmapi(NULL, ip, offset_fsb,
-                         (xfs_filblks_t)(last_fsb - offset_fsb),
-                         XFS_BMAPI_DELAY | XFS_BMAPI_WRITE |
-                         XFS_BMAPI_ENTIRE, &firstblock, 1, imap,
-                         &nimaps, NULL);
+       error = xfs_bmapi_delay(ip, offset_fsb, last_fsb - offset_fsb,
+                               imap, &nimaps, XFS_BMAPI_ENTIRE);
        switch (error) {
        case 0:
        case ENOSPC: