* tapset/dev.stp: Added a bdevname() script function.
* tapset/ioblock.stp: Rewrote the embedded-C devname function to just use
bdevname() script function.
* tapset/vfs.stp: Removed embedded-C __bdevname() C function. Calls
bdevname() script function instead.
* tapset/string.stp: Added isdigit() function.
-// Device numbering tapset
-// Copyright (C) 2008 Red Hat Corp.
+// Device tapset
+// Copyright (C) 2008, 2010 Red Hat Corp.
//
// This file is part of systemtap, and is free software. You can
// redistribute it and/or modify it under the terms of the GNU General
%{ /* pure */
THIS->__retvalue = new_decode_dev(THIS->dev);
%}
+
+function bdevname:string(bdev:long)
+{
+ if (bdev == 0)
+ return "N/A"
+
+ hd = @cast(bdev, "block_device")->bd_disk
+
+ if (@cast(bdev, "block_device")->bd_part)
+ partno = @cast(bdev, "block_device")->bd_part->partno
+ else
+ partno = MINOR(@cast(bdev, "block_device")->bd_dev)
+ - @cast(bdev, "block_device")->bd_disk->first_minor;
+
+ 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)
+}
/* returns the block device name */
function __bio_devname:string(bio:long)
-%{ /* pure */
- char b[BDEVNAME_SIZE];
- struct bio *bio = (struct bio *)(long)THIS->bio;
- struct block_device *bdev = kread(&(bio->bi_bdev));
- if (bdev == NULL) {
- strlcpy(THIS->__retvalue, "N/A", MAXSTRINGLEN);
- } else {
- const char *name = bdevname(bdev, b); /* FIXME: deref hazard! */
- deref_string(THIS->__retvalue, name, MAXSTRINGLEN);
- }
- CATCH_DEREF_FAULT();
-%}
+{
+ return bdevname(@cast(bio, "bio")->bi_bdev)
+}
global BIO_READ = 0, BIO_WRITE = 1
%{ /* pure */ /* unprivileged */
THIS->__retvalue = simple_strtol(THIS->str, NULL, THIS->base);
%}
+
+/**
+ * sfunction isdigit - Checks for a digit.
+ * @str: String to check.
+ *
+ * Description: Checks for a digit (0 through 9) as the first
+ * character of a string. Returns non-zero if true, and a zero if
+ * false.
+ */
+function isdigit:long(str:string)
+%{ /* pure */ /* unprivileged */
+ THIS->__retvalue = isdigit(THIS->str[0]);
+%}
+
/* generic vfs probes */
-/* helper functions */
-function __bdevname:string (bdev:long) %{ /* pure */
- char b[BDEVNAME_SIZE];
- struct block_device *bdev = (struct block_device *)(long)THIS->bdev;
- if (bdev == NULL) {
- strlcpy(THIS->__retvalue, "N/A", MAXSTRINGLEN);
- } else {
- const char *name = bdevname(bdev, b); /* FIXME: deref hazard! */
- deref_string(THIS->__retvalue, name, MAXSTRINGLEN);
- }
-
- CATCH_DEREF_FAULT();
-%}
-
/*
We don't want to have to do a bdevname() call every time
we want a devname, so we'll hash them here.
if (dev in __devnames)
return __devnames[dev]
else
- return __devnames[dev] = __bdevname(bdev)
+ return __devnames[dev] = bdevname(bdev)
}
function ppos_pos:long (ppos:long) %{ /* pure */