]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge git://oss.sgi.com:8090/oss/git/xfs-2.6
authorLinus Torvalds <torvalds@g5.osdl.org>
Thu, 12 Jan 2006 17:10:34 +0000 (09:10 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Thu, 12 Jan 2006 17:10:34 +0000 (09:10 -0800)
1  2 
fs/xfs/linux-2.6/xfs_ioctl.c
fs/xfs/linux-2.6/xfs_iops.c
fs/xfs/xfs_vnodeops.c

index 21667ba6dcd590c6a3a726f27184f948578c4dc0,b3b2cfda273ccbe625d79cfacf1c382a50a0c51e..4db47790415c86f5fb043bf866f20a665a54e2b6
@@@ -52,7 -52,6 +52,7 @@@
  #include "xfs_dfrag.h"
  #include "xfs_fsops.h"
  
 +#include <linux/capability.h>
  #include <linux/dcache.h>
  #include <linux/mount.h>
  #include <linux/namei.h>
@@@ -146,13 -145,10 +146,10 @@@ xfs_find_handle
  
        if (cmd != XFS_IOC_PATH_TO_FSHANDLE) {
                xfs_inode_t     *ip;
-               bhv_desc_t      *bhv;
                int             lock_mode;
  
                /* need to get access to the xfs_inode to read the generation */
-               bhv = vn_bhv_lookup_unlocked(VN_BHV_HEAD(vp), &xfs_vnodeops);
-               ASSERT(bhv);
-               ip = XFS_BHVTOI(bhv);
+               ip = xfs_vtoi(vp);
                ASSERT(ip);
                lock_mode = xfs_ilock_map_shared(ip);
  
@@@ -751,9 -747,8 +748,8 @@@ xfs_ioctl
                        (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
                        mp->m_rtdev_targp : mp->m_ddev_targp;
  
-               da.d_mem = da.d_miniosz = 1 << target->pbr_sshift;
-               /* The size dio will do in one go */
-               da.d_maxiosz = 64 * PAGE_CACHE_SIZE;
+               da.d_mem = da.d_miniosz = 1 << target->bt_sshift;
+               da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1);
  
                if (copy_to_user(arg, &da, sizeof(da)))
                        return -XFS_ERROR(EFAULT);
index 9b8ee3470ecc6448b6527db7de1f4aba10dec775,129403958044bbae5015e787bcd6fe82bd7650c8..4bd3d03b23edf6c0ba22bda785336ad0a2e54268
  #include "xfs_buf_item.h"
  #include "xfs_utils.h"
  
 +#include <linux/capability.h>
  #include <linux/xattr.h>
  #include <linux/namei.h>
+ #include <linux/security.h>
  
  #define IS_NOATIME(inode) ((inode->i_sb->s_flags & MS_NOATIME) ||     \
        (S_ISDIR(inode->i_mode) && inode->i_sb->s_flags & MS_NODIRATIME))
  
+ /*
+  * Get a XFS inode from a given vnode.
+  */
+ xfs_inode_t *
+ xfs_vtoi(
+       struct vnode    *vp)
+ {
+       bhv_desc_t      *bdp;
+       bdp = bhv_lookup_range(VN_BHV_HEAD(vp),
+                       VNODE_POSITION_XFS, VNODE_POSITION_XFS);
+       if (unlikely(bdp == NULL))
+               return NULL;
+       return XFS_BHVTOI(bdp);
+ }
+ /*
+  * Bring the atime in the XFS inode uptodate.
+  * Used before logging the inode to disk or when the Linux inode goes away.
+  */
+ void
+ xfs_synchronize_atime(
+       xfs_inode_t     *ip)
+ {
+       vnode_t         *vp;
+       vp = XFS_ITOV_NULL(ip);
+       if (vp) {
+               struct inode *inode = &vp->v_inode;
+               ip->i_d.di_atime.t_sec = (__int32_t)inode->i_atime.tv_sec;
+               ip->i_d.di_atime.t_nsec = (__int32_t)inode->i_atime.tv_nsec;
+       }
+ }
  /*
   * Change the requested timestamp in the given inode.
   * We don't lock across timestamp updates, and we don't log them but
@@@ -77,23 -111,6 +112,6 @@@ xfs_ichgtime
        struct inode    *inode = LINVFS_GET_IP(XFS_ITOV(ip));
        timespec_t      tv;
  
-       /*
-        * We're not supposed to change timestamps in readonly-mounted
-        * filesystems.  Throw it away if anyone asks us.
-        */
-       if (unlikely(IS_RDONLY(inode)))
-               return;
-       /*
-        * Don't update access timestamps on reads if mounted "noatime".
-        * Throw it away if anyone asks us.
-        */
-       if (unlikely(
-           (ip->i_mount->m_flags & XFS_MOUNT_NOATIME || IS_NOATIME(inode)) &&
-           (flags & (XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD|XFS_ICHGTIME_CHG)) ==
-                       XFS_ICHGTIME_ACC))
-               return;
        nanotime(&tv);
        if (flags & XFS_ICHGTIME_MOD) {
                inode->i_mtime = tv;
   * Variant on the above which avoids querying the system clock
   * in situations where we know the Linux inode timestamps have
   * just been updated (and so we can update our inode cheaply).
-  * We also skip the readonly and noatime checks here, they are
-  * also catered for already.
   */
  void
  xfs_ichgtime_fast(
        timespec_t      *tvp;
  
        /*
-        * We're not supposed to change timestamps in readonly-mounted
-        * filesystems.  Throw it away if anyone asks us.
+        * Atime updates for read() & friends are handled lazily now, and
+        * explicit updates must go through xfs_ichgtime()
         */
-       if (unlikely(IS_RDONLY(inode)))
-               return;
+       ASSERT((flags & XFS_ICHGTIME_ACC) == 0);
  
        /*
-        * Don't update access timestamps on reads if mounted "noatime".
-        * Throw it away if anyone asks us.
+        * We're not supposed to change timestamps in readonly-mounted
+        * filesystems.  Throw it away if anyone asks us.
         */
-       if (unlikely(
-           (ip->i_mount->m_flags & XFS_MOUNT_NOATIME || IS_NOATIME(inode)) &&
-           ((flags & (XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD|XFS_ICHGTIME_CHG)) ==
-                       XFS_ICHGTIME_ACC)))
+       if (unlikely(IS_RDONLY(inode)))
                return;
  
        if (flags & XFS_ICHGTIME_MOD) {
                ip->i_d.di_mtime.t_sec = (__int32_t)tvp->tv_sec;
                ip->i_d.di_mtime.t_nsec = (__int32_t)tvp->tv_nsec;
        }
-       if (flags & XFS_ICHGTIME_ACC) {
-               tvp = &inode->i_atime;
-               ip->i_d.di_atime.t_sec = (__int32_t)tvp->tv_sec;
-               ip->i_d.di_atime.t_nsec = (__int32_t)tvp->tv_nsec;
-       }
        if (flags & XFS_ICHGTIME_CHG) {
                tvp = &inode->i_ctime;
                ip->i_d.di_ctime.t_sec = (__int32_t)tvp->tv_sec;
@@@ -213,6 -219,39 +220,39 @@@ validate_fields
        }
  }
  
+ /*
+  * Hook in SELinux.  This is not quite correct yet, what we really need
+  * here (as we do for default ACLs) is a mechanism by which creation of
+  * these attrs can be journalled at inode creation time (along with the
+  * inode, of course, such that log replay can't cause these to be lost).
+  */
+ STATIC int
+ linvfs_init_security(
+       struct vnode    *vp,
+       struct inode    *dir)
+ {
+       struct inode    *ip = LINVFS_GET_IP(vp);
+       size_t          length;
+       void            *value;
+       char            *name;
+       int             error;
+       error = security_inode_init_security(ip, dir, &name, &value, &length);
+       if (error) {
+               if (error == -EOPNOTSUPP)
+                       return 0;
+               return -error;
+       }
+       VOP_ATTR_SET(vp, name, value, length, ATTR_SECURE, NULL, error);
+       if (!error)
+               VMODIFY(vp);
+       kfree(name);
+       kfree(value);
+       return error;
+ }
  /*
   * Determine whether a process has a valid fs_struct (kernel daemons
   * like knfsd don't have an fs_struct).
@@@ -278,6 -317,9 +318,9 @@@ linvfs_mknod
                break;
        }
  
+       if (!error)
+               error = linvfs_init_security(vp, dir);
        if (default_acl) {
                if (!error) {
                        error = _ACL_INHERIT(vp, &va, default_acl);
                                teardown.d_inode = ip = LINVFS_GET_IP(vp);
                                teardown.d_name = dentry->d_name;
  
-                               vn_mark_bad(vp);
-                               
                                if (S_ISDIR(mode))
                                        VOP_RMDIR(dvp, &teardown, NULL, err2);
                                else
@@@ -506,7 -546,7 +547,7 @@@ linvfs_follow_link
        ASSERT(dentry);
        ASSERT(nd);
  
-       link = (char *)kmalloc(MAXNAMELEN+1, GFP_KERNEL);
+       link = (char *)kmalloc(MAXPATHLEN+1, GFP_KERNEL);
        if (!link) {
                nd_set_link(nd, ERR_PTR(-ENOMEM));
                return NULL;
        vp = LINVFS_GET_VP(dentry->d_inode);
  
        iov.iov_base = link;
-       iov.iov_len = MAXNAMELEN;
+       iov.iov_len = MAXPATHLEN;
  
        uio->uio_iov = &iov;
        uio->uio_offset = 0;
        uio->uio_segflg = UIO_SYSSPACE;
-       uio->uio_resid = MAXNAMELEN;
+       uio->uio_resid = MAXPATHLEN;
        uio->uio_iovcnt = 1;
  
        VOP_READLINK(vp, uio, 0, NULL, error);
                kfree(link);
                link = ERR_PTR(-error);
        } else {
-               link[MAXNAMELEN - uio->uio_resid] = '\0';
+               link[MAXPATHLEN - uio->uio_resid] = '\0';
        }
        kfree(uio);
  
diff --combined fs/xfs/xfs_vnodeops.c
index e92cacde02f5966b8e289806ea829dbea1008d91,f8916349a9c66629a0145844c759eaa38faa7687..8076cc981e11f60cf011df7870066e1d5cd1bd3b
@@@ -15,9 -15,6 +15,9 @@@
   * along with this program; if not, write the Free Software Foundation,
   * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   */
 +
 +#include <linux/capability.h>
 +
  #include "xfs.h"
  #include "xfs_fs.h"
  #include "xfs_types.h"
@@@ -185,8 -182,7 +185,7 @@@ xfs_getattr
                break;
        }
  
-       vap->va_atime.tv_sec = ip->i_d.di_atime.t_sec;
-       vap->va_atime.tv_nsec = ip->i_d.di_atime.t_nsec;
+       vn_atime_to_timespec(vp, &vap->va_atime);
        vap->va_mtime.tv_sec = ip->i_d.di_mtime.t_sec;
        vap->va_mtime.tv_nsec = ip->i_d.di_mtime.t_nsec;
        vap->va_ctime.tv_sec = ip->i_d.di_ctime.t_sec;
@@@ -543,24 -539,6 +542,6 @@@ xfs_setattr
                        goto error_return;
                }
  
