- $Id: README.Locking,v 1.4 2002/03/08 16:20:06 dwmw2 Exp $
+ $Id: README.Locking,v 1.12 2005/04/13 13:22:35 dwmw2 Exp $
JFFS2 LOCKING DOCUMENTATION
---------------------------
(NB) the per-inode list of physical nodes. The latter is a special
case - see below.
-As the MTD API permits erase-completion callback functions to be
-called from bottom-half (timer) context, and these functions access
-the data structures protected by this lock, it must be locked with
-spin_lock_bh().
+As the MTD API no longer permits erase-completion callback functions
+to be called from bottom-half (timer) context (on the basis that nobody
+ever actually implemented such a thing), it's now sufficient to use
+a simple spin_lock() rather than spin_lock_bh().
Note that the per-inode list of physical nodes (f->nodes) is a special
case. Any changes to _valid_ nodes (i.e. ->flash_offset & 1 == 0) in
GC thread locks it, sends the signal, then unlocks it - while the GC
thread itself locks it, zeroes c->gc_task, then unlocks on the exit path.
- node_free_sem
- -------------
+
+ inocache_lock spinlock
+ ----------------------
+
+This spinlock protects the hashed list (c->inocache_list) of the
+in-core jffs2_inode_cache objects (each inode in JFFS2 has the
+correspondent jffs2_inode_cache object). So, the inocache_lock
+has to be locked while walking the c->inocache_list hash buckets.
+
+This spinlock also covers allocation of new inode numbers, which is
+currently just '++->highest_ino++', but might one day get more complicated
+if we need to deal with wrapping after 4 milliard inode numbers are used.
+
+Note, the f->sem guarantees that the correspondent jffs2_inode_cache
+will not be removed. So, it is allowed to access it without locking
+the inocache_lock spinlock.
+
+Ordering constraints:
+
+ If both erase_completion_lock and inocache_lock are needed, the
+ c->erase_completion has to be acquired first.
+
+
+ erase_free_sem
+ --------------
This semaphore is only used by the erase code which frees obsolete
node references and the jffs2_garbage_collect_deletion_dirent()
collection code is looking at them.
Suggestions for alternative solutions to this problem would be welcomed.
+
+
+ wbuf_sem
+ --------
+
+This read/write semaphore protects against concurrent access to the
+write-behind buffer ('wbuf') used for flash chips where we must write
+in blocks. It protects both the contents of the wbuf and the metadata
+which indicates which flash region (if any) is currently covered by
+the buffer.
+
+Ordering constraints:
+ Lock wbuf_sem last, after the alloc_sem or and f->sem.
+
+
+ c->xattr_sem
+ ------------
+
+This read/write semaphore protects against concurrent access to the
+xattr related objects which include stuff in superblock and ic->xref.
+In read-only path, write-semaphore is too much exclusion. It's enough
+by read-semaphore. But you must hold write-semaphore when updating,
+creating or deleting any xattr related object.
+
+Once xattr_sem released, there would be no assurance for the existence
+of those objects. Thus, a series of processes is often required to retry,
+when updating such a object is necessary under holding read semaphore.
+For example, do_jffs2_getxattr() holds read-semaphore to scan xref and
+xdatum at first. But it retries this process with holding write-semaphore
+after release read-semaphore, if it's necessary to load name/value pair
+from medium.
+
+Ordering constraints:
+ Lock xattr_sem last, after the alloc_sem.