patch-2.2.18 linux/fs/nfs/mount_clnt.c
Next file: linux/fs/nfs/nfs2xdr.c
Previous file: linux/fs/nfs/inode.c
Back to the patch index
Back to the overall index
- Lines: 175
- Date:
Fri Sep 15 22:10:43 2000
- Orig file:
v2.2.17/fs/nfs/mount_clnt.c
- Orig date:
Fri Apr 21 12:46:44 2000
diff -u --new-file --recursive --exclude-from /usr/src/exclude v2.2.17/fs/nfs/mount_clnt.c linux/fs/nfs/mount_clnt.c
@@ -17,17 +17,14 @@
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/xprt.h>
#include <linux/sunrpc/sched.h>
+#include <linux/nfs2.h>
+#include <linux/nfs3.h>
#include <linux/nfs_fs.h>
#ifdef RPC_DEBUG
# define NFSDBG_FACILITY NFSDBG_ROOT
#endif
-#ifndef MAX
-# define MAX(a, b) (((a) > (b))? (a) : (b))
-#endif
-
-
/*
#define MOUNT_PROGRAM 100005
#define MOUNT_VERSION 1
@@ -35,7 +32,9 @@
#define MOUNT_UMNT 3
*/
-static struct rpc_clnt * mnt_create(char *, struct sockaddr_in *);
+static int nfs_gen_mount(struct sockaddr_in *, char *,
+ struct nfs_fh *, int);
+static struct rpc_clnt * mnt_create(char *, struct sockaddr_in *, int);
extern struct rpc_program mnt_program;
struct mnt_fhstatus {
@@ -43,30 +42,44 @@
struct nfs_fh * fh;
};
+int
+nfs_mount(struct sockaddr_in *addr, char *path, struct nfs_fh *fh)
+{
+ return nfs_gen_mount(addr, path, fh, NFS_MNT_VERSION);
+}
+
+int
+nfs3_mount(struct sockaddr_in *addr, char *path, struct nfs_fh *fh)
+{
+ return nfs_gen_mount(addr, path, fh, NFS_MNT3_VERSION);
+}
+
/*
* Obtain an NFS file handle for the given host and path
*/
-int
-nfs_mount(struct sockaddr_in *addr, char *path, struct nfs_fh *fh)
+static int
+nfs_gen_mount(struct sockaddr_in *addr, char *path, struct nfs_fh *fh, int version)
{
struct rpc_clnt *mnt_clnt;
struct mnt_fhstatus result = { 0, fh };
char hostname[32];
int status;
+ int call;
dprintk("NFS: nfs_mount(%08x:%s)\n",
(unsigned)ntohl(addr->sin_addr.s_addr), path);
strcpy(hostname, in_ntoa(addr->sin_addr.s_addr));
- if (!(mnt_clnt = mnt_create(hostname, addr)))
+ if (!(mnt_clnt = mnt_create(hostname, addr, version)))
return -EACCES;
- status = rpc_call(mnt_clnt, NFS_MNTPROC_MNT, path, &result, 0);
+ call = (version == 3) ? MOUNTPROC3_MNT : MNTPROC_MNT;
+ status = rpc_call(mnt_clnt, call, path, &result, 0);
return status < 0? status : (result.status? -EACCES : 0);
}
static struct rpc_clnt *
-mnt_create(char *hostname, struct sockaddr_in *srvaddr)
+mnt_create(char *hostname, struct sockaddr_in *srvaddr, int version)
{
struct rpc_xprt *xprt;
struct rpc_clnt *clnt;
@@ -75,7 +88,7 @@
return NULL;
clnt = rpc_create_client(xprt, hostname,
- &mnt_program, NFS_MNT_VERSION,
+ &mnt_program, version,
RPC_AUTH_NULL);
if (!clnt) {
xprt_destroy(xprt);
@@ -100,7 +113,7 @@
static int
xdr_encode_dirpath(struct rpc_rqst *req, u32 *p, const char *path)
{
- p = xdr_encode_string(p, path);
+ p = xdr_encode_string(p, path, -1);
req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
return 0;
@@ -109,14 +122,39 @@
static int
xdr_decode_fhstatus(struct rpc_rqst *req, u32 *p, struct mnt_fhstatus *res)
{
- if ((res->status = ntohl(*p++)) == 0)
- memcpy(res->fh, p, sizeof(*res->fh));
+ struct nfs_fh *fh = res->fh;
+
+ memset((void *)fh, 0, sizeof(*fh));
+ if ((res->status = ntohl(*p++)) == 0) {
+ res->fh->size = NFS2_FHSIZE;
+ memcpy(res->fh->data, p, NFS2_FHSIZE);
+ }
+ return 0;
+}
+
+static int
+xdr_decode_fhstatus3(struct rpc_rqst *req, u32 *p, struct mnt_fhstatus *res)
+{
+ struct nfs_fh *fh = res->fh;
+
+ memset((void *)fh, 0, sizeof(*fh));
+ if ((res->status = ntohl(*p++)) == 0) {
+ unsigned int size = ntohl(*p++);
+ if (size <= NFS3_FHSIZE) {
+ res->fh->size = size;
+ memcpy(res->fh->data, p, size);
+ }
+ }
return 0;
}
#define MNT_dirpath_sz (1 + 256)
#define MNT_fhstatus_sz (1 + 8)
+#ifndef MAX
+# define MAX(a, b) (((a) > (b))? (a) : (b))
+#endif
+
static struct rpc_procinfo mnt_procedures[2] = {
{ "mnt_null",
(kxdrproc_t) xdr_error,
@@ -124,16 +162,32 @@
{ "mnt_mount",
(kxdrproc_t) xdr_encode_dirpath,
(kxdrproc_t) xdr_decode_fhstatus,
- MAX(MNT_dirpath_sz, MNT_fhstatus_sz)<<2, 0},
+ MAX(MNT_dirpath_sz, MNT_fhstatus_sz) << 2, 0 },
+};
+
+static struct rpc_procinfo mnt3_procedures[2] = {
+ { "mnt3_null",
+ (kxdrproc_t) xdr_error,
+ (kxdrproc_t) xdr_error, 0, 0 },
+ { "mnt3_mount",
+ (kxdrproc_t) xdr_encode_dirpath,
+ (kxdrproc_t) xdr_decode_fhstatus3,
+ MAX(MNT_dirpath_sz, MNT_fhstatus_sz) << 2, 0 },
};
static struct rpc_version mnt_version1 = {
1, 2, mnt_procedures
};
+static struct rpc_version mnt_version3 = {
+ 3, 2, mnt3_procedures
+};
+
static struct rpc_version * mnt_version[] = {
NULL,
&mnt_version1,
+ NULL,
+ &mnt_version3,
};
static struct rpc_stat mnt_stats;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)