Pages - Menu

Wednesday, November 13, 2013

how does mke2fs decide automatic check mount count?

Whenever you create an ext3 or ext4 filesystem with mkfs or mke2fs, a message is printed saying "This filesystem will be automatically checked every X mounts or Y days, whichever comes first".

However, the number seems to vary depending on the filesystem. How is this value calculated? I used the source of e2fsprogs-1.42.8 and the cscope source code tool to find this out.

Searching for the origin of the message, we can search for a short part of the string like "mounts or", and we see it's printed by this function in misc/util.c:

void print_check_message(int mnt, unsigned int check)
{
    if (mnt < 0)
        mnt = 0;
    if (!mnt && !check)
        return;
    printf(_("This filesystem will be automatically "
         "checked every %d mounts or\n"
         "%g days, whichever comes first.  "
         "Use tune2fs -c or -i to override.\n"),
           mnt, ((double) check) / (3600 * 24));
}

Which is called here in misc/tune2fs.c:

/*
 * Add a journal to the filesystem.
 */
static int add_journal(ext2_filsys fs)
{
    print_check_message(fs->super->s_max_mnt_count,
                fs->super->s_checkinterval);

So now we need to find what puts the value into s_max_mnt_count. Hunting for uses of that symbol, we see an equals sign here in misc/mke2fs.c:

    if (get_bool_from_profile(fs_types, "enable_periodic_fsck", 0)) {
        fs->super->s_checkinterval = EXT2_DFL_CHECKINTERVAL;
        fs->super->s_max_mnt_count = EXT2_DFL_MAX_MNT_COUNT;
        /*
         * Add "jitter" to the superblock's check interval so that we
         * don't check all the filesystems at the same time.  We use a
         * kludgy hack of using the UUID to derive a random jitter value
         */
        for (i = 0, val = 0 ; i < sizeof(fs->super->s_uuid); i++)
            val += fs->super->s_uuid[i];
        fs->super->s_max_mnt_count += val % EXT2_DFL_MAX_MNT_COUNT;

And we can see the MAX_MNT_COUNT is just a precompiler macro, defined in lib/ext2fs/ext2_fs.h:

 * Maximal mount counts between two filesystem checks
 */
#define EXT2_DFL_MAX_MNT_COUNT      20  /* Allow 20 mounts */

So we take 20, add up all the ASCII characters of the UUID and modulo that by 20, then add it to the original 20. It's just maths from here. 20+(x%20) gives an effective range of 20 to 39 days.

We can also tell from the comment in mke2fs.c as to the reason behind this randomness.

No comments: