Commit 20eb6a8b authored by Chuck Lever's avatar Chuck Lever Committed by Linus Torvalds

[PATCH] allow nfsroot to mount with TCP

nfsroot needs to pass the network protocol (UDP/TCP) into the mount
functions in order to support mounting root partitions via NFS over TCP.
parent 249502cc
...@@ -29,10 +29,9 @@ ...@@ -29,10 +29,9 @@
#define MOUNT_UMNT 3 #define MOUNT_UMNT 3
*/ */
static int nfs_gen_mount(struct sockaddr_in *, static struct rpc_clnt * mnt_create(char *, struct sockaddr_in *,
char *, struct nfs_fh *, int); int, int);
static struct rpc_clnt * mnt_create(char *, struct sockaddr_in *, int); struct rpc_program mnt_program;
extern struct rpc_program mnt_program;
struct mnt_fhstatus { struct mnt_fhstatus {
unsigned int status; unsigned int status;
...@@ -43,19 +42,8 @@ struct mnt_fhstatus { ...@@ -43,19 +42,8 @@ struct mnt_fhstatus {
* Obtain an NFS file handle for the given host and path * Obtain an NFS file handle for the given host and path
*/ */
int int
nfs_mount(struct sockaddr_in *addr, char *path, struct nfs_fh *fh) nfsroot_mount(struct sockaddr_in *addr, char *path, struct nfs_fh *fh,
{ int version, int protocol)
return nfs_gen_mount(addr, path, fh, NFS_MNT_VERSION);
}
int
nfs3_mount(struct sockaddr_in *addr, char *path, struct nfs_fh *fh)
{
return nfs_gen_mount(addr, path, fh, NFS_MNT3_VERSION);
}
static int
nfs_gen_mount(struct sockaddr_in *addr, char *path, struct nfs_fh *fh, int version)
{ {
struct rpc_clnt *mnt_clnt; struct rpc_clnt *mnt_clnt;
struct mnt_fhstatus result = { struct mnt_fhstatus result = {
...@@ -69,21 +57,22 @@ nfs_gen_mount(struct sockaddr_in *addr, char *path, struct nfs_fh *fh, int versi ...@@ -69,21 +57,22 @@ nfs_gen_mount(struct sockaddr_in *addr, char *path, struct nfs_fh *fh, int versi
(unsigned)ntohl(addr->sin_addr.s_addr), path); (unsigned)ntohl(addr->sin_addr.s_addr), path);
sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(addr->sin_addr.s_addr)); sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(addr->sin_addr.s_addr));
if (!(mnt_clnt = mnt_create(hostname, addr, version))) if (!(mnt_clnt = mnt_create(hostname, addr, version, protocol)))
return -EACCES; return -EACCES;
call = (version == 3) ? MOUNTPROC3_MNT : MNTPROC_MNT; call = (version == NFS_MNT3_VERSION) ? MOUNTPROC3_MNT : MNTPROC_MNT;
status = rpc_call(mnt_clnt, call, path, &result, 0); status = rpc_call(mnt_clnt, call, path, &result, 0);
return status < 0? status : (result.status? -EACCES : 0); return status < 0? status : (result.status? -EACCES : 0);
} }
static struct rpc_clnt * static struct rpc_clnt *
mnt_create(char *hostname, struct sockaddr_in *srvaddr, int version) mnt_create(char *hostname, struct sockaddr_in *srvaddr, int version,
int protocol)
{ {
struct rpc_xprt *xprt; struct rpc_xprt *xprt;
struct rpc_clnt *clnt; struct rpc_clnt *clnt;
if (!(xprt = xprt_create_proto(IPPROTO_UDP, srvaddr, NULL))) if (!(xprt = xprt_create_proto(protocol, srvaddr, NULL)))
return NULL; return NULL;
clnt = rpc_create_client(xprt, hostname, clnt = rpc_create_client(xprt, hostname,
......
...@@ -64,6 +64,8 @@ ...@@ -64,6 +64,8 @@
* Trond Myklebust : Add in preliminary support for NFSv3 and TCP. * Trond Myklebust : Add in preliminary support for NFSv3 and TCP.
* Fix bug in root_nfs_addr(). nfs_data.namlen * Fix bug in root_nfs_addr(). nfs_data.namlen
* is NOT for the length of the hostname. * is NOT for the length of the hostname.
* Hua Qin : Support for mounting root file system via
* NFS over TCP.
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -440,12 +442,14 @@ static int __init root_nfs_get_handle(void) ...@@ -440,12 +442,14 @@ static int __init root_nfs_get_handle(void)
{ {
struct sockaddr_in sin; struct sockaddr_in sin;
int status; int status;
int protocol = (nfs_data.flags & NFS_MOUNT_TCP) ?
IPPROTO_TCP : IPPROTO_UDP;
int version = (nfs_data.flags & NFS_MOUNT_VER3) ?
NFS_MNT3_VERSION : NFS_MNT_VERSION;
set_sockaddr(&sin, servaddr, mount_port); set_sockaddr(&sin, servaddr, mount_port);
if (nfs_data.flags & NFS_MOUNT_VER3) status = nfsroot_mount(&sin, nfs_path, &nfs_data.root,
status = nfs3_mount(&sin, nfs_path, &nfs_data.root); version, protocol);
else
status = nfs_mount(&sin, nfs_path, &nfs_data.root);
if (status < 0) if (status < 0)
printk(KERN_ERR "Root-NFS: Server returned error %d " printk(KERN_ERR "Root-NFS: Server returned error %d "
"while mounting %s\n", status, nfs_path); "while mounting %s\n", status, nfs_path);
......
...@@ -398,8 +398,8 @@ extern void nfs_readdata_release(struct rpc_task *); ...@@ -398,8 +398,8 @@ extern void nfs_readdata_release(struct rpc_task *);
* linux/fs/mount_clnt.c * linux/fs/mount_clnt.c
* (Used only by nfsroot module) * (Used only by nfsroot module)
*/ */
extern int nfs_mount(struct sockaddr_in *, char *, struct nfs_fh *); extern int nfsroot_mount(struct sockaddr_in *, char *, struct nfs_fh *,
extern int nfs3_mount(struct sockaddr_in *, char *, struct nfs_fh *); int, int);
/* /*
* inline functions * inline functions
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment