+Tue Mar 21 11:38:48 EST 2000 NeilBrown <neilb@cse.unsw.edu.au>
+
+ * support/include/nfs/nfs.h: Removed knowledge of internals of
+ kernel filehandles (which can change) and defined nfs_fh_size
+ which has variable size
+
+ * support/nfs/getfh.c: defined getfh_size to use new syscall to
+ get variable sized file handles, and change getfh{,old} to
+ use nfs_fh_size
+
+ * utils/mountd/mountd.c: use nfd_fh_size and call getfh_size for
+ NFSv3 file handles
+
+ * tools/Makefile, tools/nlmtest/nlmtest.c
+ nlmtest.c depended on internel format of file handles, so now
+ doesn't work.
+
+
2000-03-12 Chip Salzenberg <chip@valinux.com>
Neil Brown <neilb@cse.unsw.edu.au>
* support/nfs/rpcmisc.c (rpc_init): Share transports.
-Wed Mar 8 09:42:43 EST 2000 Neil Brown <neilb@cse.unsw.edu.au>
+Mon Mar 13 18:31:33 2000 H.J. Lu <hjl@lucon.org>
* etc/redhat/nfsd.init: Updated.
#include <rpcsvc/nfs_prot.h>
#include <nfs/export.h>
-struct dentry;
+#define NFS3_FHSIZE 64
+#define NFS_FHSIZE 32
-/*
- * This is the new "dentry style" Linux NFSv2 file handle.
- *
- * The xino and xdev fields are currently used to transport the
- * ino/dev of the exported inode.
- */
-struct nfs_fhbase {
- struct dentry * fb_dentry; /* dentry cookie */
- u_int32_t fb_ino; /* our inode number */
- u_int32_t fb_dirino; /* dir inode number */
- u_int32_t fb_dev; /* our device */
- u_int32_t fb_xdev;
- u_int32_t fb_xino;
+struct nfs_fh_len {
+ int fh_size;
+ u_int8_t fh_handle[NFS3_FHSIZE];
};
-
-#define NFS_FH_PADDING (NFS_FHSIZE - sizeof(struct nfs_fhbase))
-struct knfs_fh {
- struct nfs_fhbase fh_base;
- u_int8_t fh_cookie[NFS_FH_PADDING];
+struct nfs_fh_old {
+ u_int8_t fh_handle[NFS_FHSIZE];
};
-#define fh_dcookie fh_base.fb_dentry
-#define fh_ino fh_base.fb_ino
-#define fh_dirino fh_base.fb_dirino
-#define fh_dev fh_base.fb_dev
-#define fh_xdev fh_base.fb_xdev
-#define fh_xino fh_base.fb_xino
-
/*
* Version of the syscall interface
*/
#define NFSCTL_UGIDUPDATE 5 /* update a client's uid/gid map. */
#define NFSCTL_GETFH 6 /* get an fh (used by mountd) */
#define NFSCTL_GETFD 7 /* get an fh by path (used by mountd) */
+#define NFSCTL_GETFS 8 /* get an fh by path with max size (used by mountd) */
/* Above this is for lockd. */
#define NFSCTL_LOCKD 0x10000
int gd_version;
};
+/* GETFS - GET Filehandle with Size */
+struct nfsctl_fsparm {
+ struct sockaddr gd_addr;
+ char gd_path[NFS_MAXPATHLEN+1];
+ int gd_maxlen;
+};
+
/*
* This is the argument union.
*/
struct nfsctl_uidmap u_umap;
struct nfsctl_fhparm u_getfh;
struct nfsctl_fdparm u_getfd;
- unsigned int u_debug;
+ struct nfsctl_fsparm u_getfs;
} u;
#define ca_svc u.u_svc
#define ca_client u.u_client
#define ca_umap u.u_umap
#define ca_getfh u.u_getfh
#define ca_getfd u.u_getfd
+#define ca_getfs u.u_getfs
#define ca_authd u.u_authd
-#define ca_debug u.u_debug
};
union nfsctl_res {
- struct knfs_fh cr_getfh;
- unsigned int cr_debug;
+ struct nfs_fh_old cr_getfh;
+ struct nfs_fh_len cr_getfs;
};
#endif /* _NFS_NFS_H */
int nfsdelclient(struct nfsctl_client *clp);
int nfsexport(struct nfsctl_export *exp);
int nfsunexport(struct nfsctl_export *exp);
-struct knfs_fh * getfh_old(struct sockaddr *addr, dev_t dev, ino_t ino);
-struct knfs_fh * getfh(struct sockaddr *addr, const char *);
+struct nfs_fh_len * getfh_old(struct sockaddr *addr, dev_t dev, ino_t ino);
+struct nfs_fh_len * getfh(struct sockaddr *addr, const char *);
+struct nfs_fh_len * getfh_size(struct sockaddr *addr, const char *, int size);
/* lockd. */
int lockdsvc();
#include <errno.h>
#include "nfslib.h"
-struct knfs_fh *
+struct nfs_fh_len *
getfh_old (struct sockaddr *addr, dev_t dev, ino_t ino)
{
- static union nfsctl_res res;
+ union nfsctl_res res;
struct nfsctl_arg arg;
+ static struct nfs_fh_len rfh;
arg.ca_version = NFSCTL_VERSION;
arg.ca_getfh.gf_version = 2; /* obsolete */
if (nfsctl(NFSCTL_GETFH, &arg, &res) < 0)
return NULL;
- return &res.cr_getfh;
+ rfh.fh_size = 32;
+ memcpy(rfh.fh_handle, &res.cr_getfh, 32);
+ return &rfh;
}
-struct knfs_fh *
+struct nfs_fh_len *
getfh(struct sockaddr *addr, const char *path)
{
- static union nfsctl_res res;
+ static union nfsctl_res res;
struct nfsctl_arg arg;
+ static struct nfs_fh_len rfh;
arg.ca_version = NFSCTL_VERSION;
arg.ca_getfd.gd_version = 2; /* obsolete */
if (nfsctl(NFSCTL_GETFD, &arg, &res) < 0)
return NULL;
- return &res.cr_getfh;
+ rfh.fh_size = 32;
+ memcpy(rfh.fh_handle, &res.cr_getfh, 32);
+ return &rfh;
+}
+
+struct nfs_fh_len *
+getfh_size(struct sockaddr *addr, const char *path, int size)
+{
+ static union nfsctl_res res;
+ struct nfsctl_arg arg;
+
+ arg.ca_version = NFSCTL_VERSION;
+ strncpy(arg.ca_getfs.gd_path, path,
+ sizeof(arg.ca_getfs.gd_path) - 1);
+ arg.ca_getfs.gd_path[sizeof (arg.ca_getfs.gd_path) - 1] = '\0';
+ memcpy(&arg.ca_getfs.gd_addr, addr, sizeof(struct sockaddr_in));
+ arg.ca_getfs.gd_maxlen = size;
+
+ if (nfsctl(NFSCTL_GETFS, &arg, &res) < 0)
+ return NULL;
+
+ return &res.cr_getfs;
}
# Various debugging/testing tools
#
-SUBDIRS = rpcgen getiversion getkversion nlmtest rpcdebug locktest
+SUBDIRS = rpcgen getiversion getkversion rpcdebug locktest
+# nlmtest doesn't work
include $(TOP)rules.mk
{
static struct knfs_fh f;
struct stat stb;
-
+#error this needs updating if it is still wanted
memset(&f, 0, sizeof(f));
#if 0
if (stat(NLMTEST_DIR, &stb) < 0) {
static void usage(const char *, int exitcode);
static exports get_exportlist(void);
-static struct knfs_fh * get_rootfh(struct svc_req *, dirpath *, int *);
+static struct nfs_fh_len *get_rootfh(struct svc_req *, dirpath *, int *, int v3);
static struct option longopts[] =
{
bool_t
mount_mnt_1_svc(struct svc_req *rqstp, dirpath *path, fhstatus *res)
{
- struct knfs_fh *fh;
+ struct nfs_fh_len *fh;
xlog(D_CALL, "MNT1(%s) called", *path);
- if ((fh = get_rootfh(rqstp, path, &res->fhs_status)) != NULL)
- memcpy(&res->fhstatus_u.fhs_fhandle, fh, 32);
+ if ((fh = get_rootfh(rqstp, path, &res->fhs_status, 0)) != NULL)
+ memcpy(&res->fhstatus_u.fhs_fhandle, fh->fh_handle, 32);
return 1;
}
mount_mnt_3_svc(struct svc_req *rqstp, dirpath *path, mountres3 *res)
{
static int flavors[] = { AUTH_NULL, AUTH_UNIX };
- struct knfs_fh *fh;
+ struct nfs_fh_len *fh;
xlog(D_CALL, "MNT3(%s) called", *path);
- if ((fh = get_rootfh(rqstp, path, (int *) &res->fhs_status)) != NULL) {
+ if ((fh = get_rootfh(rqstp, path, (int *) &res->fhs_status, 1)) != NULL) {
struct mountres3_ok *ok = &res->mountres3_u.mountinfo;
- ok->fhandle.fhandle3_len = 32;
- ok->fhandle.fhandle3_val = (char *) fh;
+ ok->fhandle.fhandle3_len = fh->fh_size;
+ ok->fhandle.fhandle3_val = fh->fh_handle;
ok->auth_flavors.auth_flavors_len = 2;
ok->auth_flavors.auth_flavors_val = flavors;
}
return 1;
}
-static struct knfs_fh *
-get_rootfh(struct svc_req *rqstp, dirpath *path, int *error)
+static struct nfs_fh_len *
+get_rootfh(struct svc_req *rqstp, dirpath *path, int *error, int v3)
{
struct sockaddr_in *sin = svc_getcaller(rqstp->rq_xprt);
struct stat stb;
xlog(L_WARNING, "%s is not a directory or regular file", p);
*error = NFSERR_NOTDIR;
} else {
- struct knfs_fh *fh;
+ struct nfs_fh_len *fh;
if (!exp->m_exported)
export_export(exp);
if (!exp->m_xtabent)
xtab_append(exp);
- /* We first try the new nfs syscall. */
- fh = getfh ((struct sockaddr *) sin, p);
- if (fh == NULL && errno == EINVAL)
- /* Let's try the old one. */
- fh = getfh_old ((struct sockaddr *) sin,
- stb.st_dev, stb.st_ino);
+ if (v3)
+ fh = getfh_size ((struct sockaddr *) sin, p, 64);
+ if (!v3 || (fh == NULL && errno == EINVAL)) {
+ /* We first try the new nfs syscall. */
+ fh = getfh ((struct sockaddr *) sin, p);
+ if (fh == NULL && errno == EINVAL)
+ /* Let's try the old one. */
+ fh = getfh_old ((struct sockaddr *) sin,
+ stb.st_dev, stb.st_ino);
+ }
if (fh != NULL) {
mountlist_add(exp, p);
*error = NFS_OK;
usage(argv [0], 1);
/* Initialize logging. */
- xlog_open("mountd");
+/* xlog_open("mountd"); */
sa.sa_handler = SIG_IGN;
sa.sa_flags = 0;