[PATCH] USB: add ZyXEL vendor/product ID to rtl8150 driver
[pandora-kernel.git] / fs / xfs / xfs_iomap.c
index 45a77a3..f1949c1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * Copyright (c) 2000-2006 Silicon Graphics, Inc.
  * All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -23,7 +23,6 @@
 #include "xfs_trans.h"
 #include "xfs_sb.h"
 #include "xfs_ag.h"
-#include "xfs_dir.h"
 #include "xfs_dir2.h"
 #include "xfs_alloc.h"
 #include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
 #include "xfs_bmap_btree.h"
 #include "xfs_alloc_btree.h"
 #include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
 #include "xfs_dir2_sf.h"
 #include "xfs_attr_sf.h"
 #include "xfs_dinode.h"
@@ -40,7 +38,6 @@
 #include "xfs_ialloc.h"
 #include "xfs_btree.h"
 #include "xfs_bmap.h"
-#include "xfs_bit.h"
 #include "xfs_rtalloc.h"
 #include "xfs_error.h"
 #include "xfs_itable.h"
@@ -77,7 +74,7 @@ xfs_iomap_enter_trace(
                (void *)((unsigned long)count),
                (void *)((unsigned long)((io->io_new_size >> 32) & 0xffffffff)),
                (void *)((unsigned long)(io->io_new_size & 0xffffffff)),
-               (void *)NULL,
+               (void *)((unsigned long)current_pid()),
                (void *)NULL,
                (void *)NULL,
                (void *)NULL,
@@ -253,7 +250,7 @@ xfs_iomap(
        error = XFS_BMAPI(mp, NULL, io, offset_fsb,
                        (xfs_filblks_t)(end_fsb - offset_fsb),
                        bmapi_flags,  NULL, 0, &imap,
-                       &nimaps, NULL);
+                       &nimaps, NULL, NULL);
 
        if (error)
                goto out;
@@ -263,7 +260,7 @@ phase2:
        case BMAPI_WRITE:
                /* If we found an extent, return it */
                if (nimaps &&
-                   (imap.br_startblock != HOLESTARTBLOCK) && 
+                   (imap.br_startblock != HOLESTARTBLOCK) &&
                    (imap.br_startblock != DELAYSTARTBLOCK)) {
                        xfs_iomap_map_trace(XFS_IOMAP_WRITE_MAP, io,
                                        offset, count, iomapp, &imap, flags);
@@ -317,6 +314,58 @@ out:
        return XFS_ERROR(error);
 }
 
+STATIC int
+xfs_iomap_eof_align_last_fsb(
+       xfs_mount_t     *mp,
+       xfs_iocore_t    *io,
+       xfs_fsize_t     isize,
+       xfs_extlen_t    extsize,
+       xfs_fileoff_t   *last_fsb)
+{
+       xfs_fileoff_t   new_last_fsb = 0;
+       xfs_extlen_t    align;
+       int             eof, error;
+
+       if (io->io_flags & XFS_IOCORE_RT)
+               ;
+       /*
+        * If mounted with the "-o swalloc" option, roundup the allocation
+        * request to a stripe width boundary if the file size is >=
+        * stripe width and we are allocating past the allocation eof.
+        */
+       else if (mp->m_swidth && (mp->m_flags & XFS_MOUNT_SWALLOC) &&
+               (isize >= XFS_FSB_TO_B(mp, mp->m_swidth)))
+               new_last_fsb = roundup_64(*last_fsb, mp->m_swidth);
+       /*
+        * Roundup the allocation request to a stripe unit (m_dalign) boundary
+        * if the file size is >= stripe unit size, and we are allocating past
+        * the allocation eof.
+        */
+       else if (mp->m_dalign && (isize >= XFS_FSB_TO_B(mp, mp->m_dalign)))
+               new_last_fsb = roundup_64(*last_fsb, mp->m_dalign);
+
+       /*
+        * Always round up the allocation request to an extent boundary
+        * (when file on a real-time subvolume or has di_extsize hint).
+        */
+       if (extsize) {
+               if (new_last_fsb)
+                       align = roundup_64(new_last_fsb, extsize);
+               else
+                       align = extsize;
+               new_last_fsb = roundup_64(*last_fsb, align);
+       }
+
+       if (new_last_fsb) {
+               error = XFS_BMAP_EOF(mp, io, new_last_fsb, XFS_DATA_FORK, &eof);
+               if (error)
+                       return error;
+               if (eof)
+                       *last_fsb = new_last_fsb;
+       }
+       return 0;
+}
+
 STATIC int
 xfs_flush_space(
        xfs_inode_t     *ip,
@@ -363,19 +412,20 @@ xfs_iomap_write_direct(
        xfs_iocore_t    *io = &ip->i_iocore;
        xfs_fileoff_t   offset_fsb;
        xfs_fileoff_t   last_fsb;
-       xfs_filblks_t   count_fsb;
+       xfs_filblks_t   count_fsb, resaligned;
        xfs_fsblock_t   firstfsb;
+       xfs_extlen_t    extsz, temp;
+       xfs_fsize_t     isize;
        int             nimaps;
-       int             error;
        int             bmapi_flag;
        int             quota_flag;
        int             rt;
        xfs_trans_t     *tp;
        xfs_bmbt_irec_t imap;
        xfs_bmap_free_t free_list;
-       xfs_filblks_t   qblocks, resblks;
+       uint            qblocks, resblks, resrtextents;
        int             committed;
-       int             resrtextents;
+       int             error;
 
        /*
         * Make sure that the dquots are there. This doesn't hold
@@ -385,38 +435,53 @@ xfs_iomap_write_direct(
        if (error)
                return XFS_ERROR(error);
 
-       offset_fsb = XFS_B_TO_FSBT(mp, offset);
-       last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count)));
-       count_fsb = last_fsb - offset_fsb;
-       if (found && (ret_imap->br_startblock == HOLESTARTBLOCK)) {
-               xfs_fileoff_t   map_last_fsb;
-
-               map_last_fsb = ret_imap->br_blockcount + ret_imap->br_startoff;
-               if (map_last_fsb < last_fsb) {
-                       last_fsb = map_last_fsb;
-                       count_fsb = last_fsb - offset_fsb;
-               }
-               ASSERT(count_fsb > 0);
+       rt = XFS_IS_REALTIME_INODE(ip);
+       if (unlikely(rt)) {
+               if (!(extsz = ip->i_d.di_extsize))
+                       extsz = mp->m_sb.sb_rextsize;
+       } else {
+               extsz = ip->i_d.di_extsize;
        }
 
-       /*
-        * Determine if reserving space on the data or realtime partition.
-        */
-       if ((rt = XFS_IS_REALTIME_INODE(ip))) {
-               xfs_extlen_t    extsz;
+       isize = ip->i_d.di_size;
+       if (io->io_new_size > isize)
+               isize = io->io_new_size;
 
-               if (!(extsz = ip->i_d.di_extsize))
-                       extsz = mp->m_sb.sb_rextsize;
-               resrtextents = qblocks = (count_fsb + extsz - 1);
-               do_div(resrtextents, mp->m_sb.sb_rextsize);
-               resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0);
-               quota_flag = XFS_QMOPT_RES_RTBLKS;
+       offset_fsb = XFS_B_TO_FSBT(mp, offset);
+       last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count)));
+       if ((offset + count) > isize) {
+               error = xfs_iomap_eof_align_last_fsb(mp, io, isize, extsz,
+                                                       &last_fsb);
+               if (error)
+                       goto error_out;
        } else {
-               resrtextents = 0;
-               resblks = qblocks = XFS_DIOSTRAT_SPACE_RES(mp, count_fsb);
-               quota_flag = XFS_QMOPT_RES_REGBLKS;
+               if (found && (ret_imap->br_startblock == HOLESTARTBLOCK))
+                       last_fsb = MIN(last_fsb, (xfs_fileoff_t)
+                                       ret_imap->br_blockcount +
+                                       ret_imap->br_startoff);
+       }
+       count_fsb = last_fsb - offset_fsb;
+       ASSERT(count_fsb > 0);
+
+       resaligned = count_fsb;
+       if (unlikely(extsz)) {
+               if ((temp = do_mod(offset_fsb, extsz)))
+                       resaligned += temp;
+               if ((temp = do_mod(resaligned, extsz)))
+                       resaligned += extsz - temp;
        }
 
