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 * @info: pointer to mount request arguments
34 * Uses default timeout parameters specified by underlying transport.
36 int nfs_mount(struct nfs_mount_request
*info
)
38 struct mnt_fhstatus result
= {
41 struct rpc_message msg
= {
42 .rpc_argp
= info
->dirpath
,
45 struct rpc_create_args args
= {
46 .protocol
= info
->protocol
,
48 .addrsize
= info
->salen
,
49 .servername
= info
->hostname
,
50 .program
= &mnt_program
,
51 .version
= info
->version
,
52 .authflavor
= RPC_AUTH_UNIX
,
54 struct rpc_clnt
*mnt_clnt
;
57 dprintk("NFS: sending MNT request for %s:%s\n",
58 (info
->hostname
? info
->hostname
: "server"),
62 args
.flags
|= RPC_CLNT_CREATE_NONPRIVPORT
;
64 mnt_clnt
= rpc_create(&args
);
68 if (info
->version
== NFS_MNT3_VERSION
)
69 msg
.rpc_proc
= &mnt_clnt
->cl_procinfo
[MOUNTPROC3_MNT
];
71 msg
.rpc_proc
= &mnt_clnt
->cl_procinfo
[MNTPROC_MNT
];
73 status
= rpc_call_sync(mnt_clnt
, &msg
, 0);
74 rpc_shutdown_client(mnt_clnt
);
78 if (result
.status
!= 0)
81 dprintk("NFS: MNT request succeeded\n");
88 status
= PTR_ERR(mnt_clnt
);
89 dprintk("NFS: failed to create RPC client, status=%d\n", status
);
93 dprintk("NFS: failed to start MNT request, status=%d\n", status
);
97 dprintk("NFS: MNT server returned result %d\n", result
.status
);
98 status
= nfs_stat_to_errno(result
.status
);
103 * XDR encode/decode functions for MOUNT
105 static int xdr_encode_dirpath(struct rpc_rqst
*req
, __be32
*p
,
108 p
= xdr_encode_string(p
, path
);
110 req
->rq_slen
= xdr_adjust_iovec(req
->rq_svec
, p
);
114 static int xdr_decode_fhstatus(struct rpc_rqst
*req
, __be32
*p
,
115 struct mnt_fhstatus
*res
)
117 struct nfs_fh
*fh
= res
->fh
;
119 if ((res
->status
= ntohl(*p
++)) == 0) {
120 fh
->size
= NFS2_FHSIZE
;
121 memcpy(fh
->data
, p
, NFS2_FHSIZE
);
126 static int xdr_decode_fhstatus3(struct rpc_rqst
*req
, __be32
*p
,
127 struct mnt_fhstatus
*res
)
129 struct nfs_fh
*fh
= res
->fh
;
132 if ((res
->status
= ntohl(*p
++)) == 0) {
134 if (size
<= NFS3_FHSIZE
&& size
!= 0) {
136 memcpy(fh
->data
, p
, size
);
138 res
->status
= -EBADHANDLE
;
143 #define MNT_dirpath_sz (1 + 256)
144 #define MNT_fhstatus_sz (1 + 8)
145 #define MNT_fhstatus3_sz (1 + 16)
147 static struct rpc_procinfo mnt_procedures
[] = {
149 .p_proc
= MNTPROC_MNT
,
150 .p_encode
= (kxdrproc_t
) xdr_encode_dirpath
,
151 .p_decode
= (kxdrproc_t
) xdr_decode_fhstatus
,
152 .p_arglen
= MNT_dirpath_sz
,
153 .p_replen
= MNT_fhstatus_sz
,
154 .p_statidx
= MNTPROC_MNT
,
159 static struct rpc_procinfo mnt3_procedures
[] = {
161 .p_proc
= MOUNTPROC3_MNT
,
162 .p_encode
= (kxdrproc_t
) xdr_encode_dirpath
,
163 .p_decode
= (kxdrproc_t
) xdr_decode_fhstatus3
,
164 .p_arglen
= MNT_dirpath_sz
,
165 .p_replen
= MNT_fhstatus3_sz
,
166 .p_statidx
= MOUNTPROC3_MNT
,
172 static struct rpc_version mnt_version1
= {
175 .procs
= mnt_procedures
,
178 static struct rpc_version mnt_version3
= {
181 .procs
= mnt3_procedures
,
184 static struct rpc_version
*mnt_version
[] = {
191 static struct rpc_stat mnt_stats
;
193 static struct rpc_program mnt_program
= {
195 .number
= NFS_MNT_PROGRAM
,
196 .nrvers
= ARRAY_SIZE(mnt_version
),
197 .version
= mnt_version
,