summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/unfs-server/unfs-server-2.2beta47/006-reiserfs.patch
diff options
context:
space:
mode:
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