aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_bmap_util.c
diff options
context:
space:
mode:
authorBen Myers <bpm@sgi.com>2014-01-09 17:03:18 -0500
committerBen Myers <bpm@sgi.com>2014-01-09 17:03:18 -0500
commitbf3964c188d686424ff7b69a45941851b9f437f0 (patch)
treedf67c636a6c0aa9f5369a335e1aa9d37d992bd85 /fs/xfs/xfs_bmap_util.c
parentdc16b186bb12c479b6a88bc280b34806a69199ad (diff)
parenteef334e5776c8ef547ada4cec17549929fe590b4 (diff)
Merge branch 'xfs-extent-list-locking-fixes' into for-next
A set of fixes which makes sure we are taking the ilock whenever accessing the extent list. This was associated with "Access to block zero" messages which may result in extent list corruption.
Diffstat (limited to 'fs/xfs/xfs_bmap_util.c')
-rw-r--r--fs/xfs/xfs_bmap_util.c35
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);