aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_iomap.c
diff options
context:
space:
mode:
authorLachlan McIlroy <lachlan@redback.melbourne.sgi.com>2008-12-22 01:56:49 -0500
committerLachlan McIlroy <lachlan@redback.melbourne.sgi.com>2008-12-22 01:56:49 -0500
commit9f6c92b9cc2fd41d6c7b493be5637cc5b5659880 (patch)
tree64ea95c3305d2bba4191f7dec831e623bff8a911 /fs/xfs/xfs_iomap.c
parent4fdc7781799926dca6c3a3bb6e9533a9718c4dea (diff)
[XFS] Fix speculative allocation beyond eof
Speculative allocation beyond eof doesn't work properly. It was broken some time ago after a code cleanup that moved what is now xfs_iomap_eof_align_last_fsb() and xfs_iomap_eof_want_preallocate() out of xfs_iomap_write_delay() into separate functions. The code used to use the current file size in various checks but got changed to be max(file_size, i_new_size). Since i_new_size is the result of 'offset + count' then in xfs_iomap_eof_want_preallocate() the check for '(offset + count) <= isize' will always be true. ie if 'offset + count' is > ip->i_size then isize will be i_new_size and equal to 'offset + count'. This change fixes all the places that used to use the current file size. Reviewed-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_iomap.c')
-rw-r--r--fs/xfs/xfs_iomap.c28
1 files changed, 7 insertions, 21 deletions
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 67f22b2b44b3..911062cf73a6 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -290,7 +290,6 @@ STATIC int
290xfs_iomap_eof_align_last_fsb( 290xfs_iomap_eof_align_last_fsb(
291 xfs_mount_t *mp, 291 xfs_mount_t *mp,
292 xfs_inode_t *ip, 292 xfs_inode_t *ip,
293 xfs_fsize_t isize,
294 xfs_extlen_t extsize, 293 xfs_extlen_t extsize,
295 xfs_fileoff_t *last_fsb) 294 xfs_fileoff_t *last_fsb)
296{ 295{
@@ -306,14 +305,14 @@ xfs_iomap_eof_align_last_fsb(
306 * stripe width and we are allocating past the allocation eof. 305 * stripe width and we are allocating past the allocation eof.
307 */ 306 */
308 else if (mp->m_swidth && (mp->m_flags & XFS_MOUNT_SWALLOC) && 307 else if (mp->m_swidth && (mp->m_flags & XFS_MOUNT_SWALLOC) &&
309 (isize >= XFS_FSB_TO_B(mp, mp->m_swidth))) 308 (ip->i_size >= XFS_FSB_TO_B(mp, mp->m_swidth)))
310 new_last_fsb = roundup_64(*last_fsb, mp->m_swidth); 309 new_last_fsb = roundup_64(*last_fsb, mp->m_swidth);
311 /* 310 /*
312 * Roundup the allocation request to a stripe unit (m_dalign) boundary 311 * Roundup the allocation request to a stripe unit (m_dalign) boundary
313 * if the file size is >= stripe unit size, and we are allocating past 312 * if the file size is >= stripe unit size, and we are allocating past
314 * the allocation eof. 313 * the allocation eof.
315 */ 314 */
316 else if (mp->m_dalign && (isize >= XFS_FSB_TO_B(mp, mp->m_dalign))) 315 else if (mp->m_dalign && (ip->i_size >= XFS_FSB_TO_B(mp, mp->m_dalign)))
317 new_last_fsb = roundup_64(*last_fsb, mp->m_dalign); 316 new_last_fsb = roundup_64(*last_fsb, mp->m_dalign);
318 317
319 /* 318 /*
@@ -403,7 +402,6 @@ xfs_iomap_write_direct(
403 xfs_filblks_t count_fsb, resaligned; 402 xfs_filblks_t count_fsb, resaligned;
404 xfs_fsblock_t firstfsb; 403 xfs_fsblock_t firstfsb;
405 xfs_extlen_t extsz, temp; 404 xfs_extlen_t extsz, temp;
406 xfs_fsize_t isize;
407 int nimaps; 405 int nimaps;
408 int bmapi_flag; 406 int bmapi_flag;
409 int quota_flag; 407 int quota_flag;
@@ -426,15 +424,10 @@ xfs_iomap_write_direct(
426 rt = XFS_IS_REALTIME_INODE(ip); 424 rt = XFS_IS_REALTIME_INODE(ip);
427 extsz = xfs_get_extsz_hint(ip); 425 extsz = xfs_get_extsz_hint(ip);
428 426
429 isize = ip->i_size;
430 if (ip->i_new_size > isize)
431 isize = ip->i_new_size;
432
433 offset_fsb = XFS_B_TO_FSBT(mp, offset); 427 offset_fsb = XFS_B_TO_FSBT(mp, offset);
434 last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count))); 428 last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count)));
435 if ((offset + count) > isize) { 429 if ((offset + count) > ip->i_size) {
436 error = xfs_iomap_eof_align_last_fsb(mp, ip, isize, extsz, 430 error = xfs_iomap_eof_align_last_fsb(mp, ip, extsz, &last_fsb);
437 &last_fsb);
438 if (error) 431 if (error)
439 goto error_out; 432 goto error_out;
440 } else { 433 } else {
@@ -559,7 +552,6 @@ STATIC int
559xfs_iomap_eof_want_preallocate( 552xfs_iomap_eof_want_preallocate(
560 xfs_mount_t *mp, 553 xfs_mount_t *mp,
561 xfs_inode_t *ip, 554 xfs_inode_t *ip,
562 xfs_fsize_t isize,
563 xfs_off_t offset, 555 xfs_off_t offset,
564 size_t count, 556 size_t count,
565 int ioflag, 557 int ioflag,
@@ -573,7 +565,7 @@ xfs_iomap_eof_want_preallocate(
573 int n, error, imaps; 565 int n, error, imaps;
574 566
575 *prealloc = 0; 567 *prealloc = 0;
576 if ((ioflag & BMAPI_SYNC) || (offset + count) <= isize) 568 if ((ioflag & BMAPI_SYNC) || (offset + count) <= ip->i_size)
577 return 0; 569 return 0;
578 570
579 /* 571 /*
@@ -617,7 +609,6 @@ xfs_iomap_write_delay(
617 xfs_fileoff_t ioalign; 609 xfs_fileoff_t ioalign;
618 xfs_fsblock_t firstblock; 610 xfs_fsblock_t firstblock;
619 xfs_extlen_t extsz; 611 xfs_extlen_t extsz;
620 xfs_fsize_t isize;
621 int nimaps; 612 int nimaps;
622 xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS]; 613 xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS];
623 int prealloc, fsynced = 0; 614 int prealloc, fsynced = 0;
@@ -637,11 +628,7 @@ xfs_iomap_write_delay(
637 offset_fsb = XFS_B_TO_FSBT(mp, offset); 628 offset_fsb = XFS_B_TO_FSBT(mp, offset);
638 629
639retry: 630retry:
640 isize = ip->i_size; 631 error = xfs_iomap_eof_want_preallocate(mp, ip, offset, count,
641 if (ip->i_new_size > isize)
642 isize = ip->i_new_size;
643
644 error = xfs_iomap_eof_want_preallocate(mp, ip, isize, offset, count,
645 ioflag, imap, XFS_WRITE_IMAPS, &prealloc); 632 ioflag, imap, XFS_WRITE_IMAPS, &prealloc);
646 if (error) 633 if (error)
647 return error; 634 return error;
@@ -655,8 +642,7 @@ retry:
655 } 642 }
656 643
657 if (prealloc || extsz) { 644 if (prealloc || extsz) {
658 error = xfs_iomap_eof_align_last_fsb(mp, ip, isize, extsz, 645 error = xfs_iomap_eof_align_last_fsb(mp, ip, extsz, &last_fsb);
659 &last_fsb);
660 if (error) 646 if (error)
661 return error; 647 return error;
662 } 648 }