fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / fs / xfs / xfs_rtalloc.c
index 2c37822..880c732 100644 (file)
@@ -1,64 +1,43 @@
 /*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
  * published by the Free Software Foundation.
  *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like.  Any license provided herein, whether implied or
- * otherwise, applies only to this software file.  Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA  94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-/*
- * Free realtime space allocation for XFS.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
-
 #include "xfs.h"
-#include "xfs_macros.h"
+#include "xfs_fs.h"
 #include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
 #include "xfs_log.h"
+#include "xfs_inum.h"
 #include "xfs_trans.h"
 #include "xfs_sb.h"
 #include "xfs_ag.h"
-#include "xfs_dir.h"
 #include "xfs_dir2.h"
 #include "xfs_dmapi.h"
 #include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
 #include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
 #include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dir_sf.h"
 #include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
 #include "xfs_dinode.h"
 #include "xfs_inode.h"
+#include "xfs_btree.h"
+#include "xfs_ialloc.h"
 #include "xfs_alloc.h"
 #include "xfs_bmap.h"
-#include "xfs_bit.h"
 #include "xfs_rtalloc.h"
 #include "xfs_fsops.h"
 #include "xfs_error.h"
@@ -149,7 +128,8 @@ xfs_growfs_rt_alloc(
                /*
                 * Lock the inode.
                 */
-               if ((error = xfs_trans_iget(mp, tp, ino, 0, XFS_ILOCK_EXCL, &ip)))
+               if ((error = xfs_trans_iget(mp, tp, ino, 0,
+                                               XFS_ILOCK_EXCL, &ip)))
                        goto error_exit;
                XFS_BMAP_INIT(&flist, &firstblock);
                /*
@@ -159,7 +139,7 @@ xfs_growfs_rt_alloc(
                cancelflags |= XFS_TRANS_ABORT;
                error = xfs_bmapi(tp, ip, oblocks, nblocks - oblocks,
                        XFS_BMAPI_WRITE | XFS_BMAPI_METADATA, &firstblock,
-                       resblks, &map, &nmap, &flist);
+                       resblks, &map, &nmap, &flist, NULL);
                if (!error && nmap < 1)
                        error = XFS_ERROR(ENOSPC);
                if (error)
@@ -189,8 +169,8 @@ xfs_growfs_rt_alloc(
                        /*
                         * Lock the bitmap inode.
                         */
-                       if ((error = xfs_trans_iget(mp, tp, ino, 0, XFS_ILOCK_EXCL,
-                                       &ip)))
+                       if ((error = xfs_trans_iget(mp, tp, ino, 0,
+                                                       XFS_ILOCK_EXCL, &ip)))
                                goto error_exit;
                        /*
                         * Get a buffer for the block.
@@ -1949,7 +1929,7 @@ xfs_growfs_rt(
        /*
         * Initial error checking.
         */
-       if (mp->m_rtdev_targp || mp->m_rbmip == NULL ||
+       if (mp->m_rtdev_targp == NULL || mp->m_rbmip == NULL ||
            (nrblocks = in->newblocks) <= sbp->sb_rblocks ||
            (sbp->sb_rblocks && (in->extsize != sbp->sb_rextsize)))
                return XFS_ERROR(EINVAL);
@@ -1968,7 +1948,7 @@ xfs_growfs_rt(
         */
        nrextents = nrblocks;
        do_div(nrextents, in->extsize);
-       nrbmblocks = roundup_64(nrextents, NBBY * sbp->sb_blocksize);
+       nrbmblocks = howmany_64(nrextents, NBBY * sbp->sb_blocksize);
        nrextslog = xfs_highbit32(nrextents);
        nrsumlevels = nrextslog + 1;
        nrsumsize = (uint)sizeof(xfs_suminfo_t) * nrsumlevels * nrbmblocks;
@@ -1996,7 +1976,10 @@ xfs_growfs_rt(
        if ((error = xfs_growfs_rt_alloc(mp, rsumblocks, nrsumblocks,
                        mp->m_sb.sb_rsumino)))
                return error;
-       nmp = NULL;
+       /*
+        * Allocate a new (fake) mount/sb.
+        */
+       nmp = kmem_alloc(sizeof(*nmp), KM_SLEEP);
        /*
         * Loop over the bitmap blocks.
         * We will do everything one bitmap block at a time.
@@ -2007,10 +1990,6 @@ xfs_growfs_rt(
                     ((sbp->sb_rextents & ((1 << mp->m_blkbit_log) - 1)) != 0);
             bmbno < nrbmblocks;
             bmbno++) {
-               /*
-                * Allocate a new (fake) mount/sb.
-                */
-               nmp = kmem_alloc(sizeof(*nmp), KM_SLEEP);
                *nmp = *mp;
                nsbp = &nmp->m_sb;
                /*
@@ -2038,13 +2017,13 @@ xfs_growfs_rt(
                cancelflags = 0;
                if ((error = xfs_trans_reserve(tp, 0,
                                XFS_GROWRTFREE_LOG_RES(nmp), 0, 0, 0)))
-                       goto error_exit;
+                       break;
                /*
                 * Lock out other callers by grabbing the bitmap inode lock.
                 */
-               if ((error = xfs_trans_iget(mp, tp, 0, mp->m_sb.sb_rbmino,
-                               XFS_ILOCK_EXCL, &ip)))
-                       goto error_exit;
+               if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0,
+                                               XFS_ILOCK_EXCL, &ip)))
+                       break;
                ASSERT(ip == mp->m_rbmip);
                /*
                 * Update the bitmap inode's size.
@@ -2056,9 +2035,9 @@ xfs_growfs_rt(
                /*
                 * Get the summary inode into the transaction.
                 */
