diff options
author | Richard Purdie <rpurdie@linux.intel.com> | 2010-12-30 10:12:14 +0000 |
---|---|---|
committer | Richard Purdie <rpurdie@linux.intel.com> | 2010-12-30 10:12:14 +0000 |
commit | 59ad91a880695808c5b4efe88fa46286662e4cfc (patch) | |
tree | 52a40efec182c732157be1553609c9bb0d74892d /meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/006-reiserfs.patch | |
parent | acf3b8e884657101b736d32f4216655b96659f49 (diff) | |
download | openembedded-core-59ad91a880695808c5b4efe88fa46286662e4cfc.tar.gz openembedded-core-59ad91a880695808c5b4efe88fa46286662e4cfc.tar.bz2 openembedded-core-59ad91a880695808c5b4efe88fa46286662e4cfc.tar.xz openembedded-core-59ad91a880695808c5b4efe88fa46286662e4cfc.zip |
unfs-server: Fix PV so it obeys the version number policy
Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/006-reiserfs.patch')
-rw-r--r-- | meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/006-reiserfs.patch | 1272 |
1 files changed, 0 insertions, 1272 deletions
diff --git a/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/006-reiserfs.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/006-reiserfs.patch deleted file mode 100644 index abdc67476..000000000 --- a/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/006-reiserfs.patch +++ /dev/null @@ -1,1272 +0,0 @@ -# Patch origin: nfs-server source RPM from openSUSE 10.3 - ---- nfs-server/Makefile.in -+++ nfs-server/Makefile.in 2002/11/08 13:59:16 -@@ -100,7 +100,7 @@ - utimes.c mkdir.c rename.c getopt.c getopt_long.c \ - alloca.c mountlist.c xmalloc.c \ - xstrdup.c strdup.c strstr.c nfsmounted.c faccess.c \ -- haccess.c daemon.c signals.c -+ haccess.c daemon.c signals.c teahash3.c - XDRFILES = mount.x nfs_prot.x - GENFILES = mount.h mount_xdr.c mount_svc.c nfs_prot.h nfs_prot_xdr.c \ - ugid.h ugid_xdr.c ugid_clnt.c -@@ -112,7 +112,7 @@ - MANPAGES8 = showmount - MANPAGES = $(MANPAGES5) $(MANPAGES8p) $(MANPAGES8) - LIBOBJS = version.o fsusage.o mountlist.o xmalloc.o xstrdup.o \ -- nfsmounted.o faccess.o haccess.o daemon.o \ -+ nfsmounted.o faccess.o haccess.o daemon.o teahash3.o \ - signals.o @LIBOBJS@ @ALLOCA@ - OBJS = logging.o fh.o devtab.o auth_init.o auth_clnt.o auth.o - NFSD_OBJS = nfsd.o rpcmisc.o nfs_dispatch.o getattr.o setattr.o \ ---- nfs-server/auth.c -+++ nfs-server/auth.c 2002/11/08 13:59:16 -@@ -83,6 +83,7 @@ - 0, /* read-only */ - 0, /* relative links */ - 0, /* noaccess */ -+ 0, /* hashed inodes */ - 1, /* cross_mounts */ - 1, /* allow setuid */ - 65534, /* default uid */ -@@ -100,6 +101,7 @@ - 0, /* relative links */ - 0, /* noaccess */ - 1, /* cross_mounts */ -+ 0, /* hashed inodes */ - 0, /* allow setuid */ - 65534, /* default uid */ - 65534, /* default gid */ -@@ -991,6 +993,7 @@ - if (mp == 0) { - mp = (nfs_mount*) xmalloc(sizeof(nfs_mount)); - memset(mp, 0, sizeof(*mp)); -+ mp->mount_dev = 0; - mp->origin = cp; - mp->client = cp; - mp->path = xstrdup(path); -@@ -1169,6 +1172,8 @@ - default_options.nobody_gid = anon_gid; - anonymous_options.nobody_uid = anon_uid; - anonymous_options.nobody_gid = anon_gid; -+ default_options.cross_mounts = cross_mounts; -+ default_options.hashed_inodes = hashed_inodes; - - memset(cached_clients, 0, sizeof(cached_clients)); - cached_next = 0; ---- nfs-server/auth.h -+++ nfs-server/auth.h 2002/11/08 13:59:16 -@@ -43,15 +43,16 @@ - - typedef struct nfs_options { - ugid_mapping_t uidmap; /* uid/gid mapping behavior */ -- int root_squash; -- int all_squash; -- int some_squash; /* speed up luid() etc. */ -- int secure_port; -- int read_only; -- int link_relative; -- int noaccess; -- int cross_mounts; -- int allow_setuid; -+ unsigned root_squash : 1; -+ unsigned all_squash : 1; -+ unsigned some_squash : 1; /* speed up luid() etc. */ -+ unsigned secure_port : 1; -+ unsigned read_only : 1; -+ unsigned link_relative : 1; -+ unsigned noaccess : 1; -+ unsigned cross_mounts : 1; -+ unsigned hashed_inodes : 1; -+ unsigned allow_setuid : 1; - uid_t nobody_uid; - gid_t nobody_gid; - char * clnt_nisdomain; -@@ -64,6 +65,7 @@ - int length; - char * path; - nfs_options o; -+ dev_t mount_dev; - /* Original NFS client */ - struct nfs_client * origin; - } nfs_mount; -@@ -121,6 +123,8 @@ - extern void auth_check_all_netmasks(void); - extern void auth_sort_all_mountlists(void); - extern void auth_log_all(void); -+extern int auth_checkdev(nfs_mount *, dev_t dev); -+extern int auth_checkpathdev(char *, dev_t dev); - - /* This function lets us set our euid/fsuid temporarily */ - extern void auth_override_uid(uid_t); ---- nfs-server/auth_clnt.c -+++ nfs-server/auth_clnt.c 2002/11/08 13:59:16 -@@ -89,6 +89,13 @@ - return NULL; - } - -+ if (!mp->o.cross_mounts && !mp->mount_dev) { -+ struct stat st; -+ if (!lstat(mp->path, &st) < 0) -+ return NULL; -+ mp->mount_dev = st.st_dev; -+ } -+ - /* Check request originated on a privileged port. */ - if (!allow_non_root && mp->o.secure_port - && !SECURE_PORT(svc_getcaller(rqstp->rq_xprt)->sin_port)) { -@@ -350,3 +357,28 @@ - return 1; - } - #endif -+ -+int auth_checkpathdev(char *path, dev_t dev) -+{ -+ nfs_mount *mp = auth_match_mount(nfsclient, path); -+ if (!mp) -+ return 0; -+ return auth_checkdev(mp, dev); -+} -+ -+int auth_checkdev(nfs_mount *mp, dev_t dev) -+{ -+ if (!mp->mount_dev) -+ return 1; -+ if (mp->mount_dev != dev) { -+ struct stat st; -+ /* Restat in case the cd switched */ -+ if (efs_lstat(mp->path, &st) < 0) { -+ Dprintf(L_ERROR, "Unable to stat mount point %s\n", mp->path); -+ return 0; -+ } -+ mp->mount_dev = st.st_dev; -+ } -+ return mp->mount_dev == dev; -+} -+ ---- nfs-server/auth_init.c -+++ nfs-server/auth_init.c 2002/11/08 13:59:16 -@@ -320,6 +320,14 @@ - /* knfsd compatibility, ignore */; - else ifkwd(4, "sync") - /* knfsd compatibility, ignore */; -+ else ifkwd(13, "hashed_inodes") -+ mp->o.hashed_inodes = 1; -+ else ifkwd(16, "no_hashed_inodes") -+ mp->o.hashed_inodes = 0; -+ else ifkwd(12, "cross_mounts") -+ mp->o.cross_mounts = 1; -+ else ifkwd(15, "no_cross_mounts") -+ mp->o.cross_mounts = 0; - else { - Dprintf(L_ERROR, - "Unknown keyword \"%.*s\" in export file\n", ---- nfs-server/exports.man -+++ nfs-server/exports.man 2002/11/08 13:59:16 -@@ -208,6 +208,17 @@ - .IR no_all_squash , - which is the default setting. - .TP -+.IR hashed_inodes -+Use a special scheme to generate inode numbers that may work better with -+reiserfs filesystems. -+.IR no_hashed_inodes -+which uses a direct mapping is the default. -+.TP -+.IR cross_mounts -+Do not cross mount points in exports. Turning this off with -+.IR no_cross_mounts -+avoids inode number space conflicts when there are too many files. -+.TP - .IR map_daemon - This option turns on dynamic uid/gid mapping. Each uid in an NFS request - will be translated to the equivalent server uid, and each uid in an ---- nfs-server/fh.c -+++ nfs-server/fh.c 2002/11/08 14:11:31 -@@ -4,8 +4,9 @@ - * - * Interfaces: - * pseudo_inode -- * mostly used internally, but also called from unfsd.c -- * when reporting directory contents. -+ * mostly used internally, for hash tables -+ * visible_inode -+ * generate visible inode shown to the client in the fattr. - * fh_init - * Initializes the queues and 'flush' timer - * fh_pr -@@ -47,6 +48,8 @@ - * Note: the original code mistakenly assumes that the overall path - * length remains within the value given by PATH_MAX... that leads - * to interesting buffer overflows all over the place. -+ * -+ * Depends that dev_t only uses 16bits. - */ - - #include <assert.h> -@@ -137,9 +140,9 @@ - }; - - /* Forward declared local functions */ --static psi_t path_psi(char *, nfsstat *, struct stat *, int); -+static psi_t path_psi(char *, nfsstat *, struct stat *, int, int *); - static psi_t path_psi_m(char *, nfsstat *, struct stat *, -- struct stat *, int); -+ struct stat *, int, int *); - static int fh_flush_fds(void); - static char * fh_dump(svc_fh *); - static void fh_insert_fdcache(fhcache *fhc); -@@ -173,19 +176,22 @@ - fh_list_size++; - - /* Insert into hash tab. */ -- hash_slot = &(fh_hashed[fhc->h.psi % HASH_TAB_SIZE]); -+ hash_slot = &(fh_hashed[pseudo_inode(fhc->h.ino,fhc->h.dev) % HASH_TAB_SIZE]); - fhc->hash_next = *hash_slot; - *hash_slot = fhc; - } - - static fhcache * --fh_lookup(psi_t psi) -+fh_lookup(ino_t ino, dev_t dev) - { - register fhcache *fhc; - -- fhc = fh_hashed[psi % HASH_TAB_SIZE]; -- while (fhc != NULL && fhc->h.psi != psi) -+ fhc = fh_hashed[pseudo_inode(ino,dev) % HASH_TAB_SIZE]; -+ while (fhc != NULL) { -+ if (fhc->h.ino == ino && fhc->h.dev == dev) -+ break; - fhc = fhc->hash_next; -+ } - return (fhc); - } - -@@ -193,7 +199,8 @@ - fh_insert_fdcache(fhcache *fhc) - { - #ifdef FHTRACE -- Dprintf(D_FHTRACE, "insert fh %x into fdcache @%d\n", fhc->h.psi, fhc->fd); -+ Dprintf(D_FHTRACE, "insert fh %x,%x into fdcache @%d\n", -+ fhc->h.ino, fhc->h.dev, fhc->fd); - if (fhc->fd < 0) { - fh_complain("fd cache bug: bad fd", fhc); - return; -@@ -289,8 +296,9 @@ - #endif - - Dprintf(D_FHTRACE|D_FHCACHE, -- "fh_delete: deleting handle %x ('%s', fd=%d)\n", -- fhc, fhc->path ? fhc->path : "<unnamed>", fhc->fd); -+ "fh_delete: deleting handle %x [%x,%x] ('%s', fd=%d)\n", -+ fhc, fhc->h.dev, fhc->h.ino, fhc->path ? fhc->path : "<unnamed>", -+ fhc->fd); - - /* Remove from current posn */ - fhc->prev->next = fhc->next; -@@ -298,7 +306,7 @@ - fh_list_size--; - - /* Remove from hash tab */ -- hash_slot = &(fh_hashed[fhc->h.psi % HASH_TAB_SIZE]); -+ hash_slot = &(fh_hashed[pseudo_inode(fhc->h.ino,fhc->h.dev) % HASH_TAB_SIZE]); - while (*hash_slot != NULL && *hash_slot != fhc) - hash_slot = &((*hash_slot)->hash_next); - if (*hash_slot == NULL) -@@ -528,6 +536,7 @@ - index -= 8; - } - -+#if 0 - /* If we have an XXL inode number, spew out warning (but at most - * once a second) */ - if (inode & ~mask) { -@@ -541,14 +550,34 @@ - } - inode &= mask; - } -- -+#endif - return (psi_t) (prefix | inode); - #endif - } - -+/* Inode as handed out by attr calls. */ -+psi_t -+visible_inode(ino_t ino, dev_t dev, nfs_mount *mount) -+{ -+ if (!mount->o.cross_mounts) -+ return ino; -+ -+ if (mount->o.hashed_inodes) { -+ extern __u32 teahash3(/*u32 k[2], *//*u8*/const char *msg, int len); -+ -+ struct { -+ ino_t ino; -+ dev_t dev; -+ } tup = { ino,dev }; -+ return teahash3((char *) &tup, sizeof tup); -+ } -+ -+ return pseudo_inode(ino, dev); -+} -+ - #if 1 - static char * --fh_buildpath(svc_fh *h) -+fh_buildpath(svc_fh *h, dev_t basedev) - { - char pathbuf[PATH_MAX + NAME_MAX + 1], *path; - long cookie_stack[HP_LEN + 1]; -@@ -565,13 +594,17 @@ - - if (efs_stat("/", &sbuf) < 0) - return (NULL); -- psi = pseudo_inode(sbuf.st_ino, sbuf.st_dev); - if (h->hash_path[0] == 0) { -- if (psi != h->psi) -- return (NULL); -- return xstrdup("/"); -+ if (sbuf.st_ino == h->ino && sbuf.st_dev == h->dev) -+ ; -+ else -+ return NULL; -+ strcpy(pathbuf,"/"); -+ path = xstrdup(pathbuf); -+ return (path); - } - -+ psi = pseudo_inode(sbuf.st_ino, sbuf.st_dev); - if (hash_psi(psi) != h->hash_path[1]) - return (NULL); - -@@ -599,11 +632,18 @@ - - psi = pseudo_inode(dp->d_ino, sbuf.st_dev); - if (i == h->hash_path[0] + 1) { -- if (psi != h->psi) -+ if (sbuf.st_dev != h->dev || dp->d_ino != h->ino) - continue; - /* GOT IT */ - strcpy(pathbuf + pathlen, dp->d_name); -- path = xstrdup(pathbuf); -+ if (!basedev || sbuf.st_dev == basedev || -+ auth_checkpathdev(pathbuf, sbuf.st_dev)) { -+ path = xstrdup(pathbuf); -+ } else { -+ dprintf(L_ERROR, "fh_buildpath: basedev %x != dev %x for %s\n", -+ (unsigned)basedev,(unsigned)sbuf.st_dev,pathbuf); -+ path = NULL; -+ } - efs_closedir(dir); - auth_override_uid(auth_uid); - return (path); -@@ -754,16 +794,16 @@ - #endif - - static psi_t --path_psi(char *path, nfsstat *status, struct stat *sbp, int svalid) -+path_psi(char *path, nfsstat *status, struct stat *sbp, int svalid, int *mp) - { - struct stat smounted; - -- return path_psi_m(path, status, sbp, &smounted, svalid); -+ return path_psi_m(path, status, sbp, &smounted, svalid, mp); - } - - static psi_t - path_psi_m(char *path, nfsstat *status, -- struct stat *sbp, struct stat *mbp, int svalid) -+ struct stat *sbp, struct stat *mbp, int svalid, int *mp) - { - struct stat sbuf, ddbuf; - -@@ -815,6 +855,8 @@ - DIR *dirp; - struct dirent *dp; - -+ if (mp) *mp = 1; -+ - errno = 0; - dirp = efs_opendir(dname); - fname[-1] = '/'; /* Restore path */ -@@ -860,9 +902,70 @@ - } - - fhcache * --fh_find(svc_fh *h, int mode) -+fh_newfh(svc_fh *h, int mode, dev_t basedev) -+{ -+ fhcache *fhc, *flush; -+ -+ ex_state = active; -+ for (flush = fh_tail.prev; fh_list_size > FH_CACHE_LIMIT; flush = fhc) { -+ /* Don't flush current head. */ -+ if (flush == &fh_head) -+ break; -+ fhc = flush->prev; -+ fh_delete(flush); -+ } -+ fhc = (fhcache *) xmalloc(sizeof *fhc); -+ if (mode == FHFIND_FCREATE) { -+ /* File will be created */ -+ fhc->path = NULL; -+ } else { -+ /* File must exist. Attempt to construct from hash_path */ -+ char *path; -+ -+ if ((path = fh_buildpath(h, basedev)) == NULL) { -+#ifdef FHTRACE -+ Dprintf(D_FHTRACE, "fh_find: stale fh (hash path)\n"); -+ Dprintf(D_FHTRACE, "\tdata: %s\n", fh_dump(h)); -+#endif -+ free(fhc); -+ ex_state = inactive; -+ return NULL; -+ } -+ fhc->path = path; -+ } -+ fhc->flags = 0; -+ if (fhc->path && efs_lstat(fhc->path, &fhc->attrs) >= 0) { -+ if (re_export && nfsmounted(fhc->path, &fhc->attrs)) -+ fhc->flags |= FHC_NFSMOUNTED; -+ fhc->flags |= FHC_ATTRVALID; -+ } -+ fhc->fd = -1; -+ fhc->last_used = curtime; -+ fhc->h = *h; -+ fhc->last_clnt = NULL; -+ fhc->last_mount = NULL; -+ fhc->last_uid = (uid_t)-1; -+ fhc->fd_next = fhc->fd_prev = NULL; -+ fh_inserthead(fhc); -+ Dprintf(D_FHCACHE, -+ "fh_find: created new handle %x (path `%s' ino:%x dev:%x)\n", -+ fhc, fhc->path ? fhc->path : "<unnamed>", fhc->h.ino, fhc->h.dev); -+ ex_state = inactive; -+ if (fh_list_size > FH_CACHE_LIMIT) -+ flush_cache(0); -+#ifdef FHTRACE -+ if (fhc->h.hash_path[0] == 0xFF) { -+ Dprintf(L_ERROR, "newly created fh instantly flushed?!"); -+ return NULL; -+ } -+#endif -+ return (fhc); -+} -+ -+fhcache * -+fh_find(svc_fh *h, int mode, dev_t basedev) - { -- register fhcache *fhc, *flush; -+ register fhcache *fhc; - int check; - - check = (mode & FHFIND_CHECK); -@@ -877,12 +980,12 @@ - - ex_state = active; - time(&curtime); -- while ((fhc = fh_lookup(h->psi)) != NULL) { -+ while ((fhc = fh_lookup(h->ino,h->dev)) != NULL) { - struct stat sbuf, *s = NULL; - nfsstat dummy; - -- Dprintf(D_FHCACHE, "fh_find: psi=%lx... found '%s', fd=%d\n", -- (unsigned long) h->psi, -+ Dprintf(D_FHCACHE, "fh_find: (%u,%u)... found '%s', fd=%d\n", -+ h->ino, h->dev, - fhc->path ? fhc->path : "<unnamed>", - fhc->fd); - -@@ -905,6 +1008,7 @@ - Dprintf(D_FHTRACE, - "fh_find: stale fh: lstat: %m\n"); - } else { -+ int mp = 0; - /* If device/ino don't match, fhc->path may - * be a mount point (hence lstat() returns - * a different inode number than the readdir() -@@ -915,19 +1019,26 @@ - - /* Get the dev/ino of the underlying - * mount point. */ -- path_psi(fhc->path, &dummy, s, 1); -- if (fh_attrmatch(fhc, s)) -- goto fh_return; -+ if (path_psi(fhc->path, &dummy, s, 1, &mp) && -+ fh_attrmatch(fhc, s)) { -+ if (!mp) -+ Dprintf(D_FHTRACE,"fh_find: should be mount point %x,%x\n", -+ h->dev,h->ino); -+ -+ } - -- Dprintf(D_FHTRACE, "fh_find: stale fh: %lx", -- (unsigned long) h->psi); -+ Dprintf(D_FHTRACE, "fh_find: stale fh: " -+ "dev/ino %x/%lx ino:%x dev:%x", -+ s->st_dev, s->st_ino, -+ (unsigned)h->ino, (unsigned)h->dev); - } - - fh_discard: - #ifdef FHTRACE - Dprintf(D_FHTRACE, "\tdata: %s\n", fh_dump(h)); - #endif -- Dprintf(D_FHCACHE, "fh_find: delete cached handle\n"); -+ Dprintf(D_FHCACHE, "fh_find: delete cached handle %x,%x <%x>\n", -+ fhc->h.dev,fhc->h.ino,fhc->path ? fhc->path : "no path"); - fh_delete(fhc); - break; - } -@@ -947,88 +1058,13 @@ - return (fhc); - } - -- Dprintf(D_FHCACHE, "fh_find: psi=%lx... not found\n", -- (unsigned long) h->psi); -- -- if (mode == FHFIND_FCACHED) { -- ex_state = inactive; -- return NULL; -- } -- -- for (flush = fh_tail.prev; fh_list_size > FH_CACHE_LIMIT; flush = fhc) { -- /* Don't flush current head. */ -- if (flush == &fh_head) -- break; -- fhc = flush->prev; -- fh_delete(flush); -- } -- -- fhc = (fhcache *) xmalloc(sizeof *fhc); -- if (mode == FHFIND_FCREATE) { -- /* File will be created */ -- fhc->path = NULL; -- } else { -- /* File must exist. Attempt to construct from hash_path */ -- char *path; -- -- if ((path = fh_buildpath(h)) == NULL) { --#ifdef FHTRACE -- Dprintf(D_FHTRACE, "fh_find: stale fh (hash path)\n"); -- Dprintf(D_FHTRACE, "\tdata: %s\n", fh_dump(h)); --#endif -- free(fhc); -- ex_state = inactive; -- return NULL; -- } -- fhc->path = path; -- } -- -- fhc->flags = 0; -- if (fhc->path && efs_lstat(fhc->path, &fhc->attrs) >= 0) { -- if (nfsmounted(fhc->path, &fhc->attrs)) { -- fhc->flags |= FHC_NFSMOUNTED; --#if 0 -- /* We must allow the client to send us the -- * file handle for the NFS mount point itself, -- * but not for entries within an NFS mount. -- * XXX: needs fixing. -- */ -- if (!re_export) { -- Dprintf(D_FHTRACE, -- "Attempt to use %s (non-exportable)\n", -- fhc->path); -- free(fhc); -- ex_state = inactive; -- return NULL; -- } --#endif -- } -- fhc->flags |= FHC_ATTRVALID; -- fhc->dev = fhc->attrs.st_dev; -- fhc->ino = fhc->attrs.st_ino; -- fhc->type = fhc->attrs.st_mode & S_IFMT; -- } -- fhc->fd = -1; -- fhc->last_used = curtime; -- fhc->h = *h; -- fhc->last_clnt = NULL; -- fhc->last_mount = NULL; -- fhc->last_uid = (uid_t)-1; -- fhc->fd_next = fhc->fd_prev = NULL; -- fh_inserthead(fhc); -- Dprintf(D_FHCACHE, -- "fh_find: created new handle %x (path `%s' psi %08x)\n", -- fhc, fhc->path ? fhc->path : "<unnamed>", fhc->h.psi); - ex_state = inactive; -- if (fh_list_size > FH_CACHE_LIMIT) -- flush_cache(0); --#ifdef FHTRACE -- if (fhc->h.hash_path[0] == 0xFF) { -- Dprintf(L_ERROR, "newly created fh instantly flushed?!"); -+ -+ Dprintf(D_FHCACHE, "fh_find: (%u,%u) ... not found\n", -+ h->ino, h->dev); -+ if (mode == FHFIND_FCACHED) - return NULL; -- } --#endif -- return (fhc); -+ return fh_newfh(h, mode, basedev); - } - - /* -@@ -1040,7 +1076,7 @@ - { - fhcache *h; - -- if ((h = fh_find((svc_fh *) fh, FHFIND_FCACHED)) == NULL) -+ if ((h = fh_find((svc_fh *) fh, FHFIND_FCACHED, 0)) == NULL) - return fh_dump((svc_fh *) fh); - return (h->path); - } -@@ -1050,10 +1086,10 @@ - { - static char buf[65]; - char *sp; -- int i, n = fh->hash_path[0]; -+ int i, n = fh->hash_path[0], l; - -- sprintf(buf, "%08x %02x ", fh->psi, fh->hash_path[0]); -- for (i = 1, sp = buf + 12; i <= n && i < HP_LEN; i++, sp += 2) -+ l = sprintf(buf, "%08x %04x %02x ", fh->ino, fh->dev, fh->hash_path[0]); -+ for (i = 1, sp = buf + l; i <= n && i < HP_LEN; i++, sp += 2) - sprintf(sp, "%02x", fh->hash_path[i]); - return buf; - } -@@ -1082,7 +1118,7 @@ - - memset(&key, 0, sizeof(key)); - status = NFS_OK; -- if ((psi = path_psi("/", &status, &stb, 0)) == 0) -+ if ((psi = path_psi("/", &status, &stb, 0, NULL)) == 0) - return ((int) status); - - s = path; -@@ -1091,7 +1127,7 @@ - return ((int) NFSERR_NAMETOOLONG); - key.hash_path[key.hash_path[0]] = hash_psi(psi); - *s = '\0'; -- if ((psi = path_psi(path, &status, &stb, 0)) == 0) -+ if ((psi = path_psi(path, &status, &stb, 0, NULL)) == 0) - return ((int) status); - *s = '/'; - } -@@ -1099,11 +1135,12 @@ - if (++(key.hash_path[0]) >= HP_LEN) - return ((int) NFSERR_NAMETOOLONG); - key.hash_path[key.hash_path[0]] = hash_psi(psi); -- if ((psi = path_psi(path, &status, &stb, 0)) == 0) -+ if ((psi = path_psi(path, &status, &stb, 0, NULL)) == 0) - return ((int) status); - } -- key.psi = psi; -- h = fh_find(&key, FHFIND_FCREATE); -+ key.dev = stb.st_dev; -+ key.ino = stb.st_ino; -+ h = fh_find(&key, FHFIND_FCREATE, 0); - - #ifdef FHTRACE - if (!h) -@@ -1123,6 +1160,7 @@ - return ((int) status); - } - -+#if 0 - char * - fh_path(nfs_fh *fh, nfsstat *status) - { -@@ -1135,6 +1173,7 @@ - *status = NFS_OK; - return (h->path); - } -+#endif - - nfs_fh * - fh_handle(fhcache *h) -@@ -1349,7 +1388,7 @@ - if (sbp == NULL) - sbp = &sbuf; - -- if ((dirh = fh_find((svc_fh *) &dopa->dir, FHFIND_FEXISTS)) == NULL) -+ if ((dirh = fh_find((svc_fh *) &dopa->dir, FHFIND_FEXISTS, 0)) == NULL) - return NFSERR_STALE; - - /* -@@ -1419,8 +1458,22 @@ - - *new_fh = dopa->dir; - key = (svc_fh *) new_fh; -- if ((key->psi = path_psi_m(pathbuf, &ret, sbp, &smount, 0)) == 0) -+ -+ if (path_psi_m(pathbuf, &ret, sbp, &smount, 0, NULL) == 0) - return (ret); -+ key->ino = sbp->st_ino; -+ key->dev = sbp->st_dev; -+ -+ if (sbp->st_dev != dirh->h.dev) { -+ nfs_mount *mp = dirh->last_mount; -+ if (!mp) -+ Dprintf(L_ERROR, "no last mount in fh_compose for %s\n", pathbuf); -+ else if (auth_checkdev(mp, sbp->st_dev) == 0) { -+ Dprintf(L_ERROR, "access to no cross path below mountpoint (<%s>, %x<->%x)\n", -+ pathbuf, mp->mount_dev, sbp->st_dev); -+ return NFSERR_STALE; -+ } -+ } - - if (is_dd) { - /* Don't cd .. from root, or mysterious ailments will -@@ -1430,11 +1483,12 @@ - } else { - if (++(key->hash_path[0]) >= HP_LEN) - return NFSERR_NAMETOOLONG; -- key->hash_path[key->hash_path[0]] = hash_psi(dirh->h.psi); -+ key->hash_path[key->hash_path[0]] = hash_psi(pseudo_inode(dirh->h.ino, -+ dirh->h.dev)); - } - /* FIXME: when crossing a mount point, we'll find the real - * dev/ino in sbp and can store it in h... */ -- h = fh_find(key, FHFIND_FCREATE); -+ h = fh_find(key, FHFIND_FCREATE, 0); - - #ifdef FHTRACE - if (h == NULL) -@@ -1456,7 +1510,7 @@ - /* We must have cached an old file under the same inode # */ - Dprintf(D_FHTRACE, "Disposing of fh with bad path.\n"); - fh_delete(h); -- h = fh_find(key, FHFIND_FCREATE); -+ h = fh_find(key, FHFIND_FCREATE, dirh->last_mount ? dirh->last_mount->mount_dev : 0); - #ifdef FHTRACE - if (!h) return NFSERR_STALE; - #endif -@@ -1511,12 +1565,14 @@ - return (NFS_OK); - } - -+#if 0 - psi_t - fh_psi(nfs_fh *fh) - { - svc_fh *h = (svc_fh *) fh; - return (h->psi); - } -+#endif - - void - fh_remove(char *path) -@@ -1524,12 +1580,13 @@ - psi_t psi; - nfsstat status; - fhcache *fhc; -+ struct stat st; - -- psi = path_psi(path, &status, NULL, 0); -+ psi = path_psi(path, &status, &st, 0, NULL); - if (psi == 0) - return; - ex_state = active; -- fhc = fh_lookup(psi); -+ fhc = fh_lookup(st.st_ino,st.st_dev); - if (fhc != NULL) - fh_delete(fhc); - -@@ -1634,6 +1691,11 @@ - fh_init(void) - { - static int initialized = 0; -+ -+ if (sizeof(svc_fh) > 32) { -+ fprintf(stderr, "filehandle wrong size %d\n", sizeof(svc_fh)); -+ exit(10); -+ } - - if (initialized) - return; ---- nfs-server/fh.h -+++ nfs-server/fh.h 2002/11/08 13:59:16 -@@ -20,6 +20,7 @@ - #define FHC_XONLY_PATH 001 /* NOT USED ANYMORE */ - #define FHC_ATTRVALID 002 - #define FHC_NFSMOUNTED 004 -+#define FHC_CROSS 010 - - /* Modes for fh_find */ - #define FHFIND_FEXISTS 0 /* file must exist */ -@@ -65,11 +66,12 @@ - * - * hash_path[hash_path[0]+1] ... hash_path[HP_LEN-1] == 0 - */ --#define HP_LEN (NFS_FHSIZE - sizeof(psi_t)) -+#define HP_LEN (NFS_FHSIZE-sizeof(u_int32_t)-sizeof(u_int16_t)) - typedef struct { -- psi_t psi; -+ u_int32_t ino; -+ u_int16_t dev; - __u8 hash_path[HP_LEN]; --} svc_fh; -+} svc_fh __attribute__((packed)); - - typedef enum { inactive, active } mutex; - -@@ -100,6 +102,7 @@ - - /* These are fixed during the lifetime of this object */ - svc_fh h; -+ psi_t psi; - dev_t dev; - ino_t ino; - mode_t type; /* st_mode & S_IFMT */ -@@ -122,10 +125,11 @@ - /* Global function prototypes. */ - extern nfsstat nfs_errno(void); - extern psi_t pseudo_inode(ino_t inode, dev_t dev); -+extern psi_t visible_inode(ino_t inode, dev_t dev, nfs_mount *); - extern void fh_init(void); - extern char *fh_pr(nfs_fh *fh); - extern int fh_create(nfs_fh *fh, char *path); --extern fhcache *fh_find(svc_fh *h, int create); -+extern fhcache *fh_find(svc_fh *h, int create, dev_t basedev); - extern char *fh_path(nfs_fh *fh, nfsstat *status); - extern int path_open(char *path, int omode, int perm); - extern int fh_fd(fhcache *fhc, nfsstat *status, int omode); -@@ -139,6 +143,7 @@ - extern void fh_flush(int force); - extern RETSIGTYPE flush_cache(int sig); - extern int nfsmounted(const char *path, struct stat *sbp); -+extern fhcache *fh_newfh(svc_fh *fh, int mode, dev_t basedev); - - #ifdef ENABLE_DEVTAB - extern unsigned int devtab_index(dev_t); ---- nfs-server/getattr.c -+++ nfs-server/getattr.c 2002/11/08 13:59:16 -@@ -43,7 +43,7 @@ - { - fhcache *fhc; - -- if ((fhc = fh_find((svc_fh*)fh, FHFIND_FEXISTS)) == NULL) { -+ if ((fhc = fh_find((svc_fh*)fh, FHFIND_FEXISTS, 0)) == NULL) { - Dprintf(D_CALL, "getattr: failed! No such file.\n"); - return (NFSERR_STALE); - } -@@ -103,18 +103,8 @@ - #else - attr->blocks = st_blocks(s); - #endif --#if 0 -- if (nfsmount->o.cross_mounts) { -- attr->fsid = 1; -- attr->fileid = fh_psi((nfs_fh *)&(fhc->h)); -- } else { -- attr->fsid = s->st_dev; -- attr->fileid = covered_ino(fhc->path); -- } --#else -- attr->fsid = 1; -- attr->fileid = fh_psi((nfs_fh *)&(fhc->h)); --#endif -+ attr->fsid = 1; // XXX -+ attr->fileid = visible_inode(fhc->h.ino, fhc->h.dev, nfsmount); - - /* This may be needed by some Suns... testing */ - #define MINTIME (24 * 2600) ---- nfs-server/mountd.c -+++ nfs-server/mountd.c 2002/11/08 13:59:16 -@@ -36,6 +36,8 @@ - #include "signals.h" - #include <rpc/pmap_clnt.h> - -+int cross_mounts = 1; -+int hashed_inodes; /* dummy */ - - static void usage(FILE *, int); - static void terminate(void); -@@ -58,9 +60,9 @@ - { "no-spoof-trace", 0, 0, 't' }, - { "version", 0, 0, 'v' }, - { "fail-safe", optional_argument, 0, 'z' }, -+ { "no-cross-mounts", 0, 0, 'x' }, - { "no-tcp", 0, 0, OPT_NOTCP }, - { "loopback-only", 0, 0, OPT_LOOPBACK }, -- - { NULL, 0, 0, 0 } - }; - static const char * shortopts = "Fd:f:hnpP:rtvz::"; -@@ -80,6 +82,7 @@ - int need_reinit = 0; - int need_flush = 0; - extern char version[]; -+nfs_client *nfsclient; /* dummy */ - - /* - * NULL -@@ -319,6 +322,9 @@ - opterr = 0; - while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != EOF) - switch (c) { -+ case 'x': -+ cross_mounts = 0; -+ break; - case 'F': - foreground = 1; - break; -@@ -444,7 +450,7 @@ - program_name); - fprintf(fp, " [--debug kind] [--help] [--allow-non-root]\n"); - fprintf(fp, " [--promiscuous] [--version] [--port portnum]\n"); -- fprintf(fp, " [--exports-file=file]\n"); -+ fprintf(fp, " [--exports-file=file] [--no-cross-mounts]\n"); - exit(n); - } - ---- nfs-server/nfsd.c -+++ nfs-server/nfsd.c 2002/11/08 14:20:57 -@@ -72,7 +72,7 @@ - { "no-tcp", 0, 0, OPT_NOTCP }, - { "udp-only", 0, 0, OPT_NOTCP }, - { "loopback-only", 0, 0, OPT_LOOPBACK }, -- -+ { "hashed-inodes", 0, 0, 'I' }, - { NULL, 0, 0, 0 } - }; - static const char * shortopts = "a:d:Ff:hlnP:prR:tvz::"; -@@ -91,6 +91,7 @@ - int need_flush = 0; /* flush fh cache */ - int read_only = 0; /* Global ro forced */ - int cross_mounts = 1; /* Transparently cross mnts */ -+int hashed_inodes = 0; - int log_transfers = 0; /* Log transfers */ - static svc_fh public_fh; /* Public NFSv2 FH */ - -@@ -122,12 +123,17 @@ - { - static int total = 0, cached = 0; - fhcache *fhc; -+ int newfh = 0; - -- /* Try to map FH. If not cached, reconstruct path with root priv */ -- fhc = fh_find((svc_fh *)fh, FHFIND_FEXISTS|FHFIND_CHECK); -- if (fhc == NULL) { -- *statp = NFSERR_STALE; -- return NULL; -+ /* Try to map FH. */ -+ fhc = fh_find((svc_fh *)fh, FHFIND_FCACHED|FHFIND_CHECK, 0); -+ if (!fhc) { -+ fhc = fh_newfh((svc_fh*)fh, FHFIND_FEXISTS|FHFIND_CHECK, 0); -+ if (!fhc) { -+ *statp = NFSERR_STALE; -+ return NULL; -+ } -+ newfh = 1; - } - - /* Try to retrieve last client who accessed this fh */ -@@ -163,6 +169,16 @@ - 100 * (double) cached / total); - */ - -+ /* Trust the crossmount check of the parent directory for creates */ -+ if (newfh && -+ (fhc->flags & FHC_ATTRVALID) && -+ auth_checkdev(nfsmount, fhc->attrs.st_dev) == 0) { -+ Dprintf(L_ERROR, "auth_fh: fh crossed mount %s: %x<->%x\n", -+ fhc->path ? fhc->path : "???", nfsmount->mount_dev, fhc->attrs.st_dev); -+ *statp = NFSERR_STALE; /* or ACCES? */ -+ return NULL; -+ } -+ - if (nfsmount->o.noaccess && - ((flags & CHK_NOACCESS) || strcmp(nfsmount->path, fhc->path))) { - struct in_addr addr = svc_getcaller(rqstp->rq_xprt)->sin_addr; -@@ -195,6 +211,7 @@ - fhcache *fhc; - nfsstat status; - char *path = buf, *sp; -+ struct stat st; - - /* Authenticate directory file handle */ - if ((fhc = auth_fh(rqstp, &dopa->dir, &status, flags)) == NULL) -@@ -219,6 +236,9 @@ - if ((nfsmount = auth_path(nfsclient, rqstp, path)) == NULL) - return NFSERR_ACCES; - -+ if (efs_lstat(path, &st) >= 0 && !auth_checkdev(nfsmount, st.st_dev)) -+ return NFSERR_ACCES; -+ - /* XXX: really need to call it again here? - * Already invoked in auth_fh */ - if (!auth_user(nfsmount, rqstp)) -@@ -318,7 +338,8 @@ - int ispublic = 0; - - /* First check whether this is the public FH */ -- if (((svc_fh *) fh)->psi == 0 && !memcmp(fh, &public_fh, FHSIZE)) { -+ if (((svc_fh *) fh)->dev == 0 && ((svc_fh*)fh)->ino == 0 && -+ !memcmp(fh, &public_fh, FHSIZE)) { - if (public_root_path == NULL) - return NFSERR_ACCES; - memcpy(&argp->dir, &public_root, NFS_FHSIZE); -@@ -333,6 +354,7 @@ - if (!(fhc = auth_fh(rqstp, fh, &status, CHK_READ))) - return status; - -+ /* FIXME: does too many stats */ - status = fh_compose(argp, &dp->file, &sbuf, -1, -1, ispublic); - if (status != NFS_OK) - return status; -@@ -896,6 +918,9 @@ - errno = 0; - if (efs_lstat(h->path, &sbuf) < 0 || !(S_ISDIR(sbuf.st_mode))) - return (NFSERR_NOTDIR); -+ if (!auth_checkdev(h->last_mount, sbuf.st_dev)) -+ dotsonly = 1; -+ - if ((dirp = efs_opendir(h->path)) == NULL) - return ((errno ? nfs_errno() : NFSERR_NAMETOOLONG)); - -@@ -923,7 +948,7 @@ - } - - e = *ep = (entry *) xmalloc(sizeof(entry)); -- e->fileid = pseudo_inode(dp->d_ino, sbuf.st_dev); -+ e->fileid = visible_inode(dp->d_ino, sbuf.st_dev, h->last_mount); - e->name = xmalloc(NLENGTH(dp) + 1); - strcpy(e->name, dp->d_name); - dloc = htonl(efs_telldir(dirp)); -@@ -1033,6 +1058,9 @@ - case 'x': - cross_mounts = 0; - break; -+ case 'I': -+ hashed_inodes = 1; -+ break; - case 'z': - if (optarg) - failsafe_level = atoi(optarg); -@@ -1189,7 +1217,7 @@ - " [--debug kind] [--exports-file=file] [--port port]\n" - " [--allow-non-root] [--promiscuous] [--version] [--foreground]\n" - " [--re-export] [--log-transfers] [--public-root path]\n" --" [--no-spoof-trace] [--help]\n" -+" [--no-spoof-trace] [--no-cross-mounts] [--hashed-inodes] [--help]\n" - , program_name); - exit(n); - } ---- nfs-server/nfsd.h -+++ nfs-server/nfsd.h 2002/11/08 13:59:16 -@@ -51,6 +51,7 @@ - extern int need_reinit; - extern int need_flush; - extern time_t nfs_dispatch_time; -+extern int cross_mounts, hashed_inodes; - - /* Include the other module definitions. */ - #include "auth.h" ---- nfs-server/setattr.c -+++ nfs-server/setattr.c 2002/11/08 13:59:16 -@@ -17,6 +17,7 @@ - - #define IGNORE_TIME ((unsigned int) -1) - -+#if 0 - /* - * Set file attributes based on file handle - */ -@@ -33,6 +34,7 @@ - } - return setattr(path, attr, s, rqstp, flags); - } -+#endif - - /* - * Set file attributes given the path. The flags argument ---- nfs-server/teahash3.c -+++ nfs-server/teahash3.c 2002/11/08 13:59:16 -@@ -0,0 +1,168 @@ -+/* Taken from the reiserfs source code and hacked slightly by AK. -+ * This is GPLed. */ -+/* -+ * Keyed 32-bit hash function using TEA in a Davis-Meyer function -+ * H0 = Key -+ * Hi = E Mi(Hi-1) + Hi-1 -+ * -+ * (see Applied Cryptography, 2nd edition, p448). -+ * -+ * Jeremy Fitzhardinge <jeremy@zip.com.au> 1998 -+ * -+ * Jeremy has agreed to the contents of reiserfs/README. -Hans -+ */ -+ -+#include <assert.h> -+ -+#if 0 -+/* OK for Intel */ -+typedef unsigned long u32; -+typedef const unsigned char u8; -+#else -+#include <inttypes.h> -+typedef uint32_t u32; -+typedef uint8_t u8; -+#endif -+ -+ -+#define DELTA 0x9E3779B9 -+#define FULLROUNDS 10 /* 32 is overkill, 16 is strong crypto */ -+#define PARTROUNDS 6 /* 6 gets complete mixing */ -+ -+/* a, b, c, d - data; h0, h1 - accumulated hash */ -+#define TEACORE(rounds) \ -+ do { \ -+ u32 sum = 0; \ -+ int n = rounds; \ -+ u32 b0, b1; \ -+ \ -+ b0 = h0; \ -+ b1 = h1; \ -+ \ -+ do \ -+ { \ -+ sum += DELTA; \ -+ b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b); \ -+ b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d); \ -+ } while(--n); \ -+ \ -+ h0 += b0; \ -+ h1 += b1; \ -+ } while(0) -+ -+u32 teahash3(/*u32 k[2], *//*u8*/const char *msg, int len) -+{ -+ u32 k[] = { 0x9464a485, 0x542e1a94, 0x3e846bff, 0xb75bcfc3}; -+ -+ u32 h0 = k[0], h1 = k[1]; -+ u32 a, b, c, d; -+ u32 pad; -+ int i; -+ -+ assert(len >= 0 && len < 256); -+ -+ pad = (u32)len | ((u32)len << 8); -+ pad |= pad << 16; -+ -+ while(len >= 16) -+ { -+ a = (u32)msg[ 0] | -+ (u32)msg[ 1] << 8 | -+ (u32)msg[ 2] << 16| -+ (u32)msg[ 3] << 24; -+ b = (u32)msg[ 4] | -+ (u32)msg[ 5] << 8 | -+ (u32)msg[ 6] << 16| -+ (u32)msg[ 7] << 24; -+ c = (u32)msg[ 8] | -+ (u32)msg[ 9] << 8 | -+ (u32)msg[10] << 16| -+ (u32)msg[11] << 24; -+ d = (u32)msg[12] | -+ (u32)msg[13] << 8 | -+ (u32)msg[14] << 16| -+ (u32)msg[15] << 24; -+ -+ TEACORE(PARTROUNDS); -+ -+ len -= 16; -+ msg += 16; -+ } -+ -+ if (len >= 12) -+ { -+ assert(len < 16); -+ -+ a = (u32)msg[ 0] | -+ (u32)msg[ 1] << 8 | -+ (u32)msg[ 2] << 16| -+ (u32)msg[ 3] << 24; -+ b = (u32)msg[ 4] | -+ (u32)msg[ 5] << 8 | -+ (u32)msg[ 6] << 16| -+ (u32)msg[ 7] << 24; -+ c = (u32)msg[ 8] | -+ (u32)msg[ 9] << 8 | -+ (u32)msg[10] << 16| -+ (u32)msg[11] << 24; -+ -+ d = pad; -+ for(i = 12; i < len; i++) -+ { -+ d <<= 8; -+ d |= msg[i]; -+ } -+ } -+ else if (len >= 8) -+ { -+ assert(len < 12); -+ -+ a = (u32)msg[ 0] | -+ (u32)msg[ 1] << 8 | -+ (u32)msg[ 2] << 16| -+ (u32)msg[ 3] << 24; -+ b = (u32)msg[ 4] | -+ (u32)msg[ 5] << 8 | -+ (u32)msg[ 6] << 16| -+ (u32)msg[ 7] << 24; -+ -+ c = d = pad; -+ for(i = 8; i < len; i++) -+ { -+ c <<= 8; -+ c |= msg[i]; -+ } -+ } -+ else if (len >= 4) -+ { -+ assert(len < 8); -+ -+ a = (u32)msg[ 0] | -+ (u32)msg[ 1] << 8 | -+ (u32)msg[ 2] << 16| -+ (u32)msg[ 3] << 24; -+ -+ b = c = d = pad; -+ for(i = 4; i < len; i++) -+ { -+ b <<= 8; -+ b |= msg[i]; -+ } -+ } -+ else -+ { -+ assert(len < 4); -+ -+ a = b = c = d = pad; -+ for(i = 0; i < len; i++) -+ { -+ a <<= 8; -+ a |= msg[i]; -+ } -+ } -+ -+ TEACORE(FULLROUNDS); -+ -+/* return 0;*/ -+ return h0^h1; -+} ---- nfs-server/ugid_map.c -+++ nfs-server/ugid_map.c 2002/11/08 13:59:16 -@@ -276,8 +276,10 @@ - if ((gid == 0 && mountp->o.root_squash) || mountp->o.all_squash) - retgid = mountp->o.nobody_gid; - -+#if 0 - Dprintf(D_UGID, "lgid(%s, %d) = %d\n", - inet_ntoa(mountp->client->clnt_addr), gid, retgid); -+#endif - return retgid; - } - |