Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | |
| 2 | Making Filesystems Exportable |
| 3 | ============================= |
| 4 | |
Christoph Hellwig | e38f981 | 2007-10-21 16:42:19 -0700 | [diff] [blame] | 5 | Overview |
| 6 | -------- |
| 7 | |
| 8 | All filesystem operations require a dentry (or two) as a starting |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 9 | point. Local applications have a reference-counted hold on suitable |
Christoph Hellwig | e38f981 | 2007-10-21 16:42:19 -0700 | [diff] [blame] | 10 | dentries via open file descriptors or cwd/root. However remote |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 11 | applications that access a filesystem via a remote filesystem protocol |
| 12 | such as NFS may not be able to hold such a reference, and so need a |
| 13 | different way to refer to a particular dentry. As the alternative |
| 14 | form of reference needs to be stable across renames, truncates, and |
| 15 | server-reboot (among other things, though these tend to be the most |
| 16 | problematic), there is no simple answer like 'filename'. |
| 17 | |
| 18 | The mechanism discussed here allows each filesystem implementation to |
Christoph Hellwig | e38f981 | 2007-10-21 16:42:19 -0700 | [diff] [blame] | 19 | specify how to generate an opaque (outside of the filesystem) byte |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 20 | string for any dentry, and how to find an appropriate dentry for any |
| 21 | given opaque byte string. |
| 22 | This byte string will be called a "filehandle fragment" as it |
| 23 | corresponds to part of an NFS filehandle. |
| 24 | |
| 25 | A filesystem which supports the mapping between filehandle fragments |
Christoph Hellwig | e38f981 | 2007-10-21 16:42:19 -0700 | [diff] [blame] | 26 | and dentries will be termed "exportable". |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 27 | |
| 28 | |
| 29 | |
| 30 | Dcache Issues |
| 31 | ------------- |
| 32 | |
| 33 | The dcache normally contains a proper prefix of any given filesystem |
| 34 | tree. This means that if any filesystem object is in the dcache, then |
| 35 | all of the ancestors of that filesystem object are also in the dcache. |
| 36 | As normal access is by filename this prefix is created naturally and |
| 37 | maintained easily (by each object maintaining a reference count on |
| 38 | its parent). |
| 39 | |
| 40 | However when objects are included into the dcache by interpreting a |
| 41 | filehandle fragment, there is no automatic creation of a path prefix |
| 42 | for the object. This leads to two related but distinct features of |
| 43 | the dcache that are not needed for normal filesystem access. |
| 44 | |
| 45 | 1/ The dcache must sometimes contain objects that are not part of the |
| 46 | proper prefix. i.e that are not connected to the root. |
| 47 | 2/ The dcache must be prepared for a newly found (via ->lookup) directory |
| 48 | to already have a (non-connected) dentry, and must be able to move |
| 49 | that dentry into place (based on the parent and name in the |
| 50 | ->lookup). This is particularly needed for directories as |
| 51 | it is a dcache invariant that directories only have one dentry. |
| 52 | |
| 53 | To implement these features, the dcache has: |
| 54 | |
| 55 | a/ A dentry flag DCACHE_DISCONNECTED which is set on |
| 56 | any dentry that might not be part of the proper prefix. |
| 57 | This is set when anonymous dentries are created, and cleared when a |
| 58 | dentry is noticed to be a child of a dentry which is in the proper |
| 59 | prefix. |
| 60 | |
| 61 | b/ A per-superblock list "s_anon" of dentries which are the roots of |
| 62 | subtrees that are not in the proper prefix. These dentries, as |
| 63 | well as the proper prefix, need to be released at unmount time. As |
| 64 | these dentries will not be hashed, they are linked together on the |
| 65 | d_hash list_head. |
| 66 | |
| 67 | c/ Helper routines to allocate anonymous dentries, and to help attach |
| 68 | loose directory dentries at lookup time. They are: |
| 69 | d_alloc_anon(inode) will return a dentry for the given inode. |
| 70 | If the inode already has a dentry, one of those is returned. |
| 71 | If it doesn't, a new anonymous (IS_ROOT and |
| 72 | DCACHE_DISCONNECTED) dentry is allocated and attached. |
| 73 | In the case of a directory, care is taken that only one dentry |
| 74 | can ever be attached. |
| 75 | d_splice_alias(inode, dentry) will make sure that there is a |
| 76 | dentry with the same name and parent as the given dentry, and |
| 77 | which refers to the given inode. |
| 78 | If the inode is a directory and already has a dentry, then that |
| 79 | dentry is d_moved over the given dentry. |
| 80 | If the passed dentry gets attached, care is taken that this is |
| 81 | mutually exclusive to a d_alloc_anon operation. |
| 82 | If the passed dentry is used, NULL is returned, else the used |
| 83 | dentry is returned. This corresponds to the calling pattern of |
| 84 | ->lookup. |
| 85 | |
| 86 | |
| 87 | Filesystem Issues |
| 88 | ----------------- |
| 89 | |
| 90 | For a filesystem to be exportable it must: |
| 91 | |
| 92 | 1/ provide the filehandle fragment routines described below. |
| 93 | 2/ make sure that d_splice_alias is used rather than d_add |
| 94 | when ->lookup finds an inode for a given parent and name. |
Christoph Hellwig | e38f981 | 2007-10-21 16:42:19 -0700 | [diff] [blame] | 95 | Typically the ->lookup routine will end with a: |
| 96 | |
| 97 | return d_splice_alias(inode, dentry); |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 98 | } |
| 99 | |
| 100 | |
| 101 | |
| 102 | A file system implementation declares that instances of the filesystem |
| 103 | are exportable by setting the s_export_op field in the struct |
| 104 | super_block. This field must point to a "struct export_operations" |
Christoph Hellwig | e38f981 | 2007-10-21 16:42:19 -0700 | [diff] [blame] | 105 | struct which has the following members: |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 106 | |
Christoph Hellwig | e38f981 | 2007-10-21 16:42:19 -0700 | [diff] [blame] | 107 | encode_fh (optional) |
| 108 | Takes a dentry and creates a filehandle fragment which can later be used |
| 109 | to find or create a dentry for the same object. The default |
| 110 | implementation creates a filehandle fragment that encodes a 32bit inode |
| 111 | and generation number for the inode encoded, and if necessary the |
| 112 | same information for the parent. |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 113 | |
Christoph Hellwig | e38f981 | 2007-10-21 16:42:19 -0700 | [diff] [blame] | 114 | fh_to_dentry (mandatory) |
| 115 | Given a filehandle fragment, this should find the implied object and |
| 116 | create a dentry for it (possibly with d_alloc_anon). |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 117 | |
Christoph Hellwig | e38f981 | 2007-10-21 16:42:19 -0700 | [diff] [blame] | 118 | fh_to_parent (optional but strongly recommended) |
| 119 | Given a filehandle fragment, this should find the parent of the |
| 120 | implied object and create a dentry for it (possibly with d_alloc_anon). |
| 121 | May fail if the filehandle fragment is too small. |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 122 | |
Christoph Hellwig | e38f981 | 2007-10-21 16:42:19 -0700 | [diff] [blame] | 123 | get_parent (optional but strongly recommended) |
| 124 | When given a dentry for a directory, this should return a dentry for |
| 125 | the parent. Quite possibly the parent dentry will have been allocated |
| 126 | by d_alloc_anon. The default get_parent function just returns an error |
| 127 | so any filehandle lookup that requires finding a parent will fail. |
| 128 | ->lookup("..") is *not* used as a default as it can leave ".." entries |
| 129 | in the dcache which are too messy to work with. |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 130 | |
Christoph Hellwig | e38f981 | 2007-10-21 16:42:19 -0700 | [diff] [blame] | 131 | get_name (optional) |
| 132 | When given a parent dentry and a child dentry, this should find a name |
| 133 | in the directory identified by the parent dentry, which leads to the |
| 134 | object identified by the child dentry. If no get_name function is |
| 135 | supplied, a default implementation is provided which uses vfs_readdir |
| 136 | to find potential names, and matches inode numbers to find the correct |
| 137 | match. |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 138 | |
| 139 | |
| 140 | A filehandle fragment consists of an array of 1 or more 4byte words, |
| 141 | together with a one byte "type". |
| 142 | The decode_fh routine should not depend on the stated size that is |
| 143 | passed to it. This size may be larger than the original filehandle |
| 144 | generated by encode_fh, in which case it will have been padded with |
| 145 | nuls. Rather, the encode_fh routine should choose a "type" which |
| 146 | indicates the decode_fh how much of the filehandle is valid, and how |
| 147 | it should be interpreted. |