down(&bus->d_inode->i_sem);
 
-       list_for_each_entry(dev, &bus->d_subdirs, d_child)
+       list_for_each_entry(dev, &bus->d_subdirs, d_u.d_child)
                if (dev->d_inode)
                        update_dev(dev);
 
 
        down(&root->d_inode->i_sem);
 
-       list_for_each_entry(bus, &root->d_subdirs, d_child) {
+       list_for_each_entry(bus, &root->d_subdirs, d_u.d_child) {
                if (bus->d_inode) {
                        switch (S_IFMT & bus->d_inode->i_mode) {
                        case S_IFDIR:
        spin_lock(&dcache_lock);
 
        list_for_each(list, &dentry->d_subdirs) {
-               struct dentry *de = list_entry(list, struct dentry, d_child);
+               struct dentry *de = list_entry(list, struct dentry, d_u.d_child);
                if (usbfs_positive(de)) {
                        spin_unlock(&dcache_lock);
                        return 0;
 
        struct dentry *child;
        int ret = 0;
 
-       list_for_each_entry(child, &dentry->d_subdirs, d_child)
+       list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child)
                if (simple_positive(child))
                        goto out;
        ret = 1;
 
        next = this_parent->d_subdirs.next;
 resume:
        while (next != &this_parent->d_subdirs) {
-               struct dentry *dentry = list_entry(next, struct dentry, d_child);
+               struct dentry *dentry = list_entry(next, struct dentry, d_u.d_child);
 
                /* Negative dentry - give up */
                if (!simple_positive(dentry)) {
        }
 
        if (this_parent != top) {
-               next = this_parent->d_child.next;
+               next = this_parent->d_u.d_child.next;
                this_parent = this_parent->d_parent;
                goto resume;
        }
        next = this_parent->d_subdirs.next;
 resume:
        while (next != &this_parent->d_subdirs) {
-               struct dentry *dentry = list_entry(next, struct dentry, d_child);
+               struct dentry *dentry = list_entry(next, struct dentry, d_u.d_child);
 
                /* Negative dentry - give up */
                if (!simple_positive(dentry)) {
        }
 
        if (this_parent != parent) {
-               next = this_parent->d_child.next;
+               next = this_parent->d_u.d_child.next;
                this_parent = this_parent->d_parent;
                goto resume;
        }
        /* On exit from the loop expire is set to a dgot dentry
         * to expire or it's NULL */
        while ( next != &root->d_subdirs ) {
-               struct dentry *dentry = list_entry(next, struct dentry, d_child);
+               struct dentry *dentry = list_entry(next, struct dentry, d_u.d_child);
 
                /* Negative dentry - give up */
                if ( !simple_positive(dentry) ) {
                        expired, (int)expired->d_name.len, expired->d_name.name);
                spin_lock(&dcache_lock);
                list_del(&expired->d_parent->d_subdirs);
-               list_add(&expired->d_parent->d_subdirs, &expired->d_child);
+               list_add(&expired->d_parent->d_subdirs, &expired->d_u.d_child);
                spin_unlock(&dcache_lock);
                return expired;
        }
 
        next = this_parent->d_subdirs.next;
 resume:
        while (next != &this_parent->d_subdirs) {
-               struct dentry *dentry = list_entry(next, struct dentry, d_child);
+               struct dentry *dentry = list_entry(next, struct dentry, d_u.d_child);
 
                /* Negative dentry - don`t care */
                if (!simple_positive(dentry)) {
        if (this_parent != sbi->root) {
                struct dentry *dentry = this_parent;
 
-               next = this_parent->d_child.next;
+               next = this_parent->d_u.d_child.next;
                this_parent = this_parent->d_parent;
                spin_unlock(&dcache_lock);
                DPRINTK("parent dentry %p %.*s",
 
                        }
 
                        while(1) {
-                               struct dentry *de = list_entry(list, struct dentry, d_child);
+                               struct dentry *de = list_entry(list,
+                                               struct dentry, d_u.d_child);
 
                                if (!d_unhashed(de) && de->d_inode) {
                                        spin_unlock(&dcache_lock);
 
        spin_lock(&dcache_lock);
        list_for_each(child, &parent->d_subdirs)
        {
-               de = list_entry(child, struct dentry, d_child);
+               de = list_entry(child, struct dentry, d_u.d_child);
                /* don't know what to do with negative dentries */
                if ( ! de->d_inode ) 
                        continue;
 
 
 static void d_callback(struct rcu_head *head)
 {
-       struct dentry * dentry = container_of(head, struct dentry, d_rcu);
+       struct dentry * dentry = container_of(head, struct dentry, d_u.d_rcu);
 
        if (dname_external(dentry))
                kfree(dentry->d_name.name);
 {
        if (dentry->d_op && dentry->d_op->d_release)
                dentry->d_op->d_release(dentry);
-       call_rcu(&dentry->d_rcu, d_callback);
+       call_rcu(&dentry->d_u.d_rcu, d_callback);
 }
 
 /*
                        list_del(&dentry->d_lru);
                        dentry_stat.nr_unused--;
                }
-               list_del(&dentry->d_child);
+               list_del(&dentry->d_u.d_child);
                dentry_stat.nr_dentry--;        /* For d_free, below */
                /*drops the locks, at that point nobody can reach this dentry */
                dentry_iput(dentry);
        struct dentry * parent;
 
        __d_drop(dentry);
-       list_del(&dentry->d_child);
+       list_del(&dentry->d_u.d_child);
        dentry_stat.nr_dentry--;        /* For d_free, below */
        dentry_iput(dentry);
        parent = dentry->d_parent;
 resume:
        while (next != &this_parent->d_subdirs) {
                struct list_head *tmp = next;
-               struct dentry *dentry = list_entry(tmp, struct dentry, d_child);
+               struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child);
                next = tmp->next;
                /* Have we found a mount point ? */
                if (d_mountpoint(dentry))
         * All done at this level ... ascend and resume the search.
         */
        if (this_parent != parent) {
-               next = this_parent->d_child.next; 
+               next = this_parent->d_u.d_child.next;
                this_parent = this_parent->d_parent;
                goto resume;
        }
 resume:
        while (next != &this_parent->d_subdirs) {
                struct list_head *tmp = next;
-               struct dentry *dentry = list_entry(tmp, struct dentry, d_child);
+               struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child);
                next = tmp->next;
 
                if (!list_empty(&dentry->d_lru)) {
         * All done at this level ... ascend and resume the search.
         */
        if (this_parent != parent) {
-               next = this_parent->d_child.next; 
+               next = this_parent->d_u.d_child.next;
                this_parent = this_parent->d_parent;
 #ifdef DCACHE_DEBUG
 printk(KERN_DEBUG "select_parent: ascending to %s/%s, found=%d\n",
                dentry->d_parent = dget(parent);
                dentry->d_sb = parent->d_sb;
        } else {
-               INIT_LIST_HEAD(&dentry->d_child);
+               INIT_LIST_HEAD(&dentry->d_u.d_child);
        }
 
        spin_lock(&dcache_lock);
        if (parent)
-               list_add(&dentry->d_child, &parent->d_subdirs);
+               list_add(&dentry->d_u.d_child, &parent->d_subdirs);
        dentry_stat.nr_dentry++;
        spin_unlock(&dcache_lock);
 
        /* Unhash the target: dput() will then get rid of it */
        __d_drop(target);
 
-       list_del(&dentry->d_child);
-       list_del(&target->d_child);
+       list_del(&dentry->d_u.d_child);
+       list_del(&target->d_u.d_child);
 
        /* Switch the names.. */
        switch_names(dentry, target);
        if (IS_ROOT(dentry)) {
                dentry->d_parent = target->d_parent;
                target->d_parent = target;
-               INIT_LIST_HEAD(&target->d_child);
+               INIT_LIST_HEAD(&target->d_u.d_child);
        } else {
                do_switch(dentry->d_parent, target->d_parent);
 
                /* And add them back to the (new) parent lists */
-               list_add(&target->d_child, &target->d_parent->d_subdirs);
+               list_add(&target->d_u.d_child, &target->d_parent->d_subdirs);
        }
 
-       list_add(&dentry->d_child, &dentry->d_parent->d_subdirs);
+       list_add(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs);
        spin_unlock(&target->d_lock);
        spin_unlock(&dentry->d_lock);
        write_sequnlock(&rename_lock);
 resume:
        while (next != &this_parent->d_subdirs) {
                struct list_head *tmp = next;
-               struct dentry *dentry = list_entry(tmp, struct dentry, d_child);
+               struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child);
                next = tmp->next;
                if (d_unhashed(dentry)||!dentry->d_inode)
                        continue;
                atomic_dec(&dentry->d_count);
        }
        if (this_parent != root) {
-               next = this_parent->d_child.next; 
+               next = this_parent->d_u.d_child.next;
                atomic_dec(&this_parent->d_count);
                this_parent = this_parent->d_parent;
                goto resume;
 
                        loff_t n = file->f_pos - 2;
 
                        spin_lock(&dcache_lock);
-                       list_del(&cursor->d_child);
+                       list_del(&cursor->d_u.d_child);
                        p = file->f_dentry->d_subdirs.next;
                        while (n && p != &file->f_dentry->d_subdirs) {
                                struct dentry *next;
-                               next = list_entry(p, struct dentry, d_child);
+                               next = list_entry(p, struct dentry, d_u.d_child);
                                if (!d_unhashed(next) && next->d_inode)
                                        n--;
                                p = p->next;
                        }
-                       list_add_tail(&cursor->d_child, p);
+                       list_add_tail(&cursor->d_u.d_child, p);
                        spin_unlock(&dcache_lock);
                }
        }
 {
        struct dentry *dentry = filp->f_dentry;
        struct dentry *cursor = filp->private_data;
-       struct list_head *p, *q = &cursor->d_child;
+       struct list_head *p, *q = &cursor->d_u.d_child;
        ino_t ino;
        int i = filp->f_pos;
 
                        }
                        for (p=q->next; p != &dentry->d_subdirs; p=p->next) {
                                struct dentry *next;
-                               next = list_entry(p, struct dentry, d_child);
+                               next = list_entry(p, struct dentry, d_u.d_child);
                                if (d_unhashed(next) || !next->d_inode)
                                        continue;
 
        int ret = 0;
 
        spin_lock(&dcache_lock);
-       list_for_each_entry(child, &dentry->d_subdirs, d_child)
+       list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child)
                if (simple_positive(child))
                        goto out;
        ret = 1;
 
        spin_lock(&dcache_lock);
        next = parent->d_subdirs.next;
        while (next != &parent->d_subdirs) {
-               dent = list_entry(next, struct dentry, d_child);
+               dent = list_entry(next, struct dentry, d_u.d_child);
                if ((unsigned long)dent->d_fsdata == fpos) {
                        if (dent->d_inode)
                                dget_locked(dent);
 
        spin_lock(&dcache_lock);
        next = parent->d_subdirs.next;
        while (next != &parent->d_subdirs) {
-               dentry = list_entry(next, struct dentry, d_child);
+               dentry = list_entry(next, struct dentry, d_u.d_child);
 
                if (dentry->d_fsdata == NULL)
                        ncp_age_dentry(server, dentry);
        spin_lock(&dcache_lock);
        next = parent->d_subdirs.next;
        while (next != &parent->d_subdirs) {
-               dentry = list_entry(next, struct dentry, d_child);
+               dentry = list_entry(next, struct dentry, d_u.d_child);
                dentry->d_fsdata = NULL;
                ncp_age_dentry(server, dentry);
                next = next->next;
 
        spin_lock(&dcache_lock);
        next = parent->d_subdirs.next;
        while (next != &parent->d_subdirs) {
-               dentry = list_entry(next, struct dentry, d_child);
+               dentry = list_entry(next, struct dentry, d_u.d_child);
                dentry->d_fsdata = NULL;
                smb_age_dentry(server, dentry);
                next = next->next;
        spin_lock(&dcache_lock);
        next = parent->d_subdirs.next;
        while (next != &parent->d_subdirs) {
-               dent = list_entry(next, struct dentry, d_child);
+               dent = list_entry(next, struct dentry, d_u.d_child);
                if ((unsigned long)dent->d_fsdata == fpos) {
                        if (dent->d_inode)
                                dget_locked(dent);
 
        struct qstr d_name;
 
        struct list_head d_lru;         /* LRU list */
-       struct list_head d_child;       /* child of parent list */
+       /*
+        * d_child and d_rcu can share memory
+        */
+       union {
+               struct list_head d_child;       /* child of parent list */
+               struct rcu_head d_rcu;
+       } d_u;
        struct list_head d_subdirs;     /* our children */
        struct list_head d_alias;       /* inode alias list */
        unsigned long d_time;           /* used by d_revalidate */
        struct dentry_operations *d_op;
        struct super_block *d_sb;       /* The root of the dentry tree */
        void *d_fsdata;                 /* fs-specific data */
-       struct rcu_head d_rcu;
        struct dcookie_struct *d_cookie; /* cookie, if any */
        int d_mounted;
        unsigned char d_iname[DNAME_INLINE_LEN_MIN];    /* small names */
 
        spin_lock(&dcache_lock);
        node = dentry->d_subdirs.next;
        while (node != &dentry->d_subdirs) {
-               struct dentry *d = list_entry(node, struct dentry, d_child);
+               struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
                list_del_init(node);
                if (d->d_inode) {
                        d = dget_locked(d);
                }
                node = dentry->d_subdirs.next;
        }
-       list_del_init(&dentry->d_child);
+       list_del_init(&dentry->d_u.d_child);
        spin_unlock(&dcache_lock);
        remove_dir(dentry);
 }
 
 repeat:
        spin_lock(&dcache_lock);
        list_for_each_safe(pos, next, &parent->d_subdirs) {
-               dentry = list_entry(pos, struct dentry, d_child);
+               dentry = list_entry(pos, struct dentry, d_u.d_child);
                spin_lock(&dentry->d_lock);
                if (!d_unhashed(dentry)) {
                        dget_locked(dentry);
 
        spin_lock(&dcache_lock);
        node = de->d_subdirs.next;
        while (node != &de->d_subdirs) {
-               struct dentry *d = list_entry(node, struct dentry, d_child);
+               struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
                list_del_init(node);
 
                if (d->d_inode) {