STAP_RETVALUE = new_decode_dev(STAP_ARG_dev);
%}
+function disk_name:string(hd:long, partno:long)
+{
+ if (!partno)
+ return kernel_string(@cast(hd, "gendisk")->disk_name)
+ disk_name = kernel_string(@cast(hd, "gendisk")->disk_name)
+ if (isdigit(substr(disk_name, strlen(disk_name)-1, 1)))
+ return sprintf("%sp%d", disk_name, partno)
+ else
+ return sprintf("%s%d", disk_name, partno)
+}
+
function bdevname:string(bdev:long)
{
bdev = & @cast(bdev, "block_device")
partno = bdev->bd_part->partno
else
partno = MINOR(bdev->bd_dev) - hd->first_minor;
-
- if (!partno)
- return kernel_string(hd->disk_name)
- disk_name = kernel_string(hd->disk_name)
- if (isdigit(substr(disk_name, strlen(disk_name) - 1, 1)))
- return sprintf("%sp%d", disk_name, partno)
- else
- return sprintf("%s%d", disk_name, partno)
+ return disk_name(hd, partno)
}
#endif
%}
+private function disk_get_part_start_sect:long(disk:long, partno:long)
+%{ /* pure */ /* unprivileged */
+#if defined(STAPCONF_DISK_GET_PART)
+ struct gendisk *disk = (struct gendisk *)(uintptr_t)STAP_ARG_disk;
+ int partno = (int)STAP_ARG_partno;
+ struct hd_struct *part;
+
+ STAP_RETVALUE = 0;
+ if (disk) {
+ /* Before calling disk_get_part() on 'disk', we need to make
+ * sure the memory is readable. */
+ (void)kread(&(disk->part_tbl));
+ part = disk_get_part(disk, partno);
+
+ if (part) {
+ /* Let's be doubly paranoid and make sure this memory is
+ * safe for reading. */
+ (void)kread(&(part->start_sect));
+ STAP_RETVALUE = part->start_sect;
+ disk_put_part(part);
+ }
+ }
+ CATCH_DEREF_FAULT();
+#endif
+%}
+
/* Returns the REQ_OP_* bits for a bio structure. */
function bio_op:long(bio:long)
%{ /* pure */ /* unprivileged */
@__private30 function __bio_start_sect:long(bio:long)
{
try {
- return @cast(bio, "bio")->bi_bdev->bd_part->start_sect
+ if (@defined(@cast(bio, "bio")->bi_dev)) {
+ return @cast(bio, "bio")->bi_bdev->bd_part->start_sect
+ }
+ else if (@defined(@cast(bio, "bio")->bi_disk)) {
+ return disk_get_part_start_sect(@cast(bio, "bio")->bi_disk,
+ @cast(bio, "bio")->bi_partno)
+ }
} catch {
return -1
}
/* returns the block device name */
@__private30 function __bio_devname:string(bio:long)
{
- return bdevname(@cast(bio, "bio")->bi_bdev)
+ if (@defined(@cast(bio, "bio")->bi_bdev)) {
+ return bdevname(@cast(bio, "bio")->bi_bdev)
+ }
+ else {
+ return disk_name(@cast(bio, "bio")->bi_disk,
+ @cast(bio, "bio")->bi_partno)
+ }
}
global BIO_READ = 0, BIO_WRITE = 1
hw_segments = @choose_defined($bio->bi_hw_segments, 0)
size = @choose_defined($bio->bi_iter->bi_size, $bio->bi_size)
- bdev = $bio->bi_bdev
- bdev_contains = $bio->bi_bdev->bd_contains
+ bdev = @choose_defined($bio->bi_bdev, 0)
+ bdev_contains = @choose_defined($bio->bi_bdev->bd_contains, 0)
p_start_sect = __bio_start_sect($bio)
}
idx = @choose_defined($bio->bi_iter->bi_idx, $bio->bi_idx)
phys_segments = $bio->bi_phys_segments
size = @choose_defined($bio->bi_iter->bi_size, $bio->bi_size)
- bdev_contains = $bio->bi_bdev->bd_contains
- bdev = $bio->bi_bdev
+ bdev_contains = @choose_defined($bio->bi_bdev->bd_contains, 0)
+ bdev = @choose_defined($bio->bi_bdev, 0)
p_start_sect = __bio_start_sect($bio)
}
idx = @choose_defined($bio->bi_iter->bi_idx, $bio->bi_idx)
phys_segments = $bio->bi_phys_segments
size = @choose_defined($bio->bi_iter->bi_size, $bio->bi_size)
- bdev_contains = $bio->bi_bdev->bd_contains
- bdev = $bio->bi_bdev
+ bdev_contains = @choose_defined($bio->bi_bdev->bd_contains, 0)
+ bdev = @choose_defined($bio->bi_bdev, 0)
p_start_sect = __bio_start_sect($bio)
}
idx = @choose_defined($bio->bi_iter->bi_idx, $bio->bi_idx)
phys_segments = $bio->bi_phys_segments
size = @choose_defined($bio->bi_iter->bi_size, $bio->bi_size)
- bdev_contains = $bio->bi_bdev->bd_contains
- bdev = $bio->bi_bdev
+ bdev_contains = @choose_defined($bio->bi_bdev->bd_contains, 0)
+ bdev = @choose_defined($bio->bi_bdev, 0)
p_start_sect = __bio_start_sect($bio)
}