248 lines · 10.1 KB · Text
RawDownload
==============Data Integrity============== 1. Introduction=============== Modern filesystems feature checksumming of data and metadata toprotect against data corruption.  However, the detection of thecorruption is done at read time which could potentially be monthsafter the data was written.  At that point the original data that theapplication tried to write is most likely lost. The solution is to ensure that the disk is actually storing what theapplication meant it to.  Recent additions to both the SCSI familyprotocols (SBC Data Integrity Field, SCC protection proposal) as wellas SATA/T13 (External Path Protection) try to remedy this by addingsupport for appending integrity metadata to an I/O.  The integritymetadata (or protection information in SCSI terminology) includes achecksum for each sector as well as an incrementing counter thatensures the individual sectors are written in the right order.  Andfor some protection schemes also that the I/O is written to the rightplace on disk. Current storage controllers and devices implement various protectivemeasures, for instance checksumming and scrubbing.  But thesetechnologies are working in their own isolated domains or at bestbetween adjacent nodes in the I/O path.  The interesting thing aboutDIF and the other integrity extensions is that the protection formatis well defined and every node in the I/O path can verify theintegrity of the I/O and reject it if corruption is detected.  Thisallows not only corruption prevention but also isolation of the pointof failure. 2. The Data Integrity Extensions================================ As written, the protocol extensions only protect the path betweencontroller and storage device.  However, many controllers actuallyallow the operating system to interact with the integrity metadata(IMD).  We have been working with several FC/SAS HBA vendors to enablethe protection information to be transferred to and from theircontrollers. The SCSI Data Integrity Field works by appending 8 bytes of protectioninformation to each sector.  The data + integrity metadata is storedin 520 byte sectors on disk.  Data + IMD are interleaved whentransferred between the controller and target.  The T13 proposal issimilar. Because it is highly inconvenient for operating systems to deal with520 (and 4104) byte sectors, we approached several HBA vendors andencouraged them to allow separation of the data and integrity metadatascatter-gather lists. The controller will interleave the buffers on write and split them onread.  This means that Linux can DMA the data buffers to and fromhost memory without changes to the page cache. Also, the 16-bit CRC checksum mandated by both the SCSI and SATA specsis somewhat heavy to compute in software.  Benchmarks found thatcalculating this checksum had a significant impact on systemperformance for a number of workloads.  Some controllers allow alighter-weight checksum to be used when interfacing with the operatingsystem.  Emulex, for instance, supports the TCP/IP checksum instead.The IP checksum received from the OS is converted to the 16-bit CRCwhen writing and vice versa.  This allows the integrity metadata to begenerated by Linux or the application at very low cost (comparable tosoftware RAID5). The IP checksum is weaker than the CRC in terms of detecting biterrors.  However, the strength is really in the separation of the databuffers and the integrity metadata.  These two distinct buffers mustmatch up for an I/O to complete. The separation of the data and integrity metadata buffers as well asthe choice in checksums is referred to as the Data IntegrityExtensions.  As these extensions are outside the scope of the protocolbodies (T10, T13), Oracle and its partners are trying to standardizethem within the Storage Networking Industry Association. 3. Kernel Changes================= The data integrity framework in Linux enables protection informationto be pinned to I/Os and sent to/received from controllers thatsupport it. The advantage to the integrity extensions in SCSI and SATA is thatthey enable us to protect the entire path from application to storagedevice.  However, at the same time this is also the biggestdisadvantage. It means that the protection information must be in aformat that can be understood by the disk. Generally Linux/POSIX applications are agnostic to the intricacies ofthe storage devices they are accessing.  The virtual filesystem switchand the block layer make things like hardware sector size andtransport protocols completely transparent to the application. However, this level of detail is required when preparing theprotection information to send to a disk.  Consequently, the veryconcept of an end-to-end protection scheme is a layering violation.It is completely unreasonable for an application to be aware whetherit is accessing a SCSI or SATA disk. The data integrity support implemented in Linux attempts to hide thisfrom the application.  As far as the application (and to some extentthe kernel) is concerned, the integrity metadata is opaque informationthat's attached to the I/O. The current implementation allows the block layer to automaticallygenerate the protection information for any I/O.  Eventually theintent is to move the integrity metadata calculation to userspace foruser data.  Metadata and other I/O that originates within the kernelwill still use the automatic generation interface. Some storage devices allow each hardware sector to be tagged with a16-bit value.  The owner of this tag space is the owner of the blockdevice.  I.e. the filesystem in most cases.  The filesystem can usethis extra space to tag sectors as they see fit.  Because the tagspace is limited, the block interface allows tagging bigger chunks byway of interleaving.  This way, 8*16 bits of information can beattached to a typical 4KB filesystem block. This also means that applications such as fsck and mkfs will needaccess to manipulate the tags from user space.  A passthroughinterface for this is being worked on.  4. Block Layer Implementation Details===================================== 4.1 Bio------- The data integrity patches add a new field to struct bio whenCONFIG_BLK_DEV_INTEGRITY is enabled.  bio_integrity(bio) returns apointer to a struct bip which contains the bio integrity payload.Essentially a bip is a trimmed down struct bio which holds a bio_veccontaining the integrity metadata and the required housekeepinginformation (bvec pool, vector count, etc.) A kernel subsystem can enable data integrity protection on a bio bycalling bio_integrity_alloc(bio).  This will allocate and attach thebip to the bio. Individual pages containing integrity metadata can subsequently beattached using bio_integrity_add_page(). bio_free() will automatically free the bip.  4.2 Block Device---------------- Block devices can set up the integrity information in the integritysub-structure of the queue_limits structure. Layered block devices will need to pick a profile that's appropriatefor all subdevices.  queue_limits_stack_integrity() can help with that.  DMand MD linear, RAID0 and RAID1 are currently supported.  RAID4/5/6will require extra work due to the application tag.  5.0 Block Layer Integrity API============================= 5.1 Normal Filesystem---------------------     The normal filesystem is unaware that the underlying block device    is capable of sending/receiving integrity metadata.  The IMD will    be automatically generated by the block layer at submit_bio() time    in case of a WRITE.  A READ request will cause the I/O integrity    to be verified upon completion.     IMD generation and verification can be toggled using the::       /sys/block/<bdev>/integrity/write_generate     and::       /sys/block/<bdev>/integrity/read_verify     flags.  5.2 Integrity-Aware Filesystem------------------------------     A filesystem that is integrity-aware can prepare I/Os with IMD    attached.  It can also use the application tag space if this is    supported by the block device.      `bool bio_integrity_prep(bio);`       To generate IMD for WRITE and to set up buffers for READ, the      filesystem must call bio_integrity_prep(bio).       Prior to calling this function, the bio data direction and start      sector must be set, and the bio should have all data pages      added.  It is up to the caller to ensure that the bio does not      change while I/O is in progress.      Complete bio with error if prepare failed for some reason.  5.3 Passing Existing Integrity Metadata---------------------------------------     Filesystems that either generate their own integrity metadata or    are capable of transferring IMD from user space can use the    following calls:      `struct bip * bio_integrity_alloc(bio, gfp_mask, nr_pages);`       Allocates the bio integrity payload and hangs it off of the bio.      nr_pages indicate how many pages of protection data need to be      stored in the integrity bio_vec list (similar to bio_alloc()).       The integrity payload will be freed at bio_free() time.      `int bio_integrity_add_page(bio, page, len, offset);`       Attaches a page containing integrity metadata to an existing      bio.  The bio must have an existing bip,      i.e. bio_integrity_alloc() must have been called.  For a WRITE,      the integrity metadata in the pages must be in a format      understood by the target device with the notable exception that      the sector numbers will be remapped as the request traverses the      I/O stack.  This implies that the pages added using this call      will be modified during I/O!  The first reference tag in the      integrity metadata must have a value of bip->bip_sector.       Pages can be added using bio_integrity_add_page() as long as      there is room in the bip bio_vec array (nr_pages).       Upon completion of a READ operation, the attached pages will      contain the integrity metadata received from the storage device.      It is up to the receiver to process them and verify data      integrity upon completion.  ---------------------------------------------------------------------- 2007-12-24 Martin K. Petersen <martin.petersen@oracle.com>