Commit 7db48a7c authored by Eric Sandeen's avatar Eric Sandeen Committed by Nathan Scott

[XFS] Code checks to trap access to fsb zero.

SGI Modid: xfs-linux:xfs-kern:176159a
Signed-off-by: default avatarNathan Scott <nathans@sgi.com>
parent 1804dc87
...@@ -234,6 +234,7 @@ xfs_map_at_offset( ...@@ -234,6 +234,7 @@ xfs_map_at_offset(
sector_shift = block_bits - BBSHIFT; sector_shift = block_bits - BBSHIFT;
bn = iomapp->iomap_bn >> sector_shift; bn = iomapp->iomap_bn >> sector_shift;
bn += delta; bn += delta;
BUG_ON(!bn && !(iomapp->iomap_flags & IOMAP_REALTIME));
ASSERT((bn << sector_shift) >= iomapp->iomap_bn); ASSERT((bn << sector_shift) >= iomapp->iomap_bn);
lock_buffer(bh); lock_buffer(bh);
...@@ -938,9 +939,8 @@ linvfs_get_block_core( ...@@ -938,9 +939,8 @@ linvfs_get_block_core(
bn = iomap.iomap_bn >> (inode->i_blkbits - BBSHIFT); bn = iomap.iomap_bn >> (inode->i_blkbits - BBSHIFT);
bn += delta; bn += delta;
BUG_ON(!bn && !(iomap.iomap_flags & IOMAP_REALTIME));
bh_result->b_blocknr = bn; bh_result->b_blocknr = bn;
bh_result->b_bdev = iomap.iomap_target->pbr_bdev;
set_buffer_mapped(bh_result); set_buffer_mapped(bh_result);
} }
if (create && (iomap.iomap_flags & IOMAP_UNWRITTEN)) { if (create && (iomap.iomap_flags & IOMAP_UNWRITTEN)) {
...@@ -965,21 +965,18 @@ linvfs_get_block_core( ...@@ -965,21 +965,18 @@ linvfs_get_block_core(
} }
if (iomap.iomap_flags & IOMAP_DELAY) { if (iomap.iomap_flags & IOMAP_DELAY) {
if (unlikely(direct)) BUG_ON(direct);
BUG();
if (create) { if (create) {
set_buffer_mapped(bh_result); set_buffer_mapped(bh_result);
set_buffer_uptodate(bh_result); set_buffer_uptodate(bh_result);
} }
bh_result->b_bdev = iomap.iomap_target->pbr_bdev;
set_buffer_delay(bh_result); set_buffer_delay(bh_result);
} }
if (blocks) { if (blocks) {
loff_t iosize; bh_result->b_size = (ssize_t)min(
iosize = (iomap.iomap_bsize - iomap.iomap_delta); (loff_t)(iomap.iomap_bsize - iomap.iomap_delta),
bh_result->b_size = (loff_t)(blocks << inode->i_blkbits));
(ssize_t)min(iosize, (loff_t)(blocks << inode->i_blkbits));
} }
return 0; return 0;
......
/* /*
* 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 * 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 * under the terms of version 2 of the GNU General Public License as
...@@ -3429,6 +3429,19 @@ xfs_bmap_do_search_extents( ...@@ -3429,6 +3429,19 @@ xfs_bmap_do_search_extents(
int high; /* high index of binary search */ int high; /* high index of binary search */
int low; /* low 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 = 0xffa5a5a5a5a5a5a5;
got.br_blockcount = 0xa55a5a5a5a5a5a5a;
got.br_state = XFS_EXT_INVALID;
#if XFS_BIG_BLKNOS
got.br_startblock = 0xffffa5a5a5a5a5a5;
#else
got.br_startblock = 0xffffa5a5;
#endif
if (lastx != NULLEXTNUM && lastx < nextents) if (lastx != NULLEXTNUM && lastx < nextents)
ep = base + lastx; ep = base + lastx;
else else
...@@ -3527,6 +3540,8 @@ xfs_bmap_search_extents( ...@@ -3527,6 +3540,8 @@ xfs_bmap_search_extents(
xfs_bmbt_rec_t *base; /* base of extent list */ xfs_bmbt_rec_t *base; /* base of extent list */
xfs_extnum_t lastx; /* last extent index used */ xfs_extnum_t lastx; /* last extent index used */
xfs_extnum_t nextents; /* extent list size */ 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); XFS_STATS_INC(xs_look_exlist);
ifp = XFS_IFORK_PTR(ip, whichfork); ifp = XFS_IFORK_PTR(ip, whichfork);
...@@ -3534,8 +3549,18 @@ xfs_bmap_search_extents( ...@@ -3534,8 +3549,18 @@ xfs_bmap_search_extents(
nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
base = &ifp->if_u1.if_extents[0]; 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); 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;
} }
......
/* /*
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. * Copyright (c) 2000,2002-2004 Silicon Graphics, Inc. All Rights Reserved.
* *
* This program is free software; you can redistribute it and/or modify it * 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 * under the terms of version 2 of the GNU General Public License as
...@@ -153,7 +153,7 @@ typedef enum { ...@@ -153,7 +153,7 @@ typedef enum {
*/ */
typedef enum { typedef enum {
XFS_EXT_NORM, XFS_EXT_UNWRITTEN, XFS_EXT_NORM, XFS_EXT_UNWRITTEN,
XFS_EXT_DMAPI_OFFLINE XFS_EXT_DMAPI_OFFLINE, XFS_EXT_INVALID
} xfs_exntst_t; } xfs_exntst_t;
/* /*
......
...@@ -165,20 +165,24 @@ xfs_imap_to_bmap( ...@@ -165,20 +165,24 @@ xfs_imap_to_bmap(
nisize = io->io_new_size; nisize = io->io_new_size;
for (pbm = 0; imaps && pbm < iomaps; imaps--, iomapp++, imap++, pbm++) { for (pbm = 0; imaps && pbm < iomaps; imaps--, iomapp++, imap++, pbm++) {
iomapp->iomap_target = io->io_flags & XFS_IOCORE_RT ?
mp->m_rtdev_targp : mp->m_ddev_targp;
iomapp->iomap_offset = XFS_FSB_TO_B(mp, imap->br_startoff); iomapp->iomap_offset = XFS_FSB_TO_B(mp, imap->br_startoff);
iomapp->iomap_delta = offset - iomapp->iomap_offset; iomapp->iomap_delta = offset - iomapp->iomap_offset;
iomapp->iomap_bsize = XFS_FSB_TO_B(mp, imap->br_blockcount); iomapp->iomap_bsize = XFS_FSB_TO_B(mp, imap->br_blockcount);
iomapp->iomap_flags = flags; iomapp->iomap_flags = flags;
if (io->io_flags & XFS_IOCORE_RT) {
iomapp->iomap_flags |= IOMAP_REALTIME;
iomapp->iomap_target = mp->m_rtdev_targp;
} else {
iomapp->iomap_target = mp->m_ddev_targp;
}
start_block = imap->br_startblock; start_block = imap->br_startblock;
if (start_block == HOLESTARTBLOCK) { if (start_block == HOLESTARTBLOCK) {
iomapp->iomap_bn = IOMAP_DADDR_NULL; iomapp->iomap_bn = IOMAP_DADDR_NULL;
iomapp->iomap_flags = IOMAP_HOLE; iomapp->iomap_flags |= IOMAP_HOLE;
} else if (start_block == DELAYSTARTBLOCK) { } else if (start_block == DELAYSTARTBLOCK) {
iomapp->iomap_bn = IOMAP_DADDR_NULL; iomapp->iomap_bn = IOMAP_DADDR_NULL;
iomapp->iomap_flags = IOMAP_DELAY; iomapp->iomap_flags |= IOMAP_DELAY;
} else { } else {
iomapp->iomap_bn = XFS_FSB_TO_DB_IO(io, start_block); iomapp->iomap_bn = XFS_FSB_TO_DB_IO(io, start_block);
if (ISUNWRITTEN(imap)) if (ISUNWRITTEN(imap))
...@@ -512,6 +516,15 @@ xfs_iomap_write_direct( ...@@ -512,6 +516,15 @@ xfs_iomap_write_direct(
*ret_imap = imap[0]; *ret_imap = imap[0];
*nmaps = 1; *nmaps = 1;
if ( !(io->io_flags & XFS_IOCORE_RT) && !ret_imap->br_startblock) {
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,
ret_imap->br_startblock, ret_imap->br_startoff,
ret_imap->br_blockcount,ret_imap->br_state);
}
return 0; return 0;
error0: /* Cancel bmap, unlock inode, and cancel trans */ error0: /* Cancel bmap, unlock inode, and cancel trans */
...@@ -598,6 +611,20 @@ xfs_iomap_write_delay( ...@@ -598,6 +611,20 @@ xfs_iomap_write_delay(
return error; return error;
} }
for (n = 0; n < nimaps; n++) { for (n = 0; n < nimaps; n++) {
if ( !(io->io_flags & XFS_IOCORE_RT) &&
!imap[n].br_startblock) {
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,
imap[n].br_startblock,
imap[n].br_startoff,
imap[n].br_blockcount,
imap[n].br_state);
}
if ((imap[n].br_startblock != HOLESTARTBLOCK) && if ((imap[n].br_startblock != HOLESTARTBLOCK) &&
(imap[n].br_startblock != DELAYSTARTBLOCK)) { (imap[n].br_startblock != DELAYSTARTBLOCK)) {
goto write_map; goto write_map;
...@@ -695,6 +722,15 @@ xfs_iomap_write_delay( ...@@ -695,6 +722,15 @@ xfs_iomap_write_delay(
*ret_imap = imap[0]; *ret_imap = imap[0];
*nmaps = 1; *nmaps = 1;
if ( !(io->io_flags & XFS_IOCORE_RT) && !ret_imap->br_startblock) {
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,
ret_imap->br_startblock, ret_imap->br_startoff,
ret_imap->br_blockcount,ret_imap->br_state);
}
return 0; return 0;
} }
...@@ -712,6 +748,7 @@ xfs_iomap_write_allocate( ...@@ -712,6 +748,7 @@ xfs_iomap_write_allocate(
int *retmap) int *retmap)
{ {
xfs_mount_t *mp = ip->i_mount; xfs_mount_t *mp = ip->i_mount;
xfs_iocore_t *io = &ip->i_iocore;
xfs_fileoff_t offset_fsb, last_block; xfs_fileoff_t offset_fsb, last_block;
xfs_fileoff_t end_fsb, map_start_fsb; xfs_fileoff_t end_fsb, map_start_fsb;
xfs_fsblock_t first_block; xfs_fsblock_t first_block;
...@@ -817,6 +854,18 @@ xfs_iomap_write_allocate( ...@@ -817,6 +854,18 @@ xfs_iomap_write_allocate(
*/ */
for (i = 0; i < nimaps; i++) { for (i = 0; i < nimaps; i++) {
if ( !(io->io_flags & XFS_IOCORE_RT) &&
!imap[i].br_startblock) {
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,
imap[i].br_startblock,
imap[i].br_startoff,
imap[i].br_blockcount,imap[i].br_state);
}
if ((map->br_startoff >= imap[i].br_startoff) && if ((map->br_startoff >= imap[i].br_startoff) &&
(map->br_startoff < (imap[i].br_startoff + (map->br_startoff < (imap[i].br_startoff +
imap[i].br_blockcount))) { imap[i].br_blockcount))) {
...@@ -852,6 +901,7 @@ xfs_iomap_write_unwritten( ...@@ -852,6 +901,7 @@ xfs_iomap_write_unwritten(
size_t count) size_t count)
{ {
xfs_mount_t *mp = ip->i_mount; xfs_mount_t *mp = ip->i_mount;
xfs_iocore_t *io = &ip->i_iocore;
xfs_trans_t *tp; xfs_trans_t *tp;
xfs_fileoff_t offset_fsb; xfs_fileoff_t offset_fsb;
xfs_filblks_t count_fsb; xfs_filblks_t count_fsb;
...@@ -914,6 +964,16 @@ xfs_iomap_write_unwritten( ...@@ -914,6 +964,16 @@ xfs_iomap_write_unwritten(
xfs_iunlock(ip, XFS_ILOCK_EXCL); xfs_iunlock(ip, XFS_ILOCK_EXCL);
if (error) if (error)
goto error0; goto error0;
if ( !(io->io_flags & XFS_IOCORE_RT) && !imap.br_startblock) {
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,
imap.br_startblock,imap.br_startoff,
imap.br_blockcount,imap.br_state);
}
if ((numblks_fsb = imap.br_blockcount) == 0) { if ((numblks_fsb = imap.br_blockcount) == 0) {
/* /*
......
/* /*
* Copyright (c) 2003 Silicon Graphics, Inc. All Rights Reserved. * Copyright (c) 2003,2004 Silicon Graphics, Inc. All Rights Reserved.
* *
* This program is free software; you can redistribute it and/or modify it * 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 * under the terms of version 2 of the GNU General Public License as
...@@ -42,6 +42,7 @@ typedef enum { /* iomap_flags values */ ...@@ -42,6 +42,7 @@ typedef enum { /* iomap_flags values */
IOMAP_EOF = 0x01, /* mapping contains EOF */ IOMAP_EOF = 0x01, /* mapping contains EOF */
IOMAP_HOLE = 0x02, /* mapping covers a hole */ IOMAP_HOLE = 0x02, /* mapping covers a hole */
IOMAP_DELAY = 0x04, /* mapping covers delalloc region */ IOMAP_DELAY = 0x04, /* mapping covers delalloc region */
IOMAP_REALTIME = 0x10, /* mapping on the realtime device */
IOMAP_UNWRITTEN = 0x20, /* mapping covers allocated */ IOMAP_UNWRITTEN = 0x20, /* mapping covers allocated */
/* but uninitialized file data */ /* but uninitialized file data */
IOMAP_NEW = 0x40 /* just allocate */ IOMAP_NEW = 0x40 /* just allocate */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment