diff options
Diffstat (limited to 'ANDROID_3.4.5/fs/jffs2/README.Locking')
-rw-r--r-- | ANDROID_3.4.5/fs/jffs2/README.Locking | 172 |
1 files changed, 0 insertions, 172 deletions
diff --git a/ANDROID_3.4.5/fs/jffs2/README.Locking b/ANDROID_3.4.5/fs/jffs2/README.Locking deleted file mode 100644 index 3ea36554..00000000 --- a/ANDROID_3.4.5/fs/jffs2/README.Locking +++ /dev/null @@ -1,172 +0,0 @@ - - JFFS2 LOCKING DOCUMENTATION - --------------------------- - -At least theoretically, JFFS2 does not require the Big Kernel Lock -(BKL), which was always helpfully obtained for it by Linux 2.4 VFS -code. It has its own locking, as described below. - -This document attempts to describe the existing locking rules for -JFFS2. It is not expected to remain perfectly up to date, but ought to -be fairly close. - - - alloc_sem - --------- - -The alloc_sem is a per-filesystem mutex, used primarily to ensure -contiguous allocation of space on the medium. It is automatically -obtained during space allocations (jffs2_reserve_space()) and freed -upon write completion (jffs2_complete_reservation()). Note that -the garbage collector will obtain this right at the beginning of -jffs2_garbage_collect_pass() and release it at the end, thereby -preventing any other write activity on the file system during a -garbage collect pass. - -When writing new nodes, the alloc_sem must be held until the new nodes -have been properly linked into the data structures for the inode to -which they belong. This is for the benefit of NAND flash - adding new -nodes to an inode may obsolete old ones, and by holding the alloc_sem -until this happens we ensure that any data in the write-buffer at the -time this happens are part of the new node, not just something that -was written afterwards. Hence, we can ensure the newly-obsoleted nodes -don't actually get erased until the write-buffer has been flushed to -the medium. - -With the introduction of NAND flash support and the write-buffer, -the alloc_sem is also used to protect the wbuf-related members of the -jffs2_sb_info structure. Atomically reading the wbuf_len member to see -if the wbuf is currently holding any data is permitted, though. - -Ordering constraints: See f->sem. - - - File Mutex f->sem - --------------------- - -This is the JFFS2-internal equivalent of the inode mutex i->i_sem. -It protects the contents of the jffs2_inode_info private inode data, -including the linked list of node fragments (but see the notes below on -erase_completion_lock), etc. - -The reason that the i_sem itself isn't used for this purpose is to -avoid deadlocks with garbage collection -- the VFS will lock the i_sem -before calling a function which may need to allocate space. The -allocation may trigger garbage-collection, which may need to move a -node belonging to the inode which was locked in the first place by the -VFS. If the garbage collection code were to attempt to lock the i_sem -of the inode from which it's garbage-collecting a physical node, this -lead to deadlock, unless we played games with unlocking the i_sem -before calling the space allocation functions. - -Instead of playing such games, we just have an extra internal -mutex, which is obtained by the garbage collection code and also -by the normal file system code _after_ allocation of space. - -Ordering constraints: - - 1. Never attempt to allocate space or lock alloc_sem with - any f->sem held. - 2. Never attempt to lock two file mutexes in one thread. - No ordering rules have been made for doing so. - - - erase_completion_lock spinlock - ------------------------------ - -This is used to serialise access to the eraseblock lists, to the -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 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 -the list are protected by the file mutex f->sem. But the erase code -may remove _obsolete_ nodes from the list while holding only the -erase_completion_lock. So you can walk the list only while holding the -erase_completion_lock, and can drop the lock temporarily mid-walk as -long as the pointer you're holding is to a _valid_ node, not an -obsolete one. - -The erase_completion_lock is also used to protect the c->gc_task -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. - - - 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 mutex is only used by the erase code which frees obsolete node -references and the jffs2_garbage_collect_deletion_dirent() function. -The latter function on NAND flash must read _obsolete_ nodes to -determine whether the 'deletion dirent' under consideration can be -discarded or whether it is still required to show that an inode has -been unlinked. Because reading from the flash may sleep, the -erase_completion_lock cannot be held, so an alternative, more -heavyweight lock was required to prevent the erase code from freeing -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. |