+       if (unlikely(rt)) {
+               resrtextents = qblocks = resaligned;
+               resrtextents /= mp->m_sb.sb_rextsize;
+               resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0);
+               quota_flag = XFS_QMOPT_RES_RTBLKS;
+       } else {
+               resrtextents = 0;
+               resblks = qblocks = XFS_DIOSTRAT_SPACE_RES(mp, resaligned);
+               quota_flag = XFS_QMOPT_RES_REGBLKS;
+       }
+
        /*
         * Allocate and setup the transaction
         */
@@ -426,7 +491,6 @@ xfs_iomap_write_direct(
                        XFS_WRITE_LOG_RES(mp), resrtextents,
                        XFS_TRANS_PERM_LOG_RES,
                        XFS_WRITE_LOG_COUNT);
-
        /*
         * Check for running out of space, note: need lock to return
         */
@@ -436,25 +500,25 @@ xfs_iomap_write_direct(
        if (error)
                goto error_out;
 
-       if (XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag)) {
-               error = (EDQUOT);
+       error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip,
+                                             qblocks, 0, quota_flag);
+       if (error)
                goto error1;
-       }
 
-       bmapi_flag = XFS_BMAPI_WRITE;
        xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
        xfs_trans_ihold(tp, ip);
 
-       if (!(flags & BMAPI_MMAP) && (offset < ip->i_d.di_size || rt))
+       bmapi_flag = XFS_BMAPI_WRITE;
+       if ((flags & BMAPI_DIRECT) && (offset < ip->i_d.di_size || extsz))
                bmapi_flag |= XFS_BMAPI_PREALLOC;
 
        /*
-        * Issue the bmapi() call to allocate the blocks
+        * Issue the xfs_bmapi() call to allocate the blocks
         */
        XFS_BMAP_INIT(&free_list, &firstfsb);
        nimaps = 1;