-               /*
-                * Can't set extent size unless the file is marked, or
-                * about to be marked as a realtime file.
-                *
-                * This check will be removed when fixed size extents
-                * with buffered data writes is implemented.
-                *
-                */
-               if ((mask & XFS_AT_EXTSIZE)                     &&
-                   ((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) !=
-                    vap->va_extsize) &&
-                   (!((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ||
-                      ((mask & XFS_AT_XFLAGS) &&
-                       (vap->va_xflags & XFS_XFLAG_REALTIME))))) {
-                       code = XFS_ERROR(EINVAL);
-                       goto error_return;
-               }
                /*
                 * Can't change realtime flag if any extents are allocated.
                 */
                                        di_flags |= XFS_DIFLAG_RTINHERIT;
                                if (vap->va_xflags & XFS_XFLAG_NOSYMLINKS)
                                        di_flags |= XFS_DIFLAG_NOSYMLINKS;
-                       } else {
+                               if (vap->va_xflags & XFS_XFLAG_EXTSZINHERIT)
+                                       di_flags |= XFS_DIFLAG_EXTSZINHERIT;
+                       } else if ((ip->i_d.di_mode & S_IFMT) == S_IFREG) {
                                if (vap->va_xflags & XFS_XFLAG_REALTIME) {
                                        di_flags |= XFS_DIFLAG_REALTIME;
                                        ip->i_iocore.io_flags |= XFS_IOCORE_RT;
                                } else {
                                        ip->i_iocore.io_flags &= ~XFS_IOCORE_RT;
                                }
+                               if (vap->va_xflags & XFS_XFLAG_EXTSIZE)
+                                       di_flags |= XFS_DIFLAG_EXTSIZE;
                        }
                        ip->i_d.di_flags = di_flags;
                }
