diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-12-31 08:14:29 +0100 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-12-31 08:14:29 +0100 |
commit | 5fdf7e5975a0b0f6a0370655612c5dca3fd6311b (patch) | |
tree | 639c536e818c6ace974aa285ba94576df0353b01 /block/genhd.c | |
parent | 7a51cffbd10886c0557677dd916c090097c691ef (diff) | |
parent | 6a94cb73064c952255336cc57731904174b2c58f (diff) | |
download | linux-3.10-5fdf7e5975a0b0f6a0370655612c5dca3fd6311b.tar.gz linux-3.10-5fdf7e5975a0b0f6a0370655612c5dca3fd6311b.tar.bz2 linux-3.10-5fdf7e5975a0b0f6a0370655612c5dca3fd6311b.zip |
Merge branch 'linus' into tracing/kmemtrace
Conflicts:
mm/slub.c
Diffstat (limited to 'block/genhd.c')
-rw-r--r-- | block/genhd.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/block/genhd.c b/block/genhd.c index 2f7feda61e3..d84a7df1e2a 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -181,6 +181,12 @@ void disk_part_iter_exit(struct disk_part_iter *piter) } EXPORT_SYMBOL_GPL(disk_part_iter_exit); +static inline int sector_in_part(struct hd_struct *part, sector_t sector) +{ + return part->start_sect <= sector && + sector < part->start_sect + part->nr_sects; +} + /** * disk_map_sector_rcu - map sector to partition * @disk: gendisk of interest @@ -199,16 +205,22 @@ EXPORT_SYMBOL_GPL(disk_part_iter_exit); struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, sector_t sector) { struct disk_part_tbl *ptbl; + struct hd_struct *part; int i; ptbl = rcu_dereference(disk->part_tbl); + part = rcu_dereference(ptbl->last_lookup); + if (part && sector_in_part(part, sector)) + return part; + for (i = 1; i < ptbl->len; i++) { - struct hd_struct *part = rcu_dereference(ptbl->part[i]); + part = rcu_dereference(ptbl->part[i]); - if (part && part->start_sect <= sector && - sector < part->start_sect + part->nr_sects) + if (part && sector_in_part(part, sector)) { + rcu_assign_pointer(ptbl->last_lookup, part); return part; + } } return &disk->part0; } @@ -888,8 +900,11 @@ static void disk_replace_part_tbl(struct gendisk *disk, struct disk_part_tbl *old_ptbl = disk->part_tbl; rcu_assign_pointer(disk->part_tbl, new_ptbl); - if (old_ptbl) + + if (old_ptbl) { + rcu_assign_pointer(old_ptbl->last_lookup, NULL); call_rcu(&old_ptbl->rcu_head, disk_free_ptbl_rcu_cb); + } } /** |