#linux-kernel #vfs #superblock
#linux-ядро #vfs #суперблок
Вопрос:
Часть определения структуры структуры super_block представлена ниже:
struct super_block {
//...
dev_t s_dev; /* identifier */
unsigned char s_blocksize_bits; /* block size in bits */
unsigned long s_blocksize; /* block size in bytes */
unsigned char s_dirt; /* dirty flag */
loff_t s_maxbytes; /* max file size */
struct file_system_type *s_type; /* filesystem type */
struct super_operations *s_op; /* superblock methods */
//...
unsigned long s_flags; /* mount flags */
unsigned long s_magic; /* filesystem’s magic number */
struct dentry *s_root; /* directory mount point */
//...
char s_id[32]; /* informational name */
void *s_fs_info; /* filesystem private info */
};
Я немного запутался в s_blocksize_bits
поле. Например, если я установил s_blocksize=512
, правильный способ записи — установить s_blocksize_bits=9
. Но двоичное представление 512 равно 1000000000, это означает, что для его хранения требуется 10 бит. Почему ядру Linux требуется на один бит меньше.
Здесь я прилагаю исходный код шестнадцатеричного преобразования в ядре Linux:
/* assumes size > 256 */
static inline unsigned int blksize_bits(unsigned int size)
{
unsigned int bits = 8;
do {
bits ;
size >>= 1;
} while (size > 256);
return bits;
}
Комментарии:
1. Предположительно, поэтому обратное преобразование просто
s_blocksize = 1 << s_blocksize_bits
. Другими словами, это количество нулевых битов, которые следуют за 1 битом.2. Это потому, что размер суперблока должен быть равен степени 2, первый бит должен быть равен 1, а остальные равны 0. Поэтому, чтобы сэкономить место, ядро Linux хранит только число 0.