Since
authorJ. Bruce Fields <bfields@citi.umich.edu>
Sun, 16 Aug 2009 20:18:17 +0000 (16:18 -0400)
committerSteve Dickson <steved@redhat.com>
Sun, 16 Aug 2009 20:18:17 +0000 (16:18 -0400)
2d77e3a27b7b211f303f.. "Fix bug when both crossmnt and fsid are set"

Subexports automatically created by "crossmnt" get the NFSEXP_FSID flag
cleared.  That flag should also be cleared in the
security-flavor-specific flag fields.  Otherwise the kernel detects the
inconsistent flags and rejects the export.

The symptoms are clients hanging the first time they export a filesystem
mounted under a filesystem that was exported with something like:

/exports *(crossmnt,fsid=0,sec=krb5)

Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Signed-off-by: Steve Dickson <steved@redhat.com>
utils/mountd/cache.c

index 9bbbfb3..e4e2f22 100644 (file)
@@ -564,7 +564,7 @@ static void write_fsloc(FILE *f, struct exportent *ep, char *path)
        release_replicas(servers);
 }
 
-static void write_secinfo(FILE *f, struct exportent *ep)
+static void write_secinfo(FILE *f, struct exportent *ep, int flag_mask)
 {
        struct sec_entry *p;
 
@@ -578,7 +578,7 @@ static void write_secinfo(FILE *f, struct exportent *ep)
        qword_printint(f, p - ep->e_secinfo);
        for (p = ep->e_secinfo; p->flav; p++) {
                qword_printint(f, p->flav->fnum);
-               qword_printint(f, p->flags);
+               qword_printint(f, p->flags & flag_mask);
        }
 
 }
@@ -590,16 +590,14 @@ static int dump_to_cache(FILE *f, char *domain, char *path, struct exportent *ex
        qword_printint(f, time(0)+30*60);
        if (exp) {
                int different_fs = strcmp(path, exp->e_path) != 0;
-               
-               if (different_fs)
-                       qword_printint(f, exp->e_flags & ~NFSEXP_FSID);
-               else
-                       qword_printint(f, exp->e_flags);
+               int flag_mask = different_fs ? ~NFSEXP_FSID : ~0;
+
+               qword_printint(f, exp->e_flags & flag_mask);
                qword_printint(f, exp->e_anonuid);
                qword_printint(f, exp->e_anongid);
                qword_printint(f, exp->e_fsid);
                write_fsloc(f, exp, path);
-               write_secinfo(f, exp);
+               write_secinfo(f, exp, flag_mask);
                if (exp->e_uuid == NULL || different_fs) {
                        char u[16];
                        if (get_uuid(path, NULL, 16, u)) {