X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fxfs%2Fxfs_bmap.c;h=4b0738238809c496d2b85f6815498159013ebd62;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=d797f406e9f122e67257f04fee2f37fb17faf942;hpb=a2c21200f1c81b08cb55e417b68150bba439b646;p=linux-2.6.git diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index d797f406e..4b0738238 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2004 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 @@ -203,8 +203,6 @@ STATIC void xfs_bmap_check_extents( xfs_inode_t *ip, /* incore inode pointer */ int whichfork); /* data or attr fork */ -#else -#define xfs_bmap_check_extents(ip,w) #endif /* @@ -3429,6 +3427,20 @@ xfs_bmap_do_search_extents( int high; /* high index of binary search */ int low; /* low index of binary search */ + /* + * Initialize the extent entry structure to catch access to + * uninitialized br_startblock field. + */ + got.br_startoff = 0xffa5a5a5a5a5a5a5LL; + got.br_blockcount = 0xa55a5a5a5a5a5a5aLL; + got.br_state = XFS_EXT_INVALID; + +#if XFS_BIG_BLKNOS + got.br_startblock = 0xffffa5a5a5a5a5a5LL; +#else + got.br_startblock = 0xffffa5a5; +#endif + if (lastx != NULLEXTNUM && lastx < nextents) ep = base + lastx; else @@ -3527,6 +3539,8 @@ xfs_bmap_search_extents( xfs_bmbt_rec_t *base; /* base of extent list */ xfs_extnum_t lastx; /* last extent index used */ xfs_extnum_t nextents; /* extent list size */ + xfs_bmbt_rec_t *ep; /* extent list entry pointer */ + int rt; /* realtime flag */ XFS_STATS_INC(xs_look_exlist); ifp = XFS_IFORK_PTR(ip, whichfork); @@ -3534,8 +3548,18 @@ xfs_bmap_search_extents( nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); base = &ifp->if_u1.if_extents[0]; - return xfs_bmap_do_search_extents(base, lastx, nextents, bno, eofp, + ep = xfs_bmap_do_search_extents(base, lastx, nextents, bno, eofp, lastxp, gotp, prevp); + rt = ip->i_d.di_flags & XFS_DIFLAG_REALTIME; + if(!rt && !gotp->br_startblock && (*lastxp != NULLEXTNUM)) { + cmn_err(CE_PANIC,"Access to block zero: fs: <%s> inode: %lld " + "start_block : %llx start_off : %llx blkcnt : %llx " + "extent-state : %x \n", + (ip->i_mount)->m_fsname,(long long)ip->i_ino, + gotp->br_startblock, gotp->br_startoff, + gotp->br_blockcount,gotp->br_state); + } + return ep; } @@ -4689,8 +4713,41 @@ xfs_bmapi( } break; } + + /* + * Split changing sb for alen and indlen since + * they could be coming from different places. + */ + if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) { + xfs_extlen_t extsz; + xfs_extlen_t ralen; + if (!(extsz = ip->i_d.di_extsize)) + extsz = mp->m_sb.sb_rextsize; + ralen = roundup(alen, extsz); + ralen = ralen / mp->m_sb.sb_rextsize; + if (xfs_mod_incore_sb(mp, + XFS_SBS_FREXTENTS, + -(ralen), rsvd)) { + if (XFS_IS_QUOTA_ON(ip->i_mount)) + XFS_TRANS_UNRESERVE_BLKQUOTA( + mp, NULL, ip, + (long)alen); + break; + } + } else { + if (xfs_mod_incore_sb(mp, + XFS_SBS_FDBLOCKS, + -(alen), rsvd)) { + if (XFS_IS_QUOTA_ON(ip->i_mount)) + XFS_TRANS_UNRESERVE_BLKQUOTA( + mp, NULL, ip, + (long)alen); + break; + } + } + if (xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, - -(alen + indlen), rsvd)) { + -(indlen), rsvd)) { XFS_TRANS_UNRESERVE_BLKQUOTA( mp, NULL, ip, (long)alen); break; @@ -5445,7 +5502,7 @@ int /* error code */ xfs_getbmap( bhv_desc_t *bdp, /* XFS behavior descriptor*/ struct getbmap *bmv, /* user bmap structure */ - void *ap, /* pointer to user's array */ + void __user *ap, /* pointer to user's array */ int interface) /* interface flags */ { __int64_t bmvend; /* last block requested */ @@ -5634,8 +5691,10 @@ xfs_getbmap( (__int64_t)(bmvend - bmv->bmv_offset)); bmv->bmv_entries++; ap = (interface & BMV_IF_EXTENDED) ? - (void *)((struct getbmapx *)ap + 1) : - (void *)((struct getbmap *)ap + 1); + (void __user *) + ((struct getbmapx __user *)ap + 1) : + (void __user *) + ((struct getbmap __user *)ap + 1); } } } while (nmap && nexleft && bmv->bmv_length);