Why in Linux Virtual File System, the s_blocksize_bits is one bit less than ordinary binary?

201 Views Asked by At

Part of the struct super_block structure definition is presented below:

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 */
};

I am a little confused in s_blocksize_bits field. For example, if I set s_blocksize=512, the correct way of writing is to set s_blocksize_bits=9. But the binary representation of 512 is 1000000000, this means it needs 10 bits to store it. Why the Linux kernel requires one bit less.

Here I am attaching the source code of hexadecimal conversion in the Linux kernel:

/* 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;
}
0

There are 0 best solutions below