Skip to content

Commit

Permalink
Condition variable usage, zp->r_{rd,wr}_cv
Browse files Browse the repository at this point in the history
The following incorrect usage of cv_broadcast() was caught by
code inspection.  The cv_broadcast() function must be called
under the associated mutex to preventing racing with cv_wait().

Signed-off-by: Brian Behlendorf <[email protected]>
  • Loading branch information
behlendorf authored and unya committed Dec 13, 2013
1 parent 8cab4db commit 6a6d1ff
Showing 1 changed file with 5 additions and 4 deletions.
9 changes: 5 additions & 4 deletions module/zfs/zfs_rlock.c
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ zfs_range_unlock_reader(znode_t *zp, rl_t *remove, list_t *free_list)
*/
if (remove->r_cnt == 1) {
avl_remove(tree, remove);
mutex_exit(&zp->z_range_lock);

if (remove->r_write_wanted)
cv_broadcast(&remove->r_wr_cv);

Expand Down Expand Up @@ -530,7 +530,6 @@ zfs_range_unlock_reader(znode_t *zp, rl_t *remove, list_t *free_list)
}
}

mutex_exit(&zp->z_range_lock);
kmem_free(remove, sizeof (rl_t));
}
}
Expand All @@ -554,7 +553,6 @@ zfs_range_unlock(rl_t *rl)
if (rl->r_type == RL_WRITER) {
/* writer locks can't be shared or split */
avl_remove(&zp->z_range_avl, rl);
mutex_exit(&zp->z_range_lock);
if (rl->r_write_wanted)
cv_broadcast(&rl->r_wr_cv);

Expand All @@ -569,6 +567,7 @@ zfs_range_unlock(rl_t *rl)
*/
zfs_range_unlock_reader(zp, rl, &free_list);
}
mutex_exit(&zp->z_range_lock);

while ((free_rl = list_head(&free_list)) != NULL) {
list_remove(&free_list, free_rl);
Expand Down Expand Up @@ -599,11 +598,13 @@ zfs_range_reduce(rl_t *rl, uint64_t off, uint64_t len)
mutex_enter(&zp->z_range_lock);
rl->r_off = off;
rl->r_len = len;
mutex_exit(&zp->z_range_lock);

if (rl->r_write_wanted)
cv_broadcast(&rl->r_wr_cv);
if (rl->r_read_wanted)
cv_broadcast(&rl->r_rd_cv);

mutex_exit(&zp->z_range_lock);
}

/*
Expand Down

0 comments on commit 6a6d1ff

Please sign in to comment.