dpk@BRL.ARPA (NFS Functionality Enhancement Committee) (12/06/86)
We are just beginning to use NFS around BRL and I have been amazed at how little thought seems to have been put into using NFS in a large collection of large hosts. Many of our machine have 8 to 16 disk segments mounted, and almost as many physical disks, so there is little that can be done to lower the number of mounted partitions. We wish to make every file system available from every system (or a close approximation of this). If we were to use the normal SUN NFS implementation, we would have mount tables with 100 to 200 mounted filesystems. This is a nightmare. I like to sleep, so I have made the following change to nfs/nfs_server.c (part of the NFS related kernel source). The effect of this change is to make tree of mounted local file systems appear as a single homogeneous file system to remote system that mount the root of such a tree. Mount points are invisibly followed as long as they go to a file system of the same type (which in this case is local). The restriction on the same type of file system is necessary to prevent file system loops. When/If more local file system types are supported, the "if" below would have to be made smarter. The statfs operation is somewhat meaningless with this change since it will only return the stats for the file system you mounted and not any file systems under it. The end result of all this is that you can now make all the file systems on a server system available by simply mounting the root file system (actually directory, e.g. mount -t nfs -o bg,soft host:/ /n/host). We have chosen to creat a directory /n and to make a directory in it for each system we wish to make available. We then mount the root of each system as /n/hostA, /n/hostB, ... It is quite possible some of you may be able to suggest some improvments to this implementation, such as ways to make it conditional or to better handle the statfs data. For us, this change alone is a big step forward in making NFS usable in a large cluster of independent super-mini computers (Vaxen, Goulds, Alliants) as well as workstations (Iris's, Suns). Comments welcome. -Doug- Encl. Diff of /sys/nfs/nfs_server.c. Line numbers are from the Gould version of the SUN sources, your mileage may vary. *** /tmp/,RCSt1000710 Fri Dec 5 21:38:09 1986 --- nfs_server.c Fri Dec 5 21:37:43 1986 *************** *** 289,294 **** --- 289,327 ---- if (error) { vp = (struct vnode *)0; } else { + #ifdef BRL + register struct vfs *vfsp; + struct vnode *tvp; + + /* + * The following allows the exporting of contiguous + * collections of local file systems. -DPK- + * + * If this vnode is mounted on, and the mounted VFS + * is the same as the current one (local), then we + * transparently indirect to the vnode which + * is the root of the mounted file system. + * Before we do this we must check that an unmount is not + * in progress on this vnode. This maintains the fs status + * quo while a possibly lengthy unmount is going on. + */ + mloop: + while ((vfsp = vp->v_vfsmountedhere) && + vfsp->vfs_op == vp->v_vfsp->vfs_op) { + while (vfsp->vfs_flag & VFS_MLOCK) { + vfsp->vfs_flag |= VFS_MWAIT; + sleep((caddr_t)vfsp, PVFS); + goto mloop; + } + error = VFS_ROOT(vp->v_vfsmountedhere, &tvp); + VN_RELE(vp); + if (error) { + vp = (struct vnode *)0; + goto bad; + } + vp = tvp; + } + #endif BRL error = VOP_GETATTR(vp, &va, u.u_cred); if (!error) { vattr_to_nattr(&va, &dr->dr_attr); *************** *** 295,300 **** --- 328,334 ---- error = makefh(&dr->dr_fhandle, vp); } } + bad: dr->dr_status = puterrno(error); if (vp) { VN_RELE(vp);