Print this page
6385 Fix unlocking order in zfs_zget
Reviewed by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Dan Kimmel <dan.kimmel@delphix.com>
Reviewed by: Andriy Gapon <avg@freebsd.org>
Approved by: Robert Mustacchi <rm@joyent.com>


1131                 zp  = sa_get_userdata(hdl);
1132 
1133 
1134                 /*
1135                  * Since "SA" does immediate eviction we
1136                  * should never find a sa handle that doesn't
1137                  * know about the znode.
1138                  */
1139 
1140                 ASSERT3P(zp, !=, NULL);
1141 
1142                 mutex_enter(&zp->z_lock);
1143                 ASSERT3U(zp->z_id, ==, obj_num);
1144                 if (zp->z_unlinked) {
1145                         err = SET_ERROR(ENOENT);
1146                 } else {
1147                         VN_HOLD(ZTOV(zp));
1148                         *zpp = zp;
1149                         err = 0;
1150                 }
1151                 sa_buf_rele(db, NULL);
1152                 mutex_exit(&zp->z_lock);

1153                 ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num);
1154                 return (err);
1155         }
1156 
1157         /*
1158          * Not found create new znode/vnode
1159          * but only if file exists.
1160          *
1161          * There is a small window where zfs_vget() could
1162          * find this object while a file create is still in
1163          * progress.  This is checked for in zfs_znode_alloc()
1164          *
1165          * if zfs_znode_alloc() fails it will drop the hold on the
1166          * bonus buffer.
1167          */
1168         zp = zfs_znode_alloc(zfsvfs, db, doi.doi_data_block_size,
1169             doi.doi_bonus_type, NULL);
1170         if (zp == NULL) {
1171                 err = SET_ERROR(ENOENT);
1172         } else {




1131                 zp  = sa_get_userdata(hdl);
1132 
1133 
1134                 /*
1135                  * Since "SA" does immediate eviction we
1136                  * should never find a sa handle that doesn't
1137                  * know about the znode.
1138                  */
1139 
1140                 ASSERT3P(zp, !=, NULL);
1141 
1142                 mutex_enter(&zp->z_lock);
1143                 ASSERT3U(zp->z_id, ==, obj_num);
1144                 if (zp->z_unlinked) {
1145                         err = SET_ERROR(ENOENT);
1146                 } else {
1147                         VN_HOLD(ZTOV(zp));
1148                         *zpp = zp;
1149                         err = 0;
1150                 }

1151                 mutex_exit(&zp->z_lock);
1152                 sa_buf_rele(db, NULL);
1153                 ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num);
1154                 return (err);
1155         }
1156 
1157         /*
1158          * Not found create new znode/vnode
1159          * but only if file exists.
1160          *
1161          * There is a small window where zfs_vget() could
1162          * find this object while a file create is still in
1163          * progress.  This is checked for in zfs_znode_alloc()
1164          *
1165          * if zfs_znode_alloc() fails it will drop the hold on the
1166          * bonus buffer.
1167          */
1168         zp = zfs_znode_alloc(zfsvfs, db, doi.doi_data_block_size,
1169             doi.doi_bonus_type, NULL);
1170         if (zp == NULL) {
1171                 err = SET_ERROR(ENOENT);
1172         } else {