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