[OpenAFS-devel] RX_MAX_FRAGS (yet again)

Nickolai Zeldovich kolya@MIT.EDU
Sat, 29 Sep 2001 01:21:14 -0400


> >so for some reason it's deciding that its local interface MTU is only
> >1500 bytes..
> 
> i think afs has to do this for backward compatibility with older afs
> clients/server.

But in rx_kcommon.c, rxi_InitPeerParams, it actually tries to extract
the ifMTU from the kernel information.  The backwards compatibility,
I believe, is handled in rxi_ReceiveAckPacket, down where it processes
the extra fields after the ack section.  If there aren't any fields
attached, then it assumes the peer is too old to know about MTUs and
sets the MTU's to 1444.  Otherwise, it extracts and uses the natMTU
and maxMTU that the peer specified.

After playing with the MTU selection code for a bit, I found at
least one bug which prevented the MTUs from being set properly
in AFS on Linux.  Could you try the patch below and see if you
get a large ifMTU/maxMTU on the Linux box with RX_MAX_FRAGS=4?

[ The bug is that syscalls only pass 5 arguments on Linux, which
  caused parm5/parm6 to be lost.  The ADVISEADDR AFS call used
  parm5 to pass a pointer to the MTU array, which got lost. ]

-- kolya

--- src/afs/afs_call.c	2001/08/08 00:03:28	1.14
+++ src/afs/afs_call.c	2001/09/29 04:43:28
@@ -935,6 +935,7 @@
     long linux_ret=0;
     long *retval = &linux_ret;
     long eparm[4]; /* matches AFSCALL_ICL in fstrace.c */
+    /* eparm is also used by AFSCALL_CALL in afsd.c */
 #else
 #if defined(UKERNEL)
 Afs_syscall ()
@@ -995,7 +996,7 @@
     uap->parm1 = parm1;
     uap->parm2 = parm2;
     uap->parm3 = parm3;
-    if (syscall == AFSCALL_ICL) {
+    if (syscall == AFSCALL_ICL || syscall == AFSCALL_CALL) {
 	AFS_COPYIN((char*)parm4, (char*)eparm, sizeof(eparm), code);
 	uap->parm4 = eparm[0];
 	uap->parm5 = eparm[1];

--- src/afsd/afsd.c	2001/09/13 23:19:19	1.14
+++ src/afsd/afsd.c	2001/09/29 04:43:28
@@ -1951,6 +1951,16 @@
 long param1, param2, param3, param4, param5, param6, param7;
 {
     int error;
+#ifdef AFS_LINUX20_ENV
+    long eparm[4];
+
+    eparm[0] = param4;
+    eparm[1] = param5;
+    eparm[2] = param6;
+    eparm[3] = param7;
+
+    param4 = eparm;
+#endif
 
     error = syscall(AFS_SYSCALL, AFSCALL_CALL, param1, param2, param3, param4, param5, param6, param7);
     if (afsd_verbose) printf("SScall(%d, %d)=%d ", AFS_SYSCALL, AFSCALL_CALL, error);