Commit 62a604de authored by Jon Krueger's avatar Jon Krueger Committed by Nathan Scott

[XFS] xfs_iomap_write_delay() was doing speculative allocations

 without checking if there were any real blocks already in the
 speculative allocation area. This could result in an allocation
 that overlaps pre-allocated space. This would result in an ASSERT
 failure in debug kernels, or invalid output from xfs_bmap.
 The code will now only do speculative allocation if we are writing
 beyond the current allocation eof.

SGI Modid: xfs-linux:xfs-kern:171163a
parent 63efe3eb
...@@ -577,16 +577,42 @@ xfs_iomap_write_delay( ...@@ -577,16 +577,42 @@ xfs_iomap_write_delay(
*/ */
if (!(ioflag & BMAPI_SYNC) && ((offset + count) > ip->i_d.di_size)) { if (!(ioflag & BMAPI_SYNC) && ((offset + count) > ip->i_d.di_size)) {
xfs_off_t aligned_offset; xfs_off_t aligned_offset;
xfs_filblks_t count_fsb;
unsigned int iosize; unsigned int iosize;
xfs_fileoff_t ioalign; xfs_fileoff_t ioalign;
int n;
xfs_fileoff_t start_fsb;
/*
* If there are any real blocks past eof, then don't
* do any speculative allocation.
*/
start_fsb = XFS_B_TO_FSBT(mp,
((xfs_ufsize_t)(offset + count - 1)));
count_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp));
while (count_fsb > 0) {
nimaps = XFS_WRITE_IMAPS;
error = XFS_BMAPI(mp, NULL, io, start_fsb, count_fsb,
0, &firstblock, 0, imap, &nimaps, NULL);
if (error) {
return error;
}
for (n = 0; n < nimaps; n++) {
if ((imap[n].br_startblock != HOLESTARTBLOCK) &&
(imap[n].br_startblock != DELAYSTARTBLOCK)) {
goto write_map;
}
start_fsb += imap[n].br_blockcount;
count_fsb -= imap[n].br_blockcount;
}
}
iosize = mp->m_writeio_blocks; iosize = mp->m_writeio_blocks;
aligned_offset = XFS_WRITEIO_ALIGN(mp, (offset + count - 1)); aligned_offset = XFS_WRITEIO_ALIGN(mp, (offset + count - 1));
ioalign = XFS_B_TO_FSBT(mp, aligned_offset); ioalign = XFS_B_TO_FSBT(mp, aligned_offset);
last_fsb = ioalign + iosize; last_fsb = ioalign + iosize;
aeof = 1; aeof = 1;
} }
write_map:
nimaps = XFS_WRITE_IMAPS; nimaps = XFS_WRITE_IMAPS;
firstblock = NULLFSBLOCK; firstblock = NULLFSBLOCK;
......
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