@@@ -999,10 -981,6 +984,6 @@@ xfs_readlink
                goto error_return;
        }
  
-       if (!(ioflags & IO_INVIS)) {
-               xfs_ichgtime(ip, XFS_ICHGTIME_ACC);
-       }
        /*
         * See if the symlink is stored inline.
         */
@@@ -1234,7 -1212,8 +1215,8 @@@ xfs_inactive_free_eofblocks
        xfs_iunlock(ip, XFS_ILOCK_SHARED);
  
        if (!error && (nimaps != 0) &&
-           (imap.br_startblock != HOLESTARTBLOCK)) {
+           (imap.br_startblock != HOLESTARTBLOCK ||
+            ip->i_delayed_blks)) {
                /*
                 * Attach the dquots to the inode up front.
                 */
@@@ -1569,9 -1548,11 +1551,11 @@@ xfs_release
  
        if (ip->i_d.di_nlink != 0) {
                if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) &&
-                    ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0)) &&
+                    ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0 ||
+                      ip->i_delayed_blks > 0)) &&
                     (ip->i_df.if_flags & XFS_IFEXTENTS))  &&
-                   (!(ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC|XFS_DIFLAG_APPEND)))) {
+                   (!(ip->i_d.di_flags &
+                               (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)))) {
                        if ((error = xfs_inactive_free_eofblocks(mp, ip)))
                                return (error);
                        /* Update linux inode block count after free above */
@@@ -1628,7 -1609,8 +1612,8 @@@ xfs_inactive
         * only one with a reference to the inode.
         */
        truncate = ((ip->i_d.di_nlink == 0) &&
-           ((ip->i_d.di_size != 0) || (ip->i_d.di_nextents > 0)) &&
+             ((ip->i_d.di_size != 0) || (ip->i_d.di_nextents > 0) ||
+              (ip->i_delayed_blks > 0)) &&
            ((ip->i_d.di_mode & S_IFMT) == S_IFREG));
  
        mp = ip->i_mount;
  
        if (ip->i_d.di_nlink != 0) {
                if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) &&
-                    ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0)) &&
-                    (ip->i_df.if_flags & XFS_IFEXTENTS))  &&
-                   (!(ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC|XFS_DIFLAG_APPEND)) ||
-                    (ip->i_delayed_blks != 0))) {
+                      ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0 ||
+                        ip->i_delayed_blks > 0)) &&
+                     (ip->i_df.if_flags & XFS_IFEXTENTS) &&
+                    (!(ip->i_d.di_flags &
+                               (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) ||
+                     (ip->i_delayed_blks != 0)))) {
                        if ((error = xfs_inactive_free_eofblocks(mp, ip)))
                                return (VN_INACTIVE_CACHE);
                        /* Update linux inode block count after free above */
@@@ -2593,7 -2577,6 +2580,6 @@@ xfs_link
        int                     cancel_flags;
        int                     committed;
        vnode_t                 *target_dir_vp;
-       bhv_desc_t              *src_bdp;
        int                     resblks;
        char                    *target_name = VNAME(dentry);
        int                     target_namelen;
        if (VN_ISDIR(src_vp))
                return XFS_ERROR(EPERM);
  
-       src_bdp = vn_bhv_lookup_unlocked(VN_BHV_HEAD(src_vp), &xfs_vnodeops);
-       sip = XFS_BHVTOI(src_bdp);
+       sip = xfs_vtoi(src_vp);
        tdp = XFS_BHVTOI(target_dir_bdp);
        mp = tdp->i_mount;
        if (XFS_FORCED_SHUTDOWN(mp))
@@@ -3240,7 -3222,6 +3225,6 @@@ xfs_readdir
        xfs_trans_t     *tp = NULL;
        int             error = 0;
        uint            lock_mode;
-       xfs_off_t       start_offset;
  
        vn_trace_entry(BHV_TO_VNODE(dir_bdp), __FUNCTION__,
                                               (inst_t *)__return_address);
        }
  
        lock_mode = xfs_ilock_map_shared(dp);
