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
= {
52 struct rpc_message msg
= {
59 dprintk("NFS: nfs_mount(%08x:%s)\n",
60 (unsigned)ntohl(addr
->sin_addr
.s_addr
), path
);
62 sprintf(hostname
, "%u.%u.%u.%u", NIPQUAD(addr
->sin_addr
.s_addr
));
63 mnt_clnt
= mnt_create(hostname
, addr
, version
, protocol
);
65 return PTR_ERR(mnt_clnt
);
67 if (version
== NFS_MNT3_VERSION
)
68 msg
.rpc_proc
= &mnt_clnt
->cl_procinfo
[MOUNTPROC3_MNT
];
70 msg
.rpc_proc
= &mnt_clnt
->cl_procinfo
[MNTPROC_MNT
];
72 status
= rpc_call_sync(mnt_clnt
, &msg
, 0);
73 return status
< 0? status
: (result
.status
? -EACCES
: 0);
76 static struct rpc_clnt
*
77 mnt_create(char *hostname
, struct sockaddr_in
*srvaddr
, int version
,
80 struct rpc_xprt
*xprt
;
81 struct rpc_clnt
*clnt
;
83 xprt
= xprt_create_proto(protocol
, srvaddr
, NULL
);
85 return (struct rpc_clnt
*)xprt
;
87 clnt
= rpc_create_client(xprt
, hostname
,
88 &mnt_program
, version
,
91 clnt
->cl_softrtry
= 1;
99 * XDR encode/decode functions for MOUNT
102 xdr_encode_dirpath(struct rpc_rqst
*req
, u32
*p
, const char *path
)
104 p
= xdr_encode_string(p
, path
);
106 req
->rq_slen
= xdr_adjust_iovec(req
->rq_svec
, p
);
111 xdr_decode_fhstatus(struct rpc_rqst
*req
, u32
*p
, struct mnt_fhstatus
*res
)
113 struct nfs_fh
*fh
= res
->fh
;
115 if ((res
->status
= ntohl(*p
++)) == 0) {
116 fh
->size
= NFS2_FHSIZE
;
117 memcpy(fh
->data
, p
, NFS2_FHSIZE
);
123 xdr_decode_fhstatus3(struct rpc_rqst
*req
, u32
*p
, struct mnt_fhstatus
*res
)
125 struct nfs_fh
*fh
= res
->fh
;
127 if ((res
->status
= ntohl(*p
++)) == 0) {
128 int size
= ntohl(*p
++);
129 if (size
<= NFS3_FHSIZE
) {
131 memcpy(fh
->data
, p
, size
);
133 res
->status
= -EBADHANDLE
;
138 #define MNT_dirpath_sz (1 + 256)
139 #define MNT_fhstatus_sz (1 + 8)
141 static struct rpc_procinfo mnt_procedures
[] = {
143 .p_proc
= MNTPROC_MNT
,
144 .p_encode
= (kxdrproc_t
) xdr_encode_dirpath
,
145 .p_decode
= (kxdrproc_t
) xdr_decode_fhstatus
,
146 .p_bufsiz
= MNT_dirpath_sz
<< 2,
147 .p_statidx
= MNTPROC_MNT
,
152 static struct rpc_procinfo mnt3_procedures
[] = {
154 .p_proc
= MOUNTPROC3_MNT
,
155 .p_encode
= (kxdrproc_t
) xdr_encode_dirpath
,
156 .p_decode
= (kxdrproc_t
) xdr_decode_fhstatus3
,
157 .p_bufsiz
= MNT_dirpath_sz
<< 2,
158 .p_statidx
= MOUNTPROC3_MNT
,
164 static struct rpc_version mnt_version1
= {
167 .procs
= mnt_procedures
170 static struct rpc_version mnt_version3
= {
173 .procs
= mnt3_procedures
176 static struct rpc_version
* mnt_version
[] = {
183 static struct rpc_stat mnt_stats
;
185 static struct rpc_program mnt_program
= {
187 .number
= NFS_MNT_PROGRAM
,
188 .nrvers
= ARRAY_SIZE(mnt_version
),
189 .version
= mnt_version
,