Handle 'crossmnt' when kernel asked for export options for a directory.
authorNeil Brown <neilb@suse.de>
Mon, 19 Mar 2007 00:52:30 +0000 (11:52 +1100)
committerNeil Brown <neilb@suse.de>
Mon, 19 Mar 2007 00:52:30 +0000 (11:52 +1100)
If the kernel finds a mountpoint below a 'crossmnt' export, it will ask
mounted what export options to use.  With this patch it will return
the same export options as for the top 'crossmnt' export unless
more specific options have been given.

utils/mountd/cache.c

index 734ddd8..2f13f03 100644 (file)
@@ -515,11 +515,36 @@ void nfsd_export(FILE *f)
                for (exp = exportlist[i]; exp; exp = exp->m_next) {
                        if (!client_member(dom, exp->m_client->m_hostname))
                                continue;
-                       if (strcmp(path, exp->m_export.e_path))
+                       if (exp->m_export.e_flags & NFSEXP_CROSSMOUNT) {
+                               /* if path is a mountpoint below e_path, then OK */
+                               int l = strlen(exp->m_export.e_path);
+                               if (strcmp(path, exp->m_export.e_path) == 0 ||
+                                   (strncmp(path, exp->m_export.e_path, l) == 0 &&
+                                    path[l] == '/' &&
+                                    is_mountpoint(path)))
+                                       /* ok */;
+                               else
+                                       continue;
+                       } else if (strcmp(path, exp->m_export.e_path) != 0)
                                continue;
                        if (!found) {
                                found = exp;
                                found_type = i;
+                               continue;
+                       }
+                       /* If one is a CROSSMOUNT, then prefer the longest path */
+                       if (((found->m_export.e_flags & NFSEXP_CROSSMOUNT) ||
+                            (found->m_export.e_flags & NFSEXP_CROSSMOUNT)) &&
+                           strlen(found->m_export.e_path) !=
+                           strlen(found->m_export.e_path)) {
+
+                               if (strlen(exp->m_export.e_path) >
+                                   strlen(found->m_export.e_path)) {
+                                       found = exp;
+                                       found_type = i;
+                               }
+                               continue;
+
                        } else if (found_type == i && found->m_warned == 0) {
                                xlog(L_WARNING, "%s exported to both %s and %s, "
                                     "arbitrarily choosing options from first",