-       start_offset = uiop->uio_offset;
        error = XFS_DIR_GETDENTS(dp->i_mount, tp, dp, uiop, eofp);
-       if (start_offset != uiop->uio_offset) {
-               xfs_ichgtime(dp, XFS_ICHGTIME_ACC);
-       }
        xfs_iunlock_map_shared(dp, lock_mode);
        return error;
  }
@@@ -3832,7 -3809,12 +3812,12 @@@ xfs_reclaim
        vn_iowait(vp);
  
        ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0);
-       ASSERT(VN_CACHED(vp) == 0);
+       /*
+        * Make sure the atime in the XFS inode is correct before freeing the
+        * Linux inode.
+        */
+       xfs_synchronize_atime(ip);
  
        /* If we have nothing to flush with this inode then complete the
         * teardown now, otherwise break the link between the xfs inode
@@@ -4002,42 -3984,36 +3987,36 @@@ xfs_alloc_file_space
        int                     alloc_type,
        int                     attr_flags)
  {
+       xfs_mount_t             *mp = ip->i_mount;
+       xfs_off_t               count;
        xfs_filblks_t           allocated_fsb;
        xfs_filblks_t           allocatesize_fsb;
-       int                     committed;
-       xfs_off_t               count;
-       xfs_filblks_t           datablocks;
-       int                     error;
+       xfs_extlen_t            extsz, temp;
+       xfs_fileoff_t           startoffset_fsb;
        xfs_fsblock_t           firstfsb;
-       xfs_bmap_free_t         free_list;
-       xfs_bmbt_irec_t         *imapp;
-       xfs_bmbt_irec_t         imaps[1];
-       xfs_mount_t             *mp;
-       int                     numrtextents;
-       int                     reccount;
-       uint                    resblks;
+       int                     nimaps;
+       int                     bmapi_flag;
+       int                     quota_flag;
        int                     rt;
-       int                     rtextsize;
-       xfs_fileoff_t           startoffset_fsb;
        xfs_trans_t             *tp;
-       int                     xfs_bmapi_flags;
+       xfs_bmbt_irec_t         imaps[1], *imapp;
+       xfs_bmap_free_t         free_list;
+       uint                    qblocks, resblks, resrtextents;
+       int                     committed;
+       int                     error;
  
        vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address);
-       mp = ip->i_mount;
  
        if (XFS_FORCED_SHUTDOWN(mp))
                return XFS_ERROR(EIO);
  
-       /*
-        * determine if this is a realtime file
-        */
-       if ((rt = XFS_IS_REALTIME_INODE(ip)) != 0) {
-               if (ip->i_d.di_extsize)
-                       rtextsize = ip->i_d.di_extsize;
-               else
-                       rtextsize = mp->m_sb.sb_rextsize;
-       } else
-               rtextsize = 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;
+       }
  
        if ((error = XFS_QM_DQATTACH(mp, ip, 0)))
                return error;
        count = len;
        error = 0;
        imapp = &imaps[0];
