Kleiman's "Vnodes: An Architecture for Multiple File System Types in Sun UNIX" describes a basic architecture that's pretty familiar at this point.
One design goal I wouldn't have thought of:
All file system operations should be atomic. In other words, the set of interface operations should be at a high enough level so that there is no need for locking (hard locking, not user advisory locking) across several operations. Locking, if required, should be left up to the file system implementation dependent layer. For example, if a relatively slow computer running a remote file system requires a supercomputer server to lock a file while it does several operations, the users of the supercomputer would be noticeably affected. It is much better to give the file system dependent code full information about what operation is being done and let it decide what locking is necessary and practical.
Linux's VFS doesn't really work that way--the VFS operations are too fine-grained. But that does mean we end up having to do special things for distributed filesystems (e.g. the intents stuff).
Note that VFS described in this paper has no common inode lock, for example; that's left up to the filesystem.