summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-06-03 09:23:20 +0000
committerRalf Baechle <ralf@linux-mips.org>1997-06-03 09:23:20 +0000
commitac5ff8f4a72f7b4e66f73c3c6cb9fe7758cf6f12 (patch)
tree9fc7f8ce32e0d9a4aa055b2a58a05a5d727b333c /fs
parent52662ff3e66770fd7e4fc508c91056d29c08bff0 (diff)
Sync with Linux 2.1.42.
Diffstat (limited to 'fs')
-rw-r--r--fs/autofs/autofs_i.h2
-rw-r--r--fs/autofs/waitq.c51
-rw-r--r--fs/buffer.c39
-rw-r--r--fs/filesystems.c41
-rw-r--r--fs/nfs/nfsroot.c172
-rw-r--r--fs/super.c17
6 files changed, 150 insertions, 172 deletions
diff --git a/fs/autofs/autofs_i.h b/fs/autofs/autofs_i.h
index 4183b88b1..cc38577aa 100644
--- a/fs/autofs/autofs_i.h
+++ b/fs/autofs/autofs_i.h
@@ -12,8 +12,6 @@
/* Internal header file for autofs */
-#define DEBUG_WAITLIST 1
-
#include <linux/auto_fs.h>
/* This is the range of ioctl() numbers we claim as ours */
diff --git a/fs/autofs/waitq.c b/fs/autofs/waitq.c
index 719e04eb4..cbe270a53 100644
--- a/fs/autofs/waitq.c
+++ b/fs/autofs/waitq.c
@@ -16,46 +16,6 @@
#include <linux/file.h>
#include "autofs_i.h"
-#ifdef DEBUG_WAITLIST
-#ifndef i386
-#error Only i386 implemented
-#endif
-
-static inline int sane_pointer(void *p)
-{
- return (p == NULL) || ((unsigned) p > 0xc0000000);
-}
-
-void autofs_check_waitlist_integrity(struct autofs_sb_info *sbi, char *op)
-{
- struct autofs_wait_queue **wqp, *wq;
-
- if ( sbi->magic != AUTOFS_SBI_MAGIC ) {
- printk("autofs: CHECK_WAITLIST with bogus sbi pointer: %p\n",
- sbi);
- return;
- }
-
- wqp = &(sbi->queues);
- while ( (wq = *wqp) ) {
- if ( !sane_pointer(wq) ) {
- printk("autofs(%s): wait queue pointer corrupt: ", op);
- wqp = &(sbi->queues);
- do {
- wq = *wqp;
- printk(" %p", wq);
- wqp = &(wq->next);
- } while ( sane_pointer(*wqp) );
- printk("\n");
- *wqp = NULL;
- break;
- } else {
- wqp = &(wq->next);
- }
- }
-}
-#endif
-
/* We make this a static variable rather than a part of the superblock; it
is better if we don't reassign numbers easily even across filesystems */
static int autofs_next_wait_queue = 1;
@@ -135,8 +95,6 @@ int autofs_wait(struct autofs_sb_info *sbi, autofs_hash_t hash, const char *name
struct autofs_wait_queue *wq;
int status;
- CHECK_WAITLIST(sbi,"wait");
-
for ( wq = sbi->queues ; wq ; wq = wq->next ) {
if ( wq->hash == hash &&
wq->len == len &&
@@ -165,7 +123,7 @@ int autofs_wait(struct autofs_sb_info *sbi, autofs_hash_t hash, const char *name
sbi->queues = wq;
/* autofs_notify_daemon() may block */
- wq->wait_ctr = 1;
+ wq->wait_ctr = 2;
autofs_notify_daemon(sbi,wq);
} else
wq->wait_ctr++;
@@ -190,8 +148,6 @@ int autofs_wait_release(struct autofs_sb_info *sbi, unsigned long wait_queue_tok
{
struct autofs_wait_queue *wq, **wql;
- CHECK_WAITLIST(sbi,"release");
-
for ( wql = &sbi->queues ; (wq = *wql) ; wql = &wq->next ) {
if ( wq->wait_queue_token == wait_queue_token )
break;
@@ -205,7 +161,10 @@ int autofs_wait_release(struct autofs_sb_info *sbi, unsigned long wait_queue_tok
wq->status = status;
- wake_up(&wq->queue);
+ if ( ! --wq->wait_ctr ) /* Is anyone still waiting for this guy? */
+ kfree(wq);
+ else
+ wake_up(&wq->queue);
return 0;
}
diff --git a/fs/buffer.c b/fs/buffer.c
index 0b35d6e00..b8bd754c1 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -685,6 +685,9 @@ static void refill_freelist(int size)
needed -= PAGE_SIZE;
repeat:
+ if(needed <= 0)
+ return;
+
/* OK, we cannot grow the buffer cache, now try to get some
* from the lru list.
*
@@ -692,9 +695,6 @@ repeat:
* should be quick nearly all of the time.
*/
- if(needed <= 0)
- return;
-
for(i=0; i<BUF_DIRTY; i++) {
buffers[i] = nr_buffers_type[i];
candidate[i] = find_candidate(lru_list[i], &buffers[i], size);
@@ -731,13 +731,9 @@ repeat:
candidate[i] = find_candidate(candidate[i],
&buffers[i], size);
}
- if (needed >= 0)
- goto repeat;
+ goto repeat;
}
- if(needed <= 0)
- return;
-
/* Too bad, that was not enough. Try a little harder to grow some. */
if (nr_free_pages > min_free_pages + 5) {
if (grow_buffers(GFP_BUFFER, size)) {
@@ -747,9 +743,10 @@ repeat:
}
/* And repeat until we find something good. */
- if (!grow_buffers(GFP_ATOMIC, size))
+ if (grow_buffers(GFP_ATOMIC, size))
+ needed -= PAGE_SIZE;
+ else
wakeup_bdflush(1);
- needed -= PAGE_SIZE;
goto repeat;
}
@@ -995,6 +992,7 @@ static void put_unused_buffer_head(struct buffer_head * bh)
kmem_cache_free(bh_cachep, bh);
return;
}
+
memset(bh,0,sizeof(*bh));
nr_unused_buffer_heads++;
bh->b_next_free = unused_list;
@@ -1034,24 +1032,17 @@ static void get_more_buffer_heads(void)
* fields after the final unlock. So, the device driver puts them on
* the reuse_list instead once IO completes, and we recover these to
* the unused_list here.
- *
- * The reuse_list receives buffers from interrupt routines, so we need
- * to be IRQ-safe here (but note that interrupts only _add_ to the
- * reuse_list, never take away. So we don't need to worry about the
- * reuse_list magically emptying).
*/
static inline void recover_reusable_buffer_heads(void)
{
- if (reuse_list) {
- struct buffer_head *head;
+ struct buffer_head *head;
- head = xchg(&reuse_list, NULL);
+ head = xchg(&reuse_list, NULL);
- do {
- struct buffer_head *bh = head;
- head = head->b_next_free;
- put_unused_buffer_head(bh);
- } while (head);
+ while (head) {
+ struct buffer_head *bh = head;
+ head = head->b_next_free;
+ put_unused_buffer_head(bh);
}
}
@@ -1139,7 +1130,7 @@ static inline void free_async_buffers (struct buffer_head * bh)
"async IO mismatch on page.\n");
return;
}
- tmp->b_next_free = reuse_list;
+ tmp->b_next_free = xchg(&reuse_list, NULL);
reuse_list = tmp;
clear_bit(BH_FreeOnIO, &tmp->b_state);
tmp = tmp->b_this_page;
diff --git a/fs/filesystems.c b/fs/filesystems.c
index 7d5b51ef1..74016aa67 100644
--- a/fs/filesystems.c
+++ b/fs/filesystems.c
@@ -30,22 +30,16 @@
#ifdef CONFIG_KERNELD
#include <linux/kerneld.h>
#endif
+#include <linux/lockd/bind.h>
+#include <linux/lockd/xdr.h>
+#include <linux/init.h>
extern void device_setup(void);
extern void binfmt_setup(void);
extern void free_initmem(void);
-/* This may be used only once, enforced by 'static int callable' */
-asmlinkage int sys_setup(void)
+__initfunc(static void do_sys_setup(void))
{
- static int callable = 1;
- int err = -1;
-
- lock_kernel();
- if (!callable)
- goto out;
- callable = 0;
-
device_setup();
binfmt_setup();
@@ -123,11 +117,28 @@ asmlinkage int sys_setup(void)
#endif
mount_root();
-
- free_initmem();
-
- err = 0;
-out:
+}
+
+int initmem_freed = 0;
+
+/* This may be used only twice, enforced by 'static int callable' */
+asmlinkage int sys_setup(int magic)
+{
+ static int callable = 1;
+ int err = -1;
+
+ lock_kernel();
+ if (magic) {
+ if (!initmem_freed) {
+ initmem_freed = 1;
+ free_initmem ();
+ err = 0;
+ }
+ } else if (callable) {
+ callable = 0;
+ do_sys_setup();
+ err = 0;
+ }
unlock_kernel();
return err;
}
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
index d68dca70d..66070efd7 100644
--- a/fs/nfs/nfsroot.c
+++ b/fs/nfs/nfsroot.c
@@ -1,10 +1,10 @@
/*
- * linux/fs/nfs/nfsroot.c -- version 2.3
+ * $Id: nfsroot.c,v 1.36 1997/05/27 15:57:47 mj Exp $
*
* Copyright (C) 1995, 1996 Gero Kuhlmann <gero@gkminix.han.de>
*
* For parts of this file:
- * Copyright (C) 1996 Martin Mares <mj@k332.feld.cvut.cz>
+ * Copyright (C) 1996, 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
*
* Allow an NFS filesystem to be mounted as root. The way this works is:
* (1) Determine the local IP address via RARP or BOOTP or from the
@@ -54,6 +54,9 @@
* Jacek Zapala : Fixed a bug which prevented server-ip address
* from nfsroot parameter from being used.
* Olaf Kirch : Adapted to new NFS code.
+ * Jakub Jelinek : Free used code segment.
+ * Marko Kohtala : Fixed some bugs.
+ * Martin Mares : Debug message cleanup
*
*/
@@ -71,6 +74,7 @@
#include <linux/fs.h>
#include <linux/random.h>
#include <linux/fcntl.h>
+#include <linux/init.h>
#include <asm/param.h>
#include <linux/utsname.h>
@@ -120,28 +124,28 @@ struct open_dev {
struct open_dev *next;
};
-static struct open_dev *open_base = NULL;
+static struct open_dev *open_base __initdata = NULL;
/* IP configuration */
-static struct device *root_dev = NULL; /* Device selected for booting */
-static char user_dev_name[IFNAMSIZ]; /* Name of user-selected boot device */
-static __u32 myaddr; /* My IP address */
-static __u32 servaddr; /* Server IP address */
-static __u32 gateway; /* Gateway IP address */
-static __u32 netmask; /* Netmask for local subnet */
+static struct device *root_dev __initdata = NULL; /* Device selected for booting */
+static char user_dev_name[IFNAMSIZ] __initdata = { 0, };/* Name of user-selected boot device */
+static __u32 myaddr __initdata = 0; /* My IP address */
+static __u32 servaddr __initdata = 0; /* Server IP address */
+static __u32 gateway __initdata = 0; /* Gateway IP address */
+static __u32 netmask __initdata = 0; /* Netmask for local subnet */
/* BOOTP/RARP variables */
-static int bootp_flag; /* User said: Use BOOTP! */
-static int rarp_flag; /* User said: Use RARP! */
-static int bootp_dev_count = 0; /* Number of devices allowing BOOTP */
-static int rarp_dev_count = 0; /* Number of devices allowing RARP */
-static __u32 rarp_serv; /* IP address of RARP server */
+static int bootp_flag __initdata = 0; /* User said: Use BOOTP! */
+static int rarp_flag __initdata = 0; /* User said: Use RARP! */
+static int bootp_dev_count __initdata = 0; /* Number of devices allowing BOOTP */
+static int rarp_dev_count __initdata = 0; /* Number of devices allowing RARP */
+static __u32 rarp_serv __initdata = 0; /* IP address of RARP server */
#if defined(CONFIG_RNFS_BOOTP) || defined(CONFIG_RNFS_RARP)
-#define CONFIG_RNFS_DYNAMIC /* Enable dynamic IP config */
-static volatile int pkt_arrived; /* BOOTP/RARP packet detected */
+#define CONFIG_RNFS_DYNAMIC /* Enable dynamic IP config */
+static volatile int pkt_arrived __initdata = 0; /* BOOTP/RARP packet detected */
#define ARRIVED_BOOTP 1
#define ARRIVED_RARP 2
@@ -149,10 +153,10 @@ static volatile int pkt_arrived; /* BOOTP/RARP packet detected */
/* NFS-related data */
-static struct nfs_mount_data nfs_data; /* NFS mount info */
-static char nfs_path[NFS_MAXPATHLEN]; /* Name of directory to mount */
-static int nfs_port; /* Port to connect to for NFS */
-static int mount_port; /* Mount daemon port number */
+static struct nfs_mount_data nfs_data __initdata = { 0, };/* NFS mount info */
+static char nfs_path[NFS_MAXPATHLEN] __initdata = { 0, };/* Name of directory to mount */
+static int nfs_port __initdata = 0; /* Port to connect to for NFS */
+static int mount_port __initdata = 0; /* Mount daemon port number */
/* Yes, we use sys_socket, but there's no include file for it */
@@ -170,7 +174,7 @@ extern asmlinkage int sys_socket(int family, int type, int protocol);
* Setup and initialize all network devices. If there is a user-preferred
* interface, ignore all other interfaces.
*/
-static int root_dev_open(void)
+__initfunc(static int root_dev_open(void))
{
struct open_dev *openp, **last;
struct device *dev;
@@ -221,8 +225,8 @@ set_sockaddr(struct sockaddr_in *sin, __u32 addr, __u16 port)
sin->sin_port = port;
}
-static int
-root_dev_chg_route(int op, struct device *dev, __u32 dest, __u32 mask, __u32 gw)
+__initfunc(static int
+root_dev_chg_route(int op, struct device *dev, __u32 dest, __u32 mask, __u32 gw))
{
struct rtentry route;
unsigned long oldfs;
@@ -250,26 +254,28 @@ root_dev_chg_route(int op, struct device *dev, __u32 dest, __u32 mask, __u32 gw)
err = ip_rt_ioctl(op, &route);
set_fs(oldfs);
+#ifdef NFSROOT_DEBUG
/* in_ntoa in ipv4/utils.c uses a single static buffer, so
* must make multiple printk calls, one for each in_ntoa
* invocation...
*/
- printk(KERN_NOTICE "%s route ", (op == SIOCADDRT ? "addr" : "del"));
+ printk(KERN_NOTICE "%s route ", (op == SIOCADDRT ? "add" : "del"));
printk("%s ", in_ntoa(dest));
printk("%s ", in_ntoa(mask));
printk("%s: res %d\n", in_ntoa(gw), err);
+#endif
return err;
}
-static int
-root_dev_add_route(struct device *dev, __u32 dest, __u32 mask, __u32 gateway)
+__initfunc(static int
+root_dev_add_route(struct device *dev, __u32 dest, __u32 mask, __u32 gateway))
{
return root_dev_chg_route(SIOCADDRT, dev, dest, mask, gateway);
}
-static int
-root_dev_del_route(struct device *dev, __u32 dest, __u32 mask, __u32 gateway)
+__initfunc(static int
+root_dev_del_route(struct device *dev, __u32 dest, __u32 mask, __u32 gateway))
{
return root_dev_chg_route(SIOCDELRT, dev, dest, mask, gateway);
}
@@ -278,7 +284,7 @@ root_dev_del_route(struct device *dev, __u32 dest, __u32 mask, __u32 gateway)
* Restore the state of all devices. However, keep the root device open
* for the upcoming mount.
*/
-static void root_dev_close(void)
+__initfunc(static void root_dev_close(void))
{
struct open_dev *openp;
struct open_dev *nextp;
@@ -318,7 +324,7 @@ static int root_rarp_recv(struct sk_buff *skb, struct device *dev,
struct packet_type *pt);
-static struct packet_type rarp_packet_type = {
+static struct packet_type rarp_packet_type __initdata = {
0, /* Should be: __constant_htons(ETH_P_RARP)
* - but this _doesn't_ come out constant! */
NULL, /* Listen to all devices */
@@ -331,7 +337,7 @@ static struct packet_type rarp_packet_type = {
/*
* Register the packet type for RARP
*/
-static void root_rarp_open(void)
+__initfunc(static void root_rarp_open(void))
{
rarp_packet_type.type = htons(ETH_P_RARP);
dev_add_pack(&rarp_packet_type);
@@ -341,7 +347,7 @@ static void root_rarp_open(void)
/*
* Deregister the RARP packet type
*/
-static void root_rarp_close(void)
+__initfunc(static void root_rarp_close(void))
{
rarp_packet_type.type = htons(ETH_P_RARP);
dev_remove_pack(&rarp_packet_type);
@@ -351,7 +357,8 @@ static void root_rarp_close(void)
/*
* Receive RARP packets.
*/
-static int root_rarp_recv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
+__initfunc(static int
+root_rarp_recv(struct sk_buff *skb, struct device *dev, struct packet_type *pt))
{
struct arphdr *rarp = (struct arphdr *)skb->h.raw;
unsigned char *rarp_ptr = (unsigned char *) (rarp + 1);
@@ -428,7 +435,7 @@ static int root_rarp_recv(struct sk_buff *skb, struct device *dev, struct packet
/*
* Send RARP request packet over all devices which allow RARP.
*/
-static void root_rarp_send(void)
+__initfunc(static void root_rarp_send(void))
{
struct open_dev *openp;
struct device *dev;
@@ -455,10 +462,10 @@ static void root_rarp_send(void)
#ifdef CONFIG_RNFS_BOOTP
-static struct device *bootp_dev = NULL; /* Device selected as best BOOTP target */
+static struct device *bootp_dev __initdata = NULL; /* Device selected as best BOOTP target */
-static struct socket *bootp_xmit_sock; /* BOOTP send socket */
-static struct socket *bootp_recv_sock; /* BOOTP receive socket */
+static struct socket *bootp_xmit_sock __initdata = NULL;/* BOOTP send socket */
+static struct socket *bootp_recv_sock __initdata = NULL;/* BOOTP receive socket */
struct bootp_pkt { /* BOOTP packet format */
u8 op; /* 1=request, 2=reply */
@@ -481,16 +488,16 @@ struct bootp_pkt { /* BOOTP packet format */
#define BOOTP_REQUEST 1
#define BOOTP_REPLY 2
-static struct bootp_pkt *xmit_bootp; /* Packet being transmitted */
-static struct bootp_pkt *recv_bootp; /* Packet being received */
+static struct bootp_pkt *xmit_bootp __initdata = NULL; /* Packet being transmitted */
+static struct bootp_pkt *recv_bootp __initdata = NULL; /* Packet being received */
-static int bootp_have_route = 0; /* BOOTP route installed */
+static int bootp_have_route __initdata = 0; /* BOOTP route installed */
/*
* Free BOOTP packet buffers
*/
-static void root_free_bootp(void)
+__initfunc(static void root_free_bootp(void))
{
if (xmit_bootp) {
kfree_s(xmit_bootp, sizeof(struct bootp_pkt));
@@ -510,7 +517,7 @@ static inline int root_alloc_bootp(void)
{
if (!(xmit_bootp = kmalloc(sizeof(struct bootp_pkt), GFP_KERNEL)) ||
!(recv_bootp = kmalloc(sizeof(struct bootp_pkt), GFP_KERNEL))) {
- printk("BOOTP: Out of memory!");
+ printk(KERN_ERR "BOOTP: Out of memory!\n");
return -1;
}
return 0;
@@ -520,7 +527,7 @@ static inline int root_alloc_bootp(void)
/*
* Create default route for BOOTP sending
*/
-static int root_add_bootp_route(void)
+__initfunc(static int root_add_bootp_route(void))
{
if (root_dev_add_route(bootp_dev, 0, 0, 0) < 0) {
printk(KERN_ERR "BOOTP: Failed to add route\n");
@@ -534,7 +541,7 @@ static int root_add_bootp_route(void)
/*
* Delete default route for BOOTP sending
*/
-static int root_del_bootp_route(void)
+__initfunc(static int root_del_bootp_route(void))
{
if (bootp_have_route && root_dev_del_route(bootp_dev, 0, 0, 0) < 0) {
printk(KERN_ERR "BOOTP: Deleting of route failed!\n");
@@ -548,7 +555,7 @@ static int root_del_bootp_route(void)
/*
* Open UDP socket.
*/
-static int root_open_udp_sock(struct socket **sock)
+__initfunc(static int root_open_udp_sock(struct socket **sock))
{
int err;
@@ -561,12 +568,13 @@ static int root_open_udp_sock(struct socket **sock)
/*
* Connect UDP socket.
*/
-static int root_connect_udp_sock(struct socket *sock, u32 addr, u16 port)
+__initfunc(static int
+root_connect_udp_sock(struct socket *sock, u32 addr, u16 port))
{
struct sockaddr_in sa;
int result;
- set_sockaddr(&sa, htonl(addr), htonl(port));
+ set_sockaddr(&sa, htonl(addr), htons(port));
result = sock->ops->connect(sock, (struct sockaddr *) &sa, sizeof(sa), 0);
if (result < 0) {
printk(KERN_ERR "BOOTP: connect() failed\n");
@@ -579,12 +587,13 @@ static int root_connect_udp_sock(struct socket *sock, u32 addr, u16 port)
/*
* Bind UDP socket.
*/
-static int root_bind_udp_sock(struct socket *sock, u32 addr, u16 port)
+__initfunc(static int
+root_bind_udp_sock(struct socket *sock, u32 addr, u16 port))
{
struct sockaddr_in sa;
int result;
- set_sockaddr(&sa, htonl(addr), htonl(port));
+ set_sockaddr(&sa, htonl(addr), htons(port));
result = sock->ops->bind(sock, (struct sockaddr *) &sa, sizeof(sa));
if (result < 0) {
printk(KERN_ERR "BOOTP: bind() failed\n");
@@ -645,7 +654,7 @@ static inline int root_recv_udp(struct socket *sock, void *buf, int size)
/*
* Initialize BOOTP extension fields in the request.
*/
-static void root_bootp_init_ext(u8 *e)
+__initfunc(static void root_bootp_init_ext(u8 *e))
{
*e++ = 99; /* RFC1048 Magic Cookie */
*e++ = 130;
@@ -673,7 +682,7 @@ static void root_bootp_init_ext(u8 *e)
/*
* Deinitialize the BOOTP mechanism.
*/
-static void root_bootp_close(void)
+__initfunc(static void root_bootp_close(void))
{
if (bootp_xmit_sock)
sock_release(bootp_xmit_sock);
@@ -687,7 +696,7 @@ static void root_bootp_close(void)
/*
* Initialize the BOOTP mechanism.
*/
-static int root_bootp_open(void)
+__initfunc(static int root_bootp_open(void))
{
struct open_dev *openp;
struct device *dev, *best_dev;
@@ -767,7 +776,7 @@ static int root_bootp_open(void)
/*
* Send BOOTP request.
*/
-static int root_bootp_send(u32 jiffies)
+__initfunc(static int root_bootp_send(u32 jiffies))
{
xmit_bootp->secs = htons(jiffies / HZ);
return root_send_udp(bootp_xmit_sock, xmit_bootp, sizeof(struct bootp_pkt));
@@ -777,7 +786,8 @@ static int root_bootp_send(u32 jiffies)
/*
* Copy BOOTP-supplied string if not already set.
*/
-static int root_bootp_string(char *dest, char *src, int len, int max)
+__initfunc(static int
+root_bootp_string(char *dest, char *src, int len, int max))
{
if (*dest || !len)
return 0;
@@ -792,12 +802,12 @@ static int root_bootp_string(char *dest, char *src, int len, int max)
/*
* Process BOOTP extension.
*/
-static void root_do_bootp_ext(u8 *ext)
+__initfunc(static void root_do_bootp_ext(u8 *ext))
{
#ifdef NFSROOT_BOOTP_DEBUG
u8 *c;
- printk("BOOTP: Got extension %02x",*ext);
+ printk(KERN_DEBUG "BOOTP: Got extension %02x",*ext);
for(c=ext+2; c<ext+2+ext[1]; c++)
printk(" %02x", *c);
printk("\n");
@@ -828,7 +838,7 @@ static void root_do_bootp_ext(u8 *ext)
/*
* Receive BOOTP request.
*/
-static void root_bootp_recv(void)
+__initfunc(static void root_bootp_recv(void))
{
int len;
u8 *ext, *end, *opt;
@@ -897,7 +907,7 @@ static void root_bootp_recv(void)
* Determine client and server IP numbers and appropriate device by using
* the RARP and BOOTP protocols.
*/
-static int root_auto_config(void)
+__initfunc(static int root_auto_config(void))
{
int retries;
unsigned long timeout, jiff;
@@ -988,8 +998,10 @@ static int root_auto_config(void)
#else
;
#endif
- if (pkt_arrived)
+ if (pkt_arrived) {
+ printk(" OK\n");
break;
+ }
if (! --retries) {
printk(" timed out!\n");
break;
@@ -1011,7 +1023,6 @@ static int root_auto_config(void)
if (!pkt_arrived)
return -1;
- printk(" OK\n");
printk(KERN_NOTICE "Root-NFS: Got %s answer from %s, ",
(pkt_arrived == ARRIVED_BOOTP) ? "BOOTP" : "RARP",
in_ntoa(servaddr));
@@ -1022,7 +1033,7 @@ static int root_auto_config(void)
#endif
/* Get default netmask - used to be exported from net/ipv4 */
-static unsigned long
+static inline unsigned long
ip_get_mask(unsigned long addr)
{
if (!addr)
@@ -1050,7 +1061,7 @@ ip_get_mask(unsigned long addr)
static struct nfs_int_opts {
char *name;
int *val;
-} root_int_opts[] = {
+} root_int_opts[] __initdata = {
{ "port", &nfs_port },
{ "rsize", &nfs_data.rsize },
{ "wsize", &nfs_data.wsize },
@@ -1071,7 +1082,7 @@ static struct nfs_bool_opts {
char *name;
int and_mask;
int or_mask;
-} root_bool_opts[] = {
+} root_bool_opts[] __initdata = {
{ "soft", ~NFS_MOUNT_SOFT, NFS_MOUNT_SOFT },
{ "hard", ~NFS_MOUNT_SOFT, 0 },
{ "intr", ~NFS_MOUNT_INTR, NFS_MOUNT_INTR },
@@ -1090,7 +1101,7 @@ static struct nfs_bool_opts {
* Prepare the NFS data structure and parse any options. This tries to
* set as many values in the nfs_data structure as known right now.
*/
-static int root_nfs_name(char *name)
+__initfunc(static int root_nfs_name(char *name))
{
char buf[NFS_MAXPATHLEN];
char *cp, *cq, *options, *val;
@@ -1120,6 +1131,7 @@ static int root_nfs_name(char *name)
memset(&nfs_data, 0, sizeof(nfs_data));
strncpy(nfs_data.hostname, in_ntoa(servaddr),
sizeof(nfs_data.hostname)-1);
+ nfs_data.namlen = strlen(nfs_data.hostname);
/* Set the name of the directory to mount */
if (nfs_path[0] == '\0' || strncmp(name, "default", 7))
@@ -1141,7 +1153,7 @@ static int root_nfs_name(char *name)
/* Set some default values */
nfs_port = -1;
- nfs_data.version = NFS_MNT_VERSION;
+ nfs_data.version = NFS_MOUNT_VERSION;
nfs_data.flags = NFS_MOUNT_NONLM; /* No lockd in nfs root yet */
nfs_data.rsize = NFS_DEF_FILE_IO_BUFFER_SIZE;
nfs_data.wsize = NFS_DEF_FILE_IO_BUFFER_SIZE;
@@ -1183,8 +1195,8 @@ static int root_nfs_name(char *name)
/*
* Tell the user what's going on.
*/
-#ifdef NFSROOT_BOOTP
-static void root_nfs_print(void)
+#ifdef NFSROOT_DEBUG
+__initfunc(static void root_nfs_print(void))
{
#define IN_NTOA(x) (((x) == INADDR_NONE) ? "none" : in_ntoa(x))
@@ -1231,7 +1243,7 @@ static void root_nfs_print(void)
* one for BOOTP
* <bootp|rarp> - use both protocols to determine my own address
*/
-static void root_nfs_addrs(char *addrs)
+__initfunc(static void root_nfs_addrs(char *addrs))
{
char *cp, *ip, *dp;
int num = 0;
@@ -1314,7 +1326,7 @@ static void root_nfs_addrs(char *addrs)
/*
* Set the interface address and configure a route to the server.
*/
-static int root_nfs_setup(void)
+__initfunc(static int root_nfs_setup(void))
{
/* Set the default system name in case none was previously found */
if (!system_utsname.nodename[0]) {
@@ -1372,7 +1384,7 @@ static int root_nfs_setup(void)
* Get the necessary IP addresses and prepare for mounting the required
* NFS filesystem.
*/
-int nfs_root_init(char *nfsname, char *nfsaddrs)
+__initfunc(int nfs_root_init(char *nfsname, char *nfsaddrs))
{
#ifdef NFSROOT_DEBUG
nfs_debug |= NFSDBG_ROOT;
@@ -1461,14 +1473,14 @@ int nfs_root_init(char *nfsname, char *nfsaddrs)
/*
* Query server portmapper for the port of a daemon program
*/
-static int root_nfs_getport(int program, int version)
+__initfunc(static int root_nfs_getport(int program, int version))
{
struct sockaddr_in sin;
-printk(KERN_NOTICE "Looking up port of RPC %d/%d on %s\n",
- program, version, in_ntoa(servaddr));
- set_sockaddr(&sin, servaddr, 0);
- return rpc_getport_external(&sin, program, version, IPPROTO_UDP);
+ printk(KERN_NOTICE "Looking up port of RPC %d/%d on %s\n",
+ program, version, in_ntoa(servaddr));
+ set_sockaddr(&sin, servaddr, 0);
+ return rpc_getport_external(&sin, program, version, IPPROTO_UDP);
}
@@ -1478,7 +1490,7 @@ printk(KERN_NOTICE "Looking up port of RPC %d/%d on %s\n",
* keep this code is that we may want to use fallback ports. But is there
* actually someone who does not run portmap?
*/
-static int root_nfs_ports(void)
+__initfunc(static int root_nfs_ports(void))
{
int port;
@@ -1488,7 +1500,7 @@ static int root_nfs_ports(void)
"number from server, using default\n");
port = NFS_PORT;
}
- nfs_port = port;
+ nfs_port = htons(port);
dprintk("Root-NFS: Portmapper on server returned %d "
"as nfsd port\n", port);
}
@@ -1511,7 +1523,7 @@ static int root_nfs_ports(void)
* Get a file handle from the server for the directory which is to be
* mounted
*/
-static int root_nfs_get_handle(void)
+__initfunc(static int root_nfs_get_handle(void))
{
struct sockaddr_in sin;
int status;
@@ -1529,7 +1541,7 @@ static int root_nfs_get_handle(void)
/*
* Now actually mount the given directory
*/
-static int root_nfs_do_mount(struct super_block *sb)
+__initfunc(static int root_nfs_do_mount(struct super_block *sb))
{
/* Pass the server address to NFS */
set_sockaddr((struct sockaddr_in *) &nfs_data.addr, servaddr, nfs_port);
@@ -1545,7 +1557,7 @@ static int root_nfs_do_mount(struct super_block *sb)
* Get the NFS port numbers and file handle, and then read the super-
* block for mounting.
*/
-int nfs_root_mount(struct super_block *sb)
+__initfunc(int nfs_root_mount(struct super_block *sb))
{
if (root_nfs_ports() < 0)
return -1;
diff --git a/fs/super.c b/fs/super.c
index d24776cca..6048b1ae7 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -938,11 +938,7 @@ out:
return retval;
}
-#ifdef CONFIG_BLK_DEV_INITRD
-static void do_mount_root(void)
-#else
__initfunc(static void do_mount_root(void))
-#endif
{
struct file_system_type * fs_type;
struct super_block * sb;
@@ -1060,7 +1056,9 @@ __initfunc(void mount_root(void))
#ifdef CONFIG_BLK_DEV_INITRD
-int change_root(kdev_t new_root_dev,const char *put_old)
+extern int initmem_freed;
+
+__initfunc(static int do_change_root(kdev_t new_root_dev,const char *put_old))
{
kdev_t old_root_dev;
struct vfsmount *vfsmnt;
@@ -1114,4 +1112,13 @@ int change_root(kdev_t new_root_dev,const char *put_old)
return 0;
}
+int change_root(kdev_t new_root_dev,const char *put_old)
+{
+ if (initmem_freed) {
+ printk (KERN_CRIT "Initmem has been already freed. Staying in initrd\n");
+ return -EBUSY;
+ }
+ return do_change_root(new_root_dev, put_old);
+}
+
#endif