2 * linux/fs/nfs/mount_clnt.c
4 * MOUNT client to support NFSroot.
6 * Copyright (C) 1997, Olaf Kirch <okir@monad.swb.de>
9 #include <linux/types.h>
10 #include <linux/socket.h>
11 #include <linux/kernel.h>
12 #include <linux/errno.h>
13 #include <linux/uio.h>
14 #include <linux/net.h>
16 #include <linux/sunrpc/clnt.h>
17 #include <linux/sunrpc/xprt.h>
18 #include <linux/sunrpc/sched.h>
19 #include <linux/nfs_fs.h>
22 # define NFSDBG_FACILITY NFSDBG_ROOT
26 #define MOUNT_PROGRAM 100005
27 #define MOUNT_VERSION 1
32 static struct rpc_clnt
* mnt_create(char *, struct sockaddr_in
*,
34 static struct rpc_program mnt_program
;
42 * Obtain an NFS file handle for the given host and path
45 nfsroot_mount(struct sockaddr_in
*addr
, char *path
, struct nfs_fh
*fh
,
46 int version
, int protocol
)
48 struct rpc_clnt
*mnt_clnt
;
49 struct mnt_fhstatus result
= {
56 dprintk("NFS: nfs_mount(%08x:%s)\n",
57 (unsigned)ntohl(addr
->sin_addr
.s_addr
), path
);
59 sprintf(hostname
, "%u.%u.%u.%u", NIPQUAD(addr
->sin_addr
.s_addr
));
60 mnt_clnt
= mnt_create(hostname
, addr
, version
, protocol
);
62 return PTR_ERR(mnt_clnt
);
64 call
= (version
== NFS_MNT3_VERSION
) ? MOUNTPROC3_MNT
: MNTPROC_MNT
;
65 status
= rpc_call(mnt_clnt
, call
, path
, &result
, 0);
66 return status
< 0? status
: (result
.status
? -EACCES
: 0);
69 static struct rpc_clnt
*
70 mnt_create(char *hostname
, struct sockaddr_in
*srvaddr
, int version
,
73 struct rpc_xprt
*xprt
;
74 struct rpc_clnt
*clnt
;
76 xprt
= xprt_create_proto(protocol
, srvaddr
, NULL
);
78 return (struct rpc_clnt
*)xprt
;
80 clnt
= rpc_create_client(xprt
, hostname
,
81 &mnt_program
, version
,
84 clnt
->cl_softrtry
= 1;
93 * XDR encode/decode functions for MOUNT
96 xdr_encode_dirpath(struct rpc_rqst
*req
, u32
*p
, const char *path
)
98 p
= xdr_encode_string(p
, path
);
100 req
->rq_slen
= xdr_adjust_iovec(req
->rq_svec
, p
);
105 xdr_decode_fhstatus(struct rpc_rqst
*req
, u32
*p
, struct mnt_fhstatus
*res
)
107 struct nfs_fh
*fh
= res
->fh
;
109 if ((res
->status
= ntohl(*p
++)) == 0) {
110 fh
->size
= NFS2_FHSIZE
;
111 memcpy(fh
->data
, p
, NFS2_FHSIZE
);
117 xdr_decode_fhstatus3(struct rpc_rqst
*req
, u32
*p
, struct mnt_fhstatus
*res
)
119 struct nfs_fh
*fh
= res
->fh
;
121 if ((res
->status
= ntohl(*p
++)) == 0) {
122 int size
= ntohl(*p
++);
123 if (size
<= NFS3_FHSIZE
) {
125 memcpy(fh
->data
, p
, size
);
127 res
->status
= -EBADHANDLE
;
132 #define MNT_dirpath_sz (1 + 256)
133 #define MNT_fhstatus_sz (1 + 8)
135 static struct rpc_procinfo mnt_procedures
[] = {
137 .p_proc
= MNTPROC_MNT
,
138 .p_encode
= (kxdrproc_t
) xdr_encode_dirpath
,
139 .p_decode
= (kxdrproc_t
) xdr_decode_fhstatus
,
140 .p_bufsiz
= MNT_dirpath_sz
<< 2,
144 static struct rpc_procinfo mnt3_procedures
[] = {
146 .p_proc
= MOUNTPROC3_MNT
,
147 .p_encode
= (kxdrproc_t
) xdr_encode_dirpath
,
148 .p_decode
= (kxdrproc_t
) xdr_decode_fhstatus3
,
149 .p_bufsiz
= MNT_dirpath_sz
<< 2,
154 static struct rpc_version mnt_version1
= {
157 .procs
= mnt_procedures
160 static struct rpc_version mnt_version3
= {
163 .procs
= mnt3_procedures
166 static struct rpc_version
* mnt_version
[] = {
173 static struct rpc_stat mnt_stats
;
175 static struct rpc_program mnt_program
= {
177 .number
= NFS_MNT_PROGRAM
,
178 .nrvers
= sizeof(mnt_version
)/sizeof(mnt_version
[0]),
179 .version
= mnt_version
,