annotate fs/jffs2/README.Locking @ 524:7f8b544237bf

netfront: Allow netfront in domain 0.

This is useful if your physical network device is in a utility domain.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Apr 15 15:18:58 2008 +0100 (2008-04-15)
parents 831230e53067
rev   line source
ian@0 1 $Id: README.Locking,v 1.12 2005/04/13 13:22:35 dwmw2 Exp $
ian@0 2
ian@0 4 ---------------------------
ian@0 5
ian@0 6 At least theoretically, JFFS2 does not require the Big Kernel Lock
ian@0 7 (BKL), which was always helpfully obtained for it by Linux 2.4 VFS
ian@0 8 code. It has its own locking, as described below.
ian@0 9
ian@0 10 This document attempts to describe the existing locking rules for
ian@0 11 JFFS2. It is not expected to remain perfectly up to date, but ought to
ian@0 12 be fairly close.
ian@0 13
ian@0 14
ian@0 15 alloc_sem
ian@0 16 ---------
ian@0 17
ian@0 18 The alloc_sem is a per-filesystem semaphore, used primarily to ensure
ian@0 19 contiguous allocation of space on the medium. It is automatically
ian@0 20 obtained during space allocations (jffs2_reserve_space()) and freed
ian@0 21 upon write completion (jffs2_complete_reservation()). Note that
ian@0 22 the garbage collector will obtain this right at the beginning of
ian@0 23 jffs2_garbage_collect_pass() and release it at the end, thereby
ian@0 24 preventing any other write activity on the file system during a
ian@0 25 garbage collect pass.
ian@0 26
ian@0 27 When writing new nodes, the alloc_sem must be held until the new nodes
ian@0 28 have been properly linked into the data structures for the inode to
ian@0 29 which they belong. This is for the benefit of NAND flash - adding new
ian@0 30 nodes to an inode may obsolete old ones, and by holding the alloc_sem
ian@0 31 until this happens we ensure that any data in the write-buffer at the
ian@0 32 time this happens are part of the new node, not just something that
ian@0 33 was written afterwards. Hence, we can ensure the newly-obsoleted nodes
ian@0 34 don't actually get erased until the write-buffer has been flushed to
ian@0 35 the medium.
ian@0 36
ian@0 37 With the introduction of NAND flash support and the write-buffer,
ian@0 38 the alloc_sem is also used to protect the wbuf-related members of the
ian@0 39 jffs2_sb_info structure. Atomically reading the wbuf_len member to see
ian@0 40 if the wbuf is currently holding any data is permitted, though.
ian@0 41
ian@0 42 Ordering constraints: See f->sem.
ian@0 43
ian@0 44
ian@0 45 File Semaphore f->sem
ian@0 46 ---------------------
ian@0 47
ian@0 48 This is the JFFS2-internal equivalent of the inode semaphore i->i_sem.
ian@0 49 It protects the contents of the jffs2_inode_info private inode data,
ian@0 50 including the linked list of node fragments (but see the notes below on
ian@0 51 erase_completion_lock), etc.
ian@0 52
ian@0 53 The reason that the i_sem itself isn't used for this purpose is to
ian@0 54 avoid deadlocks with garbage collection -- the VFS will lock the i_sem
ian@0 55 before calling a function which may need to allocate space. The
ian@0 56 allocation may trigger garbage-collection, which may need to move a
ian@0 57 node belonging to the inode which was locked in the first place by the
ian@0 58 VFS. If the garbage collection code were to attempt to lock the i_sem
ian@0 59 of the inode from which it's garbage-collecting a physical node, this
ian@0 60 lead to deadlock, unless we played games with unlocking the i_sem
ian@0 61 before calling the space allocation functions.
ian@0 62
ian@0 63 Instead of playing such games, we just have an extra internal
ian@0 64 semaphore, which is obtained by the garbage collection code and also
ian@0 65 by the normal file system code _after_ allocation of space.
ian@0 66
ian@0 67 Ordering constraints:
ian@0 68
ian@0 69 1. Never attempt to allocate space or lock alloc_sem with
ian@0 70 any f->sem held.
ian@0 71 2. Never attempt to lock two file semaphores in one thread.
ian@0 72 No ordering rules have been made for doing so.
ian@0 73
ian@0 74
ian@0 75 erase_completion_lock spinlock
ian@0 76 ------------------------------
ian@0 77
ian@0 78 This is used to serialise access to the eraseblock lists, to the
ian@0 79 per-eraseblock lists of physical jffs2_raw_node_ref structures, and
ian@0 80 (NB) the per-inode list of physical nodes. The latter is a special
ian@0 81 case - see below.
ian@0 82
ian@0 83 As the MTD API no longer permits erase-completion callback functions
ian@0 84 to be called from bottom-half (timer) context (on the basis that nobody
ian@0 85 ever actually implemented such a thing), it's now sufficient to use
ian@0 86 a simple spin_lock() rather than spin_lock_bh().
ian@0 87
ian@0 88 Note that the per-inode list of physical nodes (f->nodes) is a special
ian@0 89 case. Any changes to _valid_ nodes (i.e. ->flash_offset & 1 == 0) in
ian@0 90 the list are protected by the file semaphore f->sem. But the erase
ian@0 91 code may remove _obsolete_ nodes from the list while holding only the
ian@0 92 erase_completion_lock. So you can walk the list only while holding the
ian@0 93 erase_completion_lock, and can drop the lock temporarily mid-walk as
ian@0 94 long as the pointer you're holding is to a _valid_ node, not an
ian@0 95 obsolete one.
ian@0 96
ian@0 97 The erase_completion_lock is also used to protect the c->gc_task
ian@0 98 pointer when the garbage collection thread exits. The code to kill the
ian@0 99 GC thread locks it, sends the signal, then unlocks it - while the GC
ian@0 100 thread itself locks it, zeroes c->gc_task, then unlocks on the exit path.
ian@0 101
ian@0 102
ian@0 103 inocache_lock spinlock
ian@0 104 ----------------------
ian@0 105
ian@0 106 This spinlock protects the hashed list (c->inocache_list) of the
ian@0 107 in-core jffs2_inode_cache objects (each inode in JFFS2 has the
ian@0 108 correspondent jffs2_inode_cache object). So, the inocache_lock
ian@0 109 has to be locked while walking the c->inocache_list hash buckets.
ian@0 110
ian@0 111 This spinlock also covers allocation of new inode numbers, which is
ian@0 112 currently just '++->highest_ino++', but might one day get more complicated
ian@0 113 if we need to deal with wrapping after 4 milliard inode numbers are used.
ian@0 114
ian@0 115 Note, the f->sem guarantees that the correspondent jffs2_inode_cache
ian@0 116 will not be removed. So, it is allowed to access it without locking
ian@0 117 the inocache_lock spinlock.
ian@0 118
ian@0 119 Ordering constraints:
ian@0 120
ian@0 121 If both erase_completion_lock and inocache_lock are needed, the
ian@0 122 c->erase_completion has to be acquired first.
ian@0 123
ian@0 124
ian@0 125 erase_free_sem
ian@0 126 --------------
ian@0 127
ian@0 128 This semaphore is only used by the erase code which frees obsolete
ian@0 129 node references and the jffs2_garbage_collect_deletion_dirent()
ian@0 130 function. The latter function on NAND flash must read _obsolete_ nodes
ian@0 131 to determine whether the 'deletion dirent' under consideration can be
ian@0 132 discarded or whether it is still required to show that an inode has
ian@0 133 been unlinked. Because reading from the flash may sleep, the
ian@0 134 erase_completion_lock cannot be held, so an alternative, more
ian@0 135 heavyweight lock was required to prevent the erase code from freeing
ian@0 136 the jffs2_raw_node_ref structures in question while the garbage
ian@0 137 collection code is looking at them.
ian@0 138
ian@0 139 Suggestions for alternative solutions to this problem would be welcomed.
ian@0 140
ian@0 141
ian@0 142 wbuf_sem
ian@0 143 --------
ian@0 144
ian@0 145 This read/write semaphore protects against concurrent access to the
ian@0 146 write-behind buffer ('wbuf') used for flash chips where we must write
ian@0 147 in blocks. It protects both the contents of the wbuf and the metadata
ian@0 148 which indicates which flash region (if any) is currently covered by
ian@0 149 the buffer.
ian@0 150
ian@0 151 Ordering constraints:
ian@0 152 Lock wbuf_sem last, after the alloc_sem or and f->sem.
ian@0 153
ian@0 154
ian@0 155 c->xattr_sem
ian@0 156 ------------
ian@0 157
ian@0 158 This read/write semaphore protects against concurrent access to the
ian@0 159 xattr related objects which include stuff in superblock and ic->xref.
ian@0 160 In read-only path, write-semaphore is too much exclusion. It's enough
ian@0 161 by read-semaphore. But you must hold write-semaphore when updating,
ian@0 162 creating or deleting any xattr related object.
ian@0 163
ian@0 164 Once xattr_sem released, there would be no assurance for the existence
ian@0 165 of those objects. Thus, a series of processes is often required to retry,
ian@0 166 when updating such a object is necessary under holding read semaphore.
ian@0 167 For example, do_jffs2_getxattr() holds read-semaphore to scan xref and
ian@0 168 xdatum at first. But it retries this process with holding write-semaphore
ian@0 169 after release read-semaphore, if it's necessary to load name/value pair
ian@0 170 from medium.
ian@0 171
ian@0 172 Ordering constraints:
ian@0 173 Lock xattr_sem last, after the alloc_sem.