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
24 * Defined by RFC 1094, section A.5
31 MOUNTPROC_UMNTALL
= 4,
36 * Defined by RFC 1813, section 5.2
43 MOUNTPROC3_UMNTALL
= 4,
44 MOUNTPROC3_EXPORT
= 5,
47 static struct rpc_program mnt_program
;
55 * nfs_mount - Obtain an NFS file handle for the given host and path
56 * @info: pointer to mount request arguments
58 * Uses default timeout parameters specified by underlying transport.
60 int nfs_mount(struct nfs_mount_request
*info
)
62 struct mnt_fhstatus result
= {
65 struct rpc_message msg
= {
66 .rpc_argp
= info
->dirpath
,
69 struct rpc_create_args args
= {
70 .protocol
= info
->protocol
,
72 .addrsize
= info
->salen
,
73 .servername
= info
->hostname
,
74 .program
= &mnt_program
,
75 .version
= info
->version
,
76 .authflavor
= RPC_AUTH_UNIX
,
78 struct rpc_clnt
*mnt_clnt
;
81 dprintk("NFS: sending MNT request for %s:%s\n",
82 (info
->hostname
? info
->hostname
: "server"),
86 args
.flags
|= RPC_CLNT_CREATE_NONPRIVPORT
;
88 mnt_clnt
= rpc_create(&args
);
92 if (info
->version
== NFS_MNT3_VERSION
)
93 msg
.rpc_proc
= &mnt_clnt
->cl_procinfo
[MOUNTPROC3_MNT
];
95 msg
.rpc_proc
= &mnt_clnt
->cl_procinfo
[MOUNTPROC_MNT
];
97 status
= rpc_call_sync(mnt_clnt
, &msg
, 0);
98 rpc_shutdown_client(mnt_clnt
);
102 if (result
.status
!= 0)
105 dprintk("NFS: MNT request succeeded\n");
112 status
= PTR_ERR(mnt_clnt
);
113 dprintk("NFS: failed to create RPC client, status=%d\n", status
);
117 dprintk("NFS: failed to start MNT request, status=%d\n", status
);
121 dprintk("NFS: MNT server returned result %d\n", result
.status
);
122 status
= nfs_stat_to_errno(result
.status
);
127 * XDR encode/decode functions for MOUNT
129 static int xdr_encode_dirpath(struct rpc_rqst
*req
, __be32
*p
,
132 p
= xdr_encode_string(p
, path
);
134 req
->rq_slen
= xdr_adjust_iovec(req
->rq_svec
, p
);
138 static int xdr_decode_fhstatus(struct rpc_rqst
*req
, __be32
*p
,
139 struct mnt_fhstatus
*res
)
141 struct nfs_fh
*fh
= res
->fh
;
143 if ((res
->status
= ntohl(*p
++)) == 0) {
144 fh
->size
= NFS2_FHSIZE
;
145 memcpy(fh
->data
, p
, NFS2_FHSIZE
);
150 static int xdr_decode_fhstatus3(struct rpc_rqst
*req
, __be32
*p
,
151 struct mnt_fhstatus
*res
)
153 struct nfs_fh
*fh
= res
->fh
;
156 if ((res
->status
= ntohl(*p
++)) == 0) {
158 if (size
<= NFS3_FHSIZE
&& size
!= 0) {
160 memcpy(fh
->data
, p
, size
);
162 res
->status
= -EBADHANDLE
;
167 #define MNT_dirpath_sz (1 + 256)
168 #define MNT_fhstatus_sz (1 + 8)
169 #define MNT_fhstatus3_sz (1 + 16)
171 static struct rpc_procinfo mnt_procedures
[] = {
173 .p_proc
= MOUNTPROC_MNT
,
174 .p_encode
= (kxdrproc_t
) xdr_encode_dirpath
,
175 .p_decode
= (kxdrproc_t
) xdr_decode_fhstatus
,
176 .p_arglen
= MNT_dirpath_sz
,
177 .p_replen
= MNT_fhstatus_sz
,
178 .p_statidx
= MOUNTPROC_MNT
,
183 static struct rpc_procinfo mnt3_procedures
[] = {
185 .p_proc
= MOUNTPROC3_MNT
,
186 .p_encode
= (kxdrproc_t
) xdr_encode_dirpath
,
187 .p_decode
= (kxdrproc_t
) xdr_decode_fhstatus3
,
188 .p_arglen
= MNT_dirpath_sz
,
189 .p_replen
= MNT_fhstatus3_sz
,
190 .p_statidx
= MOUNTPROC3_MNT
,
196 static struct rpc_version mnt_version1
= {
199 .procs
= mnt_procedures
,
202 static struct rpc_version mnt_version3
= {
205 .procs
= mnt3_procedures
,
208 static struct rpc_version
*mnt_version
[] = {
215 static struct rpc_stat mnt_stats
;
217 static struct rpc_program mnt_program
= {
219 .number
= NFS_MNT_PROGRAM
,
220 .nrvers
= ARRAY_SIZE(mnt_version
),
221 .version
= mnt_version
,