Source code for crash.subsystem.filesystem.decoders
# -*- coding: utf-8 -*-
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
from typing import Any
from crash.util.symbols import Types
from crash.subsystem.storage import block_device_name
from crash.subsystem.storage.decoders import Decoder, decode_bh
from crash.subsystem.filesystem import super_fstype
import gdb
[docs]class DIOBioDecoder(Decoder):
"""
Decodes a bio used for direct i/o.
This method decodes a bio generated by the direct-io component of
the file system subsystem. The bio can either have been submitted
directly or asynchronously.
Args:
bio: The struct bio to be decoded, generated by the direct i/o
component. The value must be of type ``struct bio``.
Attributes:
bio (:obj:`gdb.Value`): The bio. The value is of type
``struct bio``.
dio (:obj:`gdb.Value`): ``struct dio *`` that represents the
direct i/o operation
fstype (str): the name of the file system type
dev (str): the name of the underlying device
offset (str): the starting offset on disk
"""
_types = Types(['struct dio *'])
__endio__ = ['dio_bio_end_io', 'dio_bio_end_io']
_description = "{:x} bio: Direct I/O for {} inode {}, sector {} on {}"
def __init__(self, bio: gdb.Value) -> None:
super().__init__()
self.bio = bio
[docs] def interpret(self) -> None:
"""Interprets a direct i/o bio to populate its attributes"""
# pylint: disable=attribute-defined-outside-init
self.dio = self.bio['bi_private'].cast(self._types.dio_p_type)
self.fstype = super_fstype(self.dio['inode']['i_sb'])
self.dev = block_device_name(self.dio['inode']['i_sb']['s_bdev'])
self.offset = self.dio['block_in_file'] << self.dio['blkbits']
def __str__(self) -> str:
return self._description.format(int(self.bio), self.fstype,
self.dio['inode']['i_ino'],
self.bio['bi_sector'], self.dev)
def __next__(self) -> Any:
return None
DIOBioDecoder.register()
[docs]class DecodeMPage(Decoder):
"""
Decodes a bio used for multipage i/o.
This method decodes a bio generated by the mpage component of
the file system subsystem.
Args:
bio: The struct bio to be decoded, generated by the mpage component.
The value must be of type ``struct bio``.
Attributes:
bio (:obj:`gdb.Value`): The bio. The value is of type
``struct bio``.
inode (:obj:`gdb.Value`): The inode associated with this bio. The
value is of type ``struct inode``.
fstype (str): the name of the file system type
"""
__endio__ = 'mpage_end_io'
description = "{:x} bio: Multipage I/O: inode {}, type {}, dev {}"
def __init__(self, bio: gdb.Value) -> None:
super().__init__()
self.bio = bio
[docs] def interpret(self) -> None:
"""Interpret the multipage bio to populate its attributes"""
# pylint: disable=attribute-defined-outside-init
self.inode = self.bio['bi_io_vec'][0]['bv_page']['mapping']['host']
self.fstype = super_fstype(self.inode['i_sb'])
def __str__(self) -> str:
return self.description.format(int(self.bio), self.inode['i_ino'],
self.fstype,
block_device_name(self.bio['bi_bdev']))
DecodeMPage.register()
[docs]class DecodeBioBH(Decoder):
"""
Decodes a bio used to perform i/o for buffer_heads
This method decodes a bio generated by buffer head submission.
Args:
bio: The struct bio to be decoded, generated by buffer head
submission. The value must be of type ``struct bio``.
Attributes:
bio (:obj:`gdb.Value`): The bio. The value is of type
``struct bio``.
bh (:obj:`gdb.Value`): The struct buffer_head associated with this
bio. The value is of type ``struct buffer_head``.
"""
_types = Types(['struct buffer_head *'])
__endio__ = 'end_bio_bh_io_sync'
_description = "{:x} bio: Bio representation of buffer head"
def __init__(self, bio: gdb.Value) -> None:
super().__init__()
self.bio = bio
[docs] def interpret(self) -> None:
"""Interpret the buffer_head bio to populate its attributes"""
# pylint: disable=attribute-defined-outside-init
self.bh = self.bio['bi_private'].cast(self._types.buffer_head_p_type)
def __str__(self) -> str:
return self._description.format(int(self.bio))
def __next__(self) -> Any:
return decode_bh(self.bh)
DecodeBioBH.register()
[docs]class DecodeSyncWBBH(Decoder):
"""
Decodes a struct buffer_head submitted by file systems for routine
synchronous writeback.
Args:
bio: The ``struct buffer_head`` to be decoded. The value must be of
``struct buffer_head``.
Attributes:
bh (:obj:`gdb.Value`): The ``struct buffer_head`` being decoded.
The value is of type ``struct buffer_head``.
"""
__endio__ = 'end_buffer_write_sync'
_description = "{:x} buffer_head: for dev {}, block {}, size {} (unassociated)"
def __init__(self, bh: gdb.Value) -> None:
super().__init__()
self.bh = bh
def __str__(self) -> str:
return self._description.format(block_device_name(self.bh['b_bdev']),
self.bh['b_blocknr'], self.bh['b_size'])
DecodeSyncWBBH.register()