Subject: PSARC FastTrack [03/14/2007]: Strong Type-Checking for VFS Operation Registration Mechanism Template Version: @(#)sac_nextcase 1.2 03/28/07 SMI This information is Copyright 2007, Sun Microsystems 1. Introduction 1.1. Project/Component Working Name: Strong Type-Checking for VFS Operation Registration Mechanism 1.2. Name of Document Author/Supplier: Author: Rich Brown 1.3 Date of This Document: 05 March, 2007 4. Technical Description STRONGER TYPE-CHECKING FOR VNODE/VFS/FEM OPERATIONS Problem Description In Solaris 10, a mechanism to register vnode/vfs/fem operations was introduced as part of the File System Interfaces project (PSARC/2001/679). This operation registration mechanism provided the flexibility to add new vnode/vfs operations without requiring all file systems to be aware of the new operation. The downside of this was that strong type-checking of the operation signatures could not be done. Brief History The solution that was considered for the original implementation of the operation registration mechanism was to use C99's "designated initializer" feature. (This is briefly but incompletely described in section 2.1.3.1 "Alternative Implementations Considered" in the functional spec for PSARC/2001/679.) The implementation requires a union containing all the vnode and vfs operations including their full signatures (what each function returns and the type of each of the functions arguments). Next, each of the operation definition tables would be updated such that the implemented vnode/vfs operation would be initialized with a designated type from the union. For example: const fs_operation_def_t xxx_vnodeops_template[] = { { VOPNAME_OPEN, .vop_open = xxx_open }, { VOPNAME_CLOSE, .vop_close = xxx_close }, ... }; Unfortunately, the compiler used for Solaris 10 did not support this feature so that alternative could not be implemented at that time. But the Good News is... The good news is that the current compiler for Solaris Nevada *does* support "designated initializers" and its use for vnode/vfs/fem/fsem operations has been successfully prototyped. (In fact, several inconsistencies in vnode operation definitions were found in changes that were added since Solaris 10. Change requests have been filed and have since been fixed as a result of that discovery.) Proposed Solution The solution is relatively simple although it touches every file that uses the operation registration facilities (around 90 files). 1) Change names of vsop_* to femop_* and vfsop_* to fsemop_* in sys/fem.h and common/fs/fem.c This is mostly cosmetic, but will make it easier for developers of file/filesystem monitors to remember the names of the routines. For example, femop_open and fsemop_mount versus vsop_open and vfsop_mount. These names are currently project private since no one else would need to use them. They will now be consolidation private since anyone in the consolidation could develop a monitor. There are currently no consumers of this outside the ON consolidation. 2) Extract the contents (structure members) of each of the following structures and create a #define to represent them: vnodeops_t or "struct vnodeops" --> VNODE_OPS vfsops_t or "struct vfsops --> VFS_OPS fem_t or "struct fem" --> FEM_OPS fsem_t or "struct fsem" --> FSEM_OPS This is so that we can keep the signatures of each set of routines in one place and use the list in the structure as well as the union (see below). In other words, if VNODE_OPS contains the list of function prototypes for the vnodeops structure, we would have: sys/vnode.h: #define VNODE_OPS \ int (*vop_open)(vnode_t **, int, cred_t *); \ int (*vop_close)(vnode_t *, int, int, offset_t, cred_t *); \ ... int (*vop_vnevent)(vnode_t *, vnevent_t); typedef struct vnodeops { const char *vnop_name; VNODE_OPS } vnodeops_t; Similar changes would be made as described above for sys/vfs.h (VFS_OPS, vfsops_t) and sys/fem.h (FEM_OPS, fem_t, FSEM_OPS, fsem_t). 2) Create a new union and typedef, fs_func/fs_func_p, of all vop, vfsop, femop, fsemop routines: sys/vfs_opreg.h: typedef union fs_func { fs_generic_func_p fs_generic; /* Generic signature */ int (*error)(); /* Signature of error func */ VFS_OPS /* All vfs op signatures */ VNODE_OPS /* All vnode op signatures */ FEM_OPS /* All fem op signatures */ FSEM_OPS /* All fsem op signatures */ } fs_func_p; 3) Move all operation registration related declarations from sys/vnode.h and sys/vfs.h to a separate header file: (This is to avoid circular dependencies on the header files. 4) Update all file systems to include , where appropriate, and modify all fs_operation_def_t template arrays to use "designated initializers". Using the example above: const fs_operation_def_t xxx_vnodeops_template[] = { { VOPNAME_OPEN, .vop_open = xxx_open }, { VOPNAME_CLOSE, .vop_close = xxx_close }, ... }; So, What Does This Mean For Unbundled File System Developers? At a bare minimum, file system developers will have to add the following to any file that uses the operation registration mechanism: #include No further changes are required, but that means the file system does not take advantage of the strong type-checking described by these changes. The change that takes advantage of the strong type-checking is described by #4 above. All fs_operation_def_t template arrays would be modified to use "designated initializers". So, an fs_operation_def_t array that looks like this today: const fs_operation_def_t xxx_vnodeops_template[] = { { VOPNAME_OPEN, xxx_open }, { VOPNAME_CLOSE, xxx_close }, ... }; ...would be modified to look like this: const fs_operation_def_t xxx_vnodeops_template[] = { { VOPNAME_OPEN, .vop_open = xxx_open }, { VOPNAME_CLOSE, .vop_close = xxx_close }, ... }; Communication to 3rd Party FS Vendors As I have in the past, I will take responsibility for informing the contacts for 3rd party file systems. Just in case my PowerBall lottery numbers match this week, here is the contact information: Mail alias: unbundled-fs-developers@sun.com Exported Interface Table +-----------------------+---------------+---------------+----------------------+ | Interface Name | Proposed | Specified in | Comments | | | Stability | What Document?| | +=======================+===============+===============+======================+ | | Consolidation | This document | Contains new fs_func | | | Private | | union plus interface | | | | | declarations moved | | | | | from sys/vnode.h and | | | | | sys/vfs.h | +-----------------------+---------------+---------------+----------------------+ | union fs_func | Consolidation | This document | See #2 in "Proposed | | fs_func_p (typedef) | Private | | Solution" section | +-----------------------+---------------+---------------+----------------------+ | femop_open | Consolidation | This document.| These names were | | femop_close | Private | See #1 in | changed from vsop_*. | | femop_read | | "Proposed | Previously, they were| | femop_write | | Solution" | considered "Project | | femop_ioctl | | above | Private" but are now | | femop_setfl | | | exposed within the | | femop_getattr | | | consolidation to any | | femop_setattr | | | project that would | | femop_access | | | use FEM. | | femop_lookup | | | | | femop_create | | | Note that the only | | femop_remove | | | reason to expose | | femop_link | | | these is for their | | femop_rename | | | use as "designated | | femop_mkdir | | | initializers" | | femop_rmdir | | | | | femop_readdir | | | | | femop_symlink | | | | | femop_readlink | | | | | femop_fsync | | | | | femop_inactive | | | | | femop_fid | | | | | femop_rwlock | | | | | femop_rwunlock | | | | | femop_seek | | | | | femop_cmp | | | | | femop_frlock | | | | | femop_space | | | | | femop_realvp | | | | | femop_getpage | | | | | femop_putpage | | | | | femop_map | | | | | femop_addmap | | | | | femop_delmap | | | | | femop_poll | | | | | femop_dump | | | | | femop_pathconf | | | | | femop_pageio | | | | | femop_dumpctl | | | | | femop_dispose | | | | | femop_setsecattr | | | | | femop_getsecattr | | | | | femop_shrlock | | | | | femop_vnevent | | | | +-----------------------+---------------+---------------+----------------------+ | fsemop_mount | Consolidation | This document.| As above, except | | fsemop_unmount | Private | See #1 of | changed from vfsop_* | | fsemop_root | | "Proposed | | | fsemop_statvfs | | Solution" | | | fsemop_sync | | above. | | | fsemop_vget | | | | | fsemop_mountroot | | | | | fsemop_freevfs | | | | | fsemop_vnstate | | | | +-----------------------+---------------+---------------+----------------------+ 6. Resources and Schedule 6.4. Steering Committee requested information 6.4.1. Consolidation C-team Name: ON 6.5. ARC review type: FastTrack