Skip to content

Commit

Permalink
Large restruction of mounting code
Browse files Browse the repository at this point in the history
This is a large commit that rewrites most of the mounting code,
so there is high risk of regression.
Most noticable should be running "zfs mount", or the
"mountvol" command should list both driveletters and
reparsepoints. Ie, "E:" and "E:/dataset".

The unmount code has become more sane and reliable, although
may have new issues.

Storport interface also needed to be re-addressed, since we
both create a BUS device.

Many various bugs also discovered while going through everything,
so many things need retesting.

Signed-off-by: Jorgen Lundman <[email protected]>
  • Loading branch information
lundman committed Sep 4, 2024
1 parent 78c6077 commit 8c07c15
Show file tree
Hide file tree
Showing 24 changed files with 2,855 additions and 762 deletions.
6 changes: 3 additions & 3 deletions cmd/os/windows/zfsinstaller/zfsinstaller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ DWORD
executeInfSection(const char *cmd, char *inf_path) {

#ifdef _DEBUG
system("sc query ZFSin");
system("sc query OpenZFS");
fprintf(stderr, "\n\n");
#endif

Expand All @@ -528,7 +528,7 @@ executeInfSection(const char *cmd, char *inf_path) {


#ifdef _DEBUG
system("sc query ZFSin");
system("sc query OpenZFS");
#endif

return (error);
Expand Down Expand Up @@ -665,7 +665,7 @@ send_zfs_ioc_unregister_fs(void)
#include <cfgmgr32.h>
#include <newdev.h>

#define ZFS_ROOTDEV "Root\\OpenZFS"
#define ZFS_ROOTDEV "ROOT\\OpenZFS"
// DevCon uses LoadLib() - but lets just static link
#pragma comment(lib, "Newdev.lib")

Expand Down
3 changes: 1 addition & 2 deletions contrib/windows/OpenZFS/OpenZFS/OpenZFS.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,7 @@
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
<DisableProductionSignDebugWarnings>false</DisableProductionSignDebugWarnings>
<TimeStampServer>
</TimeStampServer>
<TimeStampServer>http://timestamp.digicert.com</TimeStampServer>
<IncludePath>$(IncludePath);$(KMDF_INC_PATH)$(KMDF_VER_PATH);../../../../include</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
Expand Down
33 changes: 30 additions & 3 deletions include/os/windows/spl/sys/mount.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#ifndef _SPL_MOUNT_H
#define _SPL_MOUNT_H

#include <sys/list.h>

#define MNT_WAIT 1 /* synchronized I/O file integrity completion */
#define MNT_NOWAIT 2 /* start all I/O, but do not wait for it */

Expand Down Expand Up @@ -54,6 +56,8 @@
#define MNT_FORCE 0x00080000 /* force unmount or readonly change */
#define MNT_CMDFLAGS (MNT_UPDATE|MNT_NOBLOCK|MNT_RELOAD|MNT_FORCE)

#define MNT_UNMOUNTING 0x80000000 /* process of unmounting */

#define MNT_UNKNOWNPERMISSIONS MNT_IGNORE_OWNERSHIP

#define MFSTYPENAMELEN 16
Expand Down Expand Up @@ -81,7 +85,8 @@ struct vfsstatfs {
};

typedef enum _FSD_IDENTIFIER_TYPE {
MOUNT_TYPE_DGL = ':DGL', // Dokan Global
MOUNT_TYPE_DGL = ':DGL', // Global
MOUNT_TYPE_BUS = ':BUS', // Bus Control
MOUNT_TYPE_DCB = ':DCB', // Disk Control Block
MOUNT_TYPE_VCB = ':VCB', // Volume Control Block
MOUNT_TYPE_FCB = ':FCB', // File Control Block
Expand All @@ -96,21 +101,37 @@ struct mount
ULONG size;
void *fsprivate;
void *parent_device; // Only set so vcd can find dcb
PDEVICE_OBJECT deviceObject;
PDEVICE_OBJECT diskDeviceObject;
uuid_t rawuuid;
PDEVICE_OBJECT PhysicalDeviceObject; // From AddDevices
PDEVICE_OBJECT LowerDeviceObject; // Attaching PDO in AddDevices
PDEVICE_OBJECT FunctionalDeviceObject; // Created in AddDevices
PDEVICE_OBJECT VolumeDeviceObject;
PDEVICE_OBJECT AttachedDevice;
UNICODE_STRING bus_name;
UNICODE_STRING device_name;
UNICODE_STRING symlink_name;
UNICODE_STRING arc_name;
UNICODE_STRING fs_name;
UNICODE_STRING name;
UNICODE_STRING uuid;
UNICODE_STRING mountpoint;
UNICODE_STRING deviceInterfaceName;
UNICODE_STRING fsInterfaceName;
UNICODE_STRING volumeInterfaceName;
UNICODE_STRING MountMgr_name;
UNICODE_STRING MountMgr_mountpoint;
PFILE_OBJECT root_file;
boolean_t justDriveLetter;
uint64_t volume_opens;
PVPB vpb;

uint64_t mountflags;

KEVENT volume_removed_event;

// Linked list of mounts
list_node_t mount_node;

// NotifySync is used by notify directory change
PNOTIFY_SYNC NotifySync;
LIST_ENTRY DirNotifyList;
Expand Down Expand Up @@ -142,4 +163,10 @@ int vfs_isunmount(mount_t *mp);
int vfs_iswriteupgrade(mount_t *mp);
void vfs_setextendedsecurity(mount_t *mp);

void vfs_mount_add(mount_t *mp);
void vfs_mount_remove(mount_t *mp);
int vfs_mount_count(void);
void vfs_mount_setarray(void **array, int max);
void vfs_mount_iterate(int (*func)(void *, void *), void *);

#endif /* SPL_MOUNT_H */
53 changes: 53 additions & 0 deletions include/os/windows/zfs/sys/driver_extension.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/

/*
* Copyright (c) 2024 by Jorgen Lundman <[email protected]>.
*/

#ifndef SYS_DRIVER_EXTENSION_H
#define SYS_DRIVER_EXTENSION_H

struct OpenZFS_Driver_Extension_s {
PDEVICE_OBJECT PhysicalDeviceObject;
PDEVICE_OBJECT LowerDeviceObject;
PDEVICE_OBJECT FunctionalDeviceObject; // AddDevice unknown
PDEVICE_OBJECT AddDeviceObject; // Passed along when mounting
PDEVICE_OBJECT ChildDeviceObject; // Passed along when creating
PDEVICE_OBJECT ioctlDeviceObject; // /dev/zfs pdo
PDEVICE_OBJECT fsDiskDeviceObject; // /dev/zfs vdo
PDEVICE_OBJECT StorportDeviceObject;

PDRIVER_UNLOAD STOR_DriverUnload;
PDRIVER_ADD_DEVICE STOR_AddDevice;
PDRIVER_DISPATCH STOR_MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];
};

typedef struct OpenZFS_Driver_Extension_s OpenZFS_Driver_Extension;

#define ZFS_DRIVER_EXTENSION(DO, V) \
OpenZFS_Driver_Extension *(V) = \
(OpenZFS_Driver_Extension *) IoGetDriverObjectExtension((DO), (DO));

extern int
zfs_init_driver_extension(PDRIVER_OBJECT);

#endif
2 changes: 1 addition & 1 deletion include/os/windows/zfs/sys/fs/zfsdi.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ extern "C" {
* interface calls.
*/

#define ZFS_DEV_KERNEL L"\\Device\\ZFSCTL"
// #define ZFS_DEV_KERNEL L"\\Device\\ZFSCTL"
DEFINE_GUID(ZFSZVOLDI_GUID, 0x904ca0cdl, 0x6ae1, 0x4acb, 0xb8, 0xb9, 0x2a, 0x00,
0x2e, 0xd1, 0x10, 0xd4);

Expand Down
1 change: 1 addition & 0 deletions include/os/windows/zfs/sys/zfs_context_os.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ typedef struct spa_iokit spa_iokit_t;
extern boolean_t ml_set_interrupts_enabled(boolean_t);
extern PDRIVER_OBJECT WIN_DriverObject;


/*
* Ok this is pretty gross - until we can get rid of it from lua -
* it works as long as it doesn't parse strings
Expand Down
24 changes: 23 additions & 1 deletion include/os/windows/zfs/sys/zfs_windows.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ extern PDEVICE_OBJECT ioctlDeviceObject;
extern PDEVICE_OBJECT fsDiskDeviceObject;

#define ZFS_SERIAL (ULONG)'wZFS'
#define VOLUME_LABEL L"ZFS"
#define VOLUME_LABEL L"OpenZFSVolume"

#define ZFS_HAVE_FASTIO

Expand Down Expand Up @@ -71,6 +71,9 @@ typedef struct zfs_ccb zfs_ccb_t;

extern uint64_t zfs_module_busy;

#define DIR_LINKS(zp) \
(S_ISDIR((zp)->z_mode) ? (zp)->z_links - 1 : (zp)->z_links)

extern CACHE_MANAGER_CALLBACKS CacheManagerCallbacks;


Expand Down Expand Up @@ -143,8 +146,12 @@ extern size_t get_reparse_point_impl(znode_t *zp, char *buffer, size_t outlen);
extern void fastio_init(FAST_IO_DISPATCH **fast);
extern NTSTATUS pnp_query_di(PDEVICE_OBJECT DeviceObject, PIRP Irp,
PIO_STACK_LOCATION IrpSp);
extern NTSTATUS pnp_query_bus_information(PDEVICE_OBJECT DeviceObject, PIRP Irp,
PIO_STACK_LOCATION IrpSp);
extern NTSTATUS pnp_device_usage_notification(PDEVICE_OBJECT DeviceObject,
PIRP Irp, PIO_STACK_LOCATION IrpSp);
extern int zfs_init_cache(FILE_OBJECT *fo, struct vnode *vp,
CC_FILE_SIZES *ccfs);

/* zfs_vnop_windows_lib.h */
extern int AsciiStringToUnicodeString(char *in, PUNICODE_STRING out);
Expand All @@ -167,6 +174,18 @@ extern void acl_trivial_access_masks(mode_t mode, boolean_t isdir,
extern void zfs_save_ntsecurity(struct vnode *vp);
void zfs_load_ntsecurity(struct vnode *vp);
struct vnode *zfs_parent(struct vnode *);
extern PVOID MapUserBuffer(IN OUT PIRP Irp);
extern void mount_add_device(PDEVICE_OBJECT DriverObject,
PDEVICE_OBJECT PhysicalDeviceObject, PDEVICE_OBJECT AddDeviceObject);
extern void zfs_windows_unmount_free(PUNICODE_STRING symlink_name);
extern void zfs_release_mount(mount_t *zmo);
extern void zfs_unload_ioctl(PDEVICE_OBJECT, PVOID Context);


extern NTSTATUS volume_create(PDEVICE_OBJECT DeviceObject,
PFILE_OBJECT FileObject, USHORT ShareAccess, uint64_t AllocationSize,
ACCESS_MASK DesiredAccess);


/* IRP_MJ_SET_INFORMATION helpers */
extern NTSTATUS set_file_basic_information(PDEVICE_OBJECT, PIRP,
Expand Down Expand Up @@ -234,6 +253,7 @@ extern NTSTATUS file_hard_link_information(PDEVICE_OBJECT, PIRP,

/* IRP_MJ_DEVICE_CONTROL helpers */
extern NTSTATUS QueryCapabilities(PDEVICE_OBJECT, PIRP, PIO_STACK_LOCATION);
extern NTSTATUS QueryDeviceRelations(PDEVICE_OBJECT, PIRP, PIO_STACK_LOCATION);
extern NTSTATUS ioctl_query_device_name(PDEVICE_OBJECT, PIRP,
PIO_STACK_LOCATION);
extern NTSTATUS ioctl_disk_get_drive_geometry(PDEVICE_OBJECT, PIRP,
Expand Down Expand Up @@ -266,6 +286,8 @@ extern NTSTATUS fsctl_set_zero_data(PDEVICE_OBJECT DeviceObject, PIRP Irp,
PIO_STACK_LOCATION IrpSp);
extern NTSTATUS ioctl_get_gpt_attributes(PDEVICE_OBJECT DeviceObject, PIRP Irp,
PIO_STACK_LOCATION IrpSp);
extern NTSTATUS volume_read(PDEVICE_OBJECT DeviceObject, PIRP Irp,
PIO_STACK_LOCATION IrpSp);


#endif
2 changes: 1 addition & 1 deletion include/sys/fs/zfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1392,7 +1392,7 @@ typedef struct ddt_histogram {
#define ZFS_DEV "\\\\.\\ZFS"
#define ZFS_DEV_DOS L"\\DosDevices\\Global\\ZFS"
#define ZFS_DEV_KERNEL L"\\Device\\ZFSCTL"
#define ZFS_GLOBAL_FS_DISK_DEVICE_NAME L"\\ZFS"
#define ZFS_GLOBAL_FS_DISK_DEVICE_NAME L"\\OpenZFS"
#else
#define ZFS_DEV "/dev/zfs"
#endif
Expand Down
7 changes: 7 additions & 0 deletions lib/libspl/os/windows/getmntany.c
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,12 @@ getfsstat(struct statfs *buf, int bufsize, int flags)
// "'\\.\Volume{0b1bb601-af0b-32e8-a1d2-54c167af6277}'" and
// query its Unique ID, where we return the dataset name. "BOOM"

if (name[trail] == '\\')
name[trail] = 0;
h = CreateFile(name, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
if (name[trail] == 0)
name[trail] = '\\';

if (h != INVALID_HANDLE_VALUE) {
char *dataset;
Expand Down Expand Up @@ -440,6 +444,9 @@ getfsstat(struct statfs *buf, int bufsize, int flags)
fzvm = NULL;
}
}
} else {
// Not ZFS - cant use UniqueID
UID = NULL;
}
}
CloseHandle(h);
Expand Down
24 changes: 24 additions & 0 deletions lib/libzfs/libzfs_changelist.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ changelist_prefix(prop_changelist_t *clp)
boolean_t commit_smb_shares = B_FALSE;

if (clp->cl_prop != ZFS_PROP_MOUNTPOINT &&
#ifdef _WIN32
clp->cl_prop != ZFS_PROP_DRIVELETTER &&
#endif
clp->cl_prop != ZFS_PROP_SHARESMB)
return (0);

Expand Down Expand Up @@ -144,6 +147,15 @@ changelist_prefix(prop_changelist_t *clp)
cn->cn_needpost = B_FALSE;
}
break;
#ifdef _WIN32
case ZFS_PROP_DRIVELETTER:
if (zfs_unmount(cn->cn_handle, NULL,
clp->cl_mflags) != 0) {
ret = -1;
cn->cn_needpost = B_FALSE;
}
break;
#endif
case ZFS_PROP_SHARESMB:
(void) zfs_unshare(cn->cn_handle, NULL,
smb);
Expand Down Expand Up @@ -205,6 +217,12 @@ changelist_postfix(prop_changelist_t *clp)
!(clp->cl_gflags & CL_GATHER_DONT_UNMOUNT))
remove_mountpoint(cn->cn_handle);

#ifdef _WIN32
if (clp->cl_prop == ZFS_PROP_DRIVELETTER &&
!(clp->cl_gflags & CL_GATHER_DONT_UNMOUNT))
remove_mountpoint(cn->cn_handle);
#endif

/*
* We walk the datasets in reverse, because we want to mount any parent
* datasets before mounting the children. We walk all datasets even if
Expand Down Expand Up @@ -652,6 +670,9 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int gather_flags,
*/
if (prop == ZFS_PROP_NAME || prop == ZFS_PROP_ZONED ||
prop == ZFS_PROP_MOUNTPOINT || prop == ZFS_PROP_SHARENFS ||
#ifdef _WIN32
prop == ZFS_PROP_DRIVELETTER ||
#endif
prop == ZFS_PROP_SHARESMB) {

if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT,
Expand Down Expand Up @@ -710,6 +731,9 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int gather_flags,

if (clp->cl_prop != ZFS_PROP_MOUNTPOINT &&
clp->cl_prop != ZFS_PROP_SHARENFS &&
#ifdef _WIN32
clp->cl_prop != ZFS_PROP_DRIVELETTER &&
#endif
clp->cl_prop != ZFS_PROP_SHARESMB)
return (clp);

Expand Down
26 changes: 18 additions & 8 deletions module/os/windows/OpenZFS.inf
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,26 @@ OpenZFS.DllFiles = 11 ;%windir%\system32
%Me%=Standard,NTamd64,NTx86

[Standard.NTamd64]
%VolumeName% = OpenZFS_Install, OpenZFSVolume
%ControllerName% = OpenZFS_Install, ROOT\OpenZFS
;%VolumeName% = OpenZFS_Install, OpenZFSVolume
%DriverName% = OpenZFS_Install, ROOT\OpenZFS
;%ControllerName% = OpenZFS_Install, ROOT\OpenZFS

[Standard.NTx86]
%VolumeName% = OpenZFS_Install, OpenZFSVolume
%ControllerName% = OpenZFS_Install, ROOT\OpenZFS
;%VolumeName% = OpenZFS_Install, OpenZFSVolume
%DriverName% = OpenZFS_Install, ROOT\OpenZFS
;%ControllerName% = OpenZFS_Install, ROOT\OpenZFS

[OpenZFS_Install]
OptionDesc = %ServiceDescription%
CopyFiles = OpenZFS.DriverFiles
AddReg = OpenZFS_AddReg

[OpenZFS_AddReg]
;HKR,,DeviceType,0x00010001,0x00000002
;HKR,,Type,0x00010001,0x00000002 ; FILE_SYSTEM_DRIVER
;HKR,,System.Devices.ContainerID,, "{00000001-0002-0003-0004-000000000001}"
;HKR,,Group,0x00000000,"File System"

;;,OpenZFS.DllFiles
;;RegisterDlls = shellopenzfs

Expand All @@ -71,8 +81,8 @@ DelService = %ServiceName%,0x200 ;Ensure service is stopped before deleting
[OpenZFS.Service]
DisplayName = %ServiceName%
Description = %ServiceDescription%
ServiceBinary = %12%\OpenZFS.sys ;%windir%\system32\drivers\
ServiceType = 1
ServiceBinary = %12%\%DriverName%.sys ;%windir%\system32\drivers\
ServiceType = 2
StartType = 1 ;SERVICE_SYSTEM_START
ErrorControl = 1
LoadOrderGroup = "File System"
Expand All @@ -85,8 +95,8 @@ LoadOrderGroup = "File System"
;

[OpenZFS.DriverFiles]
OpenZFS.sys
OpenZFS.man
%DriverName%.sys
%DriverName%.man

[OpenZFS.DllFiles]
;;zpool.exe
Expand Down
Loading

0 comments on commit 8c07c15

Please sign in to comment.