How SCSI devices tell you their logical and physical block sizes

April 18, 2013

Since I spent today looking this up and working it all out, I might as well write all of this down.

Old SCSI had no distinction between logical and physical size; it just had the block size. Modern SCSI has redefined those old plain block sizes to be the logical block size and then added an odd way of encoding the physical block size. This information is reported through the SCSI operation READ CAPACITY (16), which unlike its stunted older brother READ CAPACITY (10) is not actually a SCSI command; instead it's a sub-option of a general SERVICE ACTION IN command. This may assist you in finding it in code and/or documentation.

(SERVICE ACTION IN is SCSI opcode 0x9E and READ CAPACITY (16) is sub-action 0x10. Nice code will have some #defines or the like for these; other code, well, may not. See the discussion of finding SCSI opcodes and so on in this entry.)

The logical block size is returned as a big endian byte count in response bytes 8 through 11 (counting from 0; 0 through 7 are the device's size in logical blocks, again big endian). The size of physical blocks is reported by giving the 'logical blocks per physical block exponent' in the low order four bits of byte 13. If it is set to some non-zero value N, there are 2^N logical blocks per physical block; for 4k sector disks with 512 byte logical blocks the magic exponent is thus 3.

There is no guarantee that code that uses READ CAPACITY (16) either sets or reads this exponent. My impression is that RC (16) and its use in code predates at least the need to think about the difference and perhaps the actual definition of the field (as opposed to just marking it 'reserved').

Note that some code may talk about or #define 'READ CAPACITY' when it means READ CAPACITY (10). You should ignore this code because no one wants to use RC (10) any more. If there's code that is carefully handling a device capacity case of '0xffffffff', you're reading the wrong code. Yes, this can be confusing.

(One of the problems with READ CAPACITY (10) is that the (logical block) size of the device is limited to a 32-bit field. With 512 byte blocks this translates to a disk size of about 2 Tb. It follows that if some old system can't deal with 2 Tb SCSI disks, it's extremely likely that it probably also has no idea of physical block size versus logical block size.)

I'm developing opinions on how storage systems should handle all of this, but that's going to have to wait for another entry.

Comments on this page:

By Felipe Gutierrez at 2014-11-11 08:26:08:

Hi Chris Siebenmann, first of all, thanks for your post. I was struggling to find what was the error When I tryied to open a 16TB on my microsoft iSCSI initiator connected to the iSCSI target in Java.

I could open it in Linux, but when I move to open at Windows I got the problem with READ_CAPACITY_16. Debuging it shows: READ_CAPACITY_16: java.nio.HeapByteBuffer@44624e03[hb={-98,16,0,0,0,0,0,0,0,0,0,0,0,12,0,0},offset=0,isReadOnly=false,bigEndian=true, nativeByteOrder=false,mark=-1,position=0,limit=16,capacity=16,address=0]

Debuging at Linux show: READ_CAPACITY_16: java.nio.HeapByteBuffer@25646694[hb={-98,16,0,0,0,0,0,0,0,0,0,0,0,32,0,0},offset=0,isReadOnly=false,bigEndian=true, nativeByteOrder=false,mark=-1,position=0,limit=16,capacity=16,address=0]

So it is because the microsoft iSCSI initiator is sending a wrong message? What could I do to solve this problem?

Thanks for any help! Felipe

By cks at 2014-11-11 18:41:57:

I'm afraid that I have no idea what your problem is. However, I would suggest that the best method of interpreting iSCSI protocol messages is at the raw network packet level, using something like Wireshark that can decode and understand them. Unless you know exactly what your software is showing you in its debugging messages, this is likely to be more reliable.

(If you do know exactly what your software is showing you in debug messages, well, now you get to read the SCSI specifications and decode things to see what the difference is. Note that you probably want to look at the request as well as the reply.)

Written on 18 April 2013.
« Some thoughts on going to HTTPS by default
How I want storage systems to handle disk block sizes »

Page tools: View Source, View Normal, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Thu Apr 18 00:25:44 2013
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.