-       error = xfs_bmapi(tp, ip, offset_fsb, count_fsb,
-               bmapi_flag, &firstfsb, 0, &imap, &nimaps, &free_list);
+       error = XFS_BMAPI(mp, tp, io, offset_fsb, count_fsb, bmapi_flag,
+               &firstfsb, 0, &imap, &nimaps, &free_list, NULL);
        if (error)
                goto error0;
 
@@ -484,8 +548,10 @@ xfs_iomap_write_direct(
                         "extent-state : %x \n",
                         (ip->i_mount)->m_fsname,
                         (long long)ip->i_ino,
-                        ret_imap->br_startblock, ret_imap->br_startoff,
-                        ret_imap->br_blockcount,ret_imap->br_state);
+                        (unsigned long long)ret_imap->br_startblock,
+                       (unsigned long long)ret_imap->br_startoff,
+                        (unsigned long long)ret_imap->br_blockcount,
+                       ret_imap->br_state);
         }
        return 0;
 
@@ -501,6 +567,63 @@ error_out:
        return XFS_ERROR(error);
 }
 
+/*
+ * If the caller is doing a write at the end of the file,
+ * then extend the allocation out to the file system's write
+ * iosize.  We clean up any extra space left over when the
+ * file is closed in xfs_inactive().
+ *
+ * For sync writes, we are flushing delayed allocate space to
+ * try to make additional space available for allocation near
+ * the filesystem full boundary - preallocation hurts in that
+ * situation, of course.
+ */
+STATIC int
+xfs_iomap_eof_want_preallocate(
+       xfs_mount_t     *mp,
+       xfs_iocore_t    *io,
+       xfs_fsize_t     isize,
+       xfs_off_t       offset,
+       size_t          count,
+       int             ioflag,
+       xfs_bmbt_irec_t *imap,
+       int             nimaps,
+       int             *prealloc)
+{
+       xfs_fileoff_t   start_fsb;
+       xfs_filblks_t   count_fsb;
+       xfs_fsblock_t   firstblock;
+       int             n, error, imaps;
+
+       *prealloc = 0;
+       if ((ioflag & BMAPI_SYNC) || (offset + count) <= isize)
+               return 0;
+
+       /*
+        * If there are any real blocks past eof, then don't
+        * do any speculative allocation.
+        */
+       start_fsb = XFS_B_TO_FSBT(mp, ((xfs_ufsize_t)(offset + count - 1)));
+       count_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp));
+       while (count_fsb > 0) {
+               imaps = nimaps;
+               firstblock = NULLFSBLOCK;
+               error = XFS_BMAPI(mp, NULL, io, start_fsb, count_fsb, 0,
+                                 &firstblock, 0, imap, &imaps, NULL, NULL);
+               if (error)
+                       return error;
+               for (n = 0; n < imaps; n++) {
+                       if ((imap[n].br_startblock != HOLESTARTBLOCK) &&
+                           (imap[n].br_startblock != DELAYSTARTBLOCK))
+                               return 0;
+                       start_fsb += imap[n].br_blockcount;
+                       count_fsb -= imap[n].br_blockcount;
+               }
+       }
+       *prealloc = 1;
+       return 0;
+}
+
 int
 xfs_iomap_write_delay(
        xfs_inode_t     *ip,
@@ -514,13 +637,15 @@ xfs_iomap_write_delay(
        xfs_iocore_t    *io = &ip->i_iocore;
        xfs_fileoff_t   offset_fsb;
        xfs_fileoff_t   last_fsb;
-       xfs_fsize_t     isize;
+       xfs_off_t       aligned_offset;
+       xfs_fileoff_t   ioalign;
        xfs_fsblock_t   firstblock;
+       xfs_extlen_t    extsz;
+       xfs_fsize_t     isize;
        int             nimaps;
-       int             error;
        xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS];
-       int             aeof;
-       int             fsynced = 0;
+       int             prealloc, fsynced = 0;
+       int             error;
 
        ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE) != 0);
 
