The semantics of paths in VFS modules
uri at samba.org
Sat Apr 2 19:54:55 UTC 2016
I would like to document the meaning of path names in the wiki
(add it to the vfs module writing page), and thought I'd first submit it
to the list to get comments.
Comments are welcome.
The Meaning of Path Names
What's in path names passed down to VFS functions? Are they absolute?
Are they relative? Relative to what?
The short answer is: "Paths are relative to the root of the share,
except when they are not". A slightly longer answer is "Paths are either
absolute or relative to the current working directory". Both answers
could be confusing to module writers, so the following elaborates on that.
At the SMB protocol level, path names are relative to the root of the
share. When processing SMB requests, smbd changes the working directory
(chdir()) to the root of the share, and then typically forwards those
paths as-is (translated to UTF-8). Thus, a VFS module would *normally*
see the same path requested by the SMB protocol, which is a path
relative to the root of the share. However, there are exceptions:
1. When changing the working directory, smbd also uses the VFS chdir_fn
function, and is using an absolute path - the path of the share. Thus,
if you implement chdir_fn, expect to see absolute paths.
2. Some VFS modules modify the path and forward the request to the layer
below them. Some of them can modify the path into an absolute path,
depending on configuration (for example, vfs_shadow_copy2, if configured
with an absolute snapsharepath).
3. Finally, smbd itself could use relative paths which are not relative
to the root of the share. This happens when smbd changes into a
directory inside the share to perform some "sensitive stuff". One
example is changing the ownership of the file into that of the parent
directory (inherit owner = yes). However, the recurring
pattern with this kind of chdir() is that smbd first makes a *relative*
chdir (to get into the path inside the share), and then returns to the
original path using an *absolute* path.
So as a module writer, how do I cope with all this?
Handling Absolute Paths
Absolute paths usually have meaning only in the context of real file
systems. A module that exposes a kernel file system (such as the default
VFS module or the btrfs module) would have no problem handling an
absolute path. On the other hand, getting an absolute path can be
confusing to a module which provides a user-space file system.
As noted above, smbd would only use absolute paths in order to change
directory into the share's root directory. A user-space module can
simply ignore this kind of chdir or use it to flag the current state as
"in share root dir".
On the other hand, some VFS modules could modify the path into an
absolute path. The simplest way for a user-space file system VFS module
to deal with that is to say that it cannot be stacked with other modules
which convert the path to an absolute path.
Handling Relative Paths
As explained above, a relative path would *mostly* be relative to the
share's root, and always relative to the current working directory.
One way to cope with relative paths therefore is to keep track of the
current working directory. The default VFS module for example does this
- the kernel keeps track of current directory for it.
The following algorithm could be used by VFS modules to track the
"current relative working directory", by implementing chdir_fn VFS function:
a. Initial state is "at share's root" - current relative directory is an
b. A chdir with an absolute path can be assumed to be "back into the
share's root" - clear the current relative directory (this rule could be
broken by another VFS module but it's easily verifiable by comparing
c. A chdir with a relative path appends the path to the current relative
d. For any other file operation, to reconstruct the path relative to the
share's root, append the supplied path to the current relative directory.
A different way to cope with relative paths is to ignore the cases
where the current directory is not the share's root either because your
module doesn't care about the exact location of the file (for example it
performs some character conversion on path names), or you don't intend
to support the cases where the current directory is the share's root.
More information about the samba-technical