Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / fs / xfs / xfs_fsops.c
index 2121305..dfa3527 100644 (file)
@@ -1,66 +1,51 @@
 /*
- * Copyright (c) 2000-2002 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/
+ * 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_bit.h"
 #include "xfs_inum.h"
 #include "xfs_log.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_ag.h"
-#include "xfs_alloc_btree.h"
 #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"
+#include "xfs_inode.h"
+#include "xfs_inode_item.h"
 #include "xfs_btree.h"
 #include "xfs_error.h"
 #include "xfs_alloc.h"
 #include "xfs_ialloc.h"
 #include "xfs_fsops.h"
 #include "xfs_itable.h"
-#include "xfs_rw.h"
-#include "xfs_refcache.h"
 #include "xfs_trans_space.h"
 #include "xfs_rtalloc.h"
-#include "xfs_dir2.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_inode_item.h"
+#include "xfs_rw.h"
 
 /*
  * File system operations
@@ -110,7 +95,9 @@ xfs_fs_geometry(
                        (XFS_SB_VERSION_HASDIRV2(&mp->m_sb) ?
                                XFS_FSOP_GEOM_FLAGS_DIRV2 : 0) |
                        (XFS_SB_VERSION_HASSECTOR(&mp->m_sb) ?
-                               XFS_FSOP_GEOM_FLAGS_SECTOR : 0);
+                               XFS_FSOP_GEOM_FLAGS_SECTOR : 0) |
+                       (XFS_SB_VERSION_HASATTR2(&mp->m_sb) ?
+                               XFS_FSOP_GEOM_FLAGS_ATTR2 : 0);
                geo->logsectsize = XFS_SB_VERSION_HASSECTOR(&mp->m_sb) ?
                                mp->m_sb.sb_logsectsize : BBSIZE;
                geo->rtsectsize = mp->m_sb.sb_blocksize;
@@ -184,7 +171,7 @@ xfs_growfs_data_private(
                memset(&mp->m_perag[oagcount], 0,
                        (nagcount - oagcount) * sizeof(xfs_perag_t));
                mp->m_flags |= XFS_MOUNT_32BITINODES;
-               nagimax = xfs_initialize_perag(mp, nagcount);
+               nagimax = xfs_initialize_perag(XFS_MTOVFS(mp), mp, nagcount);
                up_write(&mp->m_peraglock);
        }
        tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFS);
@@ -204,28 +191,26 @@ xfs_growfs_data_private(
                                  XFS_FSS_TO_BB(mp, 1), 0);
                agf = XFS_BUF_TO_AGF(bp);
                memset(agf, 0, mp->m_sb.sb_sectsize);
-               INT_SET(agf->agf_magicnum, ARCH_CONVERT, XFS_AGF_MAGIC);
-               INT_SET(agf->agf_versionnum, ARCH_CONVERT, XFS_AGF_VERSION);
-               INT_SET(agf->agf_seqno, ARCH_CONVERT, agno);
+               agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC);
+               agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION);
+               agf->agf_seqno = cpu_to_be32(agno);
                if (agno == nagcount - 1)
                        agsize =
                                nb -
                                (agno * (xfs_rfsblock_t)mp->m_sb.sb_agblocks);
                else
                        agsize = mp->m_sb.sb_agblocks;
-               INT_SET(agf->agf_length, ARCH_CONVERT, agsize);
-               INT_SET(agf->agf_roots[XFS_BTNUM_BNOi], ARCH_CONVERT,
-                       XFS_BNO_BLOCK(mp));
-               INT_SET(agf->agf_roots[XFS_BTNUM_CNTi], ARCH_CONVERT,
-                       XFS_CNT_BLOCK(mp));
-               INT_SET(agf->agf_levels[XFS_BTNUM_BNOi], ARCH_CONVERT, 1);
-               INT_SET(agf->agf_levels[XFS_BTNUM_CNTi], ARCH_CONVERT, 1);
+               agf->agf_length = cpu_to_be32(agsize);
+               agf->agf_roots[XFS_BTNUM_BNOi] = cpu_to_be32(XFS_BNO_BLOCK(mp));
+               agf->agf_roots[XFS_BTNUM_CNTi] = cpu_to_be32(XFS_CNT_BLOCK(mp));
+               agf->agf_levels[XFS_BTNUM_BNOi] = cpu_to_be32(1);
+               agf->agf_levels[XFS_BTNUM_CNTi] = cpu_to_be32(1);
                agf->agf_flfirst = 0;
-               INT_SET(agf->agf_fllast, ARCH_CONVERT, XFS_AGFL_SIZE(mp) - 1);
+               agf->agf_fllast = cpu_to_be32(XFS_AGFL_SIZE(mp) - 1);
                agf->agf_flcount = 0;
                tmpsize = agsize - XFS_PREALLOC_BLOCKS(mp);
-               INT_SET(agf->agf_freeblks, ARCH_CONVERT, tmpsize);
-               INT_SET(agf->agf_longest, ARCH_CONVERT, tmpsize);
+               agf->agf_freeblks = cpu_to_be32(tmpsize);
+               agf->agf_longest = cpu_to_be32(tmpsize);
                error = xfs_bwrite(mp, bp);
                if (error) {
                        goto error0;
@@ -238,19 +223,18 @@ xfs_growfs_data_private(
                                  XFS_FSS_TO_BB(mp, 1), 0);
                agi = XFS_BUF_TO_AGI(bp);
                memset(agi, 0, mp->m_sb.sb_sectsize);
-               INT_SET(agi->agi_magicnum, ARCH_CONVERT, XFS_AGI_MAGIC);
-               INT_SET(agi->agi_versionnum, ARCH_CONVERT, XFS_AGI_VERSION);
-               INT_SET(agi->agi_seqno, ARCH_CONVERT, agno);
-               INT_SET(agi->agi_length, ARCH_CONVERT, agsize);
+               agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC);
+               agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION);
+               agi->agi_seqno = cpu_to_be32(agno);
+               agi->agi_length = cpu_to_be32(agsize);
                agi->agi_count = 0;
-               INT_SET(agi->agi_root, ARCH_CONVERT, XFS_IBT_BLOCK(mp));
-               INT_SET(agi->agi_level, ARCH_CONVERT, 1);
+               agi->agi_root = cpu_to_be32(XFS_IBT_BLOCK(mp));
+               agi->agi_level = cpu_to_be32(1);
                agi->agi_freecount = 0;
-               INT_SET(agi->agi_newino, ARCH_CONVERT, NULLAGINO);
-               INT_SET(agi->agi_dirino, ARCH_CONVERT, NULLAGINO);
+               agi->agi_newino = cpu_to_be32(NULLAGINO);
+               agi->agi_dirino = cpu_to_be32(NULLAGINO);
                for (bucket = 0; bucket < XFS_AGI_UNLINKED_BUCKETS; bucket++)
-                       INT_SET(agi->agi_unlinked[bucket], ARCH_CONVERT,
-                               NULLAGINO);
+                       agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO);
                error = xfs_bwrite(mp, bp);
                if (error) {
                        goto error0;
@@ -263,17 +247,16 @@ xfs_growfs_data_private(
                        BTOBB(mp->m_sb.sb_blocksize), 0);
                block = XFS_BUF_TO_SBLOCK(bp);
                memset(block, 0, mp->m_sb.sb_blocksize);
-               INT_SET(block->bb_magic, ARCH_CONVERT, XFS_ABTB_MAGIC);
+               block->bb_magic = cpu_to_be32(XFS_ABTB_MAGIC);
                block->bb_level = 0;
-               INT_SET(block->bb_numrecs, ARCH_CONVERT, 1);
-               INT_SET(block->bb_leftsib, ARCH_CONVERT, NULLAGBLOCK);
-               INT_SET(block->bb_rightsib, ARCH_CONVERT, NULLAGBLOCK);
+               block->bb_numrecs = cpu_to_be16(1);
+               block->bb_leftsib = cpu_to_be32(NULLAGBLOCK);
+               block->bb_rightsib = cpu_to_be32(NULLAGBLOCK);
                arec = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_alloc,
                        block, 1, mp->m_alloc_mxr[0]);
-               INT_SET(arec->ar_startblock, ARCH_CONVERT,
-                       XFS_PREALLOC_BLOCKS(mp));
-               INT_SET(arec->ar_blockcount, ARCH_CONVERT,
-                       agsize - INT_GET(arec->ar_startblock, ARCH_CONVERT));
+               arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp));
+               arec->ar_blockcount = cpu_to_be32(
+                       agsize - be32_to_cpu(arec->ar_startblock));
                error = xfs_bwrite(mp, bp);
                if (error) {
                        goto error0;
@@ -286,18 +269,17 @@ xfs_growfs_data_private(
                        BTOBB(mp->m_sb.sb_blocksize), 0);
                block = XFS_BUF_TO_SBLOCK(bp);
                memset(block, 0, mp->m_sb.sb_blocksize);
-               INT_SET(block->bb_magic, ARCH_CONVERT, XFS_ABTC_MAGIC);
+               block->bb_magic = cpu_to_be32(XFS_ABTC_MAGIC);
                block->bb_level = 0;
-               INT_SET(block->bb_numrecs, ARCH_CONVERT, 1);
-               INT_SET(block->bb_leftsib, ARCH_CONVERT, NULLAGBLOCK);
-               INT_SET(block->bb_rightsib, ARCH_CONVERT, NULLAGBLOCK);
+               block->bb_numrecs = cpu_to_be16(1);
+               block->bb_leftsib = cpu_to_be32(NULLAGBLOCK);
+               block->bb_rightsib = cpu_to_be32(NULLAGBLOCK);
                arec = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_alloc,
                        block, 1, mp->m_alloc_mxr[0]);
-               INT_SET(arec->ar_startblock, ARCH_CONVERT,
-                       XFS_PREALLOC_BLOCKS(mp));
-               INT_SET(arec->ar_blockcount, ARCH_CONVERT,
-                       agsize - INT_GET(arec->ar_startblock, ARCH_CONVERT));
-               nfree += INT_GET(arec->ar_blockcount, ARCH_CONVERT);
+               arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp));
+               arec->ar_blockcount = cpu_to_be32(
+                       agsize - be32_to_cpu(arec->ar_startblock));
+               nfree += be32_to_cpu(arec->ar_blockcount);
                error = xfs_bwrite(mp, bp);
                if (error) {
                        goto error0;
@@ -310,11 +292,11 @@ xfs_growfs_data_private(
                        BTOBB(mp->m_sb.sb_blocksize), 0);
                block = XFS_BUF_TO_SBLOCK(bp);
                memset(block, 0, mp->m_sb.sb_blocksize);
-               INT_SET(block->bb_magic, ARCH_CONVERT, XFS_IBT_MAGIC);
+               block->bb_magic = cpu_to_be32(XFS_IBT_MAGIC);
                block->bb_level = 0;
                block->bb_numrecs = 0;
-               INT_SET(block->bb_leftsib, ARCH_CONVERT, NULLAGBLOCK);
-               INT_SET(block->bb_rightsib, ARCH_CONVERT, NULLAGBLOCK);
+               block->bb_leftsib = cpu_to_be32(NULLAGBLOCK);
+               block->bb_rightsib = cpu_to_be32(NULLAGBLOCK);
                error = xfs_bwrite(mp, bp);
                if (error) {
                        goto error0;
@@ -334,10 +316,9 @@ xfs_growfs_data_private(
                }
                ASSERT(bp);
                agi = XFS_BUF_TO_AGI(bp);
-               INT_MOD(agi->agi_length, ARCH_CONVERT, new);
+               be32_add(&agi->agi_length, new);
                ASSERT(nagcount == oagcount ||
-                      INT_GET(agi->agi_length, ARCH_CONVERT) ==
-                               mp->m_sb.sb_agblocks);
+                      be32_to_cpu(agi->agi_length) == mp->m_sb.sb_agblocks);
                xfs_ialloc_log_agi(tp, bp, XFS_AGI_LENGTH);
                /*
                 * Change agf length.
@@ -348,14 +329,14 @@ xfs_growfs_data_private(
                }
                ASSERT(bp);
                agf = XFS_BUF_TO_AGF(bp);
-               INT_MOD(agf->agf_length, ARCH_CONVERT, new);
-               ASSERT(INT_GET(agf->agf_length, ARCH_CONVERT) ==
-                               INT_GET(agi->agi_length, ARCH_CONVERT));
+               be32_add(&agf->agf_length, new);
+               ASSERT(be32_to_cpu(agf->agf_length) ==
+                      be32_to_cpu(agi->agi_length));
                /*
                 * Free the new space.
                 */
                error = xfs_free_extent(tp, XFS_AGB_TO_FSB(mp, agno,
-                       INT_GET(agf->agf_length, ARCH_CONVERT) - new), new);
+                       be32_to_cpu(agf->agf_length) - new), new);
                if (error) {
                        goto error0;
                }
