Почему в виртуальной файловой системе Linux размер s_blocksize_bits на один бит меньше обычного двоичного файла?

#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.