aboutsummaryrefslogtreecommitdiffstats
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
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.
-rw-r--r--fs/xfs/xfs_aops.c2
-rw-r--r--fs/xfs/xfs_attr.c5
-rw-r--r--fs/xfs/xfs_attr_list.c8
-rw-r--r--fs/xfs/xfs_bmap.c4
-rw-r--r--fs/xfs/xfs_bmap_util.c35
-rw-r--r--fs/xfs/xfs_dir2_readdir.c4
-rw-r--r--fs/xfs/xfs_dquot.c7
-rw-r--r--fs/xfs/xfs_file.c10
-rw-r--r--fs/xfs/xfs_inode.c62
-rw-r--r--fs/xfs/xfs_inode.h4
-rw-r--r--fs/xfs/xfs_inode_fork.c2
-rw-r--r--fs/xfs/xfs_ioctl.c4
-rw-r--r--fs/xfs/xfs_qm.c6
13 files changed, 84 insertions, 69 deletions
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index 71c8c9d2b882..a26739451b53 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -1217,7 +1217,7 @@ __xfs_get_blocks(
1217 lockmode = XFS_ILOCK_EXCL; 1217 lockmode = XFS_ILOCK_EXCL;
1218 xfs_ilock(ip, lockmode); 1218 xfs_ilock(ip, lockmode);
1219 } else { 1219 } else {
1220 lockmode = xfs_ilock_map_shared(ip); 1220 lockmode = xfs_ilock_data_map_shared(ip);
1221 } 1221 }
1222 1222
1223 ASSERT(offset <= mp->m_super->s_maxbytes); 1223 ASSERT(offset <= mp->m_super->s_maxbytes);
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
index b86127072ac3..01b6a0102fbd 100644
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -164,6 +164,7 @@ xfs_attr_get(
164{ 164{
165 int error; 165 int error;
166 struct xfs_name xname; 166 struct xfs_name xname;
167 uint lock_mode;
167 168
168 XFS_STATS_INC(xs_attr_get); 169 XFS_STATS_INC(xs_attr_get);
169 170
@@ -174,9 +175,9 @@ xfs_attr_get(
174 if (error) 175 if (error)
175 return error; 176 return error;
176 177
177 xfs_ilock(ip, XFS_ILOCK_SHARED); 178 lock_mode = xfs_ilock_attr_map_shared(ip);
178 error = xfs_attr_get_int(ip, &xname, value, valuelenp, flags); 179 error = xfs_attr_get_int(ip, &xname, value, valuelenp, flags);
179 xfs_iunlock(ip, XFS_ILOCK_SHARED); 180 xfs_iunlock(ip, lock_mode);
180 return(error); 181 return(error);
181} 182}
182 183
diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c
index 2d174b128153..01db96f60cf0 100644
--- a/fs/xfs/xfs_attr_list.c
+++ b/fs/xfs/xfs_attr_list.c
@@ -507,17 +507,17 @@ xfs_attr_list_int(
507{ 507{
508 int error; 508 int error;
509 xfs_inode_t *dp = context->dp; 509 xfs_inode_t *dp = context->dp;
510 uint lock_mode;
510 511
511 XFS_STATS_INC(xs_attr_list); 512 XFS_STATS_INC(xs_attr_list);
512 513
513 if (XFS_FORCED_SHUTDOWN(dp->i_mount)) 514 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
514 return EIO; 515 return EIO;
515 516
516 xfs_ilock(dp, XFS_ILOCK_SHARED);
517
518 /* 517 /*
519 * Decide on what work routines to call based on the inode size. 518 * Decide on what work routines to call based on the inode size.
520 */ 519 */
520 lock_mode = xfs_ilock_attr_map_shared(dp);
521 if (!xfs_inode_hasattr(dp)) { 521 if (!xfs_inode_hasattr(dp)) {
522 error = 0; 522 error = 0;
523 } else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { 523 } else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
@@ -527,9 +527,7 @@ xfs_attr_list_int(
527 } else { 527 } else {
528 error = xfs_attr_node_list(context); 528 error = xfs_attr_node_list(context);
529 } 529 }
530 530 xfs_iunlock(dp, lock_mode);
531 xfs_iunlock(dp, XFS_ILOCK_SHARED);
532
533 return error; 531 return error;
534} 532}
535 533
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 3b2c14b6f0fb..152543c4ca70 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -4013,6 +4013,7 @@ xfs_bmapi_read(
4013 ASSERT(*nmap >= 1); 4013 ASSERT(*nmap >= 1);
4014 ASSERT(!(flags & ~(XFS_BMAPI_ATTRFORK|XFS_BMAPI_ENTIRE| 4014 ASSERT(!(flags & ~(XFS_BMAPI_ATTRFORK|XFS_BMAPI_ENTIRE|
4015 XFS_BMAPI_IGSTATE))); 4015 XFS_BMAPI_IGSTATE)));
4016 ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED|XFS_ILOCK_EXCL));
4016 4017
4017 if (unlikely(XFS_TEST_ERROR( 4018 if (unlikely(XFS_TEST_ERROR(
4018 (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && 4019 (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
@@ -4207,6 +4208,7 @@ xfs_bmapi_delay(
4207 ASSERT(*nmap >= 1); 4208 ASSERT(*nmap >= 1);
4208 ASSERT(*nmap <= XFS_BMAP_MAX_NMAP); 4209 ASSERT(*nmap <= XFS_BMAP_MAX_NMAP);
4209 ASSERT(!(flags & ~XFS_BMAPI_ENTIRE)); 4210 ASSERT(!(flags & ~XFS_BMAPI_ENTIRE));
4211 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
4210 4212
4211 if (unlikely(XFS_TEST_ERROR( 4213 if (unlikely(XFS_TEST_ERROR(
4212 (XFS_IFORK_FORMAT(ip, XFS_DATA_FORK) != XFS_DINODE_FMT_EXTENTS && 4214 (XFS_IFORK_FORMAT(ip, XFS_DATA_FORK) != XFS_DINODE_FMT_EXTENTS &&
@@ -4500,6 +4502,7 @@ xfs_bmapi_write(
4500 ASSERT(tp != NULL); 4502 ASSERT(tp != NULL);
4501 ASSERT(len > 0); 4503 ASSERT(len > 0);
4502 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL); 4504 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL);
4505 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
4503 4506
4504 if (unlikely(XFS_TEST_ERROR( 4507 if (unlikely(XFS_TEST_ERROR(
4505 (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && 4508 (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
@@ -5051,6 +5054,7 @@ xfs_bunmapi(
5051 if (XFS_FORCED_SHUTDOWN(mp)) 5054 if (XFS_FORCED_SHUTDOWN(mp))
5052 return XFS_ERROR(EIO); 5055 return XFS_ERROR(EIO);
5053 5056
5057 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
5054 ASSERT(len > 0); 5058 ASSERT(len > 0);
5055 ASSERT(nexts >= 0); 5059 ASSERT(nexts >= 0);
5056 5060
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);
diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
index c4e50c6ed584..aead369e1c30 100644
--- a/fs/xfs/xfs_dir2_readdir.c
+++ b/fs/xfs/xfs_dir2_readdir.c
@@ -674,6 +674,7 @@ xfs_readdir(
674{ 674{
675 int rval; /* return value */ 675 int rval; /* return value */
676 int v; /* type-checking value */ 676 int v; /* type-checking value */
677 uint lock_mode;
677 678
678 trace_xfs_readdir(dp); 679 trace_xfs_readdir(dp);
679 680
@@ -683,6 +684,7 @@ xfs_readdir(
683 ASSERT(S_ISDIR(dp->i_d.di_mode)); 684 ASSERT(S_ISDIR(dp->i_d.di_mode));
684 XFS_STATS_INC(xs_dir_getdents); 685 XFS_STATS_INC(xs_dir_getdents);
685 686
687 lock_mode = xfs_ilock_data_map_shared(dp);
686 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) 688 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
687 rval = xfs_dir2_sf_getdents(dp, ctx); 689 rval = xfs_dir2_sf_getdents(dp, ctx);
688 else if ((rval = xfs_dir2_isblock(NULL, dp, &v))) 690 else if ((rval = xfs_dir2_isblock(NULL, dp, &v)))
@@ -691,5 +693,7 @@ xfs_readdir(
691 rval = xfs_dir2_block_getdents(dp, ctx); 693 rval = xfs_dir2_block_getdents(dp, ctx);
692 else 694 else
693 rval = xfs_dir2_leaf_getdents(dp, ctx, bufsize); 695 rval = xfs_dir2_leaf_getdents(dp, ctx, bufsize);
696 xfs_iunlock(dp, lock_mode);
697
694 return rval; 698 return rval;
695} 699}
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 6b1e695caf0e..7aeb4c895b32 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -469,16 +469,17 @@ xfs_qm_dqtobp(
469 struct xfs_mount *mp = dqp->q_mount; 469 struct xfs_mount *mp = dqp->q_mount;
470 xfs_dqid_t id = be32_to_cpu(dqp->q_core.d_id); 470 xfs_dqid_t id = be32_to_cpu(dqp->q_core.d_id);
471 struct xfs_trans *tp = (tpp ? *tpp : NULL); 471 struct xfs_trans *tp = (tpp ? *tpp : NULL);
472 uint lock_mode;
472 473
473 dqp->q_fileoffset = (xfs_fileoff_t)id / mp->m_quotainfo->qi_dqperchunk; 474 dqp->q_fileoffset = (xfs_fileoff_t)id / mp->m_quotainfo->qi_dqperchunk;
474 475
475 xfs_ilock(quotip, XFS_ILOCK_SHARED); 476 lock_mode = xfs_ilock_data_map_shared(quotip);
476 if (!xfs_this_quota_on(dqp->q_mount, dqp->dq_flags)) { 477 if (!xfs_this_quota_on(dqp->q_mount, dqp->dq_flags)) {
477 /* 478 /*
478 * Return if this type of quotas is turned off while we 479 * Return if this type of quotas is turned off while we
479 * didn't have the quota inode lock. 480 * didn't have the quota inode lock.
480 */ 481 */
481 xfs_iunlock(quotip, XFS_ILOCK_SHARED); 482 xfs_iunlock(quotip, lock_mode);
482 return ESRCH; 483 return ESRCH;
483 } 484 }
484 485
@@ -488,7 +489,7 @@ xfs_qm_dqtobp(
488 error = xfs_bmapi_read(quotip, dqp->q_fileoffset, 489 error = xfs_bmapi_read(quotip, dqp->q_fileoffset,
489 XFS_DQUOT_CLUSTER_SIZE_FSB, &map, &nmaps, 0); 490 XFS_DQUOT_CLUSTER_SIZE_FSB, &map, &nmaps, 0);
490 491
491 xfs_iunlock(quotip, XFS_ILOCK_SHARED); 492 xfs_iunlock(quotip, lock_mode);
492 if (error) 493 if (error)
493 return error; 494 return error;
494 495
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 52c91e143725..e00121592632 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -912,7 +912,7 @@ xfs_dir_open(
912 * If there are any blocks, read-ahead block 0 as we're almost 912 * If there are any blocks, read-ahead block 0 as we're almost
913 * certain to have the next operation be a read there. 913 * certain to have the next operation be a read there.
914 */ 914 */
915 mode = xfs_ilock_map_shared(ip); 915 mode = xfs_ilock_data_map_shared(ip);
916 if (ip->i_d.di_nextents > 0) 916 if (ip->i_d.di_nextents > 0)
917 xfs_dir3_data_readahead(NULL, ip, 0, -1); 917 xfs_dir3_data_readahead(NULL, ip, 0, -1);
918 xfs_iunlock(ip, mode); 918 xfs_iunlock(ip, mode);
@@ -1215,7 +1215,7 @@ xfs_seek_data(
1215 uint lock; 1215 uint lock;
1216 int error; 1216 int error;
1217 1217
1218 lock = xfs_ilock_map_shared(ip); 1218 lock = xfs_ilock_data_map_shared(ip);
1219 1219
1220 isize = i_size_read(inode); 1220 isize = i_size_read(inode);
1221 if (start >= isize) { 1221 if (start >= isize) {
@@ -1294,7 +1294,7 @@ out:
1294 offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes); 1294 offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
1295 1295
1296out_unlock: 1296out_unlock:
1297 xfs_iunlock_map_shared(ip, lock); 1297 xfs_iunlock(ip, lock);
1298 1298
1299 if (error) 1299 if (error)
1300 return -error; 1300 return -error;
@@ -1319,7 +1319,7 @@ xfs_seek_hole(
1319 if (XFS_FORCED_SHUTDOWN(mp)) 1319 if (XFS_FORCED_SHUTDOWN(mp))
1320 return -XFS_ERROR(EIO); 1320 return -XFS_ERROR(EIO);
1321 1321
1322 lock = xfs_ilock_map_shared(ip); 1322 lock = xfs_ilock_data_map_shared(ip);
1323 1323
1324 isize = i_size_read(inode); 1324 isize = i_size_read(inode);
1325 if (start >= isize) { 1325 if (start >= isize) {
@@ -1402,7 +1402,7 @@ out:
1402 offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes); 1402 offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
1403 1403
1404out_unlock: 1404out_unlock:
1405 xfs_iunlock_map_shared(ip, lock); 1405 xfs_iunlock(ip, lock);
1406 1406
1407 if (error) 1407 if (error)
1408 return -error; 1408 return -error;
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 833028cf205f..3a137e9f9a7d 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -77,48 +77,44 @@ xfs_get_extsz_hint(
77} 77}
78 78
79/* 79/*
80 * This is a wrapper routine around the xfs_ilock() routine used to centralize 80 * These two are wrapper routines around the xfs_ilock() routine used to
81 * some grungy code. It is used in places that wish to lock the inode solely 81 * centralize some grungy code. They are used in places that wish to lock the
82 * for reading the extents. The reason these places can't just call 82 * inode solely for reading the extents. The reason these places can't just
83 * xfs_ilock(SHARED) is that the inode lock also guards to bringing in of the 83 * call xfs_ilock(ip, XFS_ILOCK_SHARED) is that the inode lock also guards to
84 * extents from disk for a file in b-tree format. If the inode is in b-tree 84 * bringing in of the extents from disk for a file in b-tree format. If the
85 * format, then we need to lock the inode exclusively until the extents are read 85 * inode is in b-tree format, then we need to lock the inode exclusively until
86 * in. Locking it exclusively all the time would limit our parallelism 86 * the extents are read in. Locking it exclusively all the time would limit
87 * unnecessarily, though. What we do instead is check to see if the extents 87 * our parallelism unnecessarily, though. What we do instead is check to see
88 * have been read in yet, and only lock the inode exclusively if they have not. 88 * if the extents have been read in yet, and only lock the inode exclusively
89 * if they have not.
89 * 90 *
90 * The function returns a value which should be given to the corresponding 91 * The functions return a value which should be given to the corresponding
91 * xfs_iunlock_map_shared(). This value is the mode in which the lock was 92 * xfs_iunlock() call.
92 * actually taken.
93 */ 93 */
94uint 94uint
95xfs_ilock_map_shared( 95xfs_ilock_data_map_shared(
96 xfs_inode_t *ip) 96 struct xfs_inode *ip)
97{ 97{
98 uint lock_mode; 98 uint lock_mode = XFS_ILOCK_SHARED;
99 99
100 if ((ip->i_d.di_format == XFS_DINODE_FMT_BTREE) && 100 if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE &&
101 ((ip->i_df.if_flags & XFS_IFEXTENTS) == 0)) { 101 (ip->i_df.if_flags & XFS_IFEXTENTS) == 0)
102 lock_mode = XFS_ILOCK_EXCL; 102 lock_mode = XFS_ILOCK_EXCL;
103 } else {
104 lock_mode = XFS_ILOCK_SHARED;
105 }
106
107 xfs_ilock(ip, lock_mode); 103 xfs_ilock(ip, lock_mode);
108
109 return lock_mode; 104 return lock_mode;
110} 105}
111 106
112/* 107uint
113 * This is simply the unlock routine to go with xfs_ilock_map_shared(). 108xfs_ilock_attr_map_shared(
114 * All it does is call xfs_iunlock() with the given lock_mode. 109 struct xfs_inode *ip)
115 */
116void
117xfs_iunlock_map_shared(
118 xfs_inode_t *ip,
119 unsigned int lock_mode)
120{ 110{
121 xfs_iunlock(ip, lock_mode); 111 uint lock_mode = XFS_ILOCK_SHARED;
112
113 if (ip->i_d.di_aformat == XFS_DINODE_FMT_BTREE &&
114 (ip->i_afp->if_flags & XFS_IFEXTENTS) == 0)
115 lock_mode = XFS_ILOCK_EXCL;
116 xfs_ilock(ip, lock_mode);
117 return lock_mode;
122} 118}
123 119
124/* 120/*
@@ -588,9 +584,9 @@ xfs_lookup(
588 if (XFS_FORCED_SHUTDOWN(dp->i_mount)) 584 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
589 return XFS_ERROR(EIO); 585 return XFS_ERROR(EIO);
590 586
591 lock_mode = xfs_ilock_map_shared(dp); 587 lock_mode = xfs_ilock_data_map_shared(dp);
592 error = xfs_dir_lookup(NULL, dp, name, &inum, ci_name); 588 error = xfs_dir_lookup(NULL, dp, name, &inum, ci_name);
593 xfs_iunlock_map_shared(dp, lock_mode); 589 xfs_iunlock(dp, lock_mode);
594 590
595 if (error) 591 if (error)
596 goto out; 592 goto out;
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 9e6efccbae04..65e2350f449c 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -337,8 +337,8 @@ int xfs_ilock_nowait(xfs_inode_t *, uint);
337void xfs_iunlock(xfs_inode_t *, uint); 337void xfs_iunlock(xfs_inode_t *, uint);
338void xfs_ilock_demote(xfs_inode_t *, uint); 338void xfs_ilock_demote(xfs_inode_t *, uint);
339int xfs_isilocked(xfs_inode_t *, uint); 339int xfs_isilocked(xfs_inode_t *, uint);
340uint xfs_ilock_map_shared(xfs_inode_t *); 340uint xfs_ilock_data_map_shared(struct xfs_inode *);
341void xfs_iunlock_map_shared(xfs_inode_t *, uint); 341uint xfs_ilock_attr_map_shared(struct xfs_inode *);
342int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, umode_t, 342int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, umode_t,
343 xfs_nlink_t, xfs_dev_t, prid_t, int, 343 xfs_nlink_t, xfs_dev_t, prid_t, int,
344 struct xfs_buf **, xfs_inode_t **); 344 struct xfs_buf **, xfs_inode_t **);
diff --git a/fs/xfs/xfs_inode_fork.c b/fs/xfs/xfs_inode_fork.c
index 06abaeef1715..73514c0486b7 100644
--- a/fs/xfs/xfs_inode_fork.c
+++ b/fs/xfs/xfs_inode_fork.c
@@ -431,6 +431,8 @@ xfs_iread_extents(
431 xfs_ifork_t *ifp; 431 xfs_ifork_t *ifp;
432 xfs_extnum_t nextents; 432 xfs_extnum_t nextents;
433 433
434 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
435
434 if (unlikely(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) { 436 if (unlikely(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) {
435 XFS_ERROR_REPORT("xfs_iread_extents", XFS_ERRLEVEL_LOW, 437 XFS_ERROR_REPORT("xfs_iread_extents", XFS_ERRLEVEL_LOW,
436 ip->i_mount); 438 ip->i_mount);
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 33ad9a77791f..518aa56b8f2e 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -112,15 +112,11 @@ xfs_find_handle(
112 memset(&handle.ha_fid, 0, sizeof(handle.ha_fid)); 112 memset(&handle.ha_fid, 0, sizeof(handle.ha_fid));
113 hsize = sizeof(xfs_fsid_t); 113 hsize = sizeof(xfs_fsid_t);
114 } else { 114 } else {
115 int lock_mode;
116
117 lock_mode = xfs_ilock_map_shared(ip);
118 handle.ha_fid.fid_len = sizeof(xfs_fid_t) - 115 handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
119 sizeof(handle.ha_fid.fid_len); 116 sizeof(handle.ha_fid.fid_len);
120 handle.ha_fid.fid_pad = 0; 117 handle.ha_fid.fid_pad = 0;
121 handle.ha_fid.fid_gen = ip->i_d.di_gen; 118 handle.ha_fid.fid_gen = ip->i_d.di_gen;
122 handle.ha_fid.fid_ino = ip->i_ino; 119 handle.ha_fid.fid_ino = ip->i_ino;
123 xfs_iunlock_map_shared(ip, lock_mode);
124 120
125 hsize = XFS_HSIZE(handle); 121 hsize = XFS_HSIZE(handle);
126 } 122 }
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index dd88f0e27bd8..348e4d2ed6e6 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -1222,16 +1222,18 @@ xfs_qm_dqiterate(
1222 lblkno = 0; 1222 lblkno = 0;
1223 maxlblkcnt = XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes); 1223 maxlblkcnt = XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes);
1224 do { 1224 do {
1225 uint lock_mode;
1226
1225 nmaps = XFS_DQITER_MAP_SIZE; 1227 nmaps = XFS_DQITER_MAP_SIZE;
1226 /* 1228 /*
1227 * We aren't changing the inode itself. Just changing 1229 * We aren't changing the inode itself. Just changing
1228 * some of its data. No new blocks are added here, and 1230 * some of its data. No new blocks are added here, and
1229 * the inode is never added to the transaction. 1231 * the inode is never added to the transaction.
1230 */ 1232 */
1231 xfs_ilock(qip, XFS_ILOCK_SHARED); 1233 lock_mode = xfs_ilock_data_map_shared(qip);
1232 error = xfs_bmapi_read(qip, lblkno, maxlblkcnt - lblkno, 1234 error = xfs_bmapi_read(qip, lblkno, maxlblkcnt - lblkno,
1233 map, &nmaps, 0); 1235 map, &nmaps, 0);
1234 xfs_iunlock(qip, XFS_ILOCK_SHARED); 1236 xfs_iunlock(qip, lock_mode);
1235 if (error) 1237 if (error)
1236 break; 1238 break;
1237 1239