Sindbad~EG File Manager
// Block I/O tapset
// Copyright (C) 2006 Intel Corp.
// Copyright (C) 2006 IBM Corp.
// Copyright (C) 2014-2017 Red Hat Inc.
//
// 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
// Public License (GPL); either version 2, or (at your option) any
// later version.
%{
#include <linux/bio.h>
#ifdef STAPCONF_GENHD_H
#include <linux/genhd.h>
#else
#include <linux/blkdev.h>
#endif
#ifdef STAPCONF_BLK_TYPES
#include <linux/blk_types.h>
#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 */
#if defined(STAPCONF_BIO_BI_OPF)
struct bio *bio = (struct bio *)(uintptr_t)STAP_ARG_bio;
STAP_RETVALUE = 0;
if (bio) {
/* Before calling bio_op() on bio, we need to make sure the
* memory is readable. */
(void)kread(&(bio->bi_opf));
STAP_RETVALUE = bio_op(bio);
}
#else
struct bio *bio = (struct bio *)(uintptr_t)STAP_ARG_bio;
STAP_RETVALUE = 0;
if (bio) {
STAP_RETVALUE = kread(&(bio->bi_rw));
}
#endif
CATCH_DEREF_FAULT();
%}
/* get i-node number of mapped file */
@__private30 function __bio_ino:long(bio:long)
%{ /* pure */
struct bio *bio = (struct bio *)(uintptr_t)STAP_ARG_bio;
struct page *bv_page = ((bio && kread(&(bio->bi_vcnt)))
? kread(&(bio->bi_io_vec[0].bv_page)) : NULL);
STAP_RETVALUE = -1;
if (bv_page) {
/* Before calling PageSlab() and PageSwapCache() on bv_page, we
* need to make sure the bv_page struct is valid. */
(void)kderef_buffer(NULL, bv_page, sizeof(struct page));
if (!PageSlab(bv_page) && !PageSwapCache(bv_page)) {
struct address_space *mapping = kread(&(bv_page->mapping));
if (mapping && ((unsigned long)mapping & PAGE_MAPPING_ANON) == 0) {
struct inode *host = kread(&(mapping->host));
if (host)
STAP_RETVALUE = kread(&(host->i_ino));
}
}
}
CATCH_DEREF_FAULT();
%}
/* returns 0 for read, 1 for write */
function bio_rw_num:long(rw:long)
{
return (rw & BIO_WRITE)
}
/* returns R for read, W for write */
function bio_rw_str(rw:long)
{
return bio_rw_num(rw) == BIO_READ ? "R" : "W"
}
/* returns start sector */
@__private30 function __bio_start_sect:long(bio:long)
{
try {
if (@defined(@cast(bio, "bio", "kernel")->bi_dev)) {
return @cast(bio, "bio", "kernel")->bi_bdev->bd_part->start_sect
}
else if (@defined(@cast(bio, "bio", "kernel")->bi_disk)) {
return disk_get_part_start_sect(@cast(bio, "bio", "kernel")->bi_disk,
@cast(bio, "bio", "kernel")->bi_partno)
}
} catch {
return -1
}
}
/* returns the block device name */
@__private30 function __bio_devname:string(bio:long)
{
if (@defined(@cast(bio, "bio", "kernel")->bi_bdev)) {
return bdevname(@cast(bio, "bio", "kernel")->bi_bdev)
}
else {
return disk_name(@cast(bio, "bio", "kernel")->bi_disk,
@cast(bio, "bio", "kernel")->bi_partno)
}
}
global BIO_READ = 0, BIO_WRITE = 1
/**
* probe ioblock.request - Fires whenever making a generic block I/O request.
* @name : name of the probe point
* @devname : block device name
* @ino : i-node number of the mapped file
* @sector : beginning sector for the entire bio
* @flags : see below
* BIO_UPTODATE 0 ok after I/O completion
* BIO_RW_BLOCK 1 RW_AHEAD set, and read/write would block
* BIO_EOF 2 out-out-bounds error
* BIO_SEG_VALID 3 nr_hw_seg valid
* BIO_CLONED 4 doesn't own data
* BIO_BOUNCED 5 bio is a bounce bio
* BIO_USER_MAPPED 6 contains user pages
* BIO_EOPNOTSUPP 7 not supported
* @rw : binary trace for read/write request
* @opf : operations and flags
* @vcnt : bio vector count which represents number of array element (page, offset, length) which make up this I/O request
* @idx : offset into the bio vector array
* @phys_segments : number of segments in this bio after physical address coalescing is performed
* @hw_segments : number of segments after physical and DMA remapping hardware coalescing is performed
* @size : total size in bytes
* @bdev : target block device
* @bdev_contains : points to the device object which contains the partition (when bio structure represents a partition)
* @p_start_sect : points to the start sector of the partition structure of the device
*
* Context:
* The process makes block I/O request
*/
probe ioblock.request = kernel.function ("submit_bio_noacct")!,
kernel.function ("generic_make_request")
{
name = "ioblock.request"
devname = __bio_devname($bio)
ino = __bio_ino($bio)
sector = @choose_defined($bio->bi_iter->bi_sector, $bio->bi_sector)
flags = $bio->bi_flags
if (@defined($bio->bi_opf)) {
rw = bio_op($bio)
opf = $bio->bi_opf
}
else {
rw = $bio->bi_rw
opf = $bio->bi_rw
}
vcnt = $bio->bi_vcnt
idx = @choose_defined($bio->bi_iter->bi_idx, $bio->bi_idx)
phys_segments = $bio->bi_phys_segments
hw_segments = @choose_defined($bio->bi_hw_segments, 0)
size = @choose_defined($bio->bi_iter->bi_size, $bio->bi_size)
bdev = @choose_defined($bio->bi_bdev, 0)
bdev_contains = @choose_defined($bio->bi_bdev->bd_contains, 0)
p_start_sect = __bio_start_sect($bio)
}
/**
* probe ioblock.end - Fires whenever a block I/O transfer is complete.
* @name : name of the probe point
* @devname : block device name
* @ino : i-node number of the mapped file
* @bytes_done : number of bytes transferred
* @sector : beginning sector for the entire bio
* @flags : see below
* BIO_UPTODATE 0 ok after I/O completion
* BIO_RW_BLOCK 1 RW_AHEAD set, and read/write would block
* BIO_EOF 2 out-out-bounds error
* BIO_SEG_VALID 3 nr_hw_seg valid
* BIO_CLONED 4 doesn't own data
* BIO_BOUNCED 5 bio is a bounce bio
* BIO_USER_MAPPED 6 contains user pages
* BIO_EOPNOTSUPP 7 not supported
* @error : 0 on success
* @rw : binary trace for read/write request
* @opf : operations and flags
* @vcnt : bio vector count which represents number of array element (page, offset, length) which makes up this I/O request
* @idx : offset into the bio vector array
* @phys_segments : number of segments in this bio after physical address coalescing is performed.
* @hw_segments : number of segments after physical and DMA remapping hardware coalescing is performed
* @size : total size in bytes
*
* Context:
* The process signals the transfer is done.
*/
probe ioblock.end = kernel.function("bio_endio")
{
name = "ioblock.end"
devname = __bio_devname($bio)
ino = __bio_ino($bio)
bytes_done = @choose_defined($bytes_done,
@choose_defined($bio->bi_iter->bi_size,
$bio->bi_size))
error = @choose_defined($error, @choose_defined($bio->bi_error,
$bio->bi_status))
sector = @choose_defined($bio->bi_iter->bi_sector, $bio->bi_sector)
flags = $bio->bi_flags
if (@defined($bio->bi_opf)) {
rw = bio_op($bio)
opf = $bio->bi_opf
}
else {
rw = $bio->bi_rw
opf = $bio->bi_rw
}
vcnt = $bio->bi_vcnt
idx = @choose_defined($bio->bi_iter->bi_idx, $bio->bi_idx)
phys_segments = $bio->bi_phys_segments
hw_segments = @choose_defined($bio->bi_hw_segments, 0)
size = @choose_defined($bio->bi_iter->bi_size, $bio->bi_size)
}
/**
* probe ioblock_trace.bounce - Fires whenever a buffer bounce is needed for at least one page of a block IO request.
* @name : name of the probe point
* @q : request queue on which this bio was queued.
* @devname : device for which a buffer bounce was needed.
* @ino : i-node number of the mapped file
* @bytes_done : number of bytes transferred
* @sector : beginning sector for the entire bio
* @flags : see below
* BIO_UPTODATE 0 ok after I/O completion
* BIO_RW_BLOCK 1 RW_AHEAD set, and read/write would block
* BIO_EOF 2 out-out-bounds error
* BIO_SEG_VALID 3 nr_hw_seg valid
* BIO_CLONED 4 doesn't own data
* BIO_BOUNCED 5 bio is a bounce bio
* BIO_USER_MAPPED 6 contains user pages
* BIO_EOPNOTSUPP 7 not supported
* @rw : binary trace for read/write request
* @opf : operations and flags
* @vcnt : bio vector count which represents number of array element (page, offset, length) which makes up this I/O request
* @idx : offset into the bio vector array
* @phys_segments - number of segments in this bio after physical address coalescing is performed.
* @size : total size in bytes
* @bdev : target block device
* @bdev_contains : points to the device object which contains the partition (when bio structure represents a partition)
* @p_start_sect : points to the start sector of the partition structure of the device
*
* Context :
* The process creating a block IO request.
*/
probe ioblock_trace.bounce = kernel.trace("block_bio_bounce")
{
name = "ioblock_trace.bounce"
q = $q
devname = __bio_devname($bio)
ino = __bio_ino($bio)
bytes_done = @choose_defined($bio->bi_iter->bi_size, $bio->bi_size)
sector = @choose_defined($bio->bi_iter->bi_sector, $bio->bi_sector)
flags = $bio->bi_flags
if (@defined($bio->bi_opf)) {
rw = bio_op($bio)
opf = $bio->bi_opf
}
else {
rw = $bio->bi_rw
opf = $bio->bi_rw
}
vcnt = $bio->bi_vcnt
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 = @choose_defined($bio->bi_bdev->bd_contains, 0)
bdev = @choose_defined($bio->bi_bdev, 0)
p_start_sect = __bio_start_sect($bio)
}
/**
* probe ioblock_trace.request - Fires just as a generic block I/O request is created for a bio.
* @name : name of the probe point
* @q : request queue on which this bio was queued.
* @devname : block device name
* @ino : i-node number of the mapped file
* @bytes_done : number of bytes transferred
* @sector : beginning sector for the entire bio
* @flags : see below
* BIO_UPTODATE 0 ok after I/O completion
* BIO_RW_BLOCK 1 RW_AHEAD set, and read/write would block
* BIO_EOF 2 out-out-bounds error
* BIO_SEG_VALID 3 nr_hw_seg valid
* BIO_CLONED 4 doesn't own data
* BIO_BOUNCED 5 bio is a bounce bio
* BIO_USER_MAPPED 6 contains user pages
* BIO_EOPNOTSUPP 7 not supported
* @rw : binary trace for read/write request
* @opf : operations and flags
* @vcnt : bio vector count which represents number of array element (page, offset, length) which make up this I/O request
* @idx : offset into the bio vector array
* @phys_segments - number of segments in this bio after physical address coalescing is performed.
* @size : total size in bytes
* @bdev : target block device
* @bdev_contains : points to the device object which contains the partition (when bio structure represents a partition)
* @p_start_sect : points to the start sector of the partition structure of the device
*
* Context:
* The process makes block I/O request
*/
probe ioblock_trace.request = kernel.trace("block_bio_queue")
{
name = "ioblock_trace.request"
q = $q
devname = __bio_devname($bio)
ino = __bio_ino($bio)
bytes_done = @choose_defined($bio->bi_iter->bi_size, $bio->bi_size)
sector = @choose_defined($bio->bi_iter->bi_sector, $bio->bi_sector)
flags = $bio->bi_flags
if (@defined($bio->bi_opf)) {
rw = bio_op($bio)
opf = $bio->bi_opf
}
else {
rw = $bio->bi_rw
opf = $bio->bi_rw
}
vcnt = $bio->bi_vcnt
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 = @choose_defined($bio->bi_bdev->bd_contains, 0)
bdev = @choose_defined($bio->bi_bdev, 0)
p_start_sect = __bio_start_sect($bio)
}
/**
* probe ioblock_trace.end - Fires whenever a block I/O transfer is complete.
* @name : name of the probe point
* @q : request queue on which this bio was queued.
* @devname : block device name
* @ino : i-node number of the mapped file
* @bytes_done : number of bytes transferred
* @sector : beginning sector for the entire bio
* @flags : see below
* BIO_UPTODATE 0 ok after I/O completion
* BIO_RW_BLOCK 1 RW_AHEAD set, and read/write would block
* BIO_EOF 2 out-out-bounds error
* BIO_SEG_VALID 3 nr_hw_seg valid
* BIO_CLONED 4 doesn't own data
* BIO_BOUNCED 5 bio is a bounce bio
* BIO_USER_MAPPED 6 contains user pages
* BIO_EOPNOTSUPP 7 not supported
* @rw : binary trace for read/write request
* @opf : operations and flags
* @vcnt : bio vector count which represents number of array element (page, offset, length) which makes up this I/O request
* @idx : offset into the bio vector array
* @phys_segments - number of segments in this bio after physical address coalescing is performed.
* @size : total size in bytes
* @bdev : target block device
* @bdev_contains : points to the device object which contains the partition (when bio structure represents a partition)
* @p_start_sect : points to the start sector of the partition structure of the device
*
* Context:
* The process signals the transfer is done.
*/
probe ioblock_trace.end = kernel.trace("block_bio_complete")
{
name = "ioblock_trace.end"
q = $q
devname = __bio_devname($bio)
ino = __bio_ino($bio)
bytes_done = @choose_defined($bio->bi_iter->bi_size, $bio->bi_size)
sector = @choose_defined($bio->bi_iter->bi_sector, $bio->bi_sector)
flags = $bio->bi_flags
if (@defined($bio->bi_opf)) {
rw = bio_op($bio)
opf = $bio->bi_opf
}
else {
rw = $bio->bi_rw
opf = $bio->bi_rw
}
vcnt = $bio->bi_vcnt
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 = @choose_defined($bio->bi_bdev->bd_contains, 0)
bdev = @choose_defined($bio->bi_bdev, 0)
p_start_sect = __bio_start_sect($bio)
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists