]> git.decadent.org.uk Git - nfs-utils.git/commitdiff
mountd: prefer explicit subexports over crossmnt parents
authorJ. Bruce Fields <bfields@redhat.com>
Mon, 27 Jun 2011 16:29:51 +0000 (12:29 -0400)
committerSteve Dickson <steved@redhat.com>
Mon, 27 Jun 2011 16:35:21 +0000 (12:35 -0400)
If a parent is exported with crossmnt, and if a child is also explicitly
exported, then both exports could potentially produce matches in this
loop; that isn't a bug.

Instead of warning and ignoring the second match we find, we should
instead prefer whichever export is deeper in the tree, so that
children's options can override those of their parents.

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

index 68cccdfddb70535f58c248798839fff5338ba656..c3dee13c61714c50342fe6370b2782b7aa9fe327 100644 (file)
@@ -341,6 +341,17 @@ static char *next_mnt(void **v, char *p)
        return me->mnt_dir;
 }
 
        return me->mnt_dir;
 }
 
+/* True iff e1 is a child of e2 and e2 has crossmnt set: */
+static bool subexport(struct exportent *e1, struct exportent *e2)
+{
+       char *p1 = e1->e_path, *p2 = e2->e_path;
+       int l2 = strlen(p2);
+
+       return e2->e_flags & NFSEXP_CROSSMOUNT
+              && strncmp(p1, p2, l2) == 0
+              && p1[l2] == '/';
+}
+
 static void nfsd_fh(FILE *f)
 {
        /* request are:
 static void nfsd_fh(FILE *f)
 {
        /* request are:
@@ -550,13 +561,14 @@ static void nfsd_fh(FILE *f)
                                if (!client_check(exp->m_client, ai))
                                        continue;
                        }
                                if (!client_check(exp->m_client, ai))
                                        continue;
                        }
-                       /* It's a match !! */
-                       if (!found) {
+                       if (!found || subexport(&exp->m_export, found)) {
                                found = &exp->m_export;
                                found = &exp->m_export;
+                               free(found_path);
                                found_path = strdup(path);
                                if (found_path == NULL)
                                        goto out;
                                found_path = strdup(path);
                                if (found_path == NULL)
                                        goto out;
-                       } else if (strcmp(found->e_path, exp->m_export.e_path)!= 0)
+                       } else if (strcmp(found->e_path, exp->m_export.e_path)
+                                  && !subexport(found, &exp->m_export))
                        {
                                xlog(L_WARNING, "%s and %s have same filehandle for %s, using first",
                                     found_path, path, dom);
                        {
                                xlog(L_WARNING, "%s and %s have same filehandle for %s, using first",
                                     found_path, path, dom);