1 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
4 Ralph Böhme, SerNet, Samba Team
5 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
16 .. 2. Samba and O_PATH
18 ..... 2. Usecases for O_PATH in Samba
19 ..... 3. When to open with O_PATH
20 ..... 4. Fallback on systems without O_PATH support
21 ..... 5. When to use fsp_get_io_fd() or fsp_get_pathref_fd()
22 2. VFS status quo and remaining work
23 .. 1. VFS Functions Tables [2]
24 ..... 1. Existing VFS Functions
25 ..... 2. New VFS Functions
26 .. 2. VFS functions by category
27 ..... 1. Disk operations
28 ..... 2. Handle based VFS functions
29 ..... 3. Namespace changing VFS functions
30 ..... 4. Path based VFS functions
31 ..... 5. AT VFS functions that can't be based on handles
32 ..... 6. AT VFS functions needed for directory enumeration
33 ..... 7. Handle based VFS functions not allowed on O_PATH opened handles
34 ..... 8. Pure path to path translation
35 ..... 9. Special cases
44 The effort to modernize Samba's VFS interface has reached a major
45 milestone with the next release Samba 4.14.
47 Starting with version 4.14 Samba provides core infrastructure code that
48 allows basing all access to the server's filesystem on file handles and
49 not on paths. An example of this is using `fstat()' instead of `stat()',
50 or `SMB_VFS_FSTAT()' instead of `SMB_VFS_STAT()' in Samba parlance.
52 Historically Samba's fileserver code had to deal a lot with processing
53 path based SMB requests. While the SMB protocol itself has been
54 streamlined to be purely handle based starting with SMB2, large parts of
55 infrastructure code remains in place that will "degrade" handle based SMB2
56 requests to path based filesystem access.
58 In order to fully leverage the handle based nature of the SMB2 protocol we
59 came up with a straight forward way to convert this infrastructure code.
61 At the core, we introduced a helper function that opens a file handle that
62 only serves as a path reference and hence can not be used for any sort of
65 Samba's internal file handle structure is of type `struct files_struct'
66 and all variable pointing to objects of such type are typically called
67 `fsp'. Until very recently the only function that would open such a file
68 handle and return an fsp was `SMB_VFS_CREATE_FILE()'.
70 Internally `SMB_VFS_CREATE_FILE()' consisted of processing through Samba's
71 VFS open function to open the low level file and then going through
72 Samba's Windows NTFS emulation code.
74 The key point of the new helper function which is called
75 `openat_pathref_fsp()' is that it skips the NTFS emulation
76 logic. Additionally, the handle is restricted internally to be only usable
77 as a path reference but not for any sort of IO. On Linux this is achieved
78 by using the `O_PATH' `open()' flag, on systems without `O_PATH' support
79 other mechanisms are used described in more detail below.
81 Path processing in Samba typically means processing client supplied paths
82 by Samba's core path processing function `filename_convert()' which returns
83 a pointer to an object of type `struct smb_filename'. Pointers to such
84 objects are then passed around, often passing many layers of code.
86 By attaching an `fsp' file handle returned from `openat_pathref_fsp()' to
87 all `struct smb_filename' objects returned from `filename_convert()', the
88 whole infrastructure code has immediate access to a file handle and so the
89 large infrastructure codebase can be converted to use handle based VFS
90 functions whenever VFS access is done in a piecemeal fashion.
99 On Linux the `O_PATH' flag to `open()' can be used to open a filehandle on
100 a file or directory with interesting properties: [1]
102 • the file-handle indicates a location in the filesystem tree,
104 • no permission checks are done by the kernel on the filesystem object and
106 • only operations that act purely at the file descriptor level are
109 The file itself is not opened, and other file operations (e.g., `read(2)',
110 `write(2)', `fchmod(2)', `fchown(2)', `fgetxattr(2)', `ioctl(2)',
111 `mmap(2)') fail with the error `EBADF'.
113 The following subset of operations that is relevant to Samba is allowed:
117 • `fchdir(2)', if the file descriptor refers to a directory,
123 • passing the file descriptor as the dirfd argument of `openat()' and the
124 other "*at()" system calls. This includes `linkat(2)' with AT_EMPTY_PATH
125 (or via procfs using AT_SYMLINK_FOLLOW) even if the file is not a
128 Opening a file or directory with the `O_PATH' flag requires no permissions
129 on the object itself (but does require execute permission on the
130 directories in the path prefix). By contrast, obtaining a reference to a
131 filesystem object by opening it with the `O_RDONLY' flag requires that the
132 caller have read permission on the object, even when the subsequent
133 operation (e.g., `fchdir(2)', `fstat(2)') does not require read permis‐
136 If for example Samba receives an SMB request to open a file requesting
137 `SEC_FILE_READ_ATTRIBUTE' access rights because the client wants to read
138 the file's metadata from the handle, Samba will have to call `open()' with
139 at least `O_RDONLY' access rights.
142 1.2.2 Usecases for O_PATH in Samba
143 ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
145 The `O_PATH' flag is currently not used in Samba. By leveraging this Linux
146 specific flags we can avoid permission mismatches as described above.
148 Additionally `O_PATH' allows basing all filesystem accesses done by the
149 fileserver on handle based syscalls by opening all client pathnames with
150 `O_PATH' and consistently using for example `fstat()' instead of `stat()'
151 throughout the codebase.
153 Subsequent parts of this document will call such file-handles opened with
154 O_PATH *path referencing file-handles* or *pathref*s for short.
157 1.2.3 When to open with O_PATH
158 ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
160 In Samba the decision whether to call POSIX `open()' on a client pathname
161 or whether to leave the low-level handle at -1 (what we call a stat-open)
162 is based on the client requested SMB access mask.
164 The set of access rights that trigger an `open()' includes
165 `READ_CONTROL_ACCESS'. As a result, the open() will be done with at least
166 `O_RDONLY'. If the filesystem supports NT style ACLs natively (like GPFS
167 or ZFS), the filesystem may grant the user requested right
168 `READ_CONTROL_ACCESS', but it may not grant `READ_DATA' (`O_RDONLY').
170 Currently the full set of access rights that trigger opening a file is:
178 • SEC_FLAG_SYSTEM_SECURITY
179 • READ_CONTROL_ACCESS
181 In the future we can remove the following rights from the list on systems
186 • SEC_FLAG_SYSTEM_SECURITY
187 • READ_CONTROL_ACCESS
190 1.2.4 Fallback on systems without O_PATH support
191 ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
193 The code of higher level file-handle consumers must be kept simple and
194 streamlined, avoiding special casing the handling of the file-handles
195 opened with or without `O_PATH'. To achieve this, a fallback that allows
196 opening a file-handle with the same higher level semantics even if the
197 system doesn't support `O_PATH' is needed.
199 The way this is implemented on such systems is impersonating the root user
200 for the `open()' syscall. In order to avoid privilege escalations security
201 issues, we must carefully control the use these file-handles.
203 The low level filehandle is stored in a public struct `struct file_handle'
204 that is part of the widely used `struct files_struct'. Consumers used to
205 simply access the fd directly by dereferencing pointers to `struct
208 In order to guard access to such file-handles we do two things:
210 • tag the pathref file-handles and
212 • control access to the file-handle by making the structure `struct
213 file_handle' private, only allowing access with accessor functions
214 that implement a security boundary.
216 In order to avoid bypassing restrictive permissions on intermediate
217 directories of a client path, the root user is only impersonated after
218 changing directory to the parent directory of the client requested
221 Two functions can then be used to fetch the low-level system file-handle
222 from a `struct files_struct':
224 • `fsp_get_io_fd(fsp)': enforces fsp is NOT a pathref file-handle and
226 • `fsp_get_pathref_fd(fsp)': allows fsp to be either a pathref file-handle
227 or a traditional POSIX file-handle opened with O_RDONLY or any other
230 Note that the name `fsp_get_pathref_fd()' may sound confusing at first
231 given that the fsp can be either a pathref fsp or a "normal/full" fsp, but
232 as any full file-handle can be used for IO and as path reference, the name
233 correctly reflects the intended usage of the caller.
236 1.2.5 When to use fsp_get_io_fd() or fsp_get_pathref_fd()
237 ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
239 The general guideline is:
241 • if you do something like `fstat(fd)', use `fsp_get_pathref_fd()',
243 • if you do something like `*at(dirfd, ...)', use `fsp_get_pathref_fd()',
245 • if you want to print the fd for example in `DEBUG' messages, use
246 `fsp_get_pathref_fd()',
248 • if you want to call `close(fd)', use `fsp_get_pathref_fd()',
250 • if you're doing a logical comparison of fd values, use
251 `fsp_get_pathref_fd()'.
253 In any other case use `fsp_get_io_fd()'.
256 2 VFS status quo and remaining work
257 ═══════════════════════════════════
259 2.1 VFS Functions Tables [2]
260 ────────────────────────────
262 2.1.1 Existing VFS Functions
263 ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
265 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
266 VFS Function Group Status
267 ───────────────────────────────────────────────────────
268 SMB_VFS_AIO_FORCE() [fsp] -
269 SMB_VFS_AUDIT_FILE() [Special] -
270 SMB_VFS_BRL_LOCK_WINDOWS() [fsp] -
271 SMB_VFS_BRL_UNLOCK_WINDOWS() [fsp] -
272 SMB_VFS_CHDIR() [Path] Todo
273 SMB_VFS_CHFLAGS() [Path] -
274 SMB_VFS_CHMOD() [Path] -
275 SMB_VFS_CLOSE() [fsp] -
276 SMB_VFS_CLOSEDIR() [fsp] -
277 SMB_VFS_CONNECT() [Disk] -
278 SMB_VFS_CONNECTPATH() [P2px] -
279 SMB_VFS_CREATE_DFS_PATHAT() [NsC] -
280 SMB_VFS_CREATE_FILE() [NsC] -
281 SMB_VFS_DISCONNECT() [Disk] -
282 SMB_VFS_DISK_FREE() [Disk] -
283 SMB_VFS_DURABLE_COOKIE() [fsp] -
284 SMB_VFS_DURABLE_DISCONNECT() [fsp] -
285 SMB_VFS_DURABLE_RECONNECT() [fsp] -
286 SMB_VFS_FALLOCATE() [fsp] -
287 SMB_VFS_FCHMOD() [fsp] -
288 SMB_VFS_FCHOWN() [fsp] -
289 SMB_VFS_FCNTL() [fsp] -
290 SMB_VFS_FDOPENDIR() [fsp] -
291 SMB_VFS_FGET_COMPRESSION() [fsp] -
292 SMB_VFS_FGET_DOS_ATTRIBUTES() [fsp] -
293 SMB_VFS_FGET_NT_ACL() [fsp] -
294 SMB_VFS_FGETXATTR() [xpathref] -
295 SMB_VFS_FILE_ID_CREATE() [Special] -
296 SMB_VFS_FLISTXATTR() [xpathref] -
297 SMB_VFS_FREMOVEXATTR() [xpathref] -
298 SMB_VFS_FS_CAPABILITIES() [Disk] -
299 SMB_VFS_FSCTL() [fsp] -
300 SMB_VFS_FSET_DOS_ATTRIBUTES() [fsp] -
301 SMB_VFS_FSET_NT_ACL() [fsp] -
302 SMB_VFS_FSETXATTR() [xpathref] -
303 SMB_VFS_FS_FILE_ID() [Special] -
304 SMB_VFS_FSTAT() [fsp] -
305 SMB_VFS_FSYNC() [fsp] -
306 SMB_VFS_FSYNC_SEND() [fsp] -
307 SMB_VFS_FTRUNCATE() [fsp] -
308 SMB_VFS_GET_ALLOC_SIZE() [fsp] -
309 SMB_VFS_GET_DFS_REFERRALS() [Disk] -
310 SMB_VFS_GET_DOS_ATTRIBUTES_RECV() [Enum] -
311 SMB_VFS_GET_DOS_ATTRIBUTES_SEND() [Enum] -
312 SMB_VFS_GETLOCK() [fsp] -
313 SMB_VFS_GET_NT_ACL_AT() [Path] -
314 SMB_VFS_GET_QUOTA() [Special] -
315 SMB_VFS_GET_REAL_FILENAME() [P2px] -
316 SMB_VFS_GET_SHADOW_COPY_DATA() [fsp] -
317 SMB_VFS_GETWD() [Special] -
318 SMB_VFS_GETXATTR() [Path] -
319 SMB_VFS_GETXATTRAT_RECV() [Enum] -
320 SMB_VFS_GETXATTRAT_SEND() [Enum] -
321 SMB_VFS_FILESYSTEM_SHAREMODE() [fsp] -
322 SMB_VFS_LCHOWN() [Path] Todo
323 SMB_VFS_LINKAT() [NsC] -
324 SMB_VFS_LINUX_SETLEASE() [fsp] -
325 SMB_VFS_LISTXATTR() [Path] -
326 SMB_VFS_LOCK() [fsp] -
327 SMB_VFS_LSEEK() [fsp] -
328 SMB_VFS_LSTAT() [Path] Todo
329 SMB_VFS_MKDIRAT() [NsC] -
330 SMB_VFS_MKNODAT() [NsC] -
331 SMB_VFS_NTIMES() [Path] -
332 SMB_VFS_OFFLOAD_READ_RECV() [fsp] -
333 SMB_VFS_OFFLOAD_READ_SEND() [fsp] -
334 SMB_VFS_OFFLOAD_WRITE_RECV() [fsp] -
335 SMB_VFS_OFFLOAD_WRITE_SEND() [fsp] -
336 SMB_VFS_OPENAT() [NsC] -
337 SMB_VFS_PREAD() [fsp] -
338 SMB_VFS_PREAD_SEND() [fsp] -
339 SMB_VFS_PWRITE() [fsp] -
340 SMB_VFS_PWRITE_SEND() [fsp] -
341 SMB_VFS_READ_DFS_PATHAT() [Symlink] -
342 SMB_VFS_READDIR() [fsp] -
343 SMB_VFS_READDIR_ATTR() [Path] -
344 SMB_VFS_READLINKAT() [Symlink] -
345 SMB_VFS_REALPATH() [P2px] -
346 SMB_VFS_RECVFILE() [fsp] -
347 SMB_VFS_REMOVEXATTR() [Path] -
348 SMB_VFS_RENAMEAT() [Path] -
349 SMB_VFS_REWINDDIR() [fsp] -
350 SMB_VFS_SENDFILE() [fsp] -
351 SMB_VFS_SET_COMPRESSION() [fsp] -
352 SMB_VFS_SET_DOS_ATTRIBUTES() [Path] -
353 SMB_VFS_SET_QUOTA() [Special] -
354 SMB_VFS_SETXATTR() [Path] -
355 SMB_VFS_SNAP_CHECK_PATH() [Disk] -
356 SMB_VFS_SNAP_CREATE() [Disk] -
357 SMB_VFS_SNAP_DELETE() [Disk] -
358 SMB_VFS_STAT() [Path] Todo
359 SMB_VFS_STATVFS() [Disk] -
360 SMB_VFS_STREAMINFO() [Path] -
361 SMB_VFS_STRICT_LOCK_CHECK() [fsp] -
362 SMB_VFS_SYMLINKAT() [NsC] -
363 SMB_VFS_SYS_ACL_BLOB_GET_FD() [xpathref] -
364 SMB_VFS_SYS_ACL_BLOB_GET_FILE() [Path] -
365 SMB_VFS_SYS_ACL_DELETE_DEF_FILE() [Path] -
366 SMB_VFS_SYS_ACL_GET_FD() [xpathref] -
367 SMB_VFS_SYS_ACL_GET_FILE() [Path] -
368 SMB_VFS_SYS_ACL_SET_FD() [xpathref] -
369 SMB_VFS_TRANSLATE_NAME() [P2px] -
370 SMB_VFS_UNLINKAT() [NsC] -
371 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
374 [fsp] See section 2.2.2
376 [Special] See section 2.2.9
378 [Path] See section 2.2.4
380 [Disk] See section 2.2.1
382 [P2px] See section 2.2.8
384 [NsC] See section 2.2.3
386 [xpathref] See section 2.2.7
388 [Enum] See section 2.2.6
390 [Symlink] See section 2.2.5
393 2.1.2 New VFS Functions
394 ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
396 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
397 VFS Function Group Status
398 ─────────────────────────────────────────────────────
399 SMB_VFS_SYS_ACL_DELETE_DEF_FD() [xpathref] -
400 SMB_VFS_FNTIMENS() [fsp] -
401 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
404 [xpathref] See section 2.2.7
406 [Enum] See section 2.2.6
408 [fsp] See section 2.2.2
411 2.2 VFS functions by category
412 ─────────────────────────────
414 2.2.1 Disk operations
415 ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
418 • SMB_VFS_DISCONNECT()
419 • SMB_VFS_DISK_FREE()
420 • SMB_VFS_FS_CAPABILITIES()
421 • SMB_VFS_GET_DFS_REFERRALS()
422 • SMB_VFS_SNAP_CHECK_PATH()
423 • SMB_VFS_SNAP_CREATE()
424 • SMB_VFS_SNAP_DELETE()
430 2.2.2 Handle based VFS functions
431 ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
433 • SMB_VFS_AIO_FORCE()
434 • SMB_VFS_BRL_LOCK_WINDOWS()
435 • SMB_VFS_BRL_UNLOCK_WINDOWS()
438 • SMB_VFS_DURABLE_COOKIE()
439 • SMB_VFS_DURABLE_DISCONNECT()
440 • SMB_VFS_FALLOCATE()
444 • SMB_VFS_FDOPENDIR()
445 • SMB_VFS_FGET_DOS_ATTRIBUTES()
446 • SMB_VFS_FGET_NT_ACL()
448 • SMB_VFS_FSET_DOS_ATTRIBUTES()
449 • SMB_VFS_FSET_NT_ACL()
452 • SMB_VFS_FSYNC_SEND()
453 • SMB_VFS_FTRUNCATE()
455 • SMB_VFS_GET_ALLOC_SIZE()
456 • SMB_VFS_GET_SHADOW_COPY_DATA()
457 • SMB_VFS_FILESYSTEM_SHAREMODE()
458 • SMB_VFS_LINUX_SETLEASE()
461 • SMB_VFS_OFFLOAD_READ_SEND()
462 • SMB_VFS_OFFLOAD_WRITE_SEND()
464 • SMB_VFS_PREAD_SEND()
466 • SMB_VFS_PWRITE_SEND()
469 • SMB_VFS_REWINDDIR()
471 • SMB_VFS_SET_COMPRESSION()
472 • SMB_VFS_STRICT_LOCK_CHECK()
474 If an fsp is provided by the SMB layer we use that, otherwise we use the
475 pathref fsp `smb_fname->fsp' provided by `filename_convert()'.
478 2.2.3 Namespace changing VFS functions
479 ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
481 • SMB_VFS_CREATE_FILE()
483 All intermediate VFS calls within `SMB_VFS_CREATE_FILE()' will be based on
484 `smb_fname->fsp' if the requested path exists. When creating a file we
485 rely on `non_widelink_open()' which doesn't depend on a dirfsp.
489 Needs a real dirfsp (done).
493 Is only called from within `non_widelink_open()' with a dirfsp equivalent
494 of `AT_FDCWD' and so doesn't need a real dirfsp.
496 The following operations need a real dirfsp:
501 • SMB_VFS_SYMLINKAT()
504 Callers use `openat_pathref_fsp()' to open a fsp on the parent directory.
507 2.2.4 Path based VFS functions
508 ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
510 All path based VFS functions will be replaced by handle based variants
511 using the `smb_fname->fsp' provided by `filename_convert()'.
516 • SMB_VFS_DURABLE_RECONNECT()
518 • SMB_VFS_GET_COMPRESSION()
519 • SMB_VFS_GET_DOS_ATTRIBUTES()
520 • SMB_VFS_GET_NT_ACL_AT()
522 • SMB_VFS_LISTXATTR()
525 • SMB_VFS_REMOVEXATTR()
527 • SMB_VFS_SET_DOS_ATTRIBUTES()
529 • SMB_VFS_STREAMINFO()
530 • SMB_VFS_SYS_ACL_BLOB_GET_FILE()
531 • SMB_VFS_SYS_ACL_DELETE_DEF_FILE()
532 • SMB_VFS_SYS_ACL_GET_FILE()
533 • SMB_VFS_SYS_ACL_SET_FILE()
535 Replace with corresponding handle based VFS calls.
538 2.2.5 AT VFS functions that can't be based on handles
539 ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
541 • SMB_VFS_CREATE_DFS_PATHAT()
542 • SMB_VFS_READ_DFS_PATHAT()
543 • SMB_VFS_READLINKAT()
545 As the DFS link implementation is based on symlinks, we have to use *AT
546 based functions with real dirfsps.
549 2.2.6 AT VFS functions needed for directory enumeration
550 ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
552 • SMB_VFS_GET_DOS_ATTRIBUTES_SEND()
553 • SMB_VFS_GETXATTRAT_SEND()
556 2.2.7 Handle based VFS functions not allowed on O_PATH opened handles
557 ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
559 • SMB_VFS_FGETXATTR()
560 • SMB_VFS_FLISTXATTR()
561 • SMB_VFS_FREMOVEXATTR()
562 • SMB_VFS_FSETXATTR()
563 • SMB_VFS_SYS_ACL_BLOB_GET_FD()
564 • SMB_VFS_SYS_ACL_GET_FD()
565 • SMB_VFS_SYS_ACL_DELETE_DEF_FD() (NEW)
566 • SMB_VFS_SYS_ACL_SET_FD()
568 Based upon securely opening a full fd based on `/proc/self/fd/%d' as in
569 the case of xattrs, pathref handles can't be used for xattr IO, and in the
570 case of ACLs pathref handles can't be used to access default ACEs.
573 2.2.8 Pure path to path translation
574 ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
576 • SMB_VFS_CONNECTPATH()
577 • SMB_VFS_GET_REAL_FILENAME()
579 • SMB_VFS_TRANSLATE_NAME()
587 • SMB_VFS_FILE_ID_CREATE()
588 • SMB_VFS_FS_FILE_ID()
589 • SMB_VFS_GET_QUOTA()
591 • SMB_VFS_SET_QUOTA()
595 • SMB_VFS_AUDIT_FILE()
597 This is currently unused.
604 [1] parts of the following sections copied from man open(2)
606 [2] `grep 'SMB_VFS_*' source3/include/vfs_macros.h | grep -v NEXT_ | sed
607 's|.*\(SMB_VFS_.*\)(.*|\1()|' | sort'