windows upload perf (fat32, smb)

This commit is contained in:
ed 2022-08-02 20:39:51 +02:00
parent 1c3894743a
commit a669f79480

View file

@ -1,16 +1,12 @@
# coding: utf-8 # coding: utf-8
from __future__ import print_function, unicode_literals from __future__ import print_function, unicode_literals
try:
import ctypes
except:
pass
import os import os
import re import re
import time import time
from .__init__ import ANYWIN, MACOS from .__init__ import ANYWIN, MACOS
from .bos import bos
from .authsrv import AXS, VFS from .authsrv import AXS, VFS
from .util import chkcmd, min_ex from .util import chkcmd, min_ex
@ -44,13 +40,9 @@ class Fstab(object):
msg = "failed to determine filesystem at [{}]; assuming {}\n{}" msg = "failed to determine filesystem at [{}]; assuming {}\n{}"
if ANYWIN: if ANYWIN:
fs = "vfat" # can smb do sparse files? gonna guess no fs = "vfat"
try: try:
# good enough path = self._winpath(path)
disk = path.split(":", 1)[0]
disk = "{}:\\".format(disk).lower()
assert len(disk) == 3
path = disk
except: except:
self.log(msg.format(path, fs, min_ex()), 3) self.log(msg.format(path, fs, min_ex()), 3)
return fs return fs
@ -71,6 +63,15 @@ class Fstab(object):
self.log("found {} at {}".format(fs, path)) self.log("found {} at {}".format(fs, path))
return fs return fs
def _winpath(self, path: str) -> str:
# try to combine volume-label + st_dev (vsn)
path = path.replace("/", "\\")
vid = path.split(":", 1)[0].strip("\\").split("\\", 1)[0]
try:
return "{}*{}".format(vid, bos.stat(path).st_dev)
except:
return vid
def build_fallback(self) -> None: def build_fallback(self) -> None:
self.tab = VFS(self.log_func, "idk", "/", AXS(), {}) self.tab = VFS(self.log_func, "idk", "/", AXS(), {})
self.trusted = False self.trusted = False
@ -104,6 +105,9 @@ class Fstab(object):
def relabel(self, path: str, nval: str) -> None: def relabel(self, path: str, nval: str) -> None:
assert self.tab assert self.tab
self.cache = {} self.cache = {}
if ANYWIN:
path = self._winpath(path)
path = path.lstrip("/") path = path.lstrip("/")
ptn = re.compile(r"^[^\\/]*") ptn = re.compile(r"^[^\\/]*")
vn, rem = self.tab._find(path) vn, rem = self.tab._find(path)
@ -142,46 +146,9 @@ class Fstab(object):
return "idk" return "idk"
def get_w32(self, path: str) -> str: def get_w32(self, path: str) -> str:
# list mountpoints: fsutil fsinfo drives
assert ctypes
from ctypes.wintypes import BOOL, DWORD, LPCWSTR, LPDWORD, LPWSTR, MAX_PATH
if not self.tab: if not self.tab:
self.build_fallback() self.build_fallback()
def echk(rc: int, fun: Any, args: Any) -> None: assert self.tab
if not rc: ret = self.tab._find(path)[0]
raise ctypes.WinError(ctypes.get_last_error()) return ret.realpath
return None
k32 = ctypes.WinDLL("kernel32", use_last_error=True)
k32.GetVolumeInformationW.errcheck = echk
k32.GetVolumeInformationW.restype = BOOL
k32.GetVolumeInformationW.argtypes = (
LPCWSTR,
LPWSTR,
DWORD,
LPDWORD,
LPDWORD,
LPDWORD,
LPWSTR,
DWORD,
)
bvolname = ctypes.create_unicode_buffer(MAX_PATH + 1)
bfstype = ctypes.create_unicode_buffer(MAX_PATH + 1)
serial = DWORD()
max_name_len = DWORD()
fs_flags = DWORD()
k32.GetVolumeInformationW(
path,
bvolname,
ctypes.sizeof(bvolname),
ctypes.byref(serial),
ctypes.byref(max_name_len),
ctypes.byref(fs_flags),
bfstype,
ctypes.sizeof(bfstype),
)
return bfstype.value