case EBUSY:
(void) fprintf(stderr, gettext("filesystem "
"'%s' is already mounted\n"), dataset);
- return (MOUNT_SYSERR);
+ return (MOUNT_BUSY);
default:
(void) fprintf(stderr, gettext("filesystem "
"'%s' can not be mounted due to error "
#define MOUNT_FILEIO 0x10 /* Error updating/locking /etc/mtab */
#define MOUNT_FAIL 0x20 /* Mount failed */
#define MOUNT_SOMEOK 0x40 /* At least on mount succeeded */
+#define MOUNT_BUSY 0x80 /* Mount failed due to EBUSY */
#define MNTOPT_ASYNC "async" /* all I/O is asynchronous */
#define MNTOPT_ATIME "atime" /* update atime for files */
* best effort. In the case where it does fail, perhaps because
* it's in use, the unmount will fail harmlessly.
*/
-#define SET_UNMOUNT_CMD \
+#define SET_UNMOUNT_CMD \
"exec 0</dev/null " \
" 1>/dev/null " \
" 2>/dev/null; " \
return ((*count > 0) ? EEXIST : 0);
}
-#define SET_MOUNT_CMD \
+#define MOUNT_BUSY 0x80 /* Mount failed due to EBUSY (from mntent.h) */
+
+#define SET_MOUNT_CMD \
"exec 0</dev/null " \
" 1>/dev/null " \
" 2>/dev/null; " \
* function is marked GPL-only and cannot be used. On error we
* careful to log the real error to the console and return EISDIR
* to safely abort the automount. This should be very rare.
+ *
+ * If the user mode helper happens to return EBUSY, a concurrent
+ * mount is already in progress in which case the error is ignored.
+ * Take note that if the program was executed successfully the return
+ * value from call_usermodehelper() will be (exitcode << 8 + signal).
*/
argv[2] = kmem_asprintf(SET_MOUNT_CMD, full_name, full_path);
error = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
strfree(argv[2]);
- if (error) {
+ if (error && !(error & MOUNT_BUSY << 8)) {
printk("ZFS: Unable to automount %s at %s: %d\n",
full_name, full_path, error);
error = SET_ERROR(EISDIR);
goto error;
}
+ error = 0;
mutex_enter(&zsb->z_ctldir_lock);
/*