@@ -481,6 +462,7 @@ xfs_fs_counts(
 {
        unsigned long   s;
 
+       xfs_icsb_sync_counters_lazy(mp);
        s = XFS_SB_LOCK(mp);
        cnt->freedata = mp->m_sb.sb_fdblocks;
        cnt->freertx = mp->m_sb.sb_frextents;
@@ -495,7 +477,7 @@ xfs_fs_counts(
  *
  * xfs_reserve_blocks is called to set m_resblks
  * in the in-core mount table. The number of unused reserved blocks
- * is kept in m_resbls_avail.
+ * is kept in m_resblks_avail.
  *
  * Reserve the requested number of blocks if available. Otherwise return
  * as many as possible to satisfy the request. The actual number
@@ -520,7 +502,7 @@ xfs_reserve_blocks(
        if (inval == (__uint64_t *)NULL) {
                outval->resblks = mp->m_resblks;
                outval->resblks_avail = mp->m_resblks_avail;
-               return(0);
+               return 0;
        }
 
        request = *inval;
@@ -556,7 +538,7 @@ xfs_reserve_blocks(
        outval->resblks = mp->m_resblks;
        outval->resblks_avail = mp->m_resblks_avail;
        XFS_SB_UNLOCK(mp, s);
-       return(0);
+       return 0;
 }
 
 void
@@ -595,7 +577,7 @@ xfs_fs_goingdown(
                struct vfs *vfsp = XFS_MTOVFS(mp);
                struct super_block *sb = freeze_bdev(vfsp->vfs_super->s_bdev);
 
-               if (sb) {
+               if (sb && !IS_ERR(sb)) {
                        xfs_force_shutdown(mp, XFS_FORCE_UMOUNT);
                        thaw_bdev(sb->s_bdev, sb);
                }