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