vBulletin Search Engine Optimization
| |||||||
| Register | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
| ||||
| Hi, In the last few releases NFS has seen a lot of stability and performance improvements, but there remains an annoying problem, which this diff should fix. NFS clients can get I/O errors if they try to perorm I/O while file systems are being mounted or unmounted on the NFS server. To test, run this diff on your NFS server, and manipulate filesystems on it while clients are actively doing I/O, e.g. doing a make build with src on NFS. Diff original by Dale Rahn, with fixes by me. Thanks in advance for testing, -Otto Index: mountd.c ================================================== ================= RCS file: /cvs/src/sbin/mountd/mountd.c,v retrieving revision 1.63 diff -u -p -r1.63 mountd.c --- mountd.c 8 Apr 2005 20:09:38 -0000 1.63 +++ mountd.c 9 Sep 2005 07:38:29 -0000 @@ -702,9 +702,20 @@ get_exportlist(void) struct grouplist *grp, *tgrp; struct exportlist **epp; struct dirlist *dirhead; - struct statfs fsb, *fsp; + struct statfs fsb, *ofsp, *fsp; struct hostent *hpe; struct ucred anon; + union { + struct ufs_args ua; + struct iso_args ia; + struct mfs_args ma; + struct msdosfs_args da; + struct adosfs_args aa; + } targs; + struct fsarray { + int exflags; + char *mntonname; + } *fstbl; /* * First, get rid of the old list @@ -731,15 +742,17 @@ get_exportlist(void) * XXX: Should know how to handle all local exportable file systems * instead of just MOUNT_FFS. */ - num = getmntinfo(&fsp, MNT_NOWAIT); + num = getmntinfo(&ofsp, MNT_NOWAIT); + if (num == 0 && errno) + syslog(LOG_ERR, "getmntinfo: %s", strerror(errno)); + + fsp = ofsp; + + fstbl = calloc(num, sizeof (fstbl[0])); + if (fstbl == NULL) + out_of_mem(); + for (i = 0; i < num; i++) { - union { - struct ufs_args ua; - struct iso_args ia; - struct mfs_args ma; - struct msdosfs_args da; - struct adosfs_args aa; - } targs; if (!strncmp(fsp->f_fstypename, MOUNT_MFS, MFSNAMELEN) || !strncmp(fsp->f_fstypename, MOUNT_FFS, MFSNAMELEN) || @@ -747,13 +760,8 @@ get_exportlist(void) !strncmp(fsp->f_fstypename, MOUNT_MSDOS, MFSNAMELEN) || !strncmp(fsp->f_fstypename, MOUNT_ADOSFS, MFSNAMELEN) || !strncmp(fsp->f_fstypename, MOUNT_CD9660, MFSNAMELEN)) { - bzero((char *)&targs, sizeof(targs)); - targs.ua.fspec = NULL; - targs.ua.export_info.ex_flags = MNT_DELEXPORT; - if (mount(fsp->f_fstypename, fsp->f_mntonname, - fsp->f_flags | MNT_UPDATE, &targs) < 0) - syslog(LOG_ERR, "Can't delete exports for %s: %m", - fsp->f_mntonname); + fstbl[i].exflags = MNT_DELEXPORT; + fstbl[i].mntonname = fsp->f_mntonname; } fsp++; } @@ -966,6 +974,26 @@ get_exportlist(void) */ grp = tgrp; do { + + /* + * remove filesystem from unexport list + * add MNT_DELEXPORT to exflags to clean up + * any old addrlist in the kernel + */ + + for (i = 0; i < num; i++) { + if ((fstbl[i].mntonname != NULL) && + (strcmp (dirp, fstbl[i].mntonname) == 0) && + (fstbl[i].exflags & MNT_DELEXPORT)) { + exflags |= MNT_DELEXPORT; + fstbl[i].exflags = 0; + if (debug) + fprintf(stderr, "removing %s %s from unexport list\n", dirp, fstbl[i].mntonname); + } + } + + if (debug) + fprintf(stderr, "exporting %s\n", dirp); /* * Non-zero return indicates an error. Return * val of 1 means line is invalid (not just entry). @@ -1020,6 +1048,20 @@ nextline: dirhead = NULL; } } + + fsp = ofsp; + for (i = 0; i < num; i++) { + if (debug && fstbl[i].exflags & MNT_DELEXPORT) + fprintf(stderr, "unexporting %s %s\n", + fsp->f_mntonname, fstbl[i].mntonname); + bzero(&targs, sizeof(targs)); + if (mount(fsp->f_fstypename, fsp->f_mntonname, + fsp->f_flags | MNT_UPDATE, &targs) < 0) + syslog(LOG_ERR, "Can't delete exports for %s: %m", + fsp->f_mntonname); + fsp++; + } + free(fstbl); fclose(exp_file); } |