summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/unfs-server/unfs-server-2.1+2.2beta47/006-reiserfs.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/unfs-server/unfs-server-2.1+2.2beta47/006-reiserfs.patch')
-rw-r--r--meta/recipes-devtools/unfs-server/unfs-server-2.1+2.2beta47/006-reiserfs.patch1277
1 files changed, 0 insertions, 1277 deletions
diff --git a/meta/recipes-devtools/unfs-server/unfs-server-2.1+2.2beta47/006-reiserfs.patch b/meta/recipes-devtools/unfs-server/unfs-server-2.1+2.2beta47/006-reiserfs.patch
deleted file mode 100644
index 22dcc42b69..0000000000
--- a/meta/recipes-devtools/unfs-server/unfs-server-2.1+2.2beta47/006-reiserfs.patch
+++ /dev/null
@@ -1,1277 +0,0 @@
1Upstream-Status: Inappropriate [other]
2Upstream is not making further releases of this software.
3
4Signed-off-by: Scott Garman <scott.a.garman@intel.com>
5
6# Patch origin: nfs-server source RPM from openSUSE 10.3
7
8--- nfs-server/Makefile.in
9+++ nfs-server/Makefile.in 2002/11/08 13:59:16
10@@ -100,7 +100,7 @@
11 utimes.c mkdir.c rename.c getopt.c getopt_long.c \
12 alloca.c mountlist.c xmalloc.c \
13 xstrdup.c strdup.c strstr.c nfsmounted.c faccess.c \
14- haccess.c daemon.c signals.c
15+ haccess.c daemon.c signals.c teahash3.c
16 XDRFILES = mount.x nfs_prot.x
17 GENFILES = mount.h mount_xdr.c mount_svc.c nfs_prot.h nfs_prot_xdr.c \
18 ugid.h ugid_xdr.c ugid_clnt.c
19@@ -112,7 +112,7 @@
20 MANPAGES8 = showmount
21 MANPAGES = $(MANPAGES5) $(MANPAGES8p) $(MANPAGES8)
22 LIBOBJS = version.o fsusage.o mountlist.o xmalloc.o xstrdup.o \
23- nfsmounted.o faccess.o haccess.o daemon.o \
24+ nfsmounted.o faccess.o haccess.o daemon.o teahash3.o \
25 signals.o @LIBOBJS@ @ALLOCA@
26 OBJS = logging.o fh.o devtab.o auth_init.o auth_clnt.o auth.o
27 NFSD_OBJS = nfsd.o rpcmisc.o nfs_dispatch.o getattr.o setattr.o \
28--- nfs-server/auth.c
29+++ nfs-server/auth.c 2002/11/08 13:59:16
30@@ -83,6 +83,7 @@
31 0, /* read-only */
32 0, /* relative links */
33 0, /* noaccess */
34+ 0, /* hashed inodes */
35 1, /* cross_mounts */
36 1, /* allow setuid */
37 65534, /* default uid */
38@@ -100,6 +101,7 @@
39 0, /* relative links */
40 0, /* noaccess */
41 1, /* cross_mounts */
42+ 0, /* hashed inodes */
43 0, /* allow setuid */
44 65534, /* default uid */
45 65534, /* default gid */
46@@ -991,6 +993,7 @@
47 if (mp == 0) {
48 mp = (nfs_mount*) xmalloc(sizeof(nfs_mount));
49 memset(mp, 0, sizeof(*mp));
50+ mp->mount_dev = 0;
51 mp->origin = cp;
52 mp->client = cp;
53 mp->path = xstrdup(path);
54@@ -1169,6 +1172,8 @@
55 default_options.nobody_gid = anon_gid;
56 anonymous_options.nobody_uid = anon_uid;
57 anonymous_options.nobody_gid = anon_gid;
58+ default_options.cross_mounts = cross_mounts;
59+ default_options.hashed_inodes = hashed_inodes;
60
61 memset(cached_clients, 0, sizeof(cached_clients));
62 cached_next = 0;
63--- nfs-server/auth.h
64+++ nfs-server/auth.h 2002/11/08 13:59:16
65@@ -43,15 +43,16 @@
66
67 typedef struct nfs_options {
68 ugid_mapping_t uidmap; /* uid/gid mapping behavior */
69- int root_squash;
70- int all_squash;
71- int some_squash; /* speed up luid() etc. */
72- int secure_port;
73- int read_only;
74- int link_relative;
75- int noaccess;
76- int cross_mounts;
77- int allow_setuid;
78+ unsigned root_squash : 1;
79+ unsigned all_squash : 1;
80+ unsigned some_squash : 1; /* speed up luid() etc. */
81+ unsigned secure_port : 1;
82+ unsigned read_only : 1;
83+ unsigned link_relative : 1;
84+ unsigned noaccess : 1;
85+ unsigned cross_mounts : 1;
86+ unsigned hashed_inodes : 1;
87+ unsigned allow_setuid : 1;
88 uid_t nobody_uid;
89 gid_t nobody_gid;
90 char * clnt_nisdomain;
91@@ -64,6 +65,7 @@
92 int length;
93 char * path;
94 nfs_options o;
95+ dev_t mount_dev;
96 /* Original NFS client */
97 struct nfs_client * origin;
98 } nfs_mount;
99@@ -121,6 +123,8 @@
100 extern void auth_check_all_netmasks(void);
101 extern void auth_sort_all_mountlists(void);
102 extern void auth_log_all(void);
103+extern int auth_checkdev(nfs_mount *, dev_t dev);
104+extern int auth_checkpathdev(char *, dev_t dev);
105
106 /* This function lets us set our euid/fsuid temporarily */
107 extern void auth_override_uid(uid_t);
108--- nfs-server/auth_clnt.c
109+++ nfs-server/auth_clnt.c 2002/11/08 13:59:16
110@@ -89,6 +89,13 @@
111 return NULL;
112 }
113
114+ if (!mp->o.cross_mounts && !mp->mount_dev) {
115+ struct stat st;
116+ if (!lstat(mp->path, &st) < 0)
117+ return NULL;
118+ mp->mount_dev = st.st_dev;
119+ }
120+
121 /* Check request originated on a privileged port. */
122 if (!allow_non_root && mp->o.secure_port
123 && !SECURE_PORT(svc_getcaller(rqstp->rq_xprt)->sin_port)) {
124@@ -350,3 +357,28 @@
125 return 1;
126 }
127 #endif
128+
129+int auth_checkpathdev(char *path, dev_t dev)
130+{
131+ nfs_mount *mp = auth_match_mount(nfsclient, path);
132+ if (!mp)
133+ return 0;
134+ return auth_checkdev(mp, dev);
135+}
136+
137+int auth_checkdev(nfs_mount *mp, dev_t dev)
138+{
139+ if (!mp->mount_dev)
140+ return 1;
141+ if (mp->mount_dev != dev) {
142+ struct stat st;
143+ /* Restat in case the cd switched */
144+ if (efs_lstat(mp->path, &st) < 0) {
145+ Dprintf(L_ERROR, "Unable to stat mount point %s\n", mp->path);
146+ return 0;
147+ }
148+ mp->mount_dev = st.st_dev;
149+ }
150+ return mp->mount_dev == dev;
151+}
152+
153--- nfs-server/auth_init.c
154+++ nfs-server/auth_init.c 2002/11/08 13:59:16
155@@ -320,6 +320,14 @@
156 /* knfsd compatibility, ignore */;
157 else ifkwd(4, "sync")
158 /* knfsd compatibility, ignore */;
159+ else ifkwd(13, "hashed_inodes")
160+ mp->o.hashed_inodes = 1;
161+ else ifkwd(16, "no_hashed_inodes")
162+ mp->o.hashed_inodes = 0;
163+ else ifkwd(12, "cross_mounts")
164+ mp->o.cross_mounts = 1;
165+ else ifkwd(15, "no_cross_mounts")
166+ mp->o.cross_mounts = 0;
167 else {
168 Dprintf(L_ERROR,
169 "Unknown keyword \"%.*s\" in export file\n",
170--- nfs-server/exports.man
171+++ nfs-server/exports.man 2002/11/08 13:59:16
172@@ -208,6 +208,17 @@
173 .IR no_all_squash ,
174 which is the default setting.
175 .TP
176+.IR hashed_inodes
177+Use a special scheme to generate inode numbers that may work better with
178+reiserfs filesystems.
179+.IR no_hashed_inodes
180+which uses a direct mapping is the default.
181+.TP
182+.IR cross_mounts
183+Do not cross mount points in exports. Turning this off with
184+.IR no_cross_mounts
185+avoids inode number space conflicts when there are too many files.
186+.TP
187 .IR map_daemon
188 This option turns on dynamic uid/gid mapping. Each uid in an NFS request
189 will be translated to the equivalent server uid, and each uid in an
190--- nfs-server/fh.c
191+++ nfs-server/fh.c 2002/11/08 14:11:31
192@@ -4,8 +4,9 @@
193 *
194 * Interfaces:
195 * pseudo_inode
196- * mostly used internally, but also called from unfsd.c
197- * when reporting directory contents.
198+ * mostly used internally, for hash tables
199+ * visible_inode
200+ * generate visible inode shown to the client in the fattr.
201 * fh_init
202 * Initializes the queues and 'flush' timer
203 * fh_pr
204@@ -47,6 +48,8 @@
205 * Note: the original code mistakenly assumes that the overall path
206 * length remains within the value given by PATH_MAX... that leads
207 * to interesting buffer overflows all over the place.
208+ *
209+ * Depends that dev_t only uses 16bits.
210 */
211
212 #include <assert.h>
213@@ -137,9 +140,9 @@
214 };
215
216 /* Forward declared local functions */
217-static psi_t path_psi(char *, nfsstat *, struct stat *, int);
218+static psi_t path_psi(char *, nfsstat *, struct stat *, int, int *);
219 static psi_t path_psi_m(char *, nfsstat *, struct stat *,
220- struct stat *, int);
221+ struct stat *, int, int *);
222 static int fh_flush_fds(void);
223 static char * fh_dump(svc_fh *);
224 static void fh_insert_fdcache(fhcache *fhc);
225@@ -173,19 +176,22 @@
226 fh_list_size++;
227
228 /* Insert into hash tab. */
229- hash_slot = &(fh_hashed[fhc->h.psi % HASH_TAB_SIZE]);
230+ hash_slot = &(fh_hashed[pseudo_inode(fhc->h.ino,fhc->h.dev) % HASH_TAB_SIZE]);
231 fhc->hash_next = *hash_slot;
232 *hash_slot = fhc;
233 }
234
235 static fhcache *
236-fh_lookup(psi_t psi)
237+fh_lookup(ino_t ino, dev_t dev)
238 {
239 register fhcache *fhc;
240
241- fhc = fh_hashed[psi % HASH_TAB_SIZE];
242- while (fhc != NULL && fhc->h.psi != psi)
243+ fhc = fh_hashed[pseudo_inode(ino,dev) % HASH_TAB_SIZE];
244+ while (fhc != NULL) {
245+ if (fhc->h.ino == ino && fhc->h.dev == dev)
246+ break;
247 fhc = fhc->hash_next;
248+ }
249 return (fhc);
250 }
251
252@@ -193,7 +199,8 @@
253 fh_insert_fdcache(fhcache *fhc)
254 {
255 #ifdef FHTRACE
256- Dprintf(D_FHTRACE, "insert fh %x into fdcache @%d\n", fhc->h.psi, fhc->fd);
257+ Dprintf(D_FHTRACE, "insert fh %x,%x into fdcache @%d\n",
258+ fhc->h.ino, fhc->h.dev, fhc->fd);
259 if (fhc->fd < 0) {
260 fh_complain("fd cache bug: bad fd", fhc);
261 return;
262@@ -289,8 +296,9 @@
263 #endif
264
265 Dprintf(D_FHTRACE|D_FHCACHE,
266- "fh_delete: deleting handle %x ('%s', fd=%d)\n",
267- fhc, fhc->path ? fhc->path : "<unnamed>", fhc->fd);
268+ "fh_delete: deleting handle %x [%x,%x] ('%s', fd=%d)\n",
269+ fhc, fhc->h.dev, fhc->h.ino, fhc->path ? fhc->path : "<unnamed>",
270+ fhc->fd);
271
272 /* Remove from current posn */
273 fhc->prev->next = fhc->next;
274@@ -298,7 +306,7 @@
275 fh_list_size--;
276
277 /* Remove from hash tab */
278- hash_slot = &(fh_hashed[fhc->h.psi % HASH_TAB_SIZE]);
279+ hash_slot = &(fh_hashed[pseudo_inode(fhc->h.ino,fhc->h.dev) % HASH_TAB_SIZE]);
280 while (*hash_slot != NULL && *hash_slot != fhc)
281 hash_slot = &((*hash_slot)->hash_next);
282 if (*hash_slot == NULL)
283@@ -528,6 +536,7 @@
284 index -= 8;
285 }
286
287+#if 0
288 /* If we have an XXL inode number, spew out warning (but at most
289 * once a second) */
290 if (inode & ~mask) {
291@@ -541,14 +550,34 @@
292 }
293 inode &= mask;
294 }
295-
296+#endif
297 return (psi_t) (prefix | inode);
298 #endif
299 }
300
301+/* Inode as handed out by attr calls. */
302+psi_t
303+visible_inode(ino_t ino, dev_t dev, nfs_mount *mount)
304+{
305+ if (!mount->o.cross_mounts)
306+ return ino;
307+
308+ if (mount->o.hashed_inodes) {
309+ extern __u32 teahash3(/*u32 k[2], *//*u8*/const char *msg, int len);
310+
311+ struct {
312+ ino_t ino;
313+ dev_t dev;
314+ } tup = { ino,dev };
315+ return teahash3((char *) &tup, sizeof tup);
316+ }
317+
318+ return pseudo_inode(ino, dev);
319+}
320+
321 #if 1
322 static char *
323-fh_buildpath(svc_fh *h)
324+fh_buildpath(svc_fh *h, dev_t basedev)
325 {
326 char pathbuf[PATH_MAX + NAME_MAX + 1], *path;
327 long cookie_stack[HP_LEN + 1];
328@@ -565,13 +594,17 @@
329
330 if (efs_stat("/", &sbuf) < 0)
331 return (NULL);
332- psi = pseudo_inode(sbuf.st_ino, sbuf.st_dev);
333 if (h->hash_path[0] == 0) {
334- if (psi != h->psi)
335- return (NULL);
336- return xstrdup("/");
337+ if (sbuf.st_ino == h->ino && sbuf.st_dev == h->dev)
338+ ;
339+ else
340+ return NULL;
341+ strcpy(pathbuf,"/");
342+ path = xstrdup(pathbuf);
343+ return (path);
344 }
345
346+ psi = pseudo_inode(sbuf.st_ino, sbuf.st_dev);
347 if (hash_psi(psi) != h->hash_path[1])
348 return (NULL);
349
350@@ -599,11 +632,18 @@
351
352 psi = pseudo_inode(dp->d_ino, sbuf.st_dev);
353 if (i == h->hash_path[0] + 1) {
354- if (psi != h->psi)
355+ if (sbuf.st_dev != h->dev || dp->d_ino != h->ino)
356 continue;
357 /* GOT IT */
358 strcpy(pathbuf + pathlen, dp->d_name);
359- path = xstrdup(pathbuf);
360+ if (!basedev || sbuf.st_dev == basedev ||
361+ auth_checkpathdev(pathbuf, sbuf.st_dev)) {
362+ path = xstrdup(pathbuf);
363+ } else {
364+ dprintf(L_ERROR, "fh_buildpath: basedev %x != dev %x for %s\n",
365+ (unsigned)basedev,(unsigned)sbuf.st_dev,pathbuf);
366+ path = NULL;
367+ }
368 efs_closedir(dir);
369 auth_override_uid(auth_uid);
370 return (path);
371@@ -754,16 +794,16 @@
372 #endif
373
374 static psi_t
375-path_psi(char *path, nfsstat *status, struct stat *sbp, int svalid)
376+path_psi(char *path, nfsstat *status, struct stat *sbp, int svalid, int *mp)
377 {
378 struct stat smounted;
379
380- return path_psi_m(path, status, sbp, &smounted, svalid);
381+ return path_psi_m(path, status, sbp, &smounted, svalid, mp);
382 }
383
384 static psi_t
385 path_psi_m(char *path, nfsstat *status,
386- struct stat *sbp, struct stat *mbp, int svalid)
387+ struct stat *sbp, struct stat *mbp, int svalid, int *mp)
388 {
389 struct stat sbuf, ddbuf;
390
391@@ -815,6 +855,8 @@
392 DIR *dirp;
393 struct dirent *dp;
394
395+ if (mp) *mp = 1;
396+
397 errno = 0;
398 dirp = efs_opendir(dname);
399 fname[-1] = '/'; /* Restore path */
400@@ -860,9 +902,70 @@
401 }
402
403 fhcache *
404-fh_find(svc_fh *h, int mode)
405+fh_newfh(svc_fh *h, int mode, dev_t basedev)
406+{
407+ fhcache *fhc, *flush;
408+
409+ ex_state = active;
410+ for (flush = fh_tail.prev; fh_list_size > FH_CACHE_LIMIT; flush = fhc) {
411+ /* Don't flush current head. */
412+ if (flush == &fh_head)
413+ break;
414+ fhc = flush->prev;
415+ fh_delete(flush);
416+ }
417+ fhc = (fhcache *) xmalloc(sizeof *fhc);
418+ if (mode == FHFIND_FCREATE) {
419+ /* File will be created */
420+ fhc->path = NULL;
421+ } else {
422+ /* File must exist. Attempt to construct from hash_path */
423+ char *path;
424+
425+ if ((path = fh_buildpath(h, basedev)) == NULL) {
426+#ifdef FHTRACE
427+ Dprintf(D_FHTRACE, "fh_find: stale fh (hash path)\n");
428+ Dprintf(D_FHTRACE, "\tdata: %s\n", fh_dump(h));
429+#endif
430+ free(fhc);
431+ ex_state = inactive;
432+ return NULL;
433+ }
434+ fhc->path = path;
435+ }
436+ fhc->flags = 0;
437+ if (fhc->path && efs_lstat(fhc->path, &fhc->attrs) >= 0) {
438+ if (re_export && nfsmounted(fhc->path, &fhc->attrs))
439+ fhc->flags |= FHC_NFSMOUNTED;
440+ fhc->flags |= FHC_ATTRVALID;
441+ }
442+ fhc->fd = -1;
443+ fhc->last_used = curtime;
444+ fhc->h = *h;
445+ fhc->last_clnt = NULL;
446+ fhc->last_mount = NULL;
447+ fhc->last_uid = (uid_t)-1;
448+ fhc->fd_next = fhc->fd_prev = NULL;
449+ fh_inserthead(fhc);
450+ Dprintf(D_FHCACHE,
451+ "fh_find: created new handle %x (path `%s' ino:%x dev:%x)\n",
452+ fhc, fhc->path ? fhc->path : "<unnamed>", fhc->h.ino, fhc->h.dev);
453+ ex_state = inactive;
454+ if (fh_list_size > FH_CACHE_LIMIT)
455+ flush_cache(0);
456+#ifdef FHTRACE
457+ if (fhc->h.hash_path[0] == 0xFF) {
458+ Dprintf(L_ERROR, "newly created fh instantly flushed?!");
459+ return NULL;
460+ }
461+#endif
462+ return (fhc);
463+}
464+
465+fhcache *
466+fh_find(svc_fh *h, int mode, dev_t basedev)
467 {
468- register fhcache *fhc, *flush;
469+ register fhcache *fhc;
470 int check;
471
472 check = (mode & FHFIND_CHECK);
473@@ -877,12 +980,12 @@
474
475 ex_state = active;
476 time(&curtime);
477- while ((fhc = fh_lookup(h->psi)) != NULL) {
478+ while ((fhc = fh_lookup(h->ino,h->dev)) != NULL) {
479 struct stat sbuf, *s = NULL;
480 nfsstat dummy;
481
482- Dprintf(D_FHCACHE, "fh_find: psi=%lx... found '%s', fd=%d\n",
483- (unsigned long) h->psi,
484+ Dprintf(D_FHCACHE, "fh_find: (%u,%u)... found '%s', fd=%d\n",
485+ h->ino, h->dev,
486 fhc->path ? fhc->path : "<unnamed>",
487 fhc->fd);
488
489@@ -905,6 +1008,7 @@
490 Dprintf(D_FHTRACE,
491 "fh_find: stale fh: lstat: %m\n");
492 } else {
493+ int mp = 0;
494 /* If device/ino don't match, fhc->path may
495 * be a mount point (hence lstat() returns
496 * a different inode number than the readdir()
497@@ -915,19 +1019,26 @@
498
499 /* Get the dev/ino of the underlying
500 * mount point. */
501- path_psi(fhc->path, &dummy, s, 1);
502- if (fh_attrmatch(fhc, s))
503- goto fh_return;
504+ if (path_psi(fhc->path, &dummy, s, 1, &mp) &&
505+ fh_attrmatch(fhc, s)) {
506+ if (!mp)
507+ Dprintf(D_FHTRACE,"fh_find: should be mount point %x,%x\n",
508+ h->dev,h->ino);
509+
510+ }
511
512- Dprintf(D_FHTRACE, "fh_find: stale fh: %lx",
513- (unsigned long) h->psi);
514+ Dprintf(D_FHTRACE, "fh_find: stale fh: "
515+ "dev/ino %x/%lx ino:%x dev:%x",
516+ s->st_dev, s->st_ino,
517+ (unsigned)h->ino, (unsigned)h->dev);
518 }
519
520 fh_discard:
521 #ifdef FHTRACE
522 Dprintf(D_FHTRACE, "\tdata: %s\n", fh_dump(h));
523 #endif
524- Dprintf(D_FHCACHE, "fh_find: delete cached handle\n");
525+ Dprintf(D_FHCACHE, "fh_find: delete cached handle %x,%x <%x>\n",
526+ fhc->h.dev,fhc->h.ino,fhc->path ? fhc->path : "no path");
527 fh_delete(fhc);
528 break;
529 }
530@@ -947,88 +1058,13 @@
531 return (fhc);
532 }
533
534- Dprintf(D_FHCACHE, "fh_find: psi=%lx... not found\n",
535- (unsigned long) h->psi);
536-
537- if (mode == FHFIND_FCACHED) {
538- ex_state = inactive;
539- return NULL;
540- }
541-
542- for (flush = fh_tail.prev; fh_list_size > FH_CACHE_LIMIT; flush = fhc) {
543- /* Don't flush current head. */
544- if (flush == &fh_head)
545- break;
546- fhc = flush->prev;
547- fh_delete(flush);
548- }
549-
550- fhc = (fhcache *) xmalloc(sizeof *fhc);
551- if (mode == FHFIND_FCREATE) {
552- /* File will be created */
553- fhc->path = NULL;
554- } else {
555- /* File must exist. Attempt to construct from hash_path */
556- char *path;
557-
558- if ((path = fh_buildpath(h)) == NULL) {
559-#ifdef FHTRACE
560- Dprintf(D_FHTRACE, "fh_find: stale fh (hash path)\n");
561- Dprintf(D_FHTRACE, "\tdata: %s\n", fh_dump(h));
562-#endif
563- free(fhc);
564- ex_state = inactive;
565- return NULL;
566- }
567- fhc->path = path;
568- }
569-
570- fhc->flags = 0;
571- if (fhc->path && efs_lstat(fhc->path, &fhc->attrs) >= 0) {
572- if (nfsmounted(fhc->path, &fhc->attrs)) {
573- fhc->flags |= FHC_NFSMOUNTED;
574-#if 0
575- /* We must allow the client to send us the
576- * file handle for the NFS mount point itself,
577- * but not for entries within an NFS mount.
578- * XXX: needs fixing.
579- */
580- if (!re_export) {
581- Dprintf(D_FHTRACE,
582- "Attempt to use %s (non-exportable)\n",
583- fhc->path);
584- free(fhc);
585- ex_state = inactive;
586- return NULL;
587- }
588-#endif
589- }
590- fhc->flags |= FHC_ATTRVALID;
591- fhc->dev = fhc->attrs.st_dev;
592- fhc->ino = fhc->attrs.st_ino;
593- fhc->type = fhc->attrs.st_mode & S_IFMT;
594- }
595- fhc->fd = -1;
596- fhc->last_used = curtime;
597- fhc->h = *h;
598- fhc->last_clnt = NULL;
599- fhc->last_mount = NULL;
600- fhc->last_uid = (uid_t)-1;
601- fhc->fd_next = fhc->fd_prev = NULL;
602- fh_inserthead(fhc);
603- Dprintf(D_FHCACHE,
604- "fh_find: created new handle %x (path `%s' psi %08x)\n",
605- fhc, fhc->path ? fhc->path : "<unnamed>", fhc->h.psi);
606 ex_state = inactive;
607- if (fh_list_size > FH_CACHE_LIMIT)
608- flush_cache(0);
609-#ifdef FHTRACE
610- if (fhc->h.hash_path[0] == 0xFF) {
611- Dprintf(L_ERROR, "newly created fh instantly flushed?!");
612+
613+ Dprintf(D_FHCACHE, "fh_find: (%u,%u) ... not found\n",
614+ h->ino, h->dev);
615+ if (mode == FHFIND_FCACHED)
616 return NULL;
617- }
618-#endif
619- return (fhc);
620+ return fh_newfh(h, mode, basedev);
621 }
622
623 /*
624@@ -1040,7 +1076,7 @@
625 {
626 fhcache *h;
627
628- if ((h = fh_find((svc_fh *) fh, FHFIND_FCACHED)) == NULL)
629+ if ((h = fh_find((svc_fh *) fh, FHFIND_FCACHED, 0)) == NULL)
630 return fh_dump((svc_fh *) fh);
631 return (h->path);
632 }
633@@ -1050,10 +1086,10 @@
634 {
635 static char buf[65];
636 char *sp;
637- int i, n = fh->hash_path[0];
638+ int i, n = fh->hash_path[0], l;
639
640- sprintf(buf, "%08x %02x ", fh->psi, fh->hash_path[0]);
641- for (i = 1, sp = buf + 12; i <= n && i < HP_LEN; i++, sp += 2)
642+ l = sprintf(buf, "%08x %04x %02x ", fh->ino, fh->dev, fh->hash_path[0]);
643+ for (i = 1, sp = buf + l; i <= n && i < HP_LEN; i++, sp += 2)
644 sprintf(sp, "%02x", fh->hash_path[i]);
645 return buf;
646 }
647@@ -1082,7 +1118,7 @@
648
649 memset(&key, 0, sizeof(key));
650 status = NFS_OK;
651- if ((psi = path_psi("/", &status, &stb, 0)) == 0)
652+ if ((psi = path_psi("/", &status, &stb, 0, NULL)) == 0)
653 return ((int) status);
654
655 s = path;
656@@ -1091,7 +1127,7 @@
657 return ((int) NFSERR_NAMETOOLONG);
658 key.hash_path[key.hash_path[0]] = hash_psi(psi);
659 *s = '\0';
660- if ((psi = path_psi(path, &status, &stb, 0)) == 0)
661+ if ((psi = path_psi(path, &status, &stb, 0, NULL)) == 0)
662 return ((int) status);
663 *s = '/';
664 }
665@@ -1099,11 +1135,12 @@
666 if (++(key.hash_path[0]) >= HP_LEN)
667 return ((int) NFSERR_NAMETOOLONG);
668 key.hash_path[key.hash_path[0]] = hash_psi(psi);
669- if ((psi = path_psi(path, &status, &stb, 0)) == 0)
670+ if ((psi = path_psi(path, &status, &stb, 0, NULL)) == 0)
671 return ((int) status);
672 }
673- key.psi = psi;
674- h = fh_find(&key, FHFIND_FCREATE);
675+ key.dev = stb.st_dev;
676+ key.ino = stb.st_ino;
677+ h = fh_find(&key, FHFIND_FCREATE, 0);
678
679 #ifdef FHTRACE
680 if (!h)
681@@ -1123,6 +1160,7 @@
682 return ((int) status);
683 }
684
685+#if 0
686 char *
687 fh_path(nfs_fh *fh, nfsstat *status)
688 {
689@@ -1135,6 +1173,7 @@
690 *status = NFS_OK;
691 return (h->path);
692 }
693+#endif
694
695 nfs_fh *
696 fh_handle(fhcache *h)
697@@ -1349,7 +1388,7 @@
698 if (sbp == NULL)
699 sbp = &sbuf;
700
701- if ((dirh = fh_find((svc_fh *) &dopa->dir, FHFIND_FEXISTS)) == NULL)
702+ if ((dirh = fh_find((svc_fh *) &dopa->dir, FHFIND_FEXISTS, 0)) == NULL)
703 return NFSERR_STALE;
704
705 /*
706@@ -1419,8 +1458,22 @@
707
708 *new_fh = dopa->dir;
709 key = (svc_fh *) new_fh;
710- if ((key->psi = path_psi_m(pathbuf, &ret, sbp, &smount, 0)) == 0)
711+
712+ if (path_psi_m(pathbuf, &ret, sbp, &smount, 0, NULL) == 0)
713 return (ret);
714+ key->ino = sbp->st_ino;
715+ key->dev = sbp->st_dev;
716+
717+ if (sbp->st_dev != dirh->h.dev) {
718+ nfs_mount *mp = dirh->last_mount;
719+ if (!mp)
720+ Dprintf(L_ERROR, "no last mount in fh_compose for %s\n", pathbuf);
721+ else if (auth_checkdev(mp, sbp->st_dev) == 0) {
722+ Dprintf(L_ERROR, "access to no cross path below mountpoint (<%s>, %x<->%x)\n",
723+ pathbuf, mp->mount_dev, sbp->st_dev);
724+ return NFSERR_STALE;
725+ }
726+ }
727
728 if (is_dd) {
729 /* Don't cd .. from root, or mysterious ailments will
730@@ -1430,11 +1483,12 @@
731 } else {
732 if (++(key->hash_path[0]) >= HP_LEN)
733 return NFSERR_NAMETOOLONG;
734- key->hash_path[key->hash_path[0]] = hash_psi(dirh->h.psi);
735+ key->hash_path[key->hash_path[0]] = hash_psi(pseudo_inode(dirh->h.ino,
736+ dirh->h.dev));
737 }
738 /* FIXME: when crossing a mount point, we'll find the real
739 * dev/ino in sbp and can store it in h... */
740- h = fh_find(key, FHFIND_FCREATE);
741+ h = fh_find(key, FHFIND_FCREATE, 0);
742
743 #ifdef FHTRACE
744 if (h == NULL)
745@@ -1456,7 +1510,7 @@
746 /* We must have cached an old file under the same inode # */
747 Dprintf(D_FHTRACE, "Disposing of fh with bad path.\n");
748 fh_delete(h);
749- h = fh_find(key, FHFIND_FCREATE);
750+ h = fh_find(key, FHFIND_FCREATE, dirh->last_mount ? dirh->last_mount->mount_dev : 0);
751 #ifdef FHTRACE
752 if (!h) return NFSERR_STALE;
753 #endif
754@@ -1511,12 +1565,14 @@
755 return (NFS_OK);
756 }
757
758+#if 0
759 psi_t
760 fh_psi(nfs_fh *fh)
761 {
762 svc_fh *h = (svc_fh *) fh;
763 return (h->psi);
764 }
765+#endif
766
767 void
768 fh_remove(char *path)
769@@ -1524,12 +1580,13 @@
770 psi_t psi;
771 nfsstat status;
772 fhcache *fhc;
773+ struct stat st;
774
775- psi = path_psi(path, &status, NULL, 0);
776+ psi = path_psi(path, &status, &st, 0, NULL);
777 if (psi == 0)
778 return;
779 ex_state = active;
780- fhc = fh_lookup(psi);
781+ fhc = fh_lookup(st.st_ino,st.st_dev);
782 if (fhc != NULL)
783 fh_delete(fhc);
784
785@@ -1634,6 +1691,11 @@
786 fh_init(void)
787 {
788 static int initialized = 0;
789+
790+ if (sizeof(svc_fh) > 32) {
791+ fprintf(stderr, "filehandle wrong size %d\n", sizeof(svc_fh));
792+ exit(10);
793+ }
794
795 if (initialized)
796 return;
797--- nfs-server/fh.h
798+++ nfs-server/fh.h 2002/11/08 13:59:16
799@@ -20,6 +20,7 @@
800 #define FHC_XONLY_PATH 001 /* NOT USED ANYMORE */
801 #define FHC_ATTRVALID 002
802 #define FHC_NFSMOUNTED 004
803+#define FHC_CROSS 010
804
805 /* Modes for fh_find */
806 #define FHFIND_FEXISTS 0 /* file must exist */
807@@ -65,11 +66,12 @@
808 *
809 * hash_path[hash_path[0]+1] ... hash_path[HP_LEN-1] == 0
810 */
811-#define HP_LEN (NFS_FHSIZE - sizeof(psi_t))
812+#define HP_LEN (NFS_FHSIZE-sizeof(u_int32_t)-sizeof(u_int16_t))
813 typedef struct {
814- psi_t psi;
815+ u_int32_t ino;
816+ u_int16_t dev;
817 __u8 hash_path[HP_LEN];
818-} svc_fh;
819+} svc_fh __attribute__((packed));
820
821 typedef enum { inactive, active } mutex;
822
823@@ -100,6 +102,7 @@
824
825 /* These are fixed during the lifetime of this object */
826 svc_fh h;
827+ psi_t psi;
828 dev_t dev;
829 ino_t ino;
830 mode_t type; /* st_mode & S_IFMT */
831@@ -122,10 +125,11 @@
832 /* Global function prototypes. */
833 extern nfsstat nfs_errno(void);
834 extern psi_t pseudo_inode(ino_t inode, dev_t dev);
835+extern psi_t visible_inode(ino_t inode, dev_t dev, nfs_mount *);
836 extern void fh_init(void);
837 extern char *fh_pr(nfs_fh *fh);
838 extern int fh_create(nfs_fh *fh, char *path);
839-extern fhcache *fh_find(svc_fh *h, int create);
840+extern fhcache *fh_find(svc_fh *h, int create, dev_t basedev);
841 extern char *fh_path(nfs_fh *fh, nfsstat *status);
842 extern int path_open(char *path, int omode, int perm);
843 extern int fh_fd(fhcache *fhc, nfsstat *status, int omode);
844@@ -139,6 +143,7 @@
845 extern void fh_flush(int force);
846 extern RETSIGTYPE flush_cache(int sig);
847 extern int nfsmounted(const char *path, struct stat *sbp);
848+extern fhcache *fh_newfh(svc_fh *fh, int mode, dev_t basedev);
849
850 #ifdef ENABLE_DEVTAB
851 extern unsigned int devtab_index(dev_t);
852--- nfs-server/getattr.c
853+++ nfs-server/getattr.c 2002/11/08 13:59:16
854@@ -43,7 +43,7 @@
855 {
856 fhcache *fhc;
857
858- if ((fhc = fh_find((svc_fh*)fh, FHFIND_FEXISTS)) == NULL) {
859+ if ((fhc = fh_find((svc_fh*)fh, FHFIND_FEXISTS, 0)) == NULL) {
860 Dprintf(D_CALL, "getattr: failed! No such file.\n");
861 return (NFSERR_STALE);
862 }
863@@ -103,18 +103,8 @@
864 #else
865 attr->blocks = st_blocks(s);
866 #endif
867-#if 0
868- if (nfsmount->o.cross_mounts) {
869- attr->fsid = 1;
870- attr->fileid = fh_psi((nfs_fh *)&(fhc->h));
871- } else {
872- attr->fsid = s->st_dev;
873- attr->fileid = covered_ino(fhc->path);
874- }
875-#else
876- attr->fsid = 1;
877- attr->fileid = fh_psi((nfs_fh *)&(fhc->h));
878-#endif
879+ attr->fsid = 1; // XXX
880+ attr->fileid = visible_inode(fhc->h.ino, fhc->h.dev, nfsmount);
881
882 /* This may be needed by some Suns... testing */
883 #define MINTIME (24 * 2600)
884--- nfs-server/mountd.c
885+++ nfs-server/mountd.c 2002/11/08 13:59:16
886@@ -36,6 +36,8 @@
887 #include "signals.h"
888 #include <rpc/pmap_clnt.h>
889
890+int cross_mounts = 1;
891+int hashed_inodes; /* dummy */
892
893 static void usage(FILE *, int);
894 static void terminate(void);
895@@ -58,9 +60,9 @@
896 { "no-spoof-trace", 0, 0, 't' },
897 { "version", 0, 0, 'v' },
898 { "fail-safe", optional_argument, 0, 'z' },
899+ { "no-cross-mounts", 0, 0, 'x' },
900 { "no-tcp", 0, 0, OPT_NOTCP },
901 { "loopback-only", 0, 0, OPT_LOOPBACK },
902-
903 { NULL, 0, 0, 0 }
904 };
905 static const char * shortopts = "Fd:f:hnpP:rtvz::";
906@@ -80,6 +82,7 @@
907 int need_reinit = 0;
908 int need_flush = 0;
909 extern char version[];
910+nfs_client *nfsclient; /* dummy */
911
912 /*
913 * NULL
914@@ -319,6 +322,9 @@
915 opterr = 0;
916 while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != EOF)
917 switch (c) {
918+ case 'x':
919+ cross_mounts = 0;
920+ break;
921 case 'F':
922 foreground = 1;
923 break;
924@@ -444,7 +450,7 @@
925 program_name);
926 fprintf(fp, " [--debug kind] [--help] [--allow-non-root]\n");
927 fprintf(fp, " [--promiscuous] [--version] [--port portnum]\n");
928- fprintf(fp, " [--exports-file=file]\n");
929+ fprintf(fp, " [--exports-file=file] [--no-cross-mounts]\n");
930 exit(n);
931 }
932
933--- nfs-server/nfsd.c
934+++ nfs-server/nfsd.c 2002/11/08 14:20:57
935@@ -72,7 +72,7 @@
936 { "no-tcp", 0, 0, OPT_NOTCP },
937 { "udp-only", 0, 0, OPT_NOTCP },
938 { "loopback-only", 0, 0, OPT_LOOPBACK },
939-
940+ { "hashed-inodes", 0, 0, 'I' },
941 { NULL, 0, 0, 0 }
942 };
943 static const char * shortopts = "a:d:Ff:hlnP:prR:tvz::";
944@@ -91,6 +91,7 @@
945 int need_flush = 0; /* flush fh cache */
946 int read_only = 0; /* Global ro forced */
947 int cross_mounts = 1; /* Transparently cross mnts */
948+int hashed_inodes = 0;
949 int log_transfers = 0; /* Log transfers */
950 static svc_fh public_fh; /* Public NFSv2 FH */
951
952@@ -122,12 +123,17 @@
953 {
954 static int total = 0, cached = 0;
955 fhcache *fhc;
956+ int newfh = 0;
957
958- /* Try to map FH. If not cached, reconstruct path with root priv */
959- fhc = fh_find((svc_fh *)fh, FHFIND_FEXISTS|FHFIND_CHECK);
960- if (fhc == NULL) {
961- *statp = NFSERR_STALE;
962- return NULL;
963+ /* Try to map FH. */
964+ fhc = fh_find((svc_fh *)fh, FHFIND_FCACHED|FHFIND_CHECK, 0);
965+ if (!fhc) {
966+ fhc = fh_newfh((svc_fh*)fh, FHFIND_FEXISTS|FHFIND_CHECK, 0);
967+ if (!fhc) {
968+ *statp = NFSERR_STALE;
969+ return NULL;
970+ }
971+ newfh = 1;
972 }
973
974 /* Try to retrieve last client who accessed this fh */
975@@ -163,6 +169,16 @@
976 100 * (double) cached / total);
977 */
978
979+ /* Trust the crossmount check of the parent directory for creates */
980+ if (newfh &&
981+ (fhc->flags & FHC_ATTRVALID) &&
982+ auth_checkdev(nfsmount, fhc->attrs.st_dev) == 0) {
983+ Dprintf(L_ERROR, "auth_fh: fh crossed mount %s: %x<->%x\n",
984+ fhc->path ? fhc->path : "???", nfsmount->mount_dev, fhc->attrs.st_dev);
985+ *statp = NFSERR_STALE; /* or ACCES? */
986+ return NULL;
987+ }
988+
989 if (nfsmount->o.noaccess &&
990 ((flags & CHK_NOACCESS) || strcmp(nfsmount->path, fhc->path))) {
991 struct in_addr addr = svc_getcaller(rqstp->rq_xprt)->sin_addr;
992@@ -195,6 +211,7 @@
993 fhcache *fhc;
994 nfsstat status;
995 char *path = buf, *sp;
996+ struct stat st;
997
998 /* Authenticate directory file handle */
999 if ((fhc = auth_fh(rqstp, &dopa->dir, &status, flags)) == NULL)
1000@@ -219,6 +236,9 @@
1001 if ((nfsmount = auth_path(nfsclient, rqstp, path)) == NULL)
1002 return NFSERR_ACCES;
1003
1004+ if (efs_lstat(path, &st) >= 0 && !auth_checkdev(nfsmount, st.st_dev))
1005+ return NFSERR_ACCES;
1006+
1007 /* XXX: really need to call it again here?
1008 * Already invoked in auth_fh */
1009 if (!auth_user(nfsmount, rqstp))
1010@@ -318,7 +338,8 @@
1011 int ispublic = 0;
1012
1013 /* First check whether this is the public FH */
1014- if (((svc_fh *) fh)->psi == 0 && !memcmp(fh, &public_fh, FHSIZE)) {
1015+ if (((svc_fh *) fh)->dev == 0 && ((svc_fh*)fh)->ino == 0 &&
1016+ !memcmp(fh, &public_fh, FHSIZE)) {
1017 if (public_root_path == NULL)
1018 return NFSERR_ACCES;
1019 memcpy(&argp->dir, &public_root, NFS_FHSIZE);
1020@@ -333,6 +354,7 @@
1021 if (!(fhc = auth_fh(rqstp, fh, &status, CHK_READ)))
1022 return status;
1023
1024+ /* FIXME: does too many stats */
1025 status = fh_compose(argp, &dp->file, &sbuf, -1, -1, ispublic);
1026 if (status != NFS_OK)
1027 return status;
1028@@ -896,6 +918,9 @@
1029 errno = 0;
1030 if (efs_lstat(h->path, &sbuf) < 0 || !(S_ISDIR(sbuf.st_mode)))
1031 return (NFSERR_NOTDIR);
1032+ if (!auth_checkdev(h->last_mount, sbuf.st_dev))
1033+ dotsonly = 1;
1034+
1035 if ((dirp = efs_opendir(h->path)) == NULL)
1036 return ((errno ? nfs_errno() : NFSERR_NAMETOOLONG));
1037
1038@@ -923,7 +948,7 @@
1039 }
1040
1041 e = *ep = (entry *) xmalloc(sizeof(entry));
1042- e->fileid = pseudo_inode(dp->d_ino, sbuf.st_dev);
1043+ e->fileid = visible_inode(dp->d_ino, sbuf.st_dev, h->last_mount);
1044 e->name = xmalloc(NLENGTH(dp) + 1);
1045 strcpy(e->name, dp->d_name);
1046 dloc = htonl(efs_telldir(dirp));
1047@@ -1033,6 +1058,9 @@
1048 case 'x':
1049 cross_mounts = 0;
1050 break;
1051+ case 'I':
1052+ hashed_inodes = 1;
1053+ break;
1054 case 'z':
1055 if (optarg)
1056 failsafe_level = atoi(optarg);
1057@@ -1189,7 +1217,7 @@
1058 " [--debug kind] [--exports-file=file] [--port port]\n"
1059 " [--allow-non-root] [--promiscuous] [--version] [--foreground]\n"
1060 " [--re-export] [--log-transfers] [--public-root path]\n"
1061-" [--no-spoof-trace] [--help]\n"
1062+" [--no-spoof-trace] [--no-cross-mounts] [--hashed-inodes] [--help]\n"
1063 , program_name);
1064 exit(n);
1065 }
1066--- nfs-server/nfsd.h
1067+++ nfs-server/nfsd.h 2002/11/08 13:59:16
1068@@ -51,6 +51,7 @@
1069 extern int need_reinit;
1070 extern int need_flush;
1071 extern time_t nfs_dispatch_time;
1072+extern int cross_mounts, hashed_inodes;
1073
1074 /* Include the other module definitions. */
1075 #include "auth.h"
1076--- nfs-server/setattr.c
1077+++ nfs-server/setattr.c 2002/11/08 13:59:16
1078@@ -17,6 +17,7 @@
1079
1080 #define IGNORE_TIME ((unsigned int) -1)
1081
1082+#if 0
1083 /*
1084 * Set file attributes based on file handle
1085 */
1086@@ -33,6 +34,7 @@
1087 }
1088 return setattr(path, attr, s, rqstp, flags);
1089 }
1090+#endif
1091
1092 /*
1093 * Set file attributes given the path. The flags argument
1094--- nfs-server/teahash3.c
1095+++ nfs-server/teahash3.c 2002/11/08 13:59:16
1096@@ -0,0 +1,168 @@
1097+/* Taken from the reiserfs source code and hacked slightly by AK.
1098+ * This is GPLed. */
1099+/*
1100+ * Keyed 32-bit hash function using TEA in a Davis-Meyer function
1101+ * H0 = Key
1102+ * Hi = E Mi(Hi-1) + Hi-1
1103+ *
1104+ * (see Applied Cryptography, 2nd edition, p448).
1105+ *
1106+ * Jeremy Fitzhardinge <jeremy@zip.com.au> 1998
1107+ *
1108+ * Jeremy has agreed to the contents of reiserfs/README. -Hans
1109+ */
1110+
1111+#include <assert.h>
1112+
1113+#if 0
1114+/* OK for Intel */
1115+typedef unsigned long u32;
1116+typedef const unsigned char u8;
1117+#else
1118+#include <inttypes.h>
1119+typedef uint32_t u32;
1120+typedef uint8_t u8;
1121+#endif
1122+
1123+
1124+#define DELTA 0x9E3779B9
1125+#define FULLROUNDS 10 /* 32 is overkill, 16 is strong crypto */
1126+#define PARTROUNDS 6 /* 6 gets complete mixing */
1127+
1128+/* a, b, c, d - data; h0, h1 - accumulated hash */
1129+#define TEACORE(rounds) \
1130+ do { \
1131+ u32 sum = 0; \
1132+ int n = rounds; \
1133+ u32 b0, b1; \
1134+ \
1135+ b0 = h0; \
1136+ b1 = h1; \
1137+ \
1138+ do \
1139+ { \
1140+ sum += DELTA; \
1141+ b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b); \
1142+ b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d); \
1143+ } while(--n); \
1144+ \
1145+ h0 += b0; \
1146+ h1 += b1; \
1147+ } while(0)
1148+
1149+u32 teahash3(/*u32 k[2], *//*u8*/const char *msg, int len)
1150+{
1151+ u32 k[] = { 0x9464a485, 0x542e1a94, 0x3e846bff, 0xb75bcfc3};
1152+
1153+ u32 h0 = k[0], h1 = k[1];
1154+ u32 a, b, c, d;
1155+ u32 pad;
1156+ int i;
1157+
1158+ assert(len >= 0 && len < 256);
1159+
1160+ pad = (u32)len | ((u32)len << 8);
1161+ pad |= pad << 16;
1162+
1163+ while(len >= 16)
1164+ {
1165+ a = (u32)msg[ 0] |
1166+ (u32)msg[ 1] << 8 |
1167+ (u32)msg[ 2] << 16|
1168+ (u32)msg[ 3] << 24;
1169+ b = (u32)msg[ 4] |
1170+ (u32)msg[ 5] << 8 |
1171+ (u32)msg[ 6] << 16|
1172+ (u32)msg[ 7] << 24;
1173+ c = (u32)msg[ 8] |
1174+ (u32)msg[ 9] << 8 |
1175+ (u32)msg[10] << 16|
1176+ (u32)msg[11] << 24;
1177+ d = (u32)msg[12] |
1178+ (u32)msg[13] << 8 |
1179+ (u32)msg[14] << 16|
1180+ (u32)msg[15] << 24;
1181+
1182+ TEACORE(PARTROUNDS);
1183+
1184+ len -= 16;
1185+ msg += 16;
1186+ }
1187+
1188+ if (len >= 12)
1189+ {
1190+ assert(len < 16);
1191+
1192+ a = (u32)msg[ 0] |
1193+ (u32)msg[ 1] << 8 |
1194+ (u32)msg[ 2] << 16|
1195+ (u32)msg[ 3] << 24;
1196+ b = (u32)msg[ 4] |
1197+ (u32)msg[ 5] << 8 |
1198+ (u32)msg[ 6] << 16|
1199+ (u32)msg[ 7] << 24;
1200+ c = (u32)msg[ 8] |
1201+ (u32)msg[ 9] << 8 |
1202+ (u32)msg[10] << 16|
1203+ (u32)msg[11] << 24;
1204+
1205+ d = pad;
1206+ for(i = 12; i < len; i++)
1207+ {
1208+ d <<= 8;
1209+ d |= msg[i];
1210+ }
1211+ }
1212+ else if (len >= 8)
1213+ {
1214+ assert(len < 12);
1215+
1216+ a = (u32)msg[ 0] |
1217+ (u32)msg[ 1] << 8 |
1218+ (u32)msg[ 2] << 16|
1219+ (u32)msg[ 3] << 24;
1220+ b = (u32)msg[ 4] |
1221+ (u32)msg[ 5] << 8 |
1222+ (u32)msg[ 6] << 16|
1223+ (u32)msg[ 7] << 24;
1224+
1225+ c = d = pad;
1226+ for(i = 8; i < len; i++)
1227+ {
1228+ c <<= 8;
1229+ c |= msg[i];
1230+ }
1231+ }
1232+ else if (len >= 4)
1233+ {
1234+ assert(len < 8);
1235+
1236+ a = (u32)msg[ 0] |
1237+ (u32)msg[ 1] << 8 |
1238+ (u32)msg[ 2] << 16|
1239+ (u32)msg[ 3] << 24;
1240+
1241+ b = c = d = pad;
1242+ for(i = 4; i < len; i++)
1243+ {
1244+ b <<= 8;
1245+ b |= msg[i];
1246+ }
1247+ }
1248+ else
1249+ {
1250+ assert(len < 4);
1251+
1252+ a = b = c = d = pad;
1253+ for(i = 0; i < len; i++)
1254+ {
1255+ a <<= 8;
1256+ a |= msg[i];
1257+ }
1258+ }
1259+
1260+ TEACORE(FULLROUNDS);
1261+
1262+/* return 0;*/
1263+ return h0^h1;
1264+}
1265--- nfs-server/ugid_map.c
1266+++ nfs-server/ugid_map.c 2002/11/08 13:59:16
1267@@ -276,8 +276,10 @@
1268 if ((gid == 0 && mountp->o.root_squash) || mountp->o.all_squash)
1269 retgid = mountp->o.nobody_gid;
1270
1271+#if 0
1272 Dprintf(D_UGID, "lgid(%s, %d) = %d\n",
1273 inet_ntoa(mountp->client->clnt_addr), gid, retgid);
1274+#endif
1275 return retgid;
1276 }
1277