Merge branch 'stable-fodder' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[sfrench/cifs-2.6.git] / Documentation / filesystems / porting
index a60fa516d4cbb1eacdd00cae0008645c10d403cf..d392d4b0c39327d0609f8248a125c74e04b5d82e 100644 (file)
@@ -639,6 +639,31 @@ in your dentry operations instead.
        d_add(dentry, NULL); return NULL;), so that kind of special cases
        also doesn't need a separate treatment.
 --
+[strongly recommended]
+       take the RCU-delayed parts of ->destroy_inode() into a new method -
+       ->free_inode().  If ->destroy_inode() becomes empty - all the better,
+       just get rid of it.  Synchronous work (e.g. the stuff that can't
+       be done from an RCU callback, or any WARN_ON() where we want the
+       stack trace) *might* be movable to ->evict_inode(); however,
+       that goes only for the things that are not needed to balance something
+       done by ->alloc_inode().  IOW, if it's cleaning up the stuff that
+       might have accumulated over the life of in-core inode, ->evict_inode()
+       might be a fit.
+
+       Rules for inode destruction:
+               * if ->destroy_inode() is non-NULL, it gets called
+               * if ->free_inode() is non-NULL, it gets scheduled by call_rcu()
+               * combination of NULL ->destroy_inode and NULL ->free_inode is
+                 treated as NULL/free_inode_nonrcu, to preserve the compatibility.
+
+       Note that the callback (be it via ->free_inode() or explicit call_rcu()
+       in ->destroy_inode()) is *NOT* ordered wrt superblock destruction;
+       as the matter of fact, the superblock and all associated structures
+       might be already gone.  The filesystem driver is guaranteed to be still
+       there, but that's it.  Freeing memory in the callback is fine; doing
+       more than that is possible, but requires a lot of care and is best
+       avoided.
+--
 [mandatory]
        DCACHE_RCUACCESS is gone; having an RCU delay on dentry freeing is the
        default.  DCACHE_NORCU opts out, and only d_alloc_pseudo() has any