-               if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rsumino,
-                               0, XFS_ILOCK_EXCL, &ip)))
-                       goto error_exit;
+               if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rsumino, 0,
+                                               XFS_ILOCK_EXCL, &ip)))
+                       break;
                ASSERT(ip == mp->m_rsumip);
                /*
                 * Update the summary inode's size.
@@ -2073,7 +2052,7 @@ xfs_growfs_rt(
                    mp->m_rsumlevels != nmp->m_rsumlevels) {
                        error = xfs_rtcopy_summary(mp, nmp, tp);
                        if (error)
-                               goto error_exit;
+                               break;
                }
                /*
                 * Update superblock fields.
@@ -2100,17 +2079,12 @@ xfs_growfs_rt(
                error = xfs_rtfree_range(nmp, tp, sbp->sb_rextents,
                        nsbp->sb_rextents - sbp->sb_rextents, &bp, &sumbno);
                if (error)
-                       goto error_exit;
+                       break;
                /*
                 * Mark more blocks free in the superblock.
                 */
                xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS,
                        nsbp->sb_rextents - sbp->sb_rextents);
-               /*
-                * Free the fake mp structure.
-                */
-               kmem_free(nmp, sizeof(*nmp));
-               nmp = NULL;
                /*
                 * Update mp values into the real mp structure.
                 */
@@ -2121,15 +2095,15 @@ xfs_growfs_rt(
                 */
                xfs_trans_commit(tp, 0, NULL);
        }
-       return 0;
+
+       if (error)
+               xfs_trans_cancel(tp, cancelflags);
 
        /*
-        * Error paths come here.
+        * Free the fake mp structure.
         */
-error_exit:
-       if (nmp)
-               kmem_free(nmp, sizeof(*nmp));
-       xfs_trans_cancel(tp, cancelflags);
+       kmem_free(nmp, sizeof(*nmp));
+
        return error;
 }
 
@@ -2177,10 +2151,9 @@ xfs_rtallocate_extent(
        /*
         * Lock out other callers by grabbing the bitmap inode lock.
         */
-       error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0, XFS_ILOCK_EXCL, &ip);
-       if (error) {
+       if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0,
+                                       XFS_ILOCK_EXCL, &ip)))
                return error;
-       }
        sumbp = NULL;
        /*
         * Allocate by size, or near another block, or exactly at some block.
@@ -2240,10 +2213,9 @@ xfs_rtfree_extent(
        /*
         * Synchronize by locking the bitmap inode.
         */
-       error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0, XFS_ILOCK_EXCL, &ip);
-       if (error) {
+       if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0,
+                                       XFS_ILOCK_EXCL, &ip)))
                return error;
-       }
 #if defined(__KERNEL__) && defined(DEBUG)
        /*
         * Check to see that this whole range is currently allocated.
@@ -2384,8 +2356,8 @@ xfs_rtpick_extent(
        __uint64_t      seq;            /* sequence number of file creation */
        __uint64_t      *seqp;          /* pointer to seqno in inode */
 
-       error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0, XFS_ILOCK_EXCL, &ip);
-       if (error)
+       if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0,
+                                       XFS_ILOCK_EXCL, &ip)))
                return error;
        ASSERT(ip == mp->m_rbmip);
        seqp = (__uint64_t *)&ip->i_d.di_atime;
@@ -2424,10 +2396,10 @@ xfs_rtprint_range(
 {
        xfs_extlen_t    i;              /* block number in the extent */
 
-       printk("%Ld: ", (long long)start);
+       cmn_err(CE_DEBUG, "%Ld: ", (long long)start);
        for (i = 0; i < len; i++)
-               printk("%d", xfs_rtcheck_bit(mp, tp, start + i, 1));
-       printk("\n");
+               cmn_err(CE_DEBUG, "%d", xfs_rtcheck_bit(mp, tp, start + i, 1));
+       cmn_err(CE_DEBUG, "\n");
 }
 
 /*
@@ -2451,17 +2423,17 @@ xfs_rtprint_summary(
                        (void)xfs_rtget_summary(mp, tp, l, i, &sumbp, &sb, &c);
                        if (c) {
                                if (!p) {
-                                       printk("%Ld-%Ld:", 1LL << l,
+                                       cmn_err(CE_DEBUG, "%Ld-%Ld:", 1LL << l,
                                                XFS_RTMIN((1LL << l) +
                                                          ((1LL << l) - 1LL),
                                                         mp->m_sb.sb_rextents));
                                        p = 1;
                                }
-                               printk(" %Ld:%d", (long long)i, c);
+                               cmn_err(CE_DEBUG, " %Ld:%d", (long long)i, c);
                        }
                }
                if (p)
-                       printk("\n");
+                       cmn_err(CE_DEBUG, "\n");
        }
        if (sumbp)
                xfs_trans_brelse(tp, sumbp);