patch-1.3.77 linux/fs/nfs/nfsroot.c
Next file: linux/fs/proc/array.c
Previous file: linux/fs/msdos/namei.c
Back to the patch index
Back to the overall index
- Lines: 214
- Date:
Thu Mar 21 08:56:46 1996
- Orig file:
v1.3.76/linux/fs/nfs/nfsroot.c
- Orig date:
Wed Mar 20 10:59:59 1996
diff -u --recursive --new-file v1.3.76/linux/fs/nfs/nfsroot.c linux/fs/nfs/nfsroot.c
@@ -27,6 +27,9 @@
* Martin Mares : Code cleanup.
* Martin Mares : (2.1) BOOTP and RARP made configuration options.
* Martin Mares : Server hostname generation fixed.
+ * Gerd Knorr : Fixed wired inode handling
+ * Martin Mares : (2.2) "0.0.0.0" addresses from command line ignored.
+ * Martin Mares : RARP replies not tested for server address.
*
*
* Known bugs and caveats:
@@ -128,7 +131,7 @@
/* Yes, we use sys_socket, but there's no include file for it */
extern asmlinkage int sys_socket(int family, int type, int protocol);
-
+
/***************************************************************************
@@ -302,12 +305,6 @@
kfree_skb(skb, FREE_READ);
return 0;
}
- /* Discard packets which are not from specified server. */
- if (server.sin_addr.s_addr != INADDR_NONE &&
- server.sin_addr.s_addr != sip) {
- kfree_skb(skb, FREE_READ);
- return 0;
- }
/*
* The packet is what we were looking for. Setup the global
@@ -1170,7 +1167,7 @@
while (ip && *ip) {
if ((cp = strchr(ip, ':')))
*cp++ = '\0';
- if (strlen(ip) > 0) {
+ if (strlen(ip) > 0 && strcmp(ip, "0.0.0.0")) {
switch (num) {
case 0:
myaddr.sin_addr.s_addr = in_aton(ip);
@@ -1361,8 +1358,8 @@
***************************************************************************/
-static struct file nfs_file; /* File descriptor containing socket */
-static struct inode nfs_inode; /* Inode containing socket */
+static struct file *nfs_file;
+static struct inode *nfs_sock_inode; /* Inode containing socket */
static int *rpc_packet = NULL; /* RPC packet */
@@ -1371,63 +1368,28 @@
*/
static int root_nfs_open(void)
{
- struct file *filp;
-
/* Open the socket */
if ((nfs_data.fd = sys_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
printk(KERN_ERR "Root-NFS: Cannot open UDP socket!\n");
return -1;
}
- /*
- * Copy the file and inode data area so that we can remove the
- * file lateron without killing the socket. After all this the
- * closing routine just needs to remove the file pointer from the
- * init-task descriptor.
- */
- filp = current->files->fd[nfs_data.fd];
- memcpy(&nfs_file, filp, sizeof(struct file));
- nfs_file.f_next = nfs_file.f_prev = NULL;
- current->files->fd[nfs_data.fd] = &nfs_file;
- filp->f_count = 0; /* Free the file descriptor */
-
- memcpy(&nfs_inode, nfs_file.f_inode, sizeof(struct inode));
- nfs_inode.i_hash_next = nfs_inode.i_hash_prev = NULL;
- nfs_inode.i_next = nfs_inode.i_prev = NULL;
- clear_inode(nfs_file.f_inode);
- nfs_file.f_inode = &nfs_inode;
- nfs_inode.u.socket_i.inode = &nfs_inode;
- nfs_file.private_data = NULL;
+ nfs_file = current->files->fd[nfs_data.fd];
+ nfs_sock_inode = nfs_file->f_inode;
+ /* keep socket open. Do we need really this ? */
+ /* nfs_file->f_count++; */
return 0;
}
/*
- * Close the UDP file descriptor. The main part of preserving the socket
- * has already been done after opening it. Now we have to remove the file
- * descriptor from the init task.
+ * Close the UDP file descriptor. If nfs_read_super is successful, it
+ * increases the reference count, so we can simply close the file, and
+ * the socket keeps open.
*/
static void root_nfs_close(int close_all)
{
- /* Remove the file from the list of open files */
- current->files->fd[nfs_data.fd] = NULL;
- if (current->files->count > 0)
- current->files->count--;
-
- /* Clear memory used by the RPC packet */
- if (rpc_packet != NULL)
- kfree_s(rpc_packet, nfs_data.wsize + 1024);
-
- /*
- * In case of an error we also have to close the socket again
- * (sigh)
- */
- if (close_all) {
- nfs_inode.u.socket_i.inode = NULL; /* The inode is already
- * cleared */
- if (nfs_file.f_op->release)
- nfs_file.f_op->release(&nfs_inode, &nfs_file);
- }
+ sys_close(nfs_data.fd);
}
@@ -1441,14 +1403,15 @@
struct sockaddr_in *sin = &myaddr;
int i;
- if (nfs_inode.u.socket_i.ops->bind) {
+ if (nfs_sock_inode->u.socket_i.ops->bind) {
for (i = 0; i < NPORTS && res < 0; i++) {
sin->sin_port = htons(port++);
if (port > ENDPORT) {
port = STARTPORT;
}
- res = nfs_inode.u.socket_i.ops->bind(&nfs_inode.u.socket_i,
- (struct sockaddr *)sin, sizeof(struct sockaddr_in));
+ res = nfs_sock_inode->u.socket_i.ops->bind
+ (&nfs_sock_inode->u.socket_i,
+ (struct sockaddr *)sin, sizeof(struct sockaddr_in));
}
}
if (res < 0) {
@@ -1468,11 +1431,10 @@
*/
static int *root_nfs_call(int *end)
{
- struct file *filp;
struct socket *sock;
int dummylen;
static struct nfs_server s = {
- &nfs_file, /* struct file * */
+ 0, /* struct file * */
0, /* struct rsock * */
{
0, "",
@@ -1486,8 +1448,8 @@
3 * HZ, 60 * HZ, 30 * HZ, 60 * HZ, "\0"
};
- filp = &nfs_file;
- sock = &((filp->f_inode)->u.socket_i);
+ s.file = nfs_file;
+ sock = &((nfs_file->f_inode)->u.socket_i);
/* extract the other end of the socket into s->toaddr */
sock->ops->getname(sock, &(s.toaddr), &dummylen, 1);
@@ -1495,7 +1457,7 @@
((struct sockaddr_in *) &s.toaddr)->sin_family = server.sin_family;
((struct sockaddr_in *) &s.toaddr)->sin_addr.s_addr = server.sin_addr.s_addr;
- s.rsock = rpc_makesock(filp);
+ s.rsock = rpc_makesock(nfs_file);
s.flags = nfs_data.flags;
s.rsize = nfs_data.rsize;
s.wsize = nfs_data.wsize;
@@ -1507,12 +1469,13 @@
* First connect the UDP socket to a server port, then send the
* packet out, and finally check wether the answer is OK.
*/
- if (nfs_inode.u.socket_i.ops->connect &&
- nfs_inode.u.socket_i.ops->connect(&nfs_inode.u.socket_i,
- (struct sockaddr *) &server,
- sizeof(struct sockaddr_in),
- nfs_file.f_flags) < 0)
- return NULL;
+ if (nfs_sock_inode->u.socket_i.ops->connect &&
+ nfs_sock_inode->u.socket_i.ops->connect
+ (&nfs_sock_inode->u.socket_i,
+ (struct sockaddr *) &server,
+ sizeof(struct sockaddr_in),
+ nfs_file->f_flags) < 0)
+ return NULL;
if (nfs_rpc_call(&s, rpc_packet, end, nfs_data.wsize) < 0)
return NULL;
return rpc_verify(rpc_packet);
@@ -1643,11 +1606,12 @@
/* First connect to the nfsd port on the server */
server.sin_port = htons(nfs_port);
nfs_data.addr = server;
- if (nfs_inode.u.socket_i.ops->connect &&
- nfs_inode.u.socket_i.ops->connect(&nfs_inode.u.socket_i,
- (struct sockaddr *) &server,
- sizeof(struct sockaddr_in),
- nfs_file.f_flags) < 0) {
+ if (nfs_sock_inode->u.socket_i.ops->connect &&
+ nfs_sock_inode->u.socket_i.ops->connect
+ (&nfs_sock_inode->u.socket_i,
+ (struct sockaddr *) &server,
+ sizeof(struct sockaddr_in),
+ nfs_file->f_flags) < 0) {
root_nfs_close(1);
return -1;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this