Messages in this thread Patch in this message | | | From | wu000273@umn ... | Subject | [PATCH] btrfs: fix a potential racy | Date | Sat, 18 Apr 2020 20:59:07 -0500 |
| |
From: Qiushi Wu <wu000273@umn.edu>
In function reada_find_extent and reada_extent_put, kref_get(&zone->refcnt) are not called in a lock context. Potential racy may happen. It's possible that thread1 decreases the kref to 0, and thread2 increases the kref to 1, then thread1 releases the pointer.
Signed-off-by: Qiushi Wu <wu000273@umn.edu> --- fs/btrfs/reada.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/fs/btrfs/reada.c b/fs/btrfs/reada.c index 243a2e44526e..4b90d04f7a0a 100644 --- a/fs/btrfs/reada.c +++ b/fs/btrfs/reada.c @@ -361,13 +361,15 @@ static struct reada_extent *reada_find_extent(struct btrfs_fs_info *fs_info, zone = reada_find_zone(dev, logical, bbio); if (!zone) continue; - + spin_lock(&fs_info->reada_lock); re->zones[re->nzones++] = zone; spin_lock(&zone->lock); if (!zone->elems) kref_get(&zone->refcnt); + spin_unlock(&fs_info->reada_lock); ++zone->elems; spin_unlock(&zone->lock); + spin_lock(&fs_info->reada_lock); kref_put(&zone->refcnt, reada_zone_release); spin_unlock(&fs_info->reada_lock); @@ -458,8 +460,11 @@ static struct reada_extent *reada_find_extent(struct btrfs_fs_info *fs_info, for (nzones = 0; nzones < re->nzones; ++nzones) { struct reada_zone *zone; + spin_lock(&fs_info->reada_lock); zone = re->zones[nzones]; kref_get(&zone->refcnt); + spin_unlock(&fs_info->reada_lock); + spin_lock(&zone->lock); --zone->elems; if (zone->elems == 0) { @@ -502,9 +507,11 @@ static void reada_extent_put(struct btrfs_fs_info *fs_info, spin_unlock(&fs_info->reada_lock); for (i = 0; i < re->nzones; ++i) { + spin_lock(&fs_info->reada_lock); struct reada_zone *zone = re->zones[i]; - kref_get(&zone->refcnt); + spin_unlock(&fs_info->reada_lock); + spin_lock(&zone->lock); --zone->elems; if (zone->elems == 0) { -- 2.17.1
| |