/*
- * 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
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
/*
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
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);
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;
}
}
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;
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 */
(__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);