Writing a Samba VFS in Samba 3.6 and earlier
This document is intended to help people who want to write Samba VFS modules. It is a Wiki-based version of an earlier document written by Richard Sharpe that can be found at Writing a Samba VFS.
The rest of this document is organized into a number of sections that:
- Provides and outline of the Samba VFS and discuss the interactions between the main Samba code, the VFS Layer, VFS modules and the underlying OS.
- Discusses two different types of file systems that module writers might want to write a VFS module for.
- Provides more detail on actually writing a Samba VFS and some of the functions and macros Samba makes available to help you.
- Lists differences in the VFS for different versions of Samba.
- Introduces some existing VFS modules, especially in the context of the two file system types outlined above.
- Gives details on the steps module writes will have to take to add their code and build their module.
- Provides some information on adding additional VFS routines over and above those already provided.
The Samba VFS
The Samba VFS provides a mechanism to allow people to extend the functionality of Samba in useful ways. Some examples are:
- Convert NTFS ACLs to NFSv4 ACLs for storing in a file system that supports them. The GPFS VFS module does this and the same could be done for Linux when RichACL support is complete.
- Support features that a vendor has implemented in their file system that Linux file systems do not support. The OneFS VFS module from Isilon interfaces with their in-kernel distributed file system which provides more complete NTFS functionality, including four file times, etc.
- Implement features like Alternate Data Streams.
- Implement full NT ACL support by storing them in XATTRs and correctly handling the semantics (see source3/modules/vfs_acl_xattr.c and source3/modules/vfs_acl_common.c.)
- Support user-space file systems, perhaps accessible via a shared memory interface or via a user-space library (eg, Ceph's libceph.)
A Samba VFS is a shared library (eg, acl_xattr.so), or module, that implements some or all of the functions that the Samba VFS interface makes available to provides the desired functionality. In addition VFS modules can be stacked (if they have been written for that), and there is a default VFS (source3/modules/vfs_default.c) that provides the default Samba functionality for those functions that are not implemented higher in the stack or that earlier modules also call.
NOTE! Samba also makes it possible to use VFS modules statically on those systems that do not support shared libraries. Brief comments about this are included at the end of this document.
The following diagrams help illustrate some of the concepts in more detail.
The things to note here are:
- There are a number of layers to Samba.
- Protocol processing code in Samba will usually call one or more VFS Functions.
- Your specific Samba configuration can use a number of VFS modules that do not have to overlap. That is, they can each implement different sets of VFS functions (of which, more below). However, they can also be stacked.
- There is a default VFS module (which is statically linked into Samba) that provides implementations of all VFS functions and functions as a backstop. That is, it will be called in the event that no other module implements a particular function or will be called last if the functions in your module pass control down the stack.
- The default VFS module, vfs_defaults.c (source3/modules/vfs_defaults.c) calls back into Samba, usually via the sys_xxx routines, but sometimes it calls other modules.
If you want to find out what a particular VFS function does you should check the code in vfs_defaults.c.
The above figure also illustrates the flow of control through Samba and the VFS modules. The steps are similar to the following:
- An SMB request comes into Samba (steps 1 or 11), which results in Samba calling a VFS routines. The call is via a macro in the source code that looks like SMB_VFS_XXX, eg, SMB_VFS_STAT to retrieve file metadata.
- The VFS layer calls the entry point in the first VFS module in the stack that implements the requested function. In the figure above, Req 1 results in a call to an entry point (step 2) in vfs_mod_1.so while Req 2 results in a call to an entry point (step 12) in vfs_mod_2.so.
- If the called function needs the functionality provided by other modules in the stack, it calls VFS_SMB_NEXT_XXX, which in the illustration ends up in the default VFS module, vfs_default.c. The VFS function called in vfs_mod_1.so in step 2 above then results in a call to the NEXT function (step 3) and ends up in vfs_default.c
- The entry points in the default VFS module typically call functions in the system layer, eg, sys_stat (step 4).
- The system module calls into the kernel via a system call, eg, the stat system call (step 5).
- The system call returns to the system module (step 6), which
- Returns to the function in vfs_default.c that called the system layer (step 7), which
- Returns up the stack to the VFS module (step 8), which
- Returns to the main Samba code (step 9), which
- Formats and sends an SMB response (step 10).
Also, Req 2 is processed slightly differently. In this case, the entry point in vfs_mod_2.so that is called decides that it can handle everything itself, so it returns to the main Samba code (step 13) which then formats and sends an SMB response (step 14).
It should be noted that the Samba VFS interface contains some 120 different functions and that a VFS does not have to implement them all (with an exception noted below.) If a module does not implement a particular VFS function, the required function within vfs_default.c will be called. However, it should be pointed out that if your module implements a particular request in its entirety, then it does not need to invoke functions below it in the stack. Further, functions below it in the stack are not automatically invoked, rather, the module writer must explicitly invoke modules below it in the stack by calling the NEXT module.
Each of these approaches can be illustrated with code examples from existing VFS modules.
Two Types of File Systems
Writing a VFS Module
VFS Module Initialization
VFS Function Pointer Structure
The Life Cycle of a VFS
Memory Management and talloc
Providing Context between Calls
Module Specific Parameters
Extending the Samba files_struct structure
AIO Handling in a VFS Module
Conforming to the VFS Interfaces
Be prepared for "stat" opens
Things to watch out for
Samba Version VFS Differences
Some Existing VFS Modules
Building, Installing and Debugging your VFS Module