- Create src/sys/fs/tmpfs/. - Create src/sys/fs/tmpfs/files.tmpfs. - Modify src/sys/conf/files to include files.tmpfs. - Create tmpfs_vnops.c and tmp_vfsops.c stubs: all operations set to genfs_eopnotsupp in the former, NULL in the latter. - Define filesystem's name (MOUNT_TMPFS) in src/sys/sys/mount.h. - Add filesystem's magic number in src/sys/compat/linux/common/linux_misc.c and the corresponding .h file, if possible. Fallback to default number. At this point, the kernel builds with the new filesystem but panics during boot: vfs_init is not defined. - Define an empty vfs_init operation (except for the LKM stuff) and its vfs_done counterpart (to undo what the former does). Now the system boots correctly with the filesystem enabled. - Define empty vfs_mount and vfs_umount operations, returning EOPNOTSUPP. The former also needs vfs_start and vfs_statvfs to be defined; otherwise, we'll panic. After this, we should be able to call mount(2) for this filesystem. - Add a simple mount_tmpfs command that calls mount(2) to mount the filesystem. This will make the system crash unless we did the above additions. - Modify the vfs_mount hook to check for basic mount flags (MNT_GETARGS and MNT_UPDATE) and use them. Make it copy parameters from userland if needed (they are needed in our case). Fill the mount structure and mount the filesystem. Call set_statvfs_info at the end. - Modify the vfs_unmount hook to flush pending IO (honoring MNT_FORCE, if needed) and free any associated data. - Modify the vfs_statvfs hook to return fake data (done filling sbp and using copy_statvfs_info). - Add a tmpfs.h file describing the mount parameters and the filesystem specific data (per mount point). Needed to synchronize userland calls with the kernel. This file describes tmpfs_args, tmpfs_mount and TMPFS_ARGSVERSION at the moment. At this point, the filesystem may be mounted, although a panic will happen whenever the system tries to flush buffers to disk. - Define an empty vfs_sync hook returning success. It may probably remain this way in the future, since we might not need it for tmpfs. To fix system crashes during unmount: - Define an vfs_root stub returning EOPNOTSUPP. Problem: we can't unmount the filesystem because it has no root. - We also define stubs for all other vfs operations (vfs_quotactl, vfs_vget, vfs_fhtovp, vfs_vptofh, vfs_checkexp, vfs_snapshot and vfs_extattrctl) to avoid other possible crashes. I'm doing this because I added a printf() in each of them to notice when will they be needed. OK, so the filesystem is now mountable, but nothing more. It can't be unmounted, and an ls over it will return nothing (operation not supported). It is time to start implementing vnodes that represent the contents of the file system (so vfs_root can return something useful). - Define an structure to represent file-system objects: tmpfs_node. - Get the root node from disk or generate it on-the-fly in memory. Store it in tmpfs_mount for futher usage. Destroy it upon unmount. - Create functions to allocate and deallocate vnodes based on file-system specific nodes (tmpfs_{alloc,free}_vp). These may go into tmpfs_subr.c. - Change the vfs_root hook to return the root vnode of the filesystem. - Define the VT_TMPFS vnode type in vnode.h and vnode.9. After all the above, we can expect many crashes due to missing vnode operations. At the very least we need to: - Set the vfs_fsync, vfs_bwrite and vfs_putpages hooks to genfs_nullop. Needed during sync(2) or unmount(2). - Set the vfs_abortop hook to genfs_abortop. - Set the locking hooks (vfs_lock, vfs_unlock and vfs_islocked) to their respective stubs (genfs_nolock, genfs_nounlock and genvfs_noislocked). We don't know yet if we will need locking at this level. - Define a vfs_reclaim hook that frees data associated (i.e., tmpfs_node structures) with the given vnode. At the very least, it must set the v_data member to NULL. Now we have a root node for our filesystem defined, but it's completely useless. Any operation executed over it will result in 'Operation not supported' messages. Since the file-system is now "usable" in the sense that you can mount and unmount it, it's a good time to start adding regression tests in src/regress/sys/fs/tmpfs to test everything you want/need easily. The more things you test, the less chances to suffer regressions. Improve mount_tmpfs to support some of the already implemented options as well as standard options through getmntopts. Done by using getopt and filling the tmpfs_args structure as appropriate. Start addition of vnode operations. The easiest ones are access, getattr, followed by setattr which is quite complex. The latter needs to define update and possibly sync too. Add the lookup and mkdir vnode operations so that you can start trying if the lookup works when you create stuff. The lookup operation may be incomplete at this point (lacking support for RENAME and DELETE, for example). Continue by adding open, close and readdir, to be able to do directory listings to verify that all your previous operations work correctly. Add the rmdir vnode operation to be able to "undo" changes made by mkdir (and to learn how to remove stuff). Need to change the lookup operation to honour the DELETE flag. Implement vnode locking: lock, unlock and islocked operations. This should have been done earlier because problems pop up from everywhere now. Also implement the inactive vnode operation, which should also have been done earlier (as it is required by vput); maybe before rmdir. Implement the print operation. This is trivial and should have been done earlier to help in debugging. Implement the rename operation. This is complex and could be left for a later stage, specially because it cannot be completely tested at this point. Implement the create operation. Implement the remove operation. Implement the link operation. Implement the read, write, truncate and getpages operations. For real filesystems, this results in the need to implement bmap, strategy and putpages in addition to the other ones. Implement the fcntl, ioctl, poll, revoke, mmap and seek vnode operations through the ones provided by genfs. (Note that UFS does this.) Implement the pathconf operation. Easy but manual pages (pathconf(2) and vnodeops(9)) are a bit inconsistent. Implement the readlink and symlink operations to be able to manage symlinks. Implement the mknod operation. This one is tricky: - Add a fifoop operations vector for fifos. - Implement the close, read and write operations specific for fifos (have to update node timestamps). - Add a specop operations vector for special devices. - Implement the close, read and write operations specific for special devices (have to update node timestamps). - Change the allocation vnode to check for vnode aliases. - Implement the operation itself. Implement NFS support: - Add fspec and export attributes in the args structure. - Write the vptofh, checkexp and fhtovp VFS hooks. - Modify the readdir vnode operation to return the NFS-related cookies, if not done yet. Nothing else should be needed, AFAICT, if everything else is correct.