Bug in kernel code?

From: Stephen C. Biggs (s.biggs@softier.com)
Date: Tue Aug 27 2002 - 19:25:17 EST


I posted this to the newsgroup news:linux-kernel but got no response...
I'll try here.

While going thru the kernel code for 2.4.17 (uClinux patch) I noticed a
problem with functions in 3 files:
dcache_init in fs/dcache.c, inode_init in fs/inode.c and in mnt_init in
fs/namespace.c

At least on my Redhat 7.3 2.4.18-10 source, in the function

static void __init dcache_init(unsigned long mempages)
{
        struct list_head *d;
        unsigned long order;
        unsigned int nr_hash;
        int i;

        /*
         * A constructor could be added for stable state like the lists,
         * but it is probably not worth it because of the cache nature
         * of the dcache.
         * If fragmentation is too bad then the SLAB_HWCACHE_ALIGN
         * flag could be removed here, to hint to the allocator that
         * it should not try to get multiple page regions.
         */
        dentry_cache = kmem_cache_create("dentry_cache",
                                         sizeof(struct dentry),
                                         0,
                                         SLAB_HWCACHE_ALIGN,
                                         NULL, NULL);
        if (!dentry_cache)
                panic("Cannot create dentry cache");

#if PAGE_SHIFT < 13
        mempages >>= (13 - PAGE_SHIFT);
#endif
        mempages *= sizeof(struct list_head);
        for (order = 0; ((1UL << order) << PAGE_SHIFT) < mempages; order++)
                ;

        do {
                u32 tmp;

                nr_hash = (1UL << order) * PAGE_SIZE /
                        sizeof(struct list_head);
                d_hash_mask = (nr_hash - 1);

                tmp = nr_hash;
                d_hash_shift = 0;
                while ((tmp >>= 1UL) != 0UL)
                        d_hash_shift++;

                dentry_hashtable = (struct list_head *)
                        __get_free_pages(GFP_ATOMIC, order);
        } while (dentry_hashtable == NULL && --order >= 0);

........... Notice the --order >=0 in the do while test... since order
is declared as an unsigned long, this test is a pointless comparison and
never fails, causing an infinite loop if the hashtable is empty.

My fix to this is to change the test to have
while (dentry_hashtable == NULL && order-- != 0);

Could someone check me on this?

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sat Aug 31 2002 - 22:00:21 EST