@@ -528,152 +653,57 @@ xfs_iomap_write_delay(
         * Make sure that the dquots are there. This doesn't hold
         * the ilock across a disk read.
         */
-
        error = XFS_QM_DQATTACH(mp, ip, XFS_QMOPT_ILOCKED);
        if (error)
                return XFS_ERROR(error);
 
+       if (XFS_IS_REALTIME_INODE(ip)) {
+               if (!(extsz = ip->i_d.di_extsize))
+                       extsz = mp->m_sb.sb_rextsize;
+       } else {
+               extsz = ip->i_d.di_extsize;
+       }
+
+       offset_fsb = XFS_B_TO_FSBT(mp, offset);
+
 retry:
        isize = ip->i_d.di_size;
-       if (io->io_new_size > isize) {
+       if (io->io_new_size > isize)
                isize = io->io_new_size;
-       }
 
-       aeof = 0;
-       offset_fsb = XFS_B_TO_FSBT(mp, offset);
-       last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count)));
-       /*
-        * If the caller is doing a write at the end of the file,
-        * then extend the allocation (and the buffer used for the write)
-        * out to the file system's write iosize.  We clean up any extra
-        * space left over when the file is closed in xfs_inactive().
-        *
-        * For sync writes, we are flushing delayed allocate space to
-        * try to make additional space available for allocation near
-        * the filesystem full boundary - preallocation hurts in that
-        * situation, of course.
-        */
-       if (!(ioflag & BMAPI_SYNC) && ((offset + count) > ip->i_d.di_size)) {
-               xfs_off_t       aligned_offset;
-               xfs_filblks_t   count_fsb;
-               unsigned int    iosize;
-               xfs_fileoff_t   ioalign;
-               int             n;
-               xfs_fileoff_t   start_fsb;
+       error = xfs_iomap_eof_want_preallocate(mp, io, isize, offset, count,
+                               ioflag, imap, XFS_WRITE_IMAPS, &prealloc);
+       if (error)
+               return error;
 
-               /*
-                * If there are any real blocks past eof, then don't
-                * do any speculative allocation.
-                */
-               start_fsb = XFS_B_TO_FSBT(mp,
-                                       ((xfs_ufsize_t)(offset + count - 1)));
-               count_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp));
-               while (count_fsb > 0) {
-                       nimaps = XFS_WRITE_IMAPS;
-                       error = XFS_BMAPI(mp, NULL, io, start_fsb, count_fsb,
-                                       0, &firstblock, 0, imap, &nimaps, NULL);
-                       if (error) {
-                               return error;
-                       }
-                       for (n = 0; n < nimaps; n++) {
-                               if ( !(io->io_flags & XFS_IOCORE_RT)  && 
-                                       !imap[n].br_startblock) {
-                                       cmn_err(CE_PANIC,"Access to block "
-                                               "zero:  fs <%s> inode: %lld "
-                                               "start_block : %llx start_off "
-                                               ": %llx blkcnt : %llx "
-                                               "extent-state : %x \n",
-                                               (ip->i_mount)->m_fsname,
-                                               (long long)ip->i_ino,
-                                               imap[n].br_startblock,
-                                               imap[n].br_startoff,
-                                               imap[n].br_blockcount,
-                                               imap[n].br_state);
-                               }
-                               if ((imap[n].br_startblock != HOLESTARTBLOCK) &&
-                                   (imap[n].br_startblock != DELAYSTARTBLOCK)) {
-                                       goto write_map;
-                               }
-                               start_fsb += imap[n].br_blockcount;
-                               count_fsb -= imap[n].br_blockcount;
-                       }
-               }
-               iosize = mp->m_writeio_blocks;
+       if (prealloc) {
                aligned_offset = XFS_WRITEIO_ALIGN(mp, (offset + count - 1));
                ioalign = XFS_B_TO_FSBT(mp, aligned_offset);
-               last_fsb = ioalign + iosize;
-               aeof = 1;
+               last_fsb = ioalign + mp->m_writeio_blocks;
+       } else {
+               last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count)));
        }
-write_map:
-       nimaps = XFS_WRITE_IMAPS;
-       firstblock = NULLFSBLOCK;
-
-       /*
-        * If mounted with the "-o swalloc" option, roundup the allocation
-        * request to a stripe width boundary if the file size is >=
-        * stripe width and we are allocating past the allocation eof.
-        */
-       if (!(io->io_flags & XFS_IOCORE_RT) && mp->m_swidth 
-           && (mp->m_flags & XFS_MOUNT_SWALLOC)
-           && (isize >= XFS_FSB_TO_B(mp, mp->m_swidth)) && aeof) {
-               int eof;
-               xfs_fileoff_t new_last_fsb;
-
-               new_last_fsb = roundup_64(last_fsb, mp->m_swidth);
-               error = xfs_bmap_eof(ip, new_last_fsb, XFS_DATA_FORK, &eof);
-               if (error) {
-                       return error;
-               }
-               if (eof) {
-                       last_fsb = new_last_fsb;
-               }
-       /*
-        * Roundup the allocation request to a stripe unit (m_dalign) boundary
-        * if the file size is >= stripe unit size, and we are allocating past
-        * the allocation eof.
-        */
-       } else if (!(io->io_flags & XFS_IOCORE_RT) && mp->m_dalign &&
-                  (isize >= XFS_FSB_TO_B(mp, mp->m_dalign)) && aeof) {
-               int eof;
-               xfs_fileoff_t new_last_fsb;
-               new_last_fsb = roundup_64(last_fsb, mp->m_dalign);
-               error = xfs_bmap_eof(ip, new_last_fsb, XFS_DATA_FORK, &eof);
-               if (error) {
-                       return error;
-               }
-               if (eof) {
-                       last_fsb = new_last_fsb;
-               }
-       /*
-        * Round up the allocation request to a real-time extent boundary
-        * if the file is on the real-time subvolume.
-        */
-       } else if (io->io_flags & XFS_IOCORE_RT && aeof) {
-               int eof;
-               xfs_fileoff_t new_last_fsb;
 
-               new_last_fsb = roundup_64(last_fsb, mp->m_sb.sb_rextsize);
-               error = XFS_BMAP_EOF(mp, io, new_last_fsb, XFS_DATA_FORK, &eof);
-               if (error) {
+       if (prealloc || extsz) {
+               error = xfs_iomap_eof_align_last_fsb(mp, io, isize, extsz,
+                                                       &last_fsb);
+               if (error)
                        return error;
-               }
-               if (eof)
-                       last_fsb = new_last_fsb;
        }
-       error = xfs_bmapi(NULL, ip, offset_fsb,
+
+       nimaps = XFS_WRITE_IMAPS;
+       firstblock = NULLFSBLOCK;
+       error = XFS_BMAPI(mp, NULL, io, offset_fsb,
                          (xfs_filblks_t)(last_fsb - offset_fsb),
                          XFS_BMAPI_DELAY | XFS_BMAPI_WRITE |
                          XFS_BMAPI_ENTIRE, &firstblock, 1, imap,
-                         &nimaps, NULL);
-       /*
-        * This can be EDQUOT, if nimaps == 0
-        */
-       if (error && (error != ENOSPC)) {
+                         &nimaps, NULL, NULL);
+       if (error && (error != ENOSPC))
                return XFS_ERROR(error);
-       }
+
        /*
         * If bmapi returned us nothing, and if we didn't get back EDQUOT,
-        * then we must have run out of space.
+        * then we must have run out of space - flush delalloc, and retry..
         */
        if (nimaps == 0) {
                xfs_iomap_enter_trace(XFS_IOMAP_WRITE_NOSPACE,
@@ -685,17 +715,21 @@ write_map:
                goto retry;
        }
 
-       *ret_imap = imap[0];
-       *nmaps = 1;
-       if ( !(io->io_flags & XFS_IOCORE_RT)  && !ret_imap->br_startblock) {
+       if (!(io->io_flags & XFS_IOCORE_RT)  && !ret_imap->br_startblock) {
                cmn_err(CE_PANIC,"Access to block zero:  fs <%s> inode: %lld "
                         "start_block : %llx start_off : %llx blkcnt : %llx "
                         "extent-state : %x \n",
                         (ip->i_mount)->m_fsname,
                         (long long)ip->i_ino,
-                        ret_imap->br_startblock, ret_imap->br_startoff,
-                        ret_imap->br_blockcount,ret_imap->br_state);
+                        (unsigned long long)ret_imap->br_startblock,
+                       (unsigned long long)ret_imap->br_startoff,
+                        (unsigned long long)ret_imap->br_blockcount,
+                       ret_imap->br_state);
        }
+
+       *ret_imap = imap[0];
+       *nmaps = 1;
+
        return 0;
 }
 
@@ -796,9 +830,9 @@ xfs_iomap_write_allocate(
                        }
 
                        /* Go get the actual blocks */
-                       error = xfs_bmapi(tp, ip, map_start_fsb, count_fsb,
+                       error = XFS_BMAPI(mp, tp, io, map_start_fsb, count_fsb,
                                        XFS_BMAPI_WRITE, &first_block, 1,
-                                       imap, &nimaps, &free_list);
+                                       imap, &nimaps, &free_list, NULL);
                        if (error)
                                goto trans_cancel;
 
@@ -821,17 +855,21 @@ xfs_iomap_write_allocate(
                 */
 
                for (i = 0; i < nimaps; i++) {
-                       if ( !(io->io_flags & XFS_IOCORE_RT)  && 
-                               !imap[i].br_startblock) {
+                       if (!(io->io_flags & XFS_IOCORE_RT)  &&
+                           !imap[i].br_startblock) {
                                cmn_err(CE_PANIC,"Access to block zero:  "
                                        "fs <%s> inode: %lld "
-                                       "start_block : %llx start_off : %llx " 
+                                       "start_block : %llx start_off : %llx "
                                        "blkcnt : %llx extent-state : %x \n",
                                        (ip->i_mount)->m_fsname,
                                        (long long)ip->i_ino,
-                                       imap[i].br_startblock,
-                                       imap[i].br_startoff,
-                                       imap[i].br_blockcount,imap[i].br_state);
+                                       (unsigned long long)
+                                               imap[i].br_startblock,
+                                       (unsigned long long)
+                                               imap[i].br_startoff,
+                                       (unsigned long long)
+                                               imap[i].br_blockcount,
+                                       imap[i].br_state);
                         }
                        if ((offset_fsb >= imap[i].br_startoff) &&
                            (offset_fsb < (imap[i].br_startoff +
@@ -868,17 +906,17 @@ xfs_iomap_write_unwritten(
 {
        xfs_mount_t     *mp = ip->i_mount;
        xfs_iocore_t    *io = &ip->i_iocore;
-       xfs_trans_t     *tp;
        xfs_fileoff_t   offset_fsb;
        xfs_filblks_t   count_fsb;
        xfs_filblks_t   numblks_fsb;
-       xfs_bmbt_irec_t imap;
+       xfs_fsblock_t   firstfsb;
+       int             nimaps;
+       xfs_trans_t     *tp;
+       xfs_bmbt_irec_t imap;
+       xfs_bmap_free_t free_list;
+       uint            resblks;
        int             committed;
        int             error;
-       int             nres;
-       int             nimaps;
-       xfs_fsblock_t   firstfsb;
-       xfs_bmap_free_t free_list;
 
        xfs_iomap_enter_trace(XFS_IOMAP_UNWRITTEN,
                                &ip->i_iocore, offset, count);
@@ -887,9 +925,9 @@ xfs_iomap_write_unwritten(
        count_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count);
        count_fsb = (xfs_filblks_t)(count_fsb - offset_fsb);
 
-       do {
-               nres = XFS_DIOSTRAT_SPACE_RES(mp, 0);
+       resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0) << 1;
 
+       do {
                /*
                 * set up a transaction to convert the range of extents
                 * from unwritten to real. Do allocations in a loop until
@@ -897,7 +935,7 @@ xfs_iomap_write_unwritten(
                 */
 
                tp = xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE);
-               error = xfs_trans_reserve(tp, nres,
+               error = xfs_trans_reserve(tp, resblks,
                                XFS_WRITE_LOG_RES(mp), 0,
                                XFS_TRANS_PERM_LOG_RES,
                                XFS_WRITE_LOG_COUNT);
@@ -915,9 +953,9 @@ xfs_iomap_write_unwritten(
                 */
                XFS_BMAP_INIT(&free_list, &firstfsb);
                nimaps = 1;
-               error = xfs_bmapi(tp, ip, offset_fsb, count_fsb,
-                                 XFS_BMAPI_WRITE, &firstfsb,
-                                 1, &imap, &nimaps, &free_list);
+               error = XFS_BMAPI(mp, tp, io, offset_fsb, count_fsb,
+                                 XFS_BMAPI_WRITE|XFS_BMAPI_CONVERT, &firstfsb,
+                                 1, &imap, &nimaps, &free_list, NULL);
                if (error)
                        goto error_on_bmapi_transaction;
 
@@ -930,15 +968,17 @@ xfs_iomap_write_unwritten(
                xfs_iunlock(ip, XFS_ILOCK_EXCL);
                if (error)
                        goto error0;
-               
+
                if ( !(io->io_flags & XFS_IOCORE_RT)  && !imap.br_startblock) {
                        cmn_err(CE_PANIC,"Access to block zero:  fs <%s> "
                                "inode: %lld start_block : %llx start_off : "
                                "%llx blkcnt : %llx extent-state : %x \n",
                                (ip->i_mount)->m_fsname,
                                (long long)ip->i_ino,
-                               imap.br_startblock,imap.br_startoff,
-                               imap.br_blockcount,imap.br_state);
+                               (unsigned long long)imap.br_startblock,
+                               (unsigned long long)imap.br_startoff,
+                               (unsigned long long)imap.br_blockcount,
+                               imap.br_state);
                }
 
                if ((numblks_fsb = imap.br_blockcount) == 0) {