return 0;
 }
 
-static int link_mem_sections(int nid)
+int link_mem_sections(int nid, unsigned long start_pfn, unsigned long nr_pages)
 {
-       unsigned long start_pfn = NODE_DATA(nid)->node_start_pfn;
-       unsigned long end_pfn = start_pfn + NODE_DATA(nid)->node_spanned_pages;
+       unsigned long end_pfn = start_pfn + nr_pages;
        unsigned long pfn;
        struct memory_block *mem_blk = NULL;
        int err = 0;
        return NOTIFY_OK;
 }
 #endif /* CONFIG_HUGETLBFS */
-#else  /* !CONFIG_MEMORY_HOTPLUG_SPARSE */
-
-static int link_mem_sections(int nid) { return 0; }
-#endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */
+#endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */
 
 #if !defined(CONFIG_MEMORY_HOTPLUG_SPARSE) || \
     !defined(CONFIG_HUGETLBFS)
 
 #endif
 
-int register_one_node(int nid)
+int __register_one_node(int nid)
 {
-       int error = 0;
+       int p_node = parent_node(nid);
+       struct node *parent = NULL;
+       int error;
        int cpu;
 
-       if (node_online(nid)) {
-               int p_node = parent_node(nid);
-               struct node *parent = NULL;
-
-               if (p_node != nid)
-                       parent = node_devices[p_node];
-
-               node_devices[nid] = kzalloc(sizeof(struct node), GFP_KERNEL);
-               if (!node_devices[nid])
-                       return -ENOMEM;
-
-               error = register_node(node_devices[nid], nid, parent);
+       if (p_node != nid)
+               parent = node_devices[p_node];
 
-               /* link cpu under this node */
-               for_each_present_cpu(cpu) {
-                       if (cpu_to_node(cpu) == nid)
-                               register_cpu_under_node(cpu, nid);
-               }
+       node_devices[nid] = kzalloc(sizeof(struct node), GFP_KERNEL);
+       if (!node_devices[nid])
+               return -ENOMEM;
 
-               /* link memory sections under this node */
-               error = link_mem_sections(nid);
+       error = register_node(node_devices[nid], nid, parent);
 
-               /* initialize work queue for memory hot plug */
-               init_node_hugetlb_work(nid);
+       /* link cpu under this node */
+       for_each_present_cpu(cpu) {
+               if (cpu_to_node(cpu) == nid)
+                       register_cpu_under_node(cpu, nid);
        }
 
-       return error;
+       /* initialize work queue for memory hot plug */
+       init_node_hugetlb_work(nid);
 
+       return error;
 }
 
 void unregister_one_node(int nid)
 
 extern struct node *node_devices[];
 typedef  void (*node_registration_func_t)(struct node *);
 
+#if defined(CONFIG_MEMORY_HOTPLUG_SPARSE) && defined(CONFIG_NUMA)
+extern int link_mem_sections(int nid, unsigned long start_pfn, unsigned long nr_pages);
+#else
+static inline int link_mem_sections(int nid, unsigned long start_pfn, unsigned long nr_pages)
+{
+       return 0;
+}
+#endif
+
 extern void unregister_node(struct node *node);
 #ifdef CONFIG_NUMA
-extern int register_one_node(int nid);
+/* Core of the node registration - only memory hotplug should use this */
+extern int __register_one_node(int nid);
+
+/* Registers an online node */
+static inline int register_one_node(int nid)
+{
+       int error = 0;
+
+       if (node_online(nid)) {
+               struct pglist_data *pgdat = NODE_DATA(nid);
+
+               error = __register_one_node(nid);
+               if (error)
+                       return error;
+               /* link memory sections under this node */
+               error = link_mem_sections(nid, pgdat->node_start_pfn, pgdat->node_spanned_pages);
+       }
+
+       return error;
+}
+
 extern void unregister_one_node(int nid);
 extern int register_cpu_under_node(unsigned int cpu, unsigned int nid);
 extern int unregister_cpu_under_node(unsigned int cpu, unsigned int nid);
                                         node_registration_func_t unregister);
 #endif
 #else
+static inline int __register_one_node(int nid)
+{
+       return 0;
+}
 static inline int register_one_node(int nid)
 {
        return 0;
 
        node_set_online(nid);
 
        if (new_node) {
-               ret = register_one_node(nid);
+               unsigned long start_pfn = start >> PAGE_SHIFT;
+               unsigned long nr_pages = size >> PAGE_SHIFT;
+
+               ret = __register_one_node(nid);
+               if (ret)
+                       goto register_fail;
+
+               /*
+                * link memory sections under this node. This is already
+                * done when creatig memory section in register_new_memory
+                * but that depends to have the node registered so offline
+                * nodes have to go through register_node.
+                * TODO clean up this mess.
+                */
+               ret = link_mem_sections(nid, start_pfn, nr_pages);
+register_fail:
                /*
                 * If sysfs file of new node can't create, cpu on the node
                 * can't be hot-added. There is no rollback way now.