fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / fs / jffs2 / README.Locking
index 72dbcea..c8f0bd6 100644 (file)
@@ -1,4 +1,4 @@
-       $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
        ---------------------------
@@ -80,10 +80,10 @@ per-eraseblock lists of physical jffs2_raw_node_ref structures, and
 (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
@@ -99,8 +99,31 @@ pointer when the garbage collection thread exits. The code to kill the
 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()
@@ -114,3 +137,37 @@ the jffs2_raw_node_ref structures in question while the garbage
 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.