Back to home page

OSCL-LXR

 
 

    


0001 
0002         JFFS2 LOCKING DOCUMENTATION
0003         ---------------------------
0004 
0005 This document attempts to describe the existing locking rules for
0006 JFFS2. It is not expected to remain perfectly up to date, but ought to
0007 be fairly close.
0008 
0009 
0010         alloc_sem
0011         ---------
0012 
0013 The alloc_sem is a per-filesystem mutex, used primarily to ensure
0014 contiguous allocation of space on the medium. It is automatically
0015 obtained during space allocations (jffs2_reserve_space()) and freed
0016 upon write completion (jffs2_complete_reservation()). Note that
0017 the garbage collector will obtain this right at the beginning of
0018 jffs2_garbage_collect_pass() and release it at the end, thereby
0019 preventing any other write activity on the file system during a
0020 garbage collect pass.
0021 
0022 When writing new nodes, the alloc_sem must be held until the new nodes
0023 have been properly linked into the data structures for the inode to
0024 which they belong. This is for the benefit of NAND flash - adding new
0025 nodes to an inode may obsolete old ones, and by holding the alloc_sem
0026 until this happens we ensure that any data in the write-buffer at the
0027 time this happens are part of the new node, not just something that
0028 was written afterwards. Hence, we can ensure the newly-obsoleted nodes
0029 don't actually get erased until the write-buffer has been flushed to
0030 the medium.
0031 
0032 With the introduction of NAND flash support and the write-buffer, 
0033 the alloc_sem is also used to protect the wbuf-related members of the
0034 jffs2_sb_info structure. Atomically reading the wbuf_len member to see
0035 if the wbuf is currently holding any data is permitted, though.
0036 
0037 Ordering constraints: See f->sem.
0038 
0039 
0040         File Mutex f->sem
0041         ---------------------
0042 
0043 This is the JFFS2-internal equivalent of the inode mutex i->i_sem.
0044 It protects the contents of the jffs2_inode_info private inode data,
0045 including the linked list of node fragments (but see the notes below on
0046 erase_completion_lock), etc.
0047 
0048 The reason that the i_sem itself isn't used for this purpose is to
0049 avoid deadlocks with garbage collection -- the VFS will lock the i_sem
0050 before calling a function which may need to allocate space. The
0051 allocation may trigger garbage-collection, which may need to move a
0052 node belonging to the inode which was locked in the first place by the
0053 VFS. If the garbage collection code were to attempt to lock the i_sem
0054 of the inode from which it's garbage-collecting a physical node, this
0055 lead to deadlock, unless we played games with unlocking the i_sem
0056 before calling the space allocation functions.
0057 
0058 Instead of playing such games, we just have an extra internal
0059 mutex, which is obtained by the garbage collection code and also
0060 by the normal file system code _after_ allocation of space.
0061 
0062 Ordering constraints: 
0063 
0064         1. Never attempt to allocate space or lock alloc_sem with 
0065            any f->sem held.
0066         2. Never attempt to lock two file mutexes in one thread.
0067            No ordering rules have been made for doing so.
0068         3. Never lock a page cache page with f->sem held.
0069 
0070 
0071         erase_completion_lock spinlock
0072         ------------------------------
0073 
0074 This is used to serialise access to the eraseblock lists, to the
0075 per-eraseblock lists of physical jffs2_raw_node_ref structures, and
0076 (NB) the per-inode list of physical nodes. The latter is a special
0077 case - see below.
0078 
0079 As the MTD API no longer permits erase-completion callback functions
0080 to be called from bottom-half (timer) context (on the basis that nobody
0081 ever actually implemented such a thing), it's now sufficient to use
0082 a simple spin_lock() rather than spin_lock_bh().
0083 
0084 Note that the per-inode list of physical nodes (f->nodes) is a special
0085 case. Any changes to _valid_ nodes (i.e. ->flash_offset & 1 == 0) in
0086 the list are protected by the file mutex f->sem. But the erase code
0087 may remove _obsolete_ nodes from the list while holding only the
0088 erase_completion_lock. So you can walk the list only while holding the
0089 erase_completion_lock, and can drop the lock temporarily mid-walk as
0090 long as the pointer you're holding is to a _valid_ node, not an
0091 obsolete one.
0092 
0093 The erase_completion_lock is also used to protect the c->gc_task
0094 pointer when the garbage collection thread exits. The code to kill the
0095 GC thread locks it, sends the signal, then unlocks it - while the GC
0096 thread itself locks it, zeroes c->gc_task, then unlocks on the exit path.
0097 
0098 
0099         inocache_lock spinlock
0100         ----------------------
0101 
0102 This spinlock protects the hashed list (c->inocache_list) of the
0103 in-core jffs2_inode_cache objects (each inode in JFFS2 has the
0104 correspondent jffs2_inode_cache object). So, the inocache_lock
0105 has to be locked while walking the c->inocache_list hash buckets.
0106 
0107 This spinlock also covers allocation of new inode numbers, which is
0108 currently just '++->highest_ino++', but might one day get more complicated
0109 if we need to deal with wrapping after 4 milliard inode numbers are used.
0110 
0111 Note, the f->sem guarantees that the correspondent jffs2_inode_cache
0112 will not be removed. So, it is allowed to access it without locking
0113 the inocache_lock spinlock. 
0114 
0115 Ordering constraints: 
0116 
0117         If both erase_completion_lock and inocache_lock are needed, the
0118         c->erase_completion has to be acquired first.
0119 
0120 
0121         erase_free_sem
0122         --------------
0123 
0124 This mutex is only used by the erase code which frees obsolete node
0125 references and the jffs2_garbage_collect_deletion_dirent() function.
0126 The latter function on NAND flash must read _obsolete_ nodes to
0127 determine whether the 'deletion dirent' under consideration can be
0128 discarded or whether it is still required to show that an inode has
0129 been unlinked. Because reading from the flash may sleep, the
0130 erase_completion_lock cannot be held, so an alternative, more
0131 heavyweight lock was required to prevent the erase code from freeing
0132 the jffs2_raw_node_ref structures in question while the garbage
0133 collection code is looking at them.
0134 
0135 Suggestions for alternative solutions to this problem would be welcomed.
0136 
0137 
0138         wbuf_sem
0139         --------
0140 
0141 This read/write semaphore protects against concurrent access to the
0142 write-behind buffer ('wbuf') used for flash chips where we must write
0143 in blocks. It protects both the contents of the wbuf and the metadata
0144 which indicates which flash region (if any) is currently covered by 
0145 the buffer.
0146 
0147 Ordering constraints:
0148         Lock wbuf_sem last, after the alloc_sem or and f->sem.
0149 
0150 
0151         c->xattr_sem
0152         ------------
0153 
0154 This read/write semaphore protects against concurrent access to the
0155 xattr related objects which include stuff in superblock and ic->xref.
0156 In read-only path, write-semaphore is too much exclusion. It's enough
0157 by read-semaphore. But you must hold write-semaphore when updating,
0158 creating or deleting any xattr related object.
0159 
0160 Once xattr_sem released, there would be no assurance for the existence
0161 of those objects. Thus, a series of processes is often required to retry,
0162 when updating such a object is necessary under holding read semaphore.
0163 For example, do_jffs2_getxattr() holds read-semaphore to scan xref and
0164 xdatum at first. But it retries this process with holding write-semaphore
0165 after release read-semaphore, if it's necessary to load name/value pair
0166 from medium.
0167 
0168 Ordering constraints:
0169         Lock xattr_sem last, after the alloc_sem.