vserver 2.0 rc7
[linux-2.6.git] / fs / xfs / xfs_inode.c
index ef4824e..6e523ea 100644 (file)
@@ -67,6 +67,7 @@
 #include "xfs_mac.h"
 #include "xfs_acl.h"
 
+#include <linux/vserver/xid.h>
 
 kmem_zone_t *xfs_ifork_zone;
 kmem_zone_t *xfs_inode_zone;
@@ -135,11 +136,11 @@ xfs_inobp_check(
        for (i = 0; i < j; i++) {
                dip = (xfs_dinode_t *)xfs_buf_offset(bp,
                                        i * mp->m_sb.sb_inodesize);
-               if (INT_ISZERO(dip->di_next_unlinked, ARCH_CONVERT))  {
+               if (!dip->di_next_unlinked)  {
                        xfs_fs_cmn_err(CE_ALERT, mp,
                                "Detected a bogus zero next_unlinked field in incore inode buffer 0x%p.  About to pop an ASSERT.",
                                bp);
-                       ASSERT(!INT_ISZERO(dip->di_next_unlinked, ARCH_CONVERT));
+                       ASSERT(dip->di_next_unlinked);
                }
        }
 }
@@ -176,7 +177,7 @@ xfs_inobp_bwcheck(xfs_buf_t *bp)
                        xfs_fs_cmn_err(CE_WARN, mp,
                                "corrupt, unmount and run xfs_repair");
                }
-               if (INT_ISZERO(dip->di_next_unlinked, ARCH_CONVERT))  {
+               if (!dip->di_next_unlinked)  {
                        cmn_err(CE_WARN,
 "Bad next_unlinked field (0) in XFS inode buffer 0x%p, starting blockno %Ld, offset 0x%x",
                                (__uint64_t)(__psunsigned_t) bp,
@@ -520,8 +521,7 @@ xfs_iformat(
                        }
 
                        di_size = INT_GET(dip->di_core.di_size, ARCH_CONVERT);
-                       if (unlikely(di_size >
-                           XFS_DFORK_DSIZE_ARCH(dip, ip->i_mount, ARCH_CONVERT))) {
+                       if (unlikely(di_size > XFS_DFORK_DSIZE(dip, ip->i_mount))) {
                                xfs_fs_cmn_err(CE_WARN, ip->i_mount,
                                        "corrupt inode %Lu (bad size %Ld for local inode).  Unmount and run xfs_repair.",
                                        (unsigned long long) ip->i_ino,
@@ -555,7 +555,7 @@ xfs_iformat(
        if (error) {
                return error;
        }
-       if (!XFS_DFORK_Q_ARCH(dip, ARCH_CONVERT))
+       if (!XFS_DFORK_Q(dip))
                return 0;
        ASSERT(ip->i_afp == NULL);
        ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP);
@@ -563,7 +563,7 @@ xfs_iformat(
                XFS_IFORK_ASIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t);
        switch (INT_GET(dip->di_core.di_aformat, ARCH_CONVERT)) {
        case XFS_DINODE_FMT_LOCAL:
-               atp = (xfs_attr_shortform_t *)XFS_DFORK_APTR_ARCH(dip, ARCH_CONVERT);
+               atp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip);
                size = (int)INT_GET(atp->hdr.totsize, ARCH_CONVERT);
                error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK, size);
                break;
@@ -610,11 +610,11 @@ xfs_iformat_local(
         * is wrong and we just bail out rather than crash in
         * kmem_alloc() or memcpy() below.
         */
-       if (unlikely(size > XFS_DFORK_SIZE_ARCH(dip, ip->i_mount, whichfork, ARCH_CONVERT))) {
+       if (unlikely(size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) {
                xfs_fs_cmn_err(CE_WARN, ip->i_mount,
                        "corrupt inode %Lu (bad size %d for local fork, size = %d).  Unmount and run xfs_repair.",
                        (unsigned long long) ip->i_ino, size,
-                       XFS_DFORK_SIZE_ARCH(dip, ip->i_mount, whichfork, ARCH_CONVERT));
+                       XFS_DFORK_SIZE(dip, ip->i_mount, whichfork));
                XFS_CORRUPTION_ERROR("xfs_iformat_local", XFS_ERRLEVEL_LOW,
                                     ip->i_mount, dip);
                return XFS_ERROR(EFSCORRUPTED);
@@ -632,8 +632,7 @@ xfs_iformat_local(
        ifp->if_bytes = size;
        ifp->if_real_bytes = real_size;
        if (size)
-               memcpy(ifp->if_u1.if_data,
-                       XFS_DFORK_PTR_ARCH(dip, whichfork, ARCH_CONVERT), size);
+               memcpy(ifp->if_u1.if_data, XFS_DFORK_PTR(dip, whichfork), size);
        ifp->if_flags &= ~XFS_IFEXTENTS;
        ifp->if_flags |= XFS_IFINLINE;
        return 0;
@@ -662,7 +661,7 @@ xfs_iformat_extents(
        int             i;
 
        ifp = XFS_IFORK_PTR(ip, whichfork);
-       nex = XFS_DFORK_NEXTENTS_ARCH(dip, whichfork, ARCH_CONVERT);
+       nex = XFS_DFORK_NEXTENTS(dip, whichfork);
        size = nex * (uint)sizeof(xfs_bmbt_rec_t);
 
        /*
@@ -670,7 +669,7 @@ xfs_iformat_extents(
         * is wrong and we just bail out rather than crash in
         * kmem_alloc() or memcpy() below.
         */
-       if (unlikely(size < 0 || size > XFS_DFORK_SIZE_ARCH(dip, ip->i_mount, whichfork, ARCH_CONVERT))) {
+       if (unlikely(size < 0 || size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) {
                xfs_fs_cmn_err(CE_WARN, ip->i_mount,
                        "corrupt inode %Lu ((a)extents = %d).  Unmount and run xfs_repair.",
                        (unsigned long long) ip->i_ino, nex);
@@ -692,8 +691,7 @@ xfs_iformat_extents(
        ifp->if_bytes = size;
        ifp->if_real_bytes = real_size;
        if (size) {
-               dp = (xfs_bmbt_rec_t *)
-                       XFS_DFORK_PTR_ARCH(dip, whichfork, ARCH_CONVERT);
+               dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork);
                xfs_validate_extents(dp, nex, 1, XFS_EXTFMT_INODE(ip));
                ep = ifp->if_u1.if_extents;
                for (i = 0; i < nex; i++, ep++, dp++) {
@@ -739,7 +737,7 @@ xfs_iformat_btree(
        int                     size;
 
        ifp = XFS_IFORK_PTR(ip, whichfork);
-       dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR_ARCH(dip, whichfork, ARCH_CONVERT);
+       dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork);
        size = XFS_BMAP_BROOT_SPACE(dfp);
        nrecs = XFS_BMAP_BROOT_NUMRECS(dfp);
 
@@ -752,7 +750,7 @@ xfs_iformat_btree(
         */
        if (unlikely(XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max
            || XFS_BMDR_SPACE_CALC(nrecs) >
-                       XFS_DFORK_SIZE_ARCH(dip, ip->i_mount, whichfork, ARCH_CONVERT)
+                       XFS_DFORK_SIZE(dip, ip->i_mount, whichfork)
            || XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks)) {
                xfs_fs_cmn_err(CE_WARN, ip->i_mount,
                        "corrupt inode %Lu (btree).  Unmount and run xfs_repair.",
@@ -769,7 +767,7 @@ xfs_iformat_btree(
         * Copy and convert from the on-disk structure
         * to the in-memory structure.
         */
-       xfs_bmdr_to_bmbt(dfp, XFS_DFORK_SIZE_ARCH(dip, ip->i_mount, whichfork, ARCH_CONVERT),
+       xfs_bmdr_to_bmbt(dfp, XFS_DFORK_SIZE(dip, ip->i_mount, whichfork),
                ifp->if_broot, size);
        ifp->if_flags &= ~XFS_IFEXTENTS;
        ifp->if_flags |= XFS_IFBROOT;
@@ -785,28 +783,26 @@ xfs_iformat_btree(
  * dip  = native representation
  * dir  = direction - +ve -> disk to native
  *                    -ve -> native to disk
- * arch = on-disk architecture
  */
 void
 xfs_xlate_dinode_core(
        xfs_caddr_t             buf,
        xfs_dinode_core_t       *dip,
-       int                     dir,
-       xfs_arch_t              arch)
+       int                     dir)
 {
        xfs_dinode_core_t       *buf_core = (xfs_dinode_core_t *)buf;
        xfs_dinode_core_t       *mem_core = (xfs_dinode_core_t *)dip;
+       xfs_arch_t              arch = ARCH_CONVERT;
+       uint32_t                uid = 0, gid = 0;
+       uint16_t                xid = 0;
 
        ASSERT(dir);
-       if (arch == ARCH_NOCONVERT) {
-               if (dir > 0) {
-                       memcpy((xfs_caddr_t)mem_core, (xfs_caddr_t)buf_core,
-                               sizeof(xfs_dinode_core_t));
-               } else {
-                       memcpy((xfs_caddr_t)buf_core, (xfs_caddr_t)mem_core,
-                               sizeof(xfs_dinode_core_t));
-               }
-               return;
+
+       if (dir < 0) {
+               /* FIXME make that conditional on some flag */
+               xid = mem_core->di_xid;
+               uid = XIDINO_UID(1, mem_core->di_uid, xid);
+               gid = XIDINO_GID(1, mem_core->di_gid, xid);
        }
 
        INT_XLATE(buf_core->di_magic, mem_core->di_magic, dir, arch);
@@ -814,12 +810,17 @@ xfs_xlate_dinode_core(
        INT_XLATE(buf_core->di_version, mem_core->di_version, dir, arch);
        INT_XLATE(buf_core->di_format, mem_core->di_format, dir, arch);
        INT_XLATE(buf_core->di_onlink, mem_core->di_onlink, dir, arch);
-       INT_XLATE(buf_core->di_uid, mem_core->di_uid, dir, arch);
-       INT_XLATE(buf_core->di_gid, mem_core->di_gid, dir, arch);
+       INT_XLATE(buf_core->di_uid, uid, dir, arch);
+       INT_XLATE(buf_core->di_gid, gid, dir, arch);
+       INT_XLATE(buf_core->di_xid, xid, dir, arch);
        INT_XLATE(buf_core->di_nlink, mem_core->di_nlink, dir, arch);
        INT_XLATE(buf_core->di_projid, mem_core->di_projid, dir, arch);
 
        if (dir > 0) {
+               /* FIXME make that conditional on some flag */
+               mem_core->di_uid = INOXID_UID(1, uid, gid);
+               mem_core->di_gid = INOXID_GID(1, uid, gid);
+               mem_core->di_xid = INOXID_XID(1, uid, gid, xid);
                memcpy(mem_core->di_pad, buf_core->di_pad,
                        sizeof(buf_core->di_pad));
        } else {
@@ -854,16 +855,13 @@ xfs_xlate_dinode_core(
        INT_XLATE(buf_core->di_gen, mem_core->di_gen, dir, arch);
 }
 
-uint
-xfs_dic2xflags(
+STATIC uint
+_xfs_dic2xflags(
        xfs_dinode_core_t       *dic,
-       xfs_arch_t              arch)
+       __uint16_t              di_flags)
 {
-       __uint16_t              di_flags;
-       uint                    flags;
+       uint                    flags = 0;
 
-       di_flags = INT_GET(dic->di_flags, arch);
-       flags = XFS_CFORK_Q_ARCH(dic, arch) ? XFS_XFLAG_HASATTR : 0;
        if (di_flags & XFS_DIFLAG_ANY) {
                if (di_flags & XFS_DIFLAG_REALTIME)
                        flags |= XFS_XFLAG_REALTIME;
@@ -890,9 +888,28 @@ xfs_dic2xflags(
                if (di_flags & XFS_DIFLAG_NOSYMLINKS)
                        flags |= XFS_XFLAG_NOSYMLINKS;
        }
+
        return flags;
 }
 
+uint
+xfs_ip2xflags(
+       xfs_inode_t             *ip)
+{
+       xfs_dinode_core_t       *dic = &ip->i_d;
+
+       return _xfs_dic2xflags(dic, dic->di_flags) |
+               (XFS_CFORK_Q(dic) ? XFS_XFLAG_HASATTR : 0);
+}
+
+uint
+xfs_dic2xflags(
+       xfs_dinode_core_t       *dic)
+{
+       return _xfs_dic2xflags(dic, INT_GET(dic->di_flags, ARCH_CONVERT)) |
+               (XFS_CFORK_Q_DISK(dic) ? XFS_XFLAG_HASATTR : 0);
+}
+
 /*
  * Given a mount structure and an inode number, return a pointer
  * to a newly allocated in-core inode coresponding to the given
@@ -978,9 +995,9 @@ xfs_iread(
         * specific information.
         * Otherwise, just get the truly permanent information.
         */
-       if (!INT_ISZERO(dip->di_core.di_mode, ARCH_CONVERT)) {
+       if (dip->di_core.di_mode) {
                xfs_xlate_dinode_core((xfs_caddr_t)&dip->di_core,
-                    &(ip->i_d), 1, ARCH_CONVERT);
+                    &(ip->i_d), 1);
                error = xfs_iformat(ip, dip);
                if (error)  {
                        kmem_zone_free(xfs_inode_zone, ip);
@@ -1132,7 +1149,7 @@ xfs_ialloc(
        xfs_trans_t     *tp,
        xfs_inode_t     *pip,
        mode_t          mode,
-       nlink_t         nlink,
+       xfs_nlink_t     nlink,
        xfs_dev_t       rdev,
        cred_t          *cr,
        xfs_prid_t      prid,
@@ -1182,6 +1199,7 @@ xfs_ialloc(
        ASSERT(ip->i_d.di_nlink == nlink);
        ip->i_d.di_uid = current_fsuid(cr);
        ip->i_d.di_gid = current_fsgid(cr);
+       ip->i_d.di_xid = current_fsxid(cr, vp);
        ip->i_d.di_projid = prid;
        memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
 
@@ -1935,7 +1953,7 @@ xfs_iunlink(
        agino = XFS_INO_TO_AGINO(mp, ip->i_ino);
        ASSERT(agino != 0);
        bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS;
-       ASSERT(!INT_ISZERO(agi->agi_unlinked[bucket_index], ARCH_CONVERT));
+       ASSERT(agi->agi_unlinked[bucket_index]);
        ASSERT(INT_GET(agi->agi_unlinked[bucket_index], ARCH_CONVERT) != agino);
 
        if (INT_GET(agi->agi_unlinked[bucket_index], ARCH_CONVERT) != NULLAGINO) {
@@ -1950,7 +1968,7 @@ xfs_iunlink(
                        return error;
                }
                ASSERT(INT_GET(dip->di_next_unlinked, ARCH_CONVERT) == NULLAGINO);
-               ASSERT(!INT_ISZERO(dip->di_next_unlinked, ARCH_CONVERT));
+               ASSERT(dip->di_next_unlinked);
                /* both on-disk, don't endian flip twice */
                dip->di_next_unlinked = agi->agi_unlinked[bucket_index];
                offset = ip->i_boffset +
@@ -2043,7 +2061,7 @@ xfs_iunlink_remove(
        ASSERT(agino != 0);
        bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS;
        ASSERT(INT_GET(agi->agi_unlinked[bucket_index], ARCH_CONVERT) != NULLAGINO);
-       ASSERT(!INT_ISZERO(agi->agi_unlinked[bucket_index], ARCH_CONVERT));
+       ASSERT(agi->agi_unlinked[bucket_index]);
 
        if (INT_GET(agi->agi_unlinked[bucket_index], ARCH_CONVERT) == agino) {
                /*
@@ -3019,7 +3037,7 @@ xfs_iflush_fork(
                ASSERT(whichfork == XFS_ATTR_FORK);
                return 0;
        }
-       cp = XFS_DFORK_PTR_ARCH(dip, whichfork, ARCH_CONVERT);
+       cp = XFS_DFORK_PTR(dip, whichfork);
        mp = ip->i_mount;
        switch (XFS_IFORK_FORMAT(ip, whichfork)) {
        case XFS_DINODE_FMT_LOCAL:
@@ -3060,7 +3078,7 @@ xfs_iflush_fork(
                                XFS_BROOT_SIZE_ADJ));
                        xfs_bmbt_to_bmdr(ifp->if_broot, ifp->if_broot_bytes,
                                (xfs_bmdr_block_t *)cp,
-                               XFS_DFORK_SIZE_ARCH(dip, mp, whichfork, ARCH_CONVERT));
+                               XFS_DFORK_SIZE(dip, mp, whichfork));
                }
                break;
 
@@ -3478,8 +3496,7 @@ xfs_iflush_int(
         * because if the inode is dirty at all the core must
         * be.
         */
-       xfs_xlate_dinode_core((xfs_caddr_t)&(dip->di_core), &(ip->i_d),
-               -1, ARCH_CONVERT);
+       xfs_xlate_dinode_core((xfs_caddr_t)&(dip->di_core), &(ip->i_d), -1);
 
        /* Wrap, we never let the log put out DI_MAX_FLUSH */
        if (ip->i_d.di_flushiter == DI_MAX_FLUSH)
@@ -3509,7 +3526,7 @@ xfs_iflush_int(
                        ip->i_d.di_version = XFS_DINODE_VERSION_2;
                        INT_SET(dip->di_core.di_version, ARCH_CONVERT, XFS_DINODE_VERSION_2);
                        ip->i_d.di_onlink = 0;
-                       INT_ZERO(dip->di_core.di_onlink, ARCH_CONVERT);
+                       dip->di_core.di_onlink = 0;
                        memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
                        memset(&(dip->di_core.di_pad[0]), 0,
                              sizeof(dip->di_core.di_pad));