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/sched.h>
18 #include <linux/nfs_fs.h>
21 # define NFSDBG_FACILITY NFSDBG_ROOT
25 #define MOUNT_PROGRAM 100005
26 #define MOUNT_VERSION 1
31 static struct rpc_clnt
* mnt_create(char *, struct sockaddr_in
*,
33 static struct rpc_program mnt_program
;
41 * Obtain an NFS file handle for the given host and path
44 nfsroot_mount(struct sockaddr_in
*addr
, char *path
, struct nfs_fh
*fh
,
45 int version
, int protocol
)
47 struct rpc_clnt
*mnt_clnt
;
48 struct mnt_fhstatus result
= {
51 struct rpc_message msg
= {
58 dprintk("NFS: nfs_mount(%08x:%s)\n",
59 (unsigned)ntohl(addr
->sin_addr
.s_addr
), path
);
61 sprintf(hostname
, "%u.%u.%u.%u", NIPQUAD(addr
->sin_addr
.s_addr
));
62 mnt_clnt
= mnt_create(hostname
, addr
, version
, protocol
);
64 return PTR_ERR(mnt_clnt
);
66 if (version
== NFS_MNT3_VERSION
)
67 msg
.rpc_proc
= &mnt_clnt
->cl_procinfo
[MOUNTPROC3_MNT
];
69 msg
.rpc_proc
= &mnt_clnt
->cl_procinfo
[MNTPROC_MNT
];
71 status
= rpc_call_sync(mnt_clnt
, &msg
, 0);
72 return status
< 0? status
: (result
.status
? -EACCES
: 0);
75 static struct rpc_clnt
*
76 mnt_create(char *hostname
, struct sockaddr_in
*srvaddr
, int version
,
79 struct rpc_create_args args
= {
81 .address
= (struct sockaddr
*)srvaddr
,
82 .addrsize
= sizeof(*srvaddr
),
83 .servername
= hostname
,
84 .program
= &mnt_program
,
86 .authflavor
= RPC_AUTH_UNIX
,
87 .flags
= (RPC_CLNT_CREATE_ONESHOT
|
88 RPC_CLNT_CREATE_INTR
),
91 return rpc_create(&args
);
95 * XDR encode/decode functions for MOUNT
98 xdr_encode_dirpath(struct rpc_rqst
*req
, __be32
*p
, const char *path
)
100 p
= xdr_encode_string(p
, path
);
102 req
->rq_slen
= xdr_adjust_iovec(req
->rq_svec
, p
);
107 xdr_decode_fhstatus(struct rpc_rqst
*req
, __be32
*p
, struct mnt_fhstatus
*res
)
109 struct nfs_fh
*fh
= res
->fh
;
111 if ((res
->status
= ntohl(*p
++)) == 0) {
112 fh
->size
= NFS2_FHSIZE
;
113 memcpy(fh
->data
, p
, NFS2_FHSIZE
);
119 xdr_decode_fhstatus3(struct rpc_rqst
*req
, __be32
*p
, struct mnt_fhstatus
*res
)
121 struct nfs_fh
*fh
= res
->fh
;
123 if ((res
->status
= ntohl(*p
++)) == 0) {
124 int size
= ntohl(*p
++);
125 if (size
<= NFS3_FHSIZE
) {
127 memcpy(fh
->data
, p
, size
);
129 res
->status
= -EBADHANDLE
;
134 #define MNT_dirpath_sz (1 + 256)
135 #define MNT_fhstatus_sz (1 + 8)
136 #define MNT_fhstatus3_sz (1 + 16)
138 static struct rpc_procinfo mnt_procedures
[] = {
140 .p_proc
= MNTPROC_MNT
,
141 .p_encode
= (kxdrproc_t
) xdr_encode_dirpath
,
142 .p_decode
= (kxdrproc_t
) xdr_decode_fhstatus
,
143 .p_arglen
= MNT_dirpath_sz
,
144 .p_replen
= MNT_fhstatus_sz
,
145 .p_statidx
= MNTPROC_MNT
,
150 static struct rpc_procinfo mnt3_procedures
[] = {
152 .p_proc
= MOUNTPROC3_MNT
,
153 .p_encode
= (kxdrproc_t
) xdr_encode_dirpath
,
154 .p_decode
= (kxdrproc_t
) xdr_decode_fhstatus3
,
155 .p_arglen
= MNT_dirpath_sz
,
156 .p_replen
= MNT_fhstatus3_sz
,
157 .p_statidx
= MOUNTPROC3_MNT
,
163 static struct rpc_version mnt_version1
= {
166 .procs
= mnt_procedures
169 static struct rpc_version mnt_version3
= {
172 .procs
= mnt3_procedures
175 static struct rpc_version
* mnt_version
[] = {
182 static struct rpc_stat mnt_stats
;
184 static struct rpc_program mnt_program
= {
186 .number
= NFS_MNT_PROGRAM
,
187 .nrvers
= ARRAY_SIZE(mnt_version
),
188 .version
= mnt_version
,