Print this page
NEX-16159 Time spent sharing SMB filesystems could be reduced by optimizing smb_getdataset for default mount points (lint fix)
Reviewed by: Jean McCormack <jean.mccormack@nexenta.com>
NEX-16159 Time spent sharing SMB filesystems could be reduced by optimizing smb_getdataset for default mount points
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-2346 SMB server debug logging cleanup after NEX-2314
NEX-816 smbadm dumps core during first join attempt
SMB-50 User-mode SMB server
 Includes work by these authors:
 Thomas Keiser <thomas.keiser@nexenta.com>
 Albert Lee <trisk@nexenta.com>
re #12435 rb3958 r10 is added 2 times to panic info
re #12393 rb3935 Kerberos and smbd disagree about who is our AD server

@@ -18,11 +18,11 @@
  *
  * CDDL HEADER END
  */
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>

@@ -625,19 +625,47 @@
  * Returns,
  *      0  = On success.
  *      -1 = Failure to open /etc/mnttab file or to get ZFS dataset.
  */
 int
-smb_getdataset(const char *path, char *dataset, size_t len)
+smb_getdataset(libzfs_handle_t *libhdl, const char *path, char *dataset,
+    size_t len)
 {
         char tmppath[MAXPATHLEN];
         char *cp;
         FILE *fp;
         struct mnttab mnttab;
         struct mnttab mntpref;
         int rc = -1;
 
+        /*
+         * Optimisation: if the path is the default mountpoint then
+         * the dataset name can be determined from path.
+         * Attempt to open dataset by derived name and, if successful,
+         * check if its mountpoint matches path.
+         */
+        if (libhdl != NULL) {
+                zfs_handle_t *hdl;
+                char mountpnt[ZFS_MAXPROPLEN];
+                char *dsname = (char *)path + strspn(path, "/");
+
+                hdl = zfs_open(libhdl, dsname, ZFS_TYPE_FILESYSTEM);
+                if (hdl != NULL) {
+                        if ((zfs_prop_get(hdl, ZFS_PROP_MOUNTPOINT, mountpnt,
+                            sizeof (mountpnt), NULL, NULL, 0, B_FALSE) == 0) &&
+                            (strcmp(mountpnt, path) == 0)) {
+                                zfs_close(hdl);
+                                (void) strlcpy(dataset, dsname, len);
+                                return (0);
+                        }
+                        zfs_close(hdl);
+                }
+        }
+
+        /*
+         * Couldn't find a filesystem optimistically, use mnttab
+         */
         if ((fp = fopen(MNTTAB, "r")) == NULL)
                 return (-1);
 
         (void) memset(&mnttab, '\0', sizeof (mnttab));
         (void) strlcpy(tmppath, path, MAXPATHLEN);