~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/fs/nfs/mount_clnt.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * linux/fs/nfs/mount_clnt.c
  3  *
  4  * MOUNT client to support NFSroot.
  5  *
  6  * Copyright (C) 1997, Olaf Kirch <okir@monad.swb.de>
  7  */
  8 
  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>
 15 #include <linux/in.h>
 16 #include <linux/inet.h>
 17 #include <linux/sunrpc/clnt.h>
 18 #include <linux/sunrpc/xprt.h>
 19 #include <linux/sunrpc/sched.h>
 20 #include <linux/nfs_fs.h>
 21 
 22 #ifdef RPC_DEBUG
 23 # define NFSDBG_FACILITY        NFSDBG_ROOT
 24 #endif
 25 
 26 /*
 27 #define MOUNT_PROGRAM           100005
 28 #define MOUNT_VERSION           1
 29 #define MOUNT_MNT               1
 30 #define MOUNT_UMNT              3
 31  */
 32 
 33 static int                      nfs_gen_mount(struct sockaddr_in *,
 34                                               char *, struct nfs_fh *, int);
 35 static struct rpc_clnt *        mnt_create(char *, struct sockaddr_in *, int);
 36 extern struct rpc_program       mnt_program;
 37 
 38 struct mnt_fhstatus {
 39         unsigned int            status;
 40         struct nfs_fh *         fh;
 41 };
 42 
 43 /*
 44  * Obtain an NFS file handle for the given host and path
 45  */
 46 int
 47 nfs_mount(struct sockaddr_in *addr, char *path, struct nfs_fh *fh)
 48 {
 49         return nfs_gen_mount(addr, path, fh, NFS_MNT_VERSION);
 50 }
 51 
 52 int
 53 nfs3_mount(struct sockaddr_in *addr, char *path, struct nfs_fh *fh)
 54 {
 55         return nfs_gen_mount(addr, path, fh, NFS_MNT3_VERSION);
 56 }
 57 
 58 static int
 59 nfs_gen_mount(struct sockaddr_in *addr, char *path, struct nfs_fh *fh, int version)
 60 {
 61         struct rpc_clnt         *mnt_clnt;
 62         struct mnt_fhstatus     result = { 0, fh };
 63         char                    hostname[32];
 64         int                     status;
 65         int                     call;
 66 
 67         dprintk("NFS:      nfs_mount(%08x:%s)\n",
 68                         (unsigned)ntohl(addr->sin_addr.s_addr), path);
 69 
 70         strcpy(hostname, in_ntoa(addr->sin_addr.s_addr));
 71         if (!(mnt_clnt = mnt_create(hostname, addr, version)))
 72                 return -EACCES;
 73 
 74         call = (version == 3) ? MOUNTPROC3_MNT : MNTPROC_MNT;
 75         status = rpc_call(mnt_clnt, call, path, &result, 0);
 76         return status < 0? status : (result.status? -EACCES : 0);
 77 }
 78 
 79 static struct rpc_clnt *
 80 mnt_create(char *hostname, struct sockaddr_in *srvaddr, int version)
 81 {
 82         struct rpc_xprt *xprt;
 83         struct rpc_clnt *clnt;
 84 
 85         if (!(xprt = xprt_create_proto(IPPROTO_UDP, srvaddr, NULL)))
 86                 return NULL;
 87 
 88         clnt = rpc_create_client(xprt, hostname,
 89                                 &mnt_program, version,
 90                                 RPC_AUTH_NULL);
 91         if (!clnt) {
 92                 xprt_destroy(xprt);
 93         } else {
 94                 clnt->cl_softrtry = 1;
 95                 clnt->cl_chatty   = 1;
 96                 clnt->cl_oneshot  = 1;
 97                 clnt->cl_intr = 1;
 98         }
 99         return clnt;
100 }
101 
102 /*
103  * XDR encode/decode functions for MOUNT
104  */
105 static int
106 xdr_error(struct rpc_rqst *req, u32 *p, void *dummy)
107 {
108         return -EIO;
109 }
110 
111 static int
112 xdr_encode_dirpath(struct rpc_rqst *req, u32 *p, const char *path)
113 {
114         p = xdr_encode_string(p, path);
115 
116         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
117         return 0;
118 }
119 
120 static int
121 xdr_decode_fhstatus(struct rpc_rqst *req, u32 *p, struct mnt_fhstatus *res)
122 {
123         struct nfs_fh *fh = res->fh;
124 
125         memset((void *)fh, 0, sizeof(*fh));
126         if ((res->status = ntohl(*p++)) == 0) {
127                 fh->size = NFS2_FHSIZE;
128                 memcpy(fh->data, p, NFS2_FHSIZE);
129         }
130         return 0;
131 }
132 
133 static int
134 xdr_decode_fhstatus3(struct rpc_rqst *req, u32 *p, struct mnt_fhstatus *res)
135 {
136         struct nfs_fh *fh = res->fh;
137 
138         memset((void *)fh, 0, sizeof(*fh));
139         if ((res->status = ntohl(*p++)) == 0) {
140                 int size = ntohl(*p++);
141                 if (size <= NFS3_FHSIZE) {
142                         fh->size = size;
143                         memcpy(fh->data, p, size);
144                 } else
145                         res->status = -EBADHANDLE;
146         }
147         return 0;
148 }
149 
150 #define MNT_dirpath_sz          (1 + 256)
151 #define MNT_fhstatus_sz         (1 + 8)
152 
153 static struct rpc_procinfo      mnt_procedures[2] = {
154         { "mnt_null",
155                 (kxdrproc_t) xdr_error, 
156                 (kxdrproc_t) xdr_error, 0, 0 },
157         { "mnt_mount",
158                 (kxdrproc_t) xdr_encode_dirpath,        
159                 (kxdrproc_t) xdr_decode_fhstatus,
160                 MNT_dirpath_sz << 2, 0 },
161 };
162 
163 static struct rpc_procinfo mnt3_procedures[2] = {
164         { "mnt3_null",
165                 (kxdrproc_t) xdr_error,
166                 (kxdrproc_t) xdr_error, 0, 0 },
167         { "mnt3_mount",
168                 (kxdrproc_t) xdr_encode_dirpath,
169                 (kxdrproc_t) xdr_decode_fhstatus3,
170                 MNT_dirpath_sz << 2, 0 },
171 };
172 
173 
174 static struct rpc_version       mnt_version1 = {
175         1, 2, mnt_procedures
176 };
177 
178 static struct rpc_version       mnt_version3 = {
179         3, 2, mnt3_procedures
180 };
181 
182 static struct rpc_version *     mnt_version[] = {
183         NULL,
184         &mnt_version1,
185         NULL,
186         &mnt_version3,
187 };
188 
189 static struct rpc_stat          mnt_stats;
190 
191 struct rpc_program      mnt_program = {
192         "mount",
193         NFS_MNT_PROGRAM,
194         sizeof(mnt_version)/sizeof(mnt_version[0]),
195         mnt_version,
196         &mnt_stats,
197 };
198 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.