Skip to content

Commit

Permalink
Windows: zdb corrections, posix bug fixes
Browse files Browse the repository at this point in the history
This commit contains the missing bits by Shashank Kumar in
PR#17.

This brings support to "zdb -e POOL" to working, and -C POOL will
successfully read the zpool.cache file, but fail to open the pool
by receiving ERROR_SHARING_VIOLATION in wosix_open(). I am
unsure why this happens as we use FILE_SHARE_READ everywhere.

There is additional code in the PR for freeing aligned zio buffers,
but I have yet to come across them. (Probably not tried the right
switch to zdb yet).
  • Loading branch information
lundman committed Apr 22, 2021
1 parent f9acefe commit 69bd966
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 14 deletions.
3 changes: 2 additions & 1 deletion lib/libspl/include/os/windows/wosix.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@
#define ITOH(I) ((HANDLE)(unsigned __int64)(I))

/* keep the struct type before we #define */
/* We only use _stat64 in Windows, no reason to mix */
struct wosix_stat {
union {
struct stat;
struct _stat64;
};
};

Expand Down
47 changes: 36 additions & 11 deletions lib/libspl/os/windows/posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ gethostid(void)
DWORD len;

Status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"SYSTEM\\ControlSet001\\Services\\ZFSin",
"SYSTEM\\ControlSet001\\Services\\OpenZFS",
0, KEY_READ, &key);
if (Status != ERROR_SUCCESS)
return (0UL);
Expand Down Expand Up @@ -860,12 +860,15 @@ wosix_fsync(int fd)
}

int
wosix_open(const char *path, int oflag, ...)
wosix_open(const char *inpath, int oflag, ...)
{
HANDLE h;
DWORD mode = GENERIC_READ; // RDONLY=0, WRONLY=1, RDWR=2;
DWORD how = OPEN_EXISTING;
DWORD share = FILE_SHARE_READ;
char otherpath[MAXPATHLEN];
char *path = inpath;

// This is wrong, not all bitfields
if (oflag&O_WRONLY) mode = GENERIC_WRITE;
if (oflag&O_RDWR) mode = GENERIC_READ | GENERIC_WRITE;
Expand Down Expand Up @@ -896,6 +899,13 @@ wosix_open(const char *path, int oflag, ...)
if (!oflag&O_EXLOCK) share |= FILE_SHARE_WRITE;
#endif

// Support expansion of "SystemRoot"
if (strncmp(path, "\\SystemRoot\\", 12) == 0) {
snprintf(otherpath, MAXPATHLEN, "%s\\%s",
getenv("SystemRoot"), &path[12]);
path = otherpath;
}

// Try to open verbatim, but if that fail, check if it is the
// "#offset#length#name" style, and try again. We let it fail first
// just in case someone names their file with a starting '#'.
Expand Down Expand Up @@ -944,6 +954,12 @@ wosix_open(const char *path, int oflag, ...)
case ERROR_FILE_EXISTS:
errno = EEXIST;
break;
case ERROR_SHARING_VIOLATION:
errno = EBUSY; // BSD: EWOULDBLOCK
// fall through
default:
fprintf(stderr, "wosix_open(%s): error %d / 0x%x\n",
path, GetLastError(), GetLastError());
}
return (-1);
}
Expand Down Expand Up @@ -1165,7 +1181,7 @@ wosix_stat(char *path, struct _stat64 *st)
{
int fd;
int ret;
fd = open(path, O_RDONLY);
fd = wosix_open(path, O_RDONLY);
if (fd == -1)
return (-1);
ret = wosix_fstat(fd, st);
Expand All @@ -1179,7 +1195,7 @@ wosix_lstat(char *path, struct _stat64 *st)
int fd;
int ret;

fd = open(path, O_RDONLY);
fd = wosix_open(path, O_RDONLY);
if (fd == -1)
return (-1);
ret = wosix_fstat(fd, st); // Fix me? Symlinks
Expand Down Expand Up @@ -1227,15 +1243,24 @@ wosix_fstat_blk(int fd, struct _stat64 *st)
DISK_GEOMETRY_EX geometry_ex;
HANDLE handle = ITOH(fd);
DWORD len;
LARGE_INTEGER size;

// Try device first
if (DeviceIoControl(handle, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0,
&geometry_ex, sizeof (geometry_ex), &len, NULL)) {
st->st_size = (diskaddr_t)geometry_ex.DiskSize.QuadPart;
st->st_mode = S_IFBLK;
return (0);
}

if (!DeviceIoControl(handle, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0,
&geometry_ex, sizeof (geometry_ex), &len, NULL))
return (-1); // errno?

st->st_size = (diskaddr_t)geometry_ex.DiskSize.QuadPart;
st->st_mode = S_IFBLK;
// Try regular file
if (GetFileSizeEx(handle, &size)) {
st->st_size = (diskaddr_t)size.QuadPart;
st->st_mode = S_IFREG;
return (0);
}

return (0);
return (-1); // errno?
}

// os specific files can call this directly.
Expand Down
4 changes: 2 additions & 2 deletions lib/libzfs/os/windows/libzfs_util_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,9 @@ find_shares_object(differ_info_t *di)
int
zfs_version_kernel(char *version, int len)
{
HKEY hKey; // SYSTEM\ControlSet001\Services\ZFSin
HKEY hKey; // SYSTEM\ControlSet001\Services\OpenZFS
LSTATUS status = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
"SYSTEM\\ControlSet001\\Services\\ZFSin", 0, KEY_READ, &hKey);
"SYSTEM\\ControlSet001\\Services\\OpenZFS", 0, KEY_READ, &hKey);

if (status != ERROR_SUCCESS)
return (-1);
Expand Down

0 comments on commit 69bd966

Please sign in to comment.