-       reccount = 1;
-       xfs_bmapi_flags = XFS_BMAPI_WRITE | (alloc_type ? XFS_BMAPI_PREALLOC : 0);
+       nimaps = 1;
+       bmapi_flag = XFS_BMAPI_WRITE | (alloc_type ? XFS_BMAPI_PREALLOC : 0);
        startoffset_fsb = XFS_B_TO_FSBT(mp, offset);
        allocatesize_fsb = XFS_B_TO_FSB(mp, count);
  
        }
  
        /*
-        * allocate file space until done or until there is an error
+        * Allocate file space until done or until there is an error
         */
  retry:
        while (allocatesize_fsb && !error) {
+               xfs_fileoff_t   s, e;
                /*
-                * determine if reserving space on
-                * the data or realtime partition.
+                * Determine space reservations for data/realtime.
                 */
-               if (rt) {
-                       xfs_fileoff_t s, e;
+               if (unlikely(extsz)) {
                        s = startoffset_fsb;
-                       do_div(s, rtextsize);
-                       s *= rtextsize;
-                       e = roundup_64(startoffset_fsb + allocatesize_fsb,
-                               rtextsize);
-                       numrtextents = (int)(e - s) / mp->m_sb.sb_rextsize;
-                       datablocks = 0;
+                       do_div(s, extsz);
+                       s *= extsz;
+                       e = startoffset_fsb + allocatesize_fsb;
+                       if ((temp = do_mod(startoffset_fsb, extsz)))
+                               e += temp;
+                       if ((temp = do_mod(e, extsz)))
+                               e += extsz - temp;
+               } else {
+                       s = 0;
+                       e = allocatesize_fsb;
+               }
+               if (unlikely(rt)) {
+                       resrtextents = qblocks = (uint)(e - s);
+                       resrtextents /= mp->m_sb.sb_rextsize;
+                       resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0);
+                       quota_flag = XFS_QMOPT_RES_RTBLKS;
                } else {
-                       datablocks = allocatesize_fsb;
-                       numrtextents = 0;
+                       resrtextents = 0;
+                       resblks = qblocks = \
+                               XFS_DIOSTRAT_SPACE_RES(mp, (uint)(e - s));
+                       quota_flag = XFS_QMOPT_RES_REGBLKS;
                }
  
                /*
-                * allocate and setup the transaction
+                * Allocate and setup the transaction.
                 */
                tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
-               resblks = XFS_DIOSTRAT_SPACE_RES(mp, datablocks);
-               error = xfs_trans_reserve(tp,
-                                         resblks,
-                                         XFS_WRITE_LOG_RES(mp),
-                                         numrtextents,
+               error = xfs_trans_reserve(tp, resblks,
+                                         XFS_WRITE_LOG_RES(mp), resrtextents,
                                          XFS_TRANS_PERM_LOG_RES,
                                          XFS_WRITE_LOG_COUNT);
                /*
-                * check for running out of space
+                * Check for running out of space
                 */
                if (error) {
                        /*
                        break;
                }
                xfs_ilock(ip, XFS_ILOCK_EXCL);
-               error = XFS_TRANS_RESERVE_QUOTA(mp, tp,
-                               ip->i_udquot, ip->i_gdquot, resblks, 0, 0);
+               error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip,
+                                                     qblocks, 0, quota_flag);
                if (error)
                        goto error1;
  
                xfs_trans_ihold(tp, ip);
  
                /*
-                * issue the bmapi() call to allocate the blocks
+                * Issue the xfs_bmapi() call to allocate the blocks
                 */
                XFS_BMAP_INIT(&free_list, &firstfsb);
                error = xfs_bmapi(tp, ip, startoffset_fsb,
-                                 allocatesize_fsb, xfs_bmapi_flags,
-                                 &firstfsb, 0, imapp, &reccount,
+                                 allocatesize_fsb, bmapi_flag,
+                                 &firstfsb, 0, imapp, &nimaps,
                                  &free_list);
                if (error) {
                        goto error0;
                }
  
                /*
-                * complete the transaction
+                * Complete the transaction
                 */
                error = xfs_bmap_finish(&tp, &free_list, firstfsb, &committed);
                if (error) {
  
                allocated_fsb = imapp->br_blockcount;
  
-               if (reccount == 0) {
+               if (nimaps == 0) {
                        error = XFS_ERROR(ENOSPC);
                        break;
                }
@@@ -4176,9 -4160,11 +4163,11 @@@ dmapi_enospc_check
  
        return error;
  
-  error0:
+ error0:       /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */
        xfs_bmap_cancel(&free_list);
-  error1:
+       XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag);
+ error1:       /* Just cancel transaction */
        xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
        xfs_iunlock(ip, XFS_ILOCK_EXCL);
        goto dmapi_enospc_check;
@@@ -4423,8 -4409,8 +4412,8 @@@ xfs_free_file_space
                }
                xfs_ilock(ip, XFS_ILOCK_EXCL);
                error = XFS_TRANS_RESERVE_QUOTA(mp, tp,
-                               ip->i_udquot, ip->i_gdquot, resblks, 0, rt ?
-                               XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS);
+                               ip->i_udquot, ip->i_gdquot, resblks, 0,
+                               XFS_QMOPT_RES_REGBLKS);
                if (error)
                        goto error1;