diff options
Diffstat (limited to 'fs/xfs/xfs_bmap_util.c')
-rw-r--r-- | fs/xfs/xfs_bmap_util.c | 35 |
1 files changed, 23 insertions, 12 deletions
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 82e0dab46ee5..f264616080ca 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c | |||
@@ -618,22 +618,27 @@ xfs_getbmap( | |||
618 | return XFS_ERROR(ENOMEM); | 618 | return XFS_ERROR(ENOMEM); |
619 | 619 | ||
620 | xfs_ilock(ip, XFS_IOLOCK_SHARED); | 620 | xfs_ilock(ip, XFS_IOLOCK_SHARED); |
621 | if (whichfork == XFS_DATA_FORK && !(iflags & BMV_IF_DELALLOC)) { | 621 | if (whichfork == XFS_DATA_FORK) { |
622 | if (ip->i_delayed_blks || XFS_ISIZE(ip) > ip->i_d.di_size) { | 622 | if (!(iflags & BMV_IF_DELALLOC) && |
623 | (ip->i_delayed_blks || XFS_ISIZE(ip) > ip->i_d.di_size)) { | ||
623 | error = -filemap_write_and_wait(VFS_I(ip)->i_mapping); | 624 | error = -filemap_write_and_wait(VFS_I(ip)->i_mapping); |
624 | if (error) | 625 | if (error) |
625 | goto out_unlock_iolock; | 626 | goto out_unlock_iolock; |
627 | |||
628 | /* | ||
629 | * Even after flushing the inode, there can still be | ||
630 | * delalloc blocks on the inode beyond EOF due to | ||
631 | * speculative preallocation. These are not removed | ||
632 | * until the release function is called or the inode | ||
633 | * is inactivated. Hence we cannot assert here that | ||
634 | * ip->i_delayed_blks == 0. | ||
635 | */ | ||
626 | } | 636 | } |
627 | /* | ||
628 | * even after flushing the inode, there can still be delalloc | ||
629 | * blocks on the inode beyond EOF due to speculative | ||
630 | * preallocation. These are not removed until the release | ||
631 | * function is called or the inode is inactivated. Hence we | ||
632 | * cannot assert here that ip->i_delayed_blks == 0. | ||
633 | */ | ||
634 | } | ||
635 | 637 | ||
636 | lock = xfs_ilock_map_shared(ip); | 638 | lock = xfs_ilock_data_map_shared(ip); |
639 | } else { | ||
640 | lock = xfs_ilock_attr_map_shared(ip); | ||
641 | } | ||
637 | 642 | ||
638 | /* | 643 | /* |
639 | * Don't let nex be bigger than the number of extents | 644 | * Don't let nex be bigger than the number of extents |
@@ -738,7 +743,7 @@ xfs_getbmap( | |||
738 | out_free_map: | 743 | out_free_map: |
739 | kmem_free(map); | 744 | kmem_free(map); |
740 | out_unlock_ilock: | 745 | out_unlock_ilock: |
741 | xfs_iunlock_map_shared(ip, lock); | 746 | xfs_iunlock(ip, lock); |
742 | out_unlock_iolock: | 747 | out_unlock_iolock: |
743 | xfs_iunlock(ip, XFS_IOLOCK_SHARED); | 748 | xfs_iunlock(ip, XFS_IOLOCK_SHARED); |
744 | 749 | ||
@@ -1169,9 +1174,15 @@ xfs_zero_remaining_bytes( | |||
1169 | xfs_buf_unlock(bp); | 1174 | xfs_buf_unlock(bp); |
1170 | 1175 | ||
1171 | for (offset = startoff; offset <= endoff; offset = lastoffset + 1) { | 1176 | for (offset = startoff; offset <= endoff; offset = lastoffset + 1) { |
1177 | uint lock_mode; | ||
1178 | |||
1172 | offset_fsb = XFS_B_TO_FSBT(mp, offset); | 1179 | offset_fsb = XFS_B_TO_FSBT(mp, offset); |
1173 | nimap = 1; | 1180 | nimap = 1; |
1181 | |||
1182 | lock_mode = xfs_ilock_data_map_shared(ip); | ||
1174 | error = xfs_bmapi_read(ip, offset_fsb, 1, &imap, &nimap, 0); | 1183 | error = xfs_bmapi_read(ip, offset_fsb, 1, &imap, &nimap, 0); |
1184 | xfs_iunlock(ip, lock_mode); | ||
1185 | |||
1175 | if (error || nimap < 1) | 1186 | if (error || nimap < 1) |
1176 | break; | 1187 | break; |
1177 | ASSERT(imap.br_blockcount >= 1); | 1188 | ASSERT(imap.br_blockcount >= 1); |