X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fxfs%2Fxfs_inode.c;h=6e523ea8b8a7583bd2fb225f9a976a8043e12f74;hb=f7f1b0f1e2fbadeab12d24236000e778aa9b1ead;hp=ef4824e303e659793c4bb0d2d52169015141f512;hpb=6a77f38946aaee1cd85eeec6cf4229b204c15071;p=linux-2.6.git diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index ef4824e30..6e523ea8b 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -67,6 +67,7 @@ #include "xfs_mac.h" #include "xfs_acl.h" +#include 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));