From: neilbrown Date: Tue, 21 Mar 2000 00:46:14 +0000 (+0000) Subject: Change to using variable length file handles, for better v3 support, and X-Git-Tag: nfs-utils-0-1-7-1~4 X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=commitdiff_plain;h=93a8e35ff8def529f41b82a13440f2e9b46d0dbd Change to using variable length file handles, for better v3 support, and introduce getfh_size to use new (2.3.99) syscall for getting file handles with length --- diff --git a/ChangeLog b/ChangeLog index 753a073..32a1739 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,27 @@ +Tue Mar 21 11:38:48 EST 2000 NeilBrown + + * 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 Neil Brown * support/nfs/rpcmisc.c (rpc_init): Share transports. -Wed Mar 8 09:42:43 EST 2000 Neil Brown +Mon Mar 13 18:31:33 2000 H.J. Lu * etc/redhat/nfsd.init: Updated. diff --git a/support/include/nfs/nfs.h b/support/include/nfs/nfs.h index 0cfed07..937c1be 100644 --- a/support/include/nfs/nfs.h +++ b/support/include/nfs/nfs.h @@ -7,36 +7,17 @@ #include #include -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 */ @@ -53,6 +34,7 @@ struct knfs_fh { #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 @@ -113,6 +95,13 @@ struct nfsctl_fdparm { 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. */ @@ -125,7 +114,7 @@ struct nfsctl_arg { 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 @@ -133,13 +122,13 @@ struct nfsctl_arg { #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 */ diff --git a/support/include/nfslib.h b/support/include/nfslib.h index d8be926..b5c7237 100644 --- a/support/include/nfslib.h +++ b/support/include/nfslib.h @@ -116,8 +116,9 @@ int nfsaddclient(struct nfsctl_client *clp); 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(); diff --git a/support/nfs/getfh.c b/support/nfs/getfh.c index 5a6f1a4..aacba52 100644 --- a/support/nfs/getfh.c +++ b/support/nfs/getfh.c @@ -17,11 +17,12 @@ #include #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 */ @@ -32,14 +33,17 @@ getfh_old (struct sockaddr *addr, dev_t dev, ino_t ino) 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 */ @@ -51,5 +55,26 @@ getfh(struct sockaddr *addr, const char *path) 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; } diff --git a/tools/Makefile b/tools/Makefile index 6378850..0324877 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -2,6 +2,7 @@ # 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 diff --git a/tools/nlmtest/nlmtest.c b/tools/nlmtest/nlmtest.c index 77dd889..d0acc47 100644 --- a/tools/nlmtest/nlmtest.c +++ b/tools/nlmtest/nlmtest.c @@ -234,7 +234,7 @@ makefileh(struct netobj *fh) { 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) { diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c index 164983a..7f54be6 100644 --- a/utils/mountd/mountd.c +++ b/utils/mountd/mountd.c @@ -24,7 +24,7 @@ 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[] = { @@ -65,11 +65,11 @@ mount_null_1_svc(struct svc_req *rqstp, void *argp, void *resp) 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; } @@ -203,22 +203,22 @@ bool_t 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; @@ -252,19 +252,23 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, int *error) 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; @@ -424,7 +428,7 @@ main(int argc, char **argv) usage(argv [0], 1); /* Initialize logging. */ - xlog_open("mountd"); +/* xlog_open("mountd"); */ sa.sa_handler = SIG_IGN; sa.sa_flags = 0;