fsmonitor: option to allow fsmonitor to run against network-mounted repos

Though perhaps not common, there are use cases where users have large, network-mounted repos. Having the ability to run fsmonitor against network paths would benefit those users. Most modern Samba-based filers have the necessary support to enable fsmonitor on network-mounted repos. As a first step towards enabling fsmonitor to work against network-mounted repos, introduce a configuration option, 'fsmonitor.allowRemote'. Setting this option to true will override the default behavior (erroring-out) when a network-mounted repo is detected by fsmonitor. Signed-off-by: Eric DeCosta <edecosta@mathworks.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Eric DeCosta committed Aug 11, 2022 at 23:57 UTC 85dc0da6dcf21801149e747310d087abe26b2354
1 file changed +68
compat/fsmonitor/fsm-settings-win32.c
+68
@@ -24,6 +24,59 @@ static enum fsmonitor_reason check_vfs4git(struct repository *r)
24 return FSMONITOR_REASON_OK;
25 }
26
27 +/*
28 + * Check if monitoring remote working directories is allowed.
29 + *
30 + * By default, monitoring remote working directories is
31 + * disabled. Users may override this behavior in enviroments where
32 + * they have proper support.
33 + */
34 +static int check_config_allowremote(struct repository *r)
35 +{
36 + int allow;
37 +
38 + if (!repo_config_get_bool(r, "fsmonitor.allowremote", &allow))
39 + return allow;
40 +
41 + return -1; /* fsmonitor.allowremote not set */
42 +}
43 +
44 +/*
45 + * Check remote working directory protocol.
46 + *
47 + * Error if client machine cannot get remote protocol information.
48 + */
49 +static int check_remote_protocol(wchar_t *wpath)
50 +{
51 + HANDLE h;
52 + FILE_REMOTE_PROTOCOL_INFO proto_info;
53 +
54 + h = CreateFileW(wpath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
55 + FILE_FLAG_BACKUP_SEMANTICS, NULL);
56 +
57 + if (h == INVALID_HANDLE_VALUE) {
58 + error(_("[GLE %ld] unable to open for read '%ls'"),
59 + GetLastError(), wpath);
60 + return -1;
61 + }
62 +
63 + if (!GetFileInformationByHandleEx(h, FileRemoteProtocolInfo,
64 + &proto_info, sizeof(proto_info))) {
65 + error(_("[GLE %ld] unable to get protocol information for '%ls'"),
66 + GetLastError(), wpath);
67 + CloseHandle(h);
68 + return -1;
69 + }
70 +
71 + CloseHandle(h);
72 +
73 + trace_printf_key(&trace_fsmonitor,
74 + "check_remote_protocol('%ls') remote protocol %#8.8lx",
75 + wpath, proto_info.Protocol);
76 +
77 + return 0;
78 +}
79 +
80 /*
81 * Remote working directories are problematic for FSMonitor.
82 *
@@ -76,6 +129,7 @@ static enum fsmonitor_reason check_vfs4git(struct repository *r)
129 */
130 static enum fsmonitor_reason check_remote(struct repository *r)
131 {
132 + int ret;
133 wchar_t wpath[MAX_PATH];
134 wchar_t wfullpath[MAX_PATH];
135 size_t wlen;
@@ -115,6 +169,20 @@ static enum fsmonitor_reason check_remote(struct repository *r)
169 trace_printf_key(&trace_fsmonitor,
170 "check_remote('%s') true",
171 r->worktree);
172 +
173 + ret = check_remote_protocol(wfullpath);
174 + if (ret < 0)
175 + return FSMONITOR_REASON_ERROR;
176 +
177 + switch (check_config_allowremote(r)) {
178 + case 0: /* config overrides and disables */
179 + return FSMONITOR_REASON_REMOTE;
180 + case 1: /* config overrides and enables */
181 + return FSMONITOR_REASON_OK;
182 + default:
183 + break; /* config has no opinion */
184 + }
185 +
186 return FSMONITOR_REASON_REMOTE;
187 }
188