2 * In-kernel MOUNT protocol client
4 * Copyright (C) 1997, Olaf Kirch <okir@monad.swb.de>
7 #include <linux/types.h>
8 #include <linux/socket.h>
9 #include <linux/kernel.h>
10 #include <linux/errno.h>
11 #include <linux/uio.h>
12 #include <linux/net.h>
14 #include <linux/sunrpc/clnt.h>
15 #include <linux/sunrpc/sched.h>
16 #include <linux/nfs_fs.h>
20 # define NFSDBG_FACILITY NFSDBG_MOUNT
23 static struct rpc_program mnt_program
;
31 * nfs_mount - Obtain an NFS file handle for the given host and path
32 * @addr: pointer to server's address
33 * @len: size of server's address
34 * @hostname: name of server host, or NULL
35 * @path: pointer to string containing export path to mount
36 * @version: mount version to use for this request
37 * @protocol: transport protocol to use for thie request
38 * @fh: pointer to location to place returned file handle
40 * Uses default timeout parameters specified by underlying transport.
42 int nfs_mount(struct sockaddr
*addr
, size_t len
, char *hostname
, char *path
,
43 int version
, int protocol
, struct nfs_fh
*fh
)
45 struct mnt_fhstatus result
= {
48 struct rpc_message msg
= {
52 struct rpc_create_args args
= {
56 .servername
= hostname
,
57 .program
= &mnt_program
,
59 .authflavor
= RPC_AUTH_UNIX
,
62 struct rpc_clnt
*mnt_clnt
;
65 dprintk("NFS: sending MNT request for %s:%s\n",
66 (hostname
? hostname
: "server"), path
);
68 mnt_clnt
= rpc_create(&args
);
72 if (version
== NFS_MNT3_VERSION
)
73 msg
.rpc_proc
= &mnt_clnt
->cl_procinfo
[MOUNTPROC3_MNT
];
75 msg
.rpc_proc
= &mnt_clnt
->cl_procinfo
[MNTPROC_MNT
];
77 status
= rpc_call_sync(mnt_clnt
, &msg
, 0);
78 rpc_shutdown_client(mnt_clnt
);
82 if (result
.status
!= 0)
85 dprintk("NFS: MNT request succeeded\n");
92 status
= PTR_ERR(mnt_clnt
);
93 dprintk("NFS: failed to create RPC client, status=%d\n", status
);
97 dprintk("NFS: failed to start MNT request, status=%d\n", status
);
101 dprintk("NFS: MNT server returned result %d\n", result
.status
);
102 status
= nfs_stat_to_errno(result
.status
);
107 * XDR encode/decode functions for MOUNT
109 static int xdr_encode_dirpath(struct rpc_rqst
*req
, __be32
*p
,
112 p
= xdr_encode_string(p
, path
);
114 req
->rq_slen
= xdr_adjust_iovec(req
->rq_svec
, p
);
118 static int xdr_decode_fhstatus(struct rpc_rqst
*req
, __be32
*p
,
119 struct mnt_fhstatus
*res
)
121 struct nfs_fh
*fh
= res
->fh
;
123 if ((res
->status
= ntohl(*p
++)) == 0) {
124 fh
->size
= NFS2_FHSIZE
;
125 memcpy(fh
->data
, p
, NFS2_FHSIZE
);
130 static int xdr_decode_fhstatus3(struct rpc_rqst
*req
, __be32
*p
,
131 struct mnt_fhstatus
*res
)
133 struct nfs_fh
*fh
= res
->fh
;
136 if ((res
->status
= ntohl(*p
++)) == 0) {
138 if (size
<= NFS3_FHSIZE
&& size
!= 0) {
140 memcpy(fh
->data
, p
, size
);
142 res
->status
= -EBADHANDLE
;
147 #define MNT_dirpath_sz (1 + 256)
148 #define MNT_fhstatus_sz (1 + 8)
149 #define MNT_fhstatus3_sz (1 + 16)
151 static struct rpc_procinfo mnt_procedures
[] = {
153 .p_proc
= MNTPROC_MNT
,
154 .p_encode
= (kxdrproc_t
) xdr_encode_dirpath
,
155 .p_decode
= (kxdrproc_t
) xdr_decode_fhstatus
,
156 .p_arglen
= MNT_dirpath_sz
,
157 .p_replen
= MNT_fhstatus_sz
,
158 .p_statidx
= MNTPROC_MNT
,
163 static struct rpc_procinfo mnt3_procedures
[] = {
165 .p_proc
= MOUNTPROC3_MNT
,
166 .p_encode
= (kxdrproc_t
) xdr_encode_dirpath
,
167 .p_decode
= (kxdrproc_t
) xdr_decode_fhstatus3
,
168 .p_arglen
= MNT_dirpath_sz
,
169 .p_replen
= MNT_fhstatus3_sz
,
170 .p_statidx
= MOUNTPROC3_MNT
,
176 static struct rpc_version mnt_version1
= {
179 .procs
= mnt_procedures
,
182 static struct rpc_version mnt_version3
= {
185 .procs
= mnt3_procedures
,
188 static struct rpc_version
*mnt_version
[] = {
195 static struct rpc_stat mnt_stats
;
197 static struct rpc_program mnt_program
= {
199 .number
= NFS_MNT_PROGRAM
,
200 .nrvers
= ARRAY_SIZE(mnt_version
),
201 .version
= mnt_version
,