aboutsummaryrefslogtreecommitdiffstats
path: root/block/genhd.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /block/genhd.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'block/genhd.c')
-rw-r--r--block/genhd.c104
1 files changed, 56 insertions, 48 deletions
diff --git a/block/genhd.c b/block/genhd.c
index 9a289d7c84b..d3834710b95 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -15,6 +15,7 @@
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/kmod.h> 16#include <linux/kmod.h>
17#include <linux/kobj_map.h> 17#include <linux/kobj_map.h>
18#include <linux/buffer_head.h>
18#include <linux/mutex.h> 19#include <linux/mutex.h>
19#include <linux/idr.h> 20#include <linux/idr.h>
20#include <linux/log2.h> 21#include <linux/log2.h>
@@ -35,7 +36,6 @@ static DEFINE_IDR(ext_devt_idr);
35 36
36static struct device_type disk_type; 37static struct device_type disk_type;
37 38
38static void disk_alloc_events(struct gendisk *disk);
39static void disk_add_events(struct gendisk *disk); 39static void disk_add_events(struct gendisk *disk);
40static void disk_del_events(struct gendisk *disk); 40static void disk_del_events(struct gendisk *disk);
41static void disk_release_events(struct gendisk *disk); 41static void disk_release_events(struct gendisk *disk);
@@ -154,7 +154,7 @@ struct hd_struct *disk_part_iter_next(struct disk_part_iter *piter)
154 part = rcu_dereference(ptbl->part[piter->idx]); 154 part = rcu_dereference(ptbl->part[piter->idx]);
155 if (!part) 155 if (!part)
156 continue; 156 continue;
157 if (!part_nr_sects_read(part) && 157 if (!part->nr_sects &&
158 !(piter->flags & DISK_PITER_INCL_EMPTY) && 158 !(piter->flags & DISK_PITER_INCL_EMPTY) &&
159 !(piter->flags & DISK_PITER_INCL_EMPTY_PART0 && 159 !(piter->flags & DISK_PITER_INCL_EMPTY_PART0 &&
160 piter->idx == 0)) 160 piter->idx == 0))
@@ -191,7 +191,7 @@ EXPORT_SYMBOL_GPL(disk_part_iter_exit);
191static inline int sector_in_part(struct hd_struct *part, sector_t sector) 191static inline int sector_in_part(struct hd_struct *part, sector_t sector)
192{ 192{
193 return part->start_sect <= sector && 193 return part->start_sect <= sector &&
194 sector < part->start_sect + part_nr_sects_read(part); 194 sector < part->start_sect + part->nr_sects;
195} 195}
196 196
197/** 197/**
@@ -507,7 +507,7 @@ static int exact_lock(dev_t devt, void *data)
507 return 0; 507 return 0;
508} 508}
509 509
510static void register_disk(struct gendisk *disk) 510void register_disk(struct gendisk *disk)
511{ 511{
512 struct device *ddev = disk_to_dev(disk); 512 struct device *ddev = disk_to_dev(disk);
513 struct block_device *bdev; 513 struct block_device *bdev;
@@ -536,7 +536,7 @@ static void register_disk(struct gendisk *disk)
536 disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj); 536 disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj);
537 537
538 /* No minors to use for partitions */ 538 /* No minors to use for partitions */
539 if (!disk_part_scan_enabled(disk)) 539 if (!disk_partitionable(disk))
540 goto exit; 540 goto exit;
541 541
542 /* No such device (e.g., media were just removed) */ 542 /* No such device (e.g., media were just removed) */
@@ -602,8 +602,6 @@ void add_disk(struct gendisk *disk)
602 disk->major = MAJOR(devt); 602 disk->major = MAJOR(devt);
603 disk->first_minor = MINOR(devt); 603 disk->first_minor = MINOR(devt);
604 604
605 disk_alloc_events(disk);
606
607 /* Register BDI before referencing it from bdev */ 605 /* Register BDI before referencing it from bdev */
608 bdi = &disk->queue->backing_dev_info; 606 bdi = &disk->queue->backing_dev_info;
609 bdi_register_dev(bdi, disk_devt(disk)); 607 bdi_register_dev(bdi, disk_devt(disk));
@@ -617,7 +615,7 @@ void add_disk(struct gendisk *disk)
617 * Take an extra ref on queue which will be put on disk_release() 615 * Take an extra ref on queue which will be put on disk_release()
618 * so that it sticks around as long as @disk is there. 616 * so that it sticks around as long as @disk is there.
619 */ 617 */
620 WARN_ON_ONCE(!blk_get_queue(disk->queue)); 618 WARN_ON_ONCE(blk_get_queue(disk->queue));
621 619
622 retval = sysfs_create_link(&disk_to_dev(disk)->kobj, &bdi->dev->kobj, 620 retval = sysfs_create_link(&disk_to_dev(disk)->kobj, &bdi->dev->kobj,
623 "bdi"); 621 "bdi");
@@ -743,6 +741,7 @@ void __init printk_all_partitions(void)
743 struct hd_struct *part; 741 struct hd_struct *part;
744 char name_buf[BDEVNAME_SIZE]; 742 char name_buf[BDEVNAME_SIZE];
745 char devt_buf[BDEVT_SIZE]; 743 char devt_buf[BDEVT_SIZE];
744 u8 uuid[PARTITION_META_INFO_UUIDLTH * 2 + 1];
746 745
747 /* 746 /*
748 * Don't show empty devices or things that have been 747 * Don't show empty devices or things that have been
@@ -761,11 +760,14 @@ void __init printk_all_partitions(void)
761 while ((part = disk_part_iter_next(&piter))) { 760 while ((part = disk_part_iter_next(&piter))) {
762 bool is_part0 = part == &disk->part0; 761 bool is_part0 = part == &disk->part0;
763 762
763 uuid[0] = 0;
764 if (part->info)
765 part_unpack_uuid(part->info->uuid, uuid);
766
764 printk("%s%s %10llu %s %s", is_part0 ? "" : " ", 767 printk("%s%s %10llu %s %s", is_part0 ? "" : " ",
765 bdevt_str(part_devt(part), devt_buf), 768 bdevt_str(part_devt(part), devt_buf),
766 (unsigned long long)part_nr_sects_read(part) >> 1 769 (unsigned long long)part->nr_sects >> 1,
767 , disk_name(disk, part->partno, name_buf), 770 disk_name(disk, part->partno, name_buf), uuid);
768 part->info ? part->info->uuid : "");
769 if (is_part0) { 771 if (is_part0) {
770 if (disk->driverfs_dev != NULL && 772 if (disk->driverfs_dev != NULL &&
771 disk->driverfs_dev->driver != NULL) 773 disk->driverfs_dev->driver != NULL)
@@ -829,7 +831,7 @@ static void disk_seqf_stop(struct seq_file *seqf, void *v)
829 831
830static void *show_partition_start(struct seq_file *seqf, loff_t *pos) 832static void *show_partition_start(struct seq_file *seqf, loff_t *pos)
831{ 833{
832 void *p; 834 static void *p;
833 835
834 p = disk_seqf_start(seqf, pos); 836 p = disk_seqf_start(seqf, pos);
835 if (!IS_ERR_OR_NULL(p) && !*pos) 837 if (!IS_ERR_OR_NULL(p) && !*pos)
@@ -845,7 +847,7 @@ static int show_partition(struct seq_file *seqf, void *v)
845 char buf[BDEVNAME_SIZE]; 847 char buf[BDEVNAME_SIZE];
846 848
847 /* Don't show non-partitionable removeable devices or empty devices */ 849 /* Don't show non-partitionable removeable devices or empty devices */
848 if (!get_capacity(sgp) || (!disk_max_parts(sgp) && 850 if (!get_capacity(sgp) || (!disk_partitionable(sgp) &&
849 (sgp->flags & GENHD_FL_REMOVABLE))) 851 (sgp->flags & GENHD_FL_REMOVABLE)))
850 return 0; 852 return 0;
851 if (sgp->flags & GENHD_FL_SUPPRESS_PARTITION_INFO) 853 if (sgp->flags & GENHD_FL_SUPPRESS_PARTITION_INFO)
@@ -856,7 +858,7 @@ static int show_partition(struct seq_file *seqf, void *v)
856 while ((part = disk_part_iter_next(&piter))) 858 while ((part = disk_part_iter_next(&piter)))
857 seq_printf(seqf, "%4d %7d %10llu %s\n", 859 seq_printf(seqf, "%4d %7d %10llu %s\n",
858 MAJOR(part_devt(part)), MINOR(part_devt(part)), 860 MAJOR(part_devt(part)), MINOR(part_devt(part)),
859 (unsigned long long)part_nr_sects_read(part) >> 1, 861 (unsigned long long)part->nr_sects >> 1,
860 disk_name(sgp, part->partno, buf)); 862 disk_name(sgp, part->partno, buf));
861 disk_part_iter_exit(&piter); 863 disk_part_iter_exit(&piter);
862 864
@@ -1103,11 +1105,27 @@ static void disk_release(struct device *dev)
1103 blk_put_queue(disk->queue); 1105 blk_put_queue(disk->queue);
1104 kfree(disk); 1106 kfree(disk);
1105} 1107}
1108
1109static int disk_uevent(struct device *dev, struct kobj_uevent_env *env)
1110{
1111 struct gendisk *disk = dev_to_disk(dev);
1112 struct disk_part_iter piter;
1113 struct hd_struct *part;
1114 int cnt = 0;
1115
1116 disk_part_iter_init(&piter, disk, 0);
1117 while((part = disk_part_iter_next(&piter)))
1118 cnt++;
1119 disk_part_iter_exit(&piter);
1120 add_uevent_var(env, "NPARTS=%u", cnt);
1121 return 0;
1122}
1123
1106struct class block_class = { 1124struct class block_class = {
1107 .name = "block", 1125 .name = "block",
1108}; 1126};
1109 1127
1110static char *block_devnode(struct device *dev, umode_t *mode) 1128static char *block_devnode(struct device *dev, mode_t *mode)
1111{ 1129{
1112 struct gendisk *disk = dev_to_disk(dev); 1130 struct gendisk *disk = dev_to_disk(dev);
1113 1131
@@ -1121,6 +1139,7 @@ static struct device_type disk_type = {
1121 .groups = disk_attr_groups, 1139 .groups = disk_attr_groups,
1122 .release = disk_release, 1140 .release = disk_release,
1123 .devnode = block_devnode, 1141 .devnode = block_devnode,
1142 .uevent = disk_uevent,
1124}; 1143};
1125 1144
1126#ifdef CONFIG_PROC_FS 1145#ifdef CONFIG_PROC_FS
@@ -1239,7 +1258,7 @@ EXPORT_SYMBOL(blk_lookup_devt);
1239 1258
1240struct gendisk *alloc_disk(int minors) 1259struct gendisk *alloc_disk(int minors)
1241{ 1260{
1242 return alloc_disk_node(minors, NUMA_NO_NODE); 1261 return alloc_disk_node(minors, -1);
1243} 1262}
1244EXPORT_SYMBOL(alloc_disk); 1263EXPORT_SYMBOL(alloc_disk);
1245 1264
@@ -1262,16 +1281,6 @@ struct gendisk *alloc_disk_node(int minors, int node_id)
1262 } 1281 }
1263 disk->part_tbl->part[0] = &disk->part0; 1282 disk->part_tbl->part[0] = &disk->part0;
1264 1283
1265 /*
1266 * set_capacity() and get_capacity() currently don't use
1267 * seqcounter to read/update the part0->nr_sects. Still init
1268 * the counter as we can read the sectors in IO submission
1269 * patch using seqence counters.
1270 *
1271 * TODO: Ideally set_capacity() and get_capacity() should be
1272 * converted to make use of bd_mutex and sequence counters.
1273 */
1274 seqcount_init(&disk->part0.nr_sects_seq);
1275 hd_ref_init(&disk->part0); 1284 hd_ref_init(&disk->part0);
1276 1285
1277 disk->minors = minors; 1286 disk->minors = minors;
@@ -1484,9 +1493,9 @@ static void __disk_unblock_events(struct gendisk *disk, bool check_now)
1484 intv = disk_events_poll_jiffies(disk); 1493 intv = disk_events_poll_jiffies(disk);
1485 set_timer_slack(&ev->dwork.timer, intv / 4); 1494 set_timer_slack(&ev->dwork.timer, intv / 4);
1486 if (check_now) 1495 if (check_now)
1487 queue_delayed_work(system_freezable_wq, &ev->dwork, 0); 1496 queue_delayed_work(system_nrt_wq, &ev->dwork, 0);
1488 else if (intv) 1497 else if (intv)
1489 queue_delayed_work(system_freezable_wq, &ev->dwork, intv); 1498 queue_delayed_work(system_nrt_wq, &ev->dwork, intv);
1490out_unlock: 1499out_unlock:
1491 spin_unlock_irqrestore(&ev->lock, flags); 1500 spin_unlock_irqrestore(&ev->lock, flags);
1492} 1501}
@@ -1528,8 +1537,10 @@ void disk_flush_events(struct gendisk *disk, unsigned int mask)
1528 1537
1529 spin_lock_irq(&ev->lock); 1538 spin_lock_irq(&ev->lock);
1530 ev->clearing |= mask; 1539 ev->clearing |= mask;
1531 if (!ev->block) 1540 if (!ev->block) {
1532 mod_delayed_work(system_freezable_wq, &ev->dwork, 0); 1541 cancel_delayed_work(&ev->dwork);
1542 queue_delayed_work(system_nrt_wq, &ev->dwork, 0);
1543 }
1533 spin_unlock_irq(&ev->lock); 1544 spin_unlock_irq(&ev->lock);
1534} 1545}
1535 1546
@@ -1565,7 +1576,7 @@ unsigned int disk_clear_events(struct gendisk *disk, unsigned int mask)
1565 1576
1566 /* uncondtionally schedule event check and wait for it to finish */ 1577 /* uncondtionally schedule event check and wait for it to finish */
1567 disk_block_events(disk); 1578 disk_block_events(disk);
1568 queue_delayed_work(system_freezable_wq, &ev->dwork, 0); 1579 queue_delayed_work(system_nrt_wq, &ev->dwork, 0);
1569 flush_delayed_work(&ev->dwork); 1580 flush_delayed_work(&ev->dwork);
1570 __disk_unblock_events(disk, false); 1581 __disk_unblock_events(disk, false);
1571 1582
@@ -1602,7 +1613,7 @@ static void disk_events_workfn(struct work_struct *work)
1602 1613
1603 intv = disk_events_poll_jiffies(disk); 1614 intv = disk_events_poll_jiffies(disk);
1604 if (!ev->block && intv) 1615 if (!ev->block && intv)
1605 queue_delayed_work(system_freezable_wq, &ev->dwork, intv); 1616 queue_delayed_work(system_nrt_wq, &ev->dwork, intv);
1606 1617
1607 spin_unlock_irq(&ev->lock); 1618 spin_unlock_irq(&ev->lock);
1608 1619
@@ -1740,9 +1751,9 @@ module_param_cb(events_dfl_poll_msecs, &disk_events_dfl_poll_msecs_param_ops,
1740 &disk_events_dfl_poll_msecs, 0644); 1751 &disk_events_dfl_poll_msecs, 0644);
1741 1752
1742/* 1753/*
1743 * disk_{alloc|add|del|release}_events - initialize and destroy disk_events. 1754 * disk_{add|del|release}_events - initialize and destroy disk_events.
1744 */ 1755 */
1745static void disk_alloc_events(struct gendisk *disk) 1756static void disk_add_events(struct gendisk *disk)
1746{ 1757{
1747 struct disk_events *ev; 1758 struct disk_events *ev;
1748 1759
@@ -1755,6 +1766,16 @@ static void disk_alloc_events(struct gendisk *disk)
1755 return; 1766 return;
1756 } 1767 }
1757 1768
1769 if (sysfs_create_files(&disk_to_dev(disk)->kobj,
1770 disk_events_attrs) < 0) {
1771 pr_warn("%s: failed to create sysfs files for events\n",
1772 disk->disk_name);
1773 kfree(ev);
1774 return;
1775 }
1776
1777 disk->ev = ev;
1778
1758 INIT_LIST_HEAD(&ev->node); 1779 INIT_LIST_HEAD(&ev->node);
1759 ev->disk = disk; 1780 ev->disk = disk;
1760 spin_lock_init(&ev->lock); 1781 spin_lock_init(&ev->lock);
@@ -1763,21 +1784,8 @@ static void disk_alloc_events(struct gendisk *disk)
1763 ev->poll_msecs = -1; 1784 ev->poll_msecs = -1;
1764 INIT_DELAYED_WORK(&ev->dwork, disk_events_workfn); 1785 INIT_DELAYED_WORK(&ev->dwork, disk_events_workfn);
1765 1786
1766 disk->ev = ev;
1767}
1768
1769static void disk_add_events(struct gendisk *disk)
1770{
1771 if (!disk->ev)
1772 return;
1773
1774 /* FIXME: error handling */
1775 if (sysfs_create_files(&disk_to_dev(disk)->kobj, disk_events_attrs) < 0)
1776 pr_warn("%s: failed to create sysfs files for events\n",
1777 disk->disk_name);
1778
1779 mutex_lock(&disk_events_mutex); 1787 mutex_lock(&disk_events_mutex);
1780 list_add_tail(&disk->ev->node, &disk_events); 1788 list_add_tail(&ev->node, &disk_events);
1781 mutex_unlock(&disk_events_mutex); 1789 mutex_unlock(&disk_events_mutex);
1782 1790
1783 /* 1791 /*