diff options
| author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-09 20:31:38 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-09 20:31:38 -0500 |
| commit | 80c0531514516e43ae118ddf38424e06e5c3cb3c (patch) | |
| tree | 2eef8cf8fdf505b18f83078d1eb41167e98f5b54 | |
| parent | a457aa6c2bdd743bbbffd3f9e4fdbd8c71f8af1b (diff) | |
| parent | 11b751ae8c8ca3fa24c85bd5a3e51dd9f95cda17 (diff) | |
Merge master.kernel.org:/pub/scm/linux/kernel/git/mingo/mutex-2.6
198 files changed, 2754 insertions, 649 deletions
diff --git a/Documentation/DocBook/kernel-locking.tmpl b/Documentation/DocBook/kernel-locking.tmpl index 90dc2de8e0af..158ffe9bfade 100644 --- a/Documentation/DocBook/kernel-locking.tmpl +++ b/Documentation/DocBook/kernel-locking.tmpl | |||
| @@ -222,7 +222,7 @@ | |||
| 222 | <title>Two Main Types of Kernel Locks: Spinlocks and Semaphores</title> | 222 | <title>Two Main Types of Kernel Locks: Spinlocks and Semaphores</title> |
| 223 | 223 | ||
| 224 | <para> | 224 | <para> |
| 225 | There are two main types of kernel locks. The fundamental type | 225 | There are three main types of kernel locks. The fundamental type |
| 226 | is the spinlock | 226 | is the spinlock |
| 227 | (<filename class="headerfile">include/asm/spinlock.h</filename>), | 227 | (<filename class="headerfile">include/asm/spinlock.h</filename>), |
| 228 | which is a very simple single-holder lock: if you can't get the | 228 | which is a very simple single-holder lock: if you can't get the |
| @@ -230,16 +230,22 @@ | |||
| 230 | very small and fast, and can be used anywhere. | 230 | very small and fast, and can be used anywhere. |
| 231 | </para> | 231 | </para> |
| 232 | <para> | 232 | <para> |
| 233 | The second type is a semaphore | 233 | The second type is a mutex |
| 234 | (<filename class="headerfile">include/linux/mutex.h</filename>): it | ||
| 235 | is like a spinlock, but you may block holding a mutex. | ||
| 236 | If you can't lock a mutex, your task will suspend itself, and be woken | ||
| 237 | up when the mutex is released. This means the CPU can do something | ||
| 238 | else while you are waiting. There are many cases when you simply | ||
| 239 | can't sleep (see <xref linkend="sleeping-things"/>), and so have to | ||
| 240 | use a spinlock instead. | ||
| 241 | </para> | ||
| 242 | <para> | ||
| 243 | The third type is a semaphore | ||
| 234 | (<filename class="headerfile">include/asm/semaphore.h</filename>): it | 244 | (<filename class="headerfile">include/asm/semaphore.h</filename>): it |
| 235 | can have more than one holder at any time (the number decided at | 245 | can have more than one holder at any time (the number decided at |
| 236 | initialization time), although it is most commonly used as a | 246 | initialization time), although it is most commonly used as a |
| 237 | single-holder lock (a mutex). If you can't get a semaphore, | 247 | single-holder lock (a mutex). If you can't get a semaphore, your |
| 238 | your task will put itself on the queue, and be woken up when the | 248 | task will be suspended and later on woken up - just like for mutexes. |
| 239 | semaphore is released. This means the CPU will do something | ||
| 240 | else while you are waiting, but there are many cases when you | ||
| 241 | simply can't sleep (see <xref linkend="sleeping-things"/>), and so | ||
| 242 | have to use a spinlock instead. | ||
| 243 | </para> | 249 | </para> |
| 244 | <para> | 250 | <para> |
| 245 | Neither type of lock is recursive: see | 251 | Neither type of lock is recursive: see |
diff --git a/Documentation/mutex-design.txt b/Documentation/mutex-design.txt new file mode 100644 index 000000000000..cbf79881a41c --- /dev/null +++ b/Documentation/mutex-design.txt | |||
| @@ -0,0 +1,135 @@ | |||
| 1 | Generic Mutex Subsystem | ||
| 2 | |||
| 3 | started by Ingo Molnar <mingo@redhat.com> | ||
| 4 | |||
| 5 | "Why on earth do we need a new mutex subsystem, and what's wrong | ||
| 6 | with semaphores?" | ||
| 7 | |||
| 8 | firstly, there's nothing wrong with semaphores. But if the simpler | ||
| 9 | mutex semantics are sufficient for your code, then there are a couple | ||
| 10 | of advantages of mutexes: | ||
| 11 | |||
| 12 | - 'struct mutex' is smaller on most architectures: .e.g on x86, | ||
| 13 | 'struct semaphore' is 20 bytes, 'struct mutex' is 16 bytes. | ||
| 14 | A smaller structure size means less RAM footprint, and better | ||
| 15 | CPU-cache utilization. | ||
| 16 | |||
| 17 | - tighter code. On x86 i get the following .text sizes when | ||
| 18 | switching all mutex-alike semaphores in the kernel to the mutex | ||
| 19 | subsystem: | ||
| 20 | |||
| 21 | text data bss dec hex filename | ||
| 22 | 3280380 868188 396860 4545428 455b94 vmlinux-semaphore | ||
| 23 | 3255329 865296 396732 4517357 44eded vmlinux-mutex | ||
| 24 | |||
| 25 | that's 25051 bytes of code saved, or a 0.76% win - off the hottest | ||
| 26 | codepaths of the kernel. (The .data savings are 2892 bytes, or 0.33%) | ||
| 27 | Smaller code means better icache footprint, which is one of the | ||
| 28 | major optimization goals in the Linux kernel currently. | ||
| 29 | |||
| 30 | - the mutex subsystem is slightly faster and has better scalability for | ||
| 31 | contended workloads. On an 8-way x86 system, running a mutex-based | ||
| 32 | kernel and testing creat+unlink+close (of separate, per-task files) | ||
| 33 | in /tmp with 16 parallel tasks, the average number of ops/sec is: | ||
| 34 | |||
| 35 | Semaphores: Mutexes: | ||
| 36 | |||
| 37 | $ ./test-mutex V 16 10 $ ./test-mutex V 16 10 | ||
| 38 | 8 CPUs, running 16 tasks. 8 CPUs, running 16 tasks. | ||
| 39 | checking VFS performance. checking VFS performance. | ||
| 40 | avg loops/sec: 34713 avg loops/sec: 84153 | ||
| 41 | CPU utilization: 63% CPU utilization: 22% | ||
| 42 | |||
| 43 | i.e. in this workload, the mutex based kernel was 2.4 times faster | ||
| 44 | than the semaphore based kernel, _and_ it also had 2.8 times less CPU | ||
| 45 | utilization. (In terms of 'ops per CPU cycle', the semaphore kernel | ||
| 46 | performed 551 ops/sec per 1% of CPU time used, while the mutex kernel | ||
| 47 | performed 3825 ops/sec per 1% of CPU time used - it was 6.9 times | ||
| 48 | more efficient.) | ||
| 49 | |||
| 50 | the scalability difference is visible even on a 2-way P4 HT box: | ||
| 51 | |||
| 52 | Semaphores: Mutexes: | ||
| 53 | |||
| 54 | $ ./test-mutex V 16 10 $ ./test-mutex V 16 10 | ||
| 55 | 4 CPUs, running 16 tasks. 8 CPUs, running 16 tasks. | ||
| 56 | checking VFS performance. checking VFS performance. | ||
| 57 | avg loops/sec: 127659 avg loops/sec: 181082 | ||
| 58 | CPU utilization: 100% CPU utilization: 34% | ||
| 59 | |||
| 60 | (the straight performance advantage of mutexes is 41%, the per-cycle | ||
| 61 | efficiency of mutexes is 4.1 times better.) | ||
| 62 | |||
| 63 | - there are no fastpath tradeoffs, the mutex fastpath is just as tight | ||
| 64 | as the semaphore fastpath. On x86, the locking fastpath is 2 | ||
| 65 | instructions: | ||
| 66 | |||
| 67 | c0377ccb <mutex_lock>: | ||
| 68 | c0377ccb: f0 ff 08 lock decl (%eax) | ||
| 69 | c0377cce: 78 0e js c0377cde <.text.lock.mutex> | ||
| 70 | c0377cd0: c3 ret | ||
| 71 | |||
| 72 | the unlocking fastpath is equally tight: | ||
| 73 | |||
| 74 | c0377cd1 <mutex_unlock>: | ||
| 75 | c0377cd1: f0 ff 00 lock incl (%eax) | ||
| 76 | c0377cd4: 7e 0f jle c0377ce5 <.text.lock.mutex+0x7> | ||
| 77 | c0377cd6: c3 ret | ||
| 78 | |||
| 79 | - 'struct mutex' semantics are well-defined and are enforced if | ||
| 80 | CONFIG_DEBUG_MUTEXES is turned on. Semaphores on the other hand have | ||
| 81 | virtually no debugging code or instrumentation. The mutex subsystem | ||
| 82 | checks and enforces the following rules: | ||
| 83 | |||
| 84 | * - only one task can hold the mutex at a time | ||
| 85 | * - only the owner can unlock the mutex | ||
| 86 | * - multiple unlocks are not permitted | ||
| 87 | * - recursive locking is not permitted | ||
| 88 | * - a mutex object must be initialized via the API | ||
| 89 | * - a mutex object must not be initialized via memset or copying | ||
| 90 | * - task may not exit with mutex held | ||
| 91 | * - memory areas where held locks reside must not be freed | ||
| 92 | * - held mutexes must not be reinitialized | ||
| 93 | * - mutexes may not be used in irq contexts | ||
| 94 | |||
| 95 | furthermore, there are also convenience features in the debugging | ||
| 96 | code: | ||
| 97 | |||
| 98 | * - uses symbolic names of mutexes, whenever they are printed in debug output | ||
| 99 | * - point-of-acquire tracking, symbolic lookup of function names | ||
| 100 | * - list of all locks held in the system, printout of them | ||
| 101 | * - owner tracking | ||
| 102 | * - detects self-recursing locks and prints out all relevant info | ||
| 103 | * - detects multi-task circular deadlocks and prints out all affected | ||
| 104 | * locks and tasks (and only those tasks) | ||
| 105 | |||
| 106 | Disadvantages | ||
| 107 | ------------- | ||
| 108 | |||
| 109 | The stricter mutex API means you cannot use mutexes the same way you | ||
| 110 | can use semaphores: e.g. they cannot be used from an interrupt context, | ||
| 111 | nor can they be unlocked from a different context that which acquired | ||
| 112 | it. [ I'm not aware of any other (e.g. performance) disadvantages from | ||
| 113 | using mutexes at the moment, please let me know if you find any. ] | ||
| 114 | |||
| 115 | Implementation of mutexes | ||
| 116 | ------------------------- | ||
| 117 | |||
| 118 | 'struct mutex' is the new mutex type, defined in include/linux/mutex.h | ||
| 119 | and implemented in kernel/mutex.c. It is a counter-based mutex with a | ||
| 120 | spinlock and a wait-list. The counter has 3 states: 1 for "unlocked", | ||
| 121 | 0 for "locked" and negative numbers (usually -1) for "locked, potential | ||
| 122 | waiters queued". | ||
| 123 | |||
| 124 | the APIs of 'struct mutex' have been streamlined: | ||
| 125 | |||
| 126 | DEFINE_MUTEX(name); | ||
| 127 | |||
| 128 | mutex_init(mutex); | ||
| 129 | |||
| 130 | void mutex_lock(struct mutex *lock); | ||
| 131 | int mutex_lock_interruptible(struct mutex *lock); | ||
| 132 | int mutex_trylock(struct mutex *lock); | ||
| 133 | void mutex_unlock(struct mutex *lock); | ||
| 134 | int mutex_is_locked(struct mutex *lock); | ||
| 135 | |||
diff --git a/arch/i386/mm/pageattr.c b/arch/i386/mm/pageattr.c index c30a16df6440..e8a53552b13d 100644 --- a/arch/i386/mm/pageattr.c +++ b/arch/i386/mm/pageattr.c | |||
| @@ -222,6 +222,10 @@ void kernel_map_pages(struct page *page, int numpages, int enable) | |||
| 222 | { | 222 | { |
| 223 | if (PageHighMem(page)) | 223 | if (PageHighMem(page)) |
| 224 | return; | 224 | return; |
| 225 | if (!enable) | ||
| 226 | mutex_debug_check_no_locks_freed(page_address(page), | ||
| 227 | page_address(page+numpages)); | ||
| 228 | |||
| 225 | /* the return value is ignored - the calls cannot fail, | 229 | /* the return value is ignored - the calls cannot fail, |
| 226 | * large pages are disabled at boot time. | 230 | * large pages are disabled at boot time. |
| 227 | */ | 231 | */ |
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 1f3507c75e90..d2ba358c6e38 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c | |||
| @@ -137,7 +137,7 @@ spufs_delete_inode(struct inode *inode) | |||
| 137 | static void spufs_prune_dir(struct dentry *dir) | 137 | static void spufs_prune_dir(struct dentry *dir) |
| 138 | { | 138 | { |
| 139 | struct dentry *dentry, *tmp; | 139 | struct dentry *dentry, *tmp; |
| 140 | down(&dir->d_inode->i_sem); | 140 | mutex_lock(&dir->d_inode->i_mutex); |
| 141 | list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_child) { | 141 | list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_child) { |
| 142 | spin_lock(&dcache_lock); | 142 | spin_lock(&dcache_lock); |
| 143 | spin_lock(&dentry->d_lock); | 143 | spin_lock(&dentry->d_lock); |
| @@ -154,7 +154,7 @@ static void spufs_prune_dir(struct dentry *dir) | |||
| 154 | } | 154 | } |
| 155 | } | 155 | } |
| 156 | shrink_dcache_parent(dir); | 156 | shrink_dcache_parent(dir); |
| 157 | up(&dir->d_inode->i_sem); | 157 | mutex_unlock(&dir->d_inode->i_mutex); |
| 158 | } | 158 | } |
| 159 | 159 | ||
| 160 | static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry) | 160 | static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry) |
| @@ -162,15 +162,15 @@ static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry) | |||
| 162 | struct spu_context *ctx; | 162 | struct spu_context *ctx; |
| 163 | 163 | ||
| 164 | /* remove all entries */ | 164 | /* remove all entries */ |
| 165 | down(&root->i_sem); | 165 | mutex_lock(&root->i_mutex); |
| 166 | spufs_prune_dir(dir_dentry); | 166 | spufs_prune_dir(dir_dentry); |
| 167 | up(&root->i_sem); | 167 | mutex_unlock(&root->i_mutex); |
| 168 | 168 | ||
| 169 | /* We have to give up the mm_struct */ | 169 | /* We have to give up the mm_struct */ |
| 170 | ctx = SPUFS_I(dir_dentry->d_inode)->i_ctx; | 170 | ctx = SPUFS_I(dir_dentry->d_inode)->i_ctx; |
| 171 | spu_forget(ctx); | 171 | spu_forget(ctx); |
| 172 | 172 | ||
| 173 | /* XXX Do we need to hold i_sem here ? */ | 173 | /* XXX Do we need to hold i_mutex here ? */ |
| 174 | return simple_rmdir(root, dir_dentry); | 174 | return simple_rmdir(root, dir_dentry); |
| 175 | } | 175 | } |
| 176 | 176 | ||
| @@ -330,7 +330,7 @@ long spufs_create_thread(struct nameidata *nd, | |||
| 330 | out_dput: | 330 | out_dput: |
| 331 | dput(dentry); | 331 | dput(dentry); |
| 332 | out_dir: | 332 | out_dir: |
| 333 | up(&nd->dentry->d_inode->i_sem); | 333 | mutex_unlock(&nd->dentry->d_inode->i_mutex); |
| 334 | out: | 334 | out: |
| 335 | return ret; | 335 | return ret; |
| 336 | } | 336 | } |
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index a452b13620a2..864729046e22 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
| @@ -215,7 +215,7 @@ static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec, | |||
| 215 | unsigned offset, bv_offs; | 215 | unsigned offset, bv_offs; |
| 216 | int len, ret; | 216 | int len, ret; |
| 217 | 217 | ||
| 218 | down(&mapping->host->i_sem); | 218 | mutex_lock(&mapping->host->i_mutex); |
| 219 | index = pos >> PAGE_CACHE_SHIFT; | 219 | index = pos >> PAGE_CACHE_SHIFT; |
| 220 | offset = pos & ((pgoff_t)PAGE_CACHE_SIZE - 1); | 220 | offset = pos & ((pgoff_t)PAGE_CACHE_SIZE - 1); |
| 221 | bv_offs = bvec->bv_offset; | 221 | bv_offs = bvec->bv_offset; |
| @@ -278,7 +278,7 @@ static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec, | |||
| 278 | } | 278 | } |
| 279 | ret = 0; | 279 | ret = 0; |
| 280 | out: | 280 | out: |
| 281 | up(&mapping->host->i_sem); | 281 | mutex_unlock(&mapping->host->i_mutex); |
| 282 | return ret; | 282 | return ret; |
| 283 | unlock: | 283 | unlock: |
| 284 | unlock_page(page); | 284 | unlock_page(page); |
| @@ -527,12 +527,12 @@ static int loop_make_request(request_queue_t *q, struct bio *old_bio) | |||
| 527 | lo->lo_pending++; | 527 | lo->lo_pending++; |
| 528 | loop_add_bio(lo, old_bio); | 528 | loop_add_bio(lo, old_bio); |
| 529 | spin_unlock_irq(&lo->lo_lock); | 529 | spin_unlock_irq(&lo->lo_lock); |
| 530 | up(&lo->lo_bh_mutex); | 530 | complete(&lo->lo_bh_done); |
| 531 | return 0; | 531 | return 0; |
| 532 | 532 | ||
| 533 | out: | 533 | out: |
| 534 | if (lo->lo_pending == 0) | 534 | if (lo->lo_pending == 0) |
| 535 | up(&lo->lo_bh_mutex); | 535 | complete(&lo->lo_bh_done); |
| 536 | spin_unlock_irq(&lo->lo_lock); | 536 | spin_unlock_irq(&lo->lo_lock); |
| 537 | bio_io_error(old_bio, old_bio->bi_size); | 537 | bio_io_error(old_bio, old_bio->bi_size); |
| 538 | return 0; | 538 | return 0; |
| @@ -593,23 +593,20 @@ static int loop_thread(void *data) | |||
| 593 | lo->lo_pending = 1; | 593 | lo->lo_pending = 1; |
| 594 | 594 | ||
| 595 | /* | 595 | /* |
| 596 | * up sem, we are running | 596 | * complete it, we are running |
| 597 | */ | 597 | */ |
| 598 | up(&lo->lo_sem); | 598 | complete(&lo->lo_done); |
| 599 | 599 | ||
| 600 | for (;;) { | 600 | for (;;) { |
| 601 | int pending; | 601 | int pending; |
| 602 | 602 | ||
| 603 | /* | 603 | if (wait_for_completion_interruptible(&lo->lo_bh_done)) |
| 604 | * interruptible just to not contribute to load avg | ||
| 605 | */ | ||
| 606 | if (down_interruptible(&lo->lo_bh_mutex)) | ||
| 607 | continue; | 604 | continue; |
| 608 | 605 | ||
| 609 | spin_lock_irq(&lo->lo_lock); | 606 | spin_lock_irq(&lo->lo_lock); |
| 610 | 607 | ||
| 611 | /* | 608 | /* |
| 612 | * could be upped because of tear-down, not pending work | 609 | * could be completed because of tear-down, not pending work |
| 613 | */ | 610 | */ |
| 614 | if (unlikely(!lo->lo_pending)) { | 611 | if (unlikely(!lo->lo_pending)) { |
| 615 | spin_unlock_irq(&lo->lo_lock); | 612 | spin_unlock_irq(&lo->lo_lock); |
| @@ -632,7 +629,7 @@ static int loop_thread(void *data) | |||
| 632 | break; | 629 | break; |
| 633 | } | 630 | } |
| 634 | 631 | ||
| 635 | up(&lo->lo_sem); | 632 | complete(&lo->lo_done); |
| 636 | return 0; | 633 | return 0; |
| 637 | } | 634 | } |
| 638 | 635 | ||
| @@ -843,7 +840,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, | |||
| 843 | set_blocksize(bdev, lo_blocksize); | 840 | set_blocksize(bdev, lo_blocksize); |
| 844 | 841 | ||
| 845 | kernel_thread(loop_thread, lo, CLONE_KERNEL); | 842 | kernel_thread(loop_thread, lo, CLONE_KERNEL); |
| 846 | down(&lo->lo_sem); | 843 | wait_for_completion(&lo->lo_done); |
| 847 | return 0; | 844 | return 0; |
| 848 | 845 | ||
| 849 | out_putf: | 846 | out_putf: |
| @@ -909,10 +906,10 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) | |||
| 909 | lo->lo_state = Lo_rundown; | 906 | lo->lo_state = Lo_rundown; |
| 910 | lo->lo_pending--; | 907 | lo->lo_pending--; |
| 911 | if (!lo->lo_pending) | 908 | if (!lo->lo_pending) |
| 912 | up(&lo->lo_bh_mutex); | 909 | complete(&lo->lo_bh_done); |
| 913 | spin_unlock_irq(&lo->lo_lock); | 910 | spin_unlock_irq(&lo->lo_lock); |
| 914 | 911 | ||
| 915 | down(&lo->lo_sem); | 912 | wait_for_completion(&lo->lo_done); |
| 916 | 913 | ||
| 917 | lo->lo_backing_file = NULL; | 914 | lo->lo_backing_file = NULL; |
| 918 | 915 | ||
| @@ -1289,8 +1286,8 @@ static int __init loop_init(void) | |||
| 1289 | if (!lo->lo_queue) | 1286 | if (!lo->lo_queue) |
| 1290 | goto out_mem4; | 1287 | goto out_mem4; |
| 1291 | init_MUTEX(&lo->lo_ctl_mutex); | 1288 | init_MUTEX(&lo->lo_ctl_mutex); |
| 1292 | init_MUTEX_LOCKED(&lo->lo_sem); | 1289 | init_completion(&lo->lo_done); |
| 1293 | init_MUTEX_LOCKED(&lo->lo_bh_mutex); | 1290 | init_completion(&lo->lo_bh_done); |
| 1294 | lo->lo_number = i; | 1291 | lo->lo_number = i; |
| 1295 | spin_lock_init(&lo->lo_lock); | 1292 | spin_lock_init(&lo->lo_lock); |
| 1296 | disk->major = LOOP_MAJOR; | 1293 | disk->major = LOOP_MAJOR; |
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c index c0cdc182a8b0..4bdf95716e2b 100644 --- a/drivers/block/sx8.c +++ b/drivers/block/sx8.c | |||
| @@ -27,8 +27,8 @@ | |||
| 27 | #include <linux/time.h> | 27 | #include <linux/time.h> |
| 28 | #include <linux/hdreg.h> | 28 | #include <linux/hdreg.h> |
| 29 | #include <linux/dma-mapping.h> | 29 | #include <linux/dma-mapping.h> |
| 30 | #include <linux/completion.h> | ||
| 30 | #include <asm/io.h> | 31 | #include <asm/io.h> |
| 31 | #include <asm/semaphore.h> | ||
| 32 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
| 33 | 33 | ||
| 34 | #if 0 | 34 | #if 0 |
| @@ -303,7 +303,7 @@ struct carm_host { | |||
| 303 | 303 | ||
| 304 | struct work_struct fsm_task; | 304 | struct work_struct fsm_task; |
| 305 | 305 | ||
| 306 | struct semaphore probe_sem; | 306 | struct completion probe_comp; |
| 307 | }; | 307 | }; |
| 308 | 308 | ||
| 309 | struct carm_response { | 309 | struct carm_response { |
| @@ -1346,7 +1346,7 @@ static void carm_fsm_task (void *_data) | |||
| 1346 | } | 1346 | } |
| 1347 | 1347 | ||
| 1348 | case HST_PROBE_FINISHED: | 1348 | case HST_PROBE_FINISHED: |
| 1349 | up(&host->probe_sem); | 1349 | complete(&host->probe_comp); |
| 1350 | break; | 1350 | break; |
| 1351 | 1351 | ||
| 1352 | case HST_ERROR: | 1352 | case HST_ERROR: |
| @@ -1622,7 +1622,7 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 1622 | host->flags = pci_dac ? FL_DAC : 0; | 1622 | host->flags = pci_dac ? FL_DAC : 0; |
| 1623 | spin_lock_init(&host->lock); | 1623 | spin_lock_init(&host->lock); |
| 1624 | INIT_WORK(&host->fsm_task, carm_fsm_task, host); | 1624 | INIT_WORK(&host->fsm_task, carm_fsm_task, host); |
| 1625 | init_MUTEX_LOCKED(&host->probe_sem); | 1625 | init_completion(&host->probe_comp); |
| 1626 | 1626 | ||
| 1627 | for (i = 0; i < ARRAY_SIZE(host->req); i++) | 1627 | for (i = 0; i < ARRAY_SIZE(host->req); i++) |
| 1628 | host->req[i].tag = i; | 1628 | host->req[i].tag = i; |
| @@ -1691,8 +1691,8 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 1691 | if (rc) | 1691 | if (rc) |
| 1692 | goto err_out_free_irq; | 1692 | goto err_out_free_irq; |
| 1693 | 1693 | ||
| 1694 | DPRINTK("waiting for probe_sem\n"); | 1694 | DPRINTK("waiting for probe_comp\n"); |
| 1695 | down(&host->probe_sem); | 1695 | wait_for_completion(&host->probe_comp); |
| 1696 | 1696 | ||
| 1697 | printk(KERN_INFO "%s: pci %s, ports %d, io %lx, irq %u, major %d\n", | 1697 | printk(KERN_INFO "%s: pci %s, ports %d, io %lx, irq %u, major %d\n", |
| 1698 | host->name, pci_name(pdev), (int) CARM_MAX_PORTS, | 1698 | host->name, pci_name(pdev), (int) CARM_MAX_PORTS, |
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 5b2d18035073..704c3c07f0ab 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
| @@ -741,7 +741,7 @@ static loff_t memory_lseek(struct file * file, loff_t offset, int orig) | |||
| 741 | { | 741 | { |
| 742 | loff_t ret; | 742 | loff_t ret; |
| 743 | 743 | ||
| 744 | down(&file->f_dentry->d_inode->i_sem); | 744 | mutex_lock(&file->f_dentry->d_inode->i_mutex); |
| 745 | switch (orig) { | 745 | switch (orig) { |
| 746 | case 0: | 746 | case 0: |
| 747 | file->f_pos = offset; | 747 | file->f_pos = offset; |
| @@ -756,7 +756,7 @@ static loff_t memory_lseek(struct file * file, loff_t offset, int orig) | |||
| 756 | default: | 756 | default: |
| 757 | ret = -EINVAL; | 757 | ret = -EINVAL; |
| 758 | } | 758 | } |
| 759 | up(&file->f_dentry->d_inode->i_sem); | 759 | mutex_unlock(&file->f_dentry->d_inode->i_mutex); |
| 760 | return ret; | 760 | return ret; |
| 761 | } | 761 | } |
| 762 | 762 | ||
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 145275ebdd7e..5765f672e853 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
| @@ -153,6 +153,21 @@ static struct sysrq_key_op sysrq_mountro_op = { | |||
| 153 | 153 | ||
| 154 | /* END SYNC SYSRQ HANDLERS BLOCK */ | 154 | /* END SYNC SYSRQ HANDLERS BLOCK */ |
| 155 | 155 | ||
| 156 | #ifdef CONFIG_DEBUG_MUTEXES | ||
| 157 | |||
| 158 | static void | ||
| 159 | sysrq_handle_showlocks(int key, struct pt_regs *pt_regs, struct tty_struct *tty) | ||
| 160 | { | ||
| 161 | mutex_debug_show_all_locks(); | ||
| 162 | } | ||
| 163 | |||
| 164 | static struct sysrq_key_op sysrq_showlocks_op = { | ||
| 165 | .handler = sysrq_handle_showlocks, | ||
| 166 | .help_msg = "show-all-locks(D)", | ||
| 167 | .action_msg = "Show Locks Held", | ||
| 168 | }; | ||
| 169 | |||
| 170 | #endif | ||
| 156 | 171 | ||
| 157 | /* SHOW SYSRQ HANDLERS BLOCK */ | 172 | /* SHOW SYSRQ HANDLERS BLOCK */ |
| 158 | 173 | ||
| @@ -294,7 +309,11 @@ static struct sysrq_key_op *sysrq_key_table[SYSRQ_KEY_TABLE_LENGTH] = { | |||
| 294 | #else | 309 | #else |
| 295 | /* c */ NULL, | 310 | /* c */ NULL, |
| 296 | #endif | 311 | #endif |
| 312 | #ifdef CONFIG_DEBUG_MUTEXES | ||
| 313 | /* d */ &sysrq_showlocks_op, | ||
| 314 | #else | ||
| 297 | /* d */ NULL, | 315 | /* d */ NULL, |
| 316 | #endif | ||
| 298 | /* e */ &sysrq_term_op, | 317 | /* e */ &sysrq_term_op, |
| 299 | /* f */ &sysrq_moom_op, | 318 | /* f */ &sysrq_moom_op, |
| 300 | /* g */ NULL, | 319 | /* g */ NULL, |
diff --git a/drivers/char/watchdog/cpu5wdt.c b/drivers/char/watchdog/cpu5wdt.c index e75045fe2641..3e8410b5a65e 100644 --- a/drivers/char/watchdog/cpu5wdt.c +++ b/drivers/char/watchdog/cpu5wdt.c | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
| 29 | #include <linux/ioport.h> | 29 | #include <linux/ioport.h> |
| 30 | #include <linux/timer.h> | 30 | #include <linux/timer.h> |
| 31 | #include <linux/completion.h> | ||
| 31 | #include <linux/jiffies.h> | 32 | #include <linux/jiffies.h> |
| 32 | #include <asm/io.h> | 33 | #include <asm/io.h> |
| 33 | #include <asm/uaccess.h> | 34 | #include <asm/uaccess.h> |
| @@ -57,7 +58,7 @@ static int ticks = 10000; | |||
| 57 | /* some device data */ | 58 | /* some device data */ |
| 58 | 59 | ||
| 59 | static struct { | 60 | static struct { |
| 60 | struct semaphore stop; | 61 | struct completion stop; |
| 61 | volatile int running; | 62 | volatile int running; |
| 62 | struct timer_list timer; | 63 | struct timer_list timer; |
| 63 | volatile int queue; | 64 | volatile int queue; |
| @@ -85,7 +86,7 @@ static void cpu5wdt_trigger(unsigned long unused) | |||
| 85 | } | 86 | } |
| 86 | else { | 87 | else { |
| 87 | /* ticks doesn't matter anyway */ | 88 | /* ticks doesn't matter anyway */ |
| 88 | up(&cpu5wdt_device.stop); | 89 | complete(&cpu5wdt_device.stop); |
| 89 | } | 90 | } |
| 90 | 91 | ||
| 91 | } | 92 | } |
| @@ -239,7 +240,7 @@ static int __devinit cpu5wdt_init(void) | |||
| 239 | if ( !val ) | 240 | if ( !val ) |
| 240 | printk(KERN_INFO PFX "sorry, was my fault\n"); | 241 | printk(KERN_INFO PFX "sorry, was my fault\n"); |
| 241 | 242 | ||
| 242 | init_MUTEX_LOCKED(&cpu5wdt_device.stop); | 243 | init_completion(&cpu5wdt_device.stop); |
| 243 | cpu5wdt_device.queue = 0; | 244 | cpu5wdt_device.queue = 0; |
| 244 | 245 | ||
| 245 | clear_bit(0, &cpu5wdt_device.inuse); | 246 | clear_bit(0, &cpu5wdt_device.inuse); |
| @@ -269,7 +270,7 @@ static void __devexit cpu5wdt_exit(void) | |||
| 269 | { | 270 | { |
| 270 | if ( cpu5wdt_device.queue ) { | 271 | if ( cpu5wdt_device.queue ) { |
| 271 | cpu5wdt_device.queue = 0; | 272 | cpu5wdt_device.queue = 0; |
| 272 | down(&cpu5wdt_device.stop); | 273 | wait_for_completion(&cpu5wdt_device.stop); |
| 273 | } | 274 | } |
| 274 | 275 | ||
| 275 | misc_deregister(&cpu5wdt_misc); | 276 | misc_deregister(&cpu5wdt_misc); |
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 1ddaa71a8f45..7cb2d86601db 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
| @@ -655,7 +655,7 @@ static void hwif_release_dev (struct device *dev) | |||
| 655 | { | 655 | { |
| 656 | ide_hwif_t *hwif = container_of(dev, ide_hwif_t, gendev); | 656 | ide_hwif_t *hwif = container_of(dev, ide_hwif_t, gendev); |
| 657 | 657 | ||
| 658 | up(&hwif->gendev_rel_sem); | 658 | complete(&hwif->gendev_rel_comp); |
| 659 | } | 659 | } |
| 660 | 660 | ||
| 661 | static void hwif_register (ide_hwif_t *hwif) | 661 | static void hwif_register (ide_hwif_t *hwif) |
| @@ -1327,7 +1327,7 @@ static void drive_release_dev (struct device *dev) | |||
| 1327 | drive->queue = NULL; | 1327 | drive->queue = NULL; |
| 1328 | spin_unlock_irq(&ide_lock); | 1328 | spin_unlock_irq(&ide_lock); |
| 1329 | 1329 | ||
| 1330 | up(&drive->gendev_rel_sem); | 1330 | complete(&drive->gendev_rel_comp); |
| 1331 | } | 1331 | } |
| 1332 | 1332 | ||
| 1333 | /* | 1333 | /* |
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index b069b13b75a7..ec5a4cb173b0 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
| @@ -222,7 +222,7 @@ static void init_hwif_data(ide_hwif_t *hwif, unsigned int index) | |||
| 222 | hwif->mwdma_mask = 0x80; /* disable all mwdma */ | 222 | hwif->mwdma_mask = 0x80; /* disable all mwdma */ |
| 223 | hwif->swdma_mask = 0x80; /* disable all swdma */ | 223 | hwif->swdma_mask = 0x80; /* disable all swdma */ |
| 224 | 224 | ||
| 225 | sema_init(&hwif->gendev_rel_sem, 0); | 225 | init_completion(&hwif->gendev_rel_comp); |
| 226 | 226 | ||
| 227 | default_hwif_iops(hwif); | 227 | default_hwif_iops(hwif); |
| 228 | default_hwif_transport(hwif); | 228 | default_hwif_transport(hwif); |
| @@ -245,7 +245,7 @@ static void init_hwif_data(ide_hwif_t *hwif, unsigned int index) | |||
| 245 | drive->is_flash = 0; | 245 | drive->is_flash = 0; |
| 246 | drive->vdma = 0; | 246 | drive->vdma = 0; |
| 247 | INIT_LIST_HEAD(&drive->list); | 247 | INIT_LIST_HEAD(&drive->list); |
| 248 | sema_init(&drive->gendev_rel_sem, 0); | 248 | init_completion(&drive->gendev_rel_comp); |
| 249 | } | 249 | } |
| 250 | } | 250 | } |
| 251 | 251 | ||
| @@ -602,7 +602,7 @@ void ide_unregister(unsigned int index) | |||
| 602 | } | 602 | } |
| 603 | spin_unlock_irq(&ide_lock); | 603 | spin_unlock_irq(&ide_lock); |
| 604 | device_unregister(&drive->gendev); | 604 | device_unregister(&drive->gendev); |
| 605 | down(&drive->gendev_rel_sem); | 605 | wait_for_completion(&drive->gendev_rel_comp); |
| 606 | spin_lock_irq(&ide_lock); | 606 | spin_lock_irq(&ide_lock); |
| 607 | } | 607 | } |
| 608 | hwif->present = 0; | 608 | hwif->present = 0; |
| @@ -662,7 +662,7 @@ void ide_unregister(unsigned int index) | |||
| 662 | /* More messed up locking ... */ | 662 | /* More messed up locking ... */ |
| 663 | spin_unlock_irq(&ide_lock); | 663 | spin_unlock_irq(&ide_lock); |
| 664 | device_unregister(&hwif->gendev); | 664 | device_unregister(&hwif->gendev); |
| 665 | down(&hwif->gendev_rel_sem); | 665 | wait_for_completion(&hwif->gendev_rel_comp); |
| 666 | 666 | ||
| 667 | /* | 667 | /* |
| 668 | * Remove us from the kernel's knowledge | 668 | * Remove us from the kernel's knowledge |
diff --git a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c index 207cae366256..0a37aded4b54 100644 --- a/drivers/isdn/capi/capifs.c +++ b/drivers/isdn/capi/capifs.c | |||
| @@ -138,7 +138,7 @@ static struct dentry *get_node(int num) | |||
| 138 | { | 138 | { |
| 139 | char s[10]; | 139 | char s[10]; |
| 140 | struct dentry *root = capifs_root; | 140 | struct dentry *root = capifs_root; |
| 141 | down(&root->d_inode->i_sem); | 141 | mutex_lock(&root->d_inode->i_mutex); |
| 142 | return lookup_one_len(s, root, sprintf(s, "%d", num)); | 142 | return lookup_one_len(s, root, sprintf(s, "%d", num)); |
| 143 | } | 143 | } |
| 144 | 144 | ||
| @@ -159,7 +159,7 @@ void capifs_new_ncci(unsigned int number, dev_t device) | |||
| 159 | dentry = get_node(number); | 159 | dentry = get_node(number); |
| 160 | if (!IS_ERR(dentry) && !dentry->d_inode) | 160 | if (!IS_ERR(dentry) && !dentry->d_inode) |
| 161 | d_instantiate(dentry, inode); | 161 | d_instantiate(dentry, inode); |
| 162 | up(&capifs_root->d_inode->i_sem); | 162 | mutex_unlock(&capifs_root->d_inode->i_mutex); |
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | void capifs_free_ncci(unsigned int number) | 165 | void capifs_free_ncci(unsigned int number) |
| @@ -175,7 +175,7 @@ void capifs_free_ncci(unsigned int number) | |||
| 175 | } | 175 | } |
| 176 | dput(dentry); | 176 | dput(dentry); |
| 177 | } | 177 | } |
| 178 | up(&capifs_root->d_inode->i_sem); | 178 | mutex_unlock(&capifs_root->d_inode->i_mutex); |
| 179 | } | 179 | } |
| 180 | 180 | ||
| 181 | static int __init capifs_init(void) | 181 | static int __init capifs_init(void) |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 0e481512f918..5c210b0a4cb0 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
| @@ -837,9 +837,9 @@ static void __set_size(struct mapped_device *md, sector_t size) | |||
| 837 | { | 837 | { |
| 838 | set_capacity(md->disk, size); | 838 | set_capacity(md->disk, size); |
| 839 | 839 | ||
| 840 | down(&md->suspended_bdev->bd_inode->i_sem); | 840 | mutex_lock(&md->suspended_bdev->bd_inode->i_mutex); |
| 841 | i_size_write(md->suspended_bdev->bd_inode, (loff_t)size << SECTOR_SHIFT); | 841 | i_size_write(md->suspended_bdev->bd_inode, (loff_t)size << SECTOR_SHIFT); |
| 842 | up(&md->suspended_bdev->bd_inode->i_sem); | 842 | mutex_unlock(&md->suspended_bdev->bd_inode->i_mutex); |
| 843 | } | 843 | } |
| 844 | 844 | ||
| 845 | static int __bind(struct mapped_device *md, struct dm_table *t) | 845 | static int __bind(struct mapped_device *md, struct dm_table *t) |
diff --git a/drivers/md/md.c b/drivers/md/md.c index e423a16ba3c9..0302723fa21f 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -3460,9 +3460,9 @@ static int update_size(mddev_t *mddev, unsigned long size) | |||
| 3460 | 3460 | ||
| 3461 | bdev = bdget_disk(mddev->gendisk, 0); | 3461 | bdev = bdget_disk(mddev->gendisk, 0); |
| 3462 | if (bdev) { | 3462 | if (bdev) { |
| 3463 | down(&bdev->bd_inode->i_sem); | 3463 | mutex_lock(&bdev->bd_inode->i_mutex); |
| 3464 | i_size_write(bdev->bd_inode, mddev->array_size << 10); | 3464 | i_size_write(bdev->bd_inode, mddev->array_size << 10); |
| 3465 | up(&bdev->bd_inode->i_sem); | 3465 | mutex_unlock(&bdev->bd_inode->i_mutex); |
| 3466 | bdput(bdev); | 3466 | bdput(bdev); |
| 3467 | } | 3467 | } |
| 3468 | } | 3468 | } |
| @@ -3486,9 +3486,9 @@ static int update_raid_disks(mddev_t *mddev, int raid_disks) | |||
| 3486 | 3486 | ||
| 3487 | bdev = bdget_disk(mddev->gendisk, 0); | 3487 | bdev = bdget_disk(mddev->gendisk, 0); |
| 3488 | if (bdev) { | 3488 | if (bdev) { |
| 3489 | down(&bdev->bd_inode->i_sem); | 3489 | mutex_lock(&bdev->bd_inode->i_mutex); |
| 3490 | i_size_write(bdev->bd_inode, mddev->array_size << 10); | 3490 | i_size_write(bdev->bd_inode, mddev->array_size << 10); |
| 3491 | up(&bdev->bd_inode->i_sem); | 3491 | mutex_unlock(&bdev->bd_inode->i_mutex); |
| 3492 | bdput(bdev); | 3492 | bdput(bdev); |
| 3493 | } | 3493 | } |
| 3494 | } | 3494 | } |
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 9eb465727fce..9cb6dd0834be 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c | |||
| @@ -25,7 +25,7 @@ proc_bus_pci_lseek(struct file *file, loff_t off, int whence) | |||
| 25 | loff_t new = -1; | 25 | loff_t new = -1; |
| 26 | struct inode *inode = file->f_dentry->d_inode; | 26 | struct inode *inode = file->f_dentry->d_inode; |
| 27 | 27 | ||
| 28 | down(&inode->i_sem); | 28 | mutex_lock(&inode->i_mutex); |
| 29 | switch (whence) { | 29 | switch (whence) { |
| 30 | case 0: | 30 | case 0: |
| 31 | new = off; | 31 | new = off; |
| @@ -41,7 +41,7 @@ proc_bus_pci_lseek(struct file *file, loff_t off, int whence) | |||
| 41 | new = -EINVAL; | 41 | new = -EINVAL; |
| 42 | else | 42 | else |
| 43 | file->f_pos = new; | 43 | file->f_pos = new; |
| 44 | up(&inode->i_sem); | 44 | mutex_unlock(&inode->i_mutex); |
| 45 | return new; | 45 | return new; |
| 46 | } | 46 | } |
| 47 | 47 | ||
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c index 4ddc453023a2..3cf945cc5b9a 100644 --- a/drivers/usb/core/inode.c +++ b/drivers/usb/core/inode.c | |||
| @@ -184,13 +184,13 @@ static void update_bus(struct dentry *bus) | |||
| 184 | bus->d_inode->i_gid = busgid; | 184 | bus->d_inode->i_gid = busgid; |
| 185 | bus->d_inode->i_mode = S_IFDIR | busmode; | 185 | bus->d_inode->i_mode = S_IFDIR | busmode; |
| 186 | 186 | ||
| 187 | down(&bus->d_inode->i_sem); | 187 | mutex_lock(&bus->d_inode->i_mutex); |
| 188 | 188 | ||
| 189 | list_for_each_entry(dev, &bus->d_subdirs, d_u.d_child) | 189 | list_for_each_entry(dev, &bus->d_subdirs, d_u.d_child) |
| 190 | if (dev->d_inode) | 190 | if (dev->d_inode) |
| 191 | update_dev(dev); | 191 | update_dev(dev); |
| 192 | 192 | ||
| 193 | up(&bus->d_inode->i_sem); | 193 | mutex_unlock(&bus->d_inode->i_mutex); |
| 194 | } | 194 | } |
| 195 | 195 | ||
| 196 | static void update_sb(struct super_block *sb) | 196 | static void update_sb(struct super_block *sb) |
| @@ -201,7 +201,7 @@ static void update_sb(struct super_block *sb) | |||
| 201 | if (!root) | 201 | if (!root) |
| 202 | return; | 202 | return; |
| 203 | 203 | ||
| 204 | down(&root->d_inode->i_sem); | 204 | mutex_lock(&root->d_inode->i_mutex); |
| 205 | 205 | ||
| 206 | list_for_each_entry(bus, &root->d_subdirs, d_u.d_child) { | 206 | list_for_each_entry(bus, &root->d_subdirs, d_u.d_child) { |
| 207 | if (bus->d_inode) { | 207 | if (bus->d_inode) { |
| @@ -219,7 +219,7 @@ static void update_sb(struct super_block *sb) | |||
| 219 | } | 219 | } |
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | up(&root->d_inode->i_sem); | 222 | mutex_unlock(&root->d_inode->i_mutex); |
| 223 | } | 223 | } |
| 224 | 224 | ||
| 225 | static int remount(struct super_block *sb, int *flags, char *data) | 225 | static int remount(struct super_block *sb, int *flags, char *data) |
| @@ -333,10 +333,10 @@ static int usbfs_empty (struct dentry *dentry) | |||
| 333 | static int usbfs_unlink (struct inode *dir, struct dentry *dentry) | 333 | static int usbfs_unlink (struct inode *dir, struct dentry *dentry) |
| 334 | { | 334 | { |
| 335 | struct inode *inode = dentry->d_inode; | 335 | struct inode *inode = dentry->d_inode; |
| 336 | down(&inode->i_sem); | 336 | mutex_lock(&inode->i_mutex); |
| 337 | dentry->d_inode->i_nlink--; | 337 | dentry->d_inode->i_nlink--; |
| 338 | dput(dentry); | 338 | dput(dentry); |
| 339 | up(&inode->i_sem); | 339 | mutex_unlock(&inode->i_mutex); |
| 340 | d_delete(dentry); | 340 | d_delete(dentry); |
| 341 | return 0; | 341 | return 0; |
| 342 | } | 342 | } |
| @@ -346,7 +346,7 @@ static int usbfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 346 | int error = -ENOTEMPTY; | 346 | int error = -ENOTEMPTY; |
| 347 | struct inode * inode = dentry->d_inode; | 347 | struct inode * inode = dentry->d_inode; |
| 348 | 348 | ||
| 349 | down(&inode->i_sem); | 349 | mutex_lock(&inode->i_mutex); |
| 350 | dentry_unhash(dentry); | 350 | dentry_unhash(dentry); |
| 351 | if (usbfs_empty(dentry)) { | 351 | if (usbfs_empty(dentry)) { |
| 352 | dentry->d_inode->i_nlink -= 2; | 352 | dentry->d_inode->i_nlink -= 2; |
| @@ -355,7 +355,7 @@ static int usbfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 355 | dir->i_nlink--; | 355 | dir->i_nlink--; |
| 356 | error = 0; | 356 | error = 0; |
| 357 | } | 357 | } |
| 358 | up(&inode->i_sem); | 358 | mutex_unlock(&inode->i_mutex); |
| 359 | if (!error) | 359 | if (!error) |
| 360 | d_delete(dentry); | 360 | d_delete(dentry); |
| 361 | dput(dentry); | 361 | dput(dentry); |
| @@ -380,7 +380,7 @@ static loff_t default_file_lseek (struct file *file, loff_t offset, int orig) | |||
| 380 | { | 380 | { |
| 381 | loff_t retval = -EINVAL; | 381 | loff_t retval = -EINVAL; |
| 382 | 382 | ||
| 383 | down(&file->f_dentry->d_inode->i_sem); | 383 | mutex_lock(&file->f_dentry->d_inode->i_mutex); |
| 384 | switch(orig) { | 384 | switch(orig) { |
| 385 | case 0: | 385 | case 0: |
| 386 | if (offset > 0) { | 386 | if (offset > 0) { |
| @@ -397,7 +397,7 @@ static loff_t default_file_lseek (struct file *file, loff_t offset, int orig) | |||
| 397 | default: | 397 | default: |
| 398 | break; | 398 | break; |
| 399 | } | 399 | } |
| 400 | up(&file->f_dentry->d_inode->i_sem); | 400 | mutex_unlock(&file->f_dentry->d_inode->i_mutex); |
| 401 | return retval; | 401 | return retval; |
| 402 | } | 402 | } |
| 403 | 403 | ||
| @@ -480,7 +480,7 @@ static int fs_create_by_name (const char *name, mode_t mode, | |||
| 480 | } | 480 | } |
| 481 | 481 | ||
| 482 | *dentry = NULL; | 482 | *dentry = NULL; |
| 483 | down(&parent->d_inode->i_sem); | 483 | mutex_lock(&parent->d_inode->i_mutex); |
| 484 | *dentry = lookup_one_len(name, parent, strlen(name)); | 484 | *dentry = lookup_one_len(name, parent, strlen(name)); |
| 485 | if (!IS_ERR(dentry)) { | 485 | if (!IS_ERR(dentry)) { |
| 486 | if ((mode & S_IFMT) == S_IFDIR) | 486 | if ((mode & S_IFMT) == S_IFDIR) |
| @@ -489,7 +489,7 @@ static int fs_create_by_name (const char *name, mode_t mode, | |||
| 489 | error = usbfs_create (parent->d_inode, *dentry, mode); | 489 | error = usbfs_create (parent->d_inode, *dentry, mode); |
| 490 | } else | 490 | } else |
| 491 | error = PTR_ERR(dentry); | 491 | error = PTR_ERR(dentry); |
| 492 | up(&parent->d_inode->i_sem); | 492 | mutex_unlock(&parent->d_inode->i_mutex); |
| 493 | 493 | ||
| 494 | return error; | 494 | return error; |
| 495 | } | 495 | } |
| @@ -528,7 +528,7 @@ static void fs_remove_file (struct dentry *dentry) | |||
| 528 | if (!parent || !parent->d_inode) | 528 | if (!parent || !parent->d_inode) |
| 529 | return; | 529 | return; |
| 530 | 530 | ||
| 531 | down(&parent->d_inode->i_sem); | 531 | mutex_lock(&parent->d_inode->i_mutex); |
| 532 | if (usbfs_positive(dentry)) { | 532 | if (usbfs_positive(dentry)) { |
| 533 | if (dentry->d_inode) { | 533 | if (dentry->d_inode) { |
| 534 | if (S_ISDIR(dentry->d_inode->i_mode)) | 534 | if (S_ISDIR(dentry->d_inode->i_mode)) |
| @@ -538,7 +538,7 @@ static void fs_remove_file (struct dentry *dentry) | |||
| 538 | dput(dentry); | 538 | dput(dentry); |
| 539 | } | 539 | } |
| 540 | } | 540 | } |
| 541 | up(&parent->d_inode->i_sem); | 541 | mutex_unlock(&parent->d_inode->i_mutex); |
| 542 | } | 542 | } |
| 543 | 543 | ||
| 544 | /* --------------------------------------------------------------------- */ | 544 | /* --------------------------------------------------------------------- */ |
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 0cea9782d7d4..de59c58896d6 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
| @@ -1891,7 +1891,7 @@ static int fsync_sub(struct lun *curlun) | |||
| 1891 | return -EINVAL; | 1891 | return -EINVAL; |
| 1892 | 1892 | ||
| 1893 | inode = filp->f_dentry->d_inode; | 1893 | inode = filp->f_dentry->d_inode; |
| 1894 | down(&inode->i_sem); | 1894 | mutex_lock(&inode->i_mutex); |
| 1895 | current->flags |= PF_SYNCWRITE; | 1895 | current->flags |= PF_SYNCWRITE; |
| 1896 | rc = filemap_fdatawrite(inode->i_mapping); | 1896 | rc = filemap_fdatawrite(inode->i_mapping); |
| 1897 | err = filp->f_op->fsync(filp, filp->f_dentry, 1); | 1897 | err = filp->f_op->fsync(filp, filp->f_dentry, 1); |
| @@ -1901,7 +1901,7 @@ static int fsync_sub(struct lun *curlun) | |||
| 1901 | if (!rc) | 1901 | if (!rc) |
| 1902 | rc = err; | 1902 | rc = err; |
| 1903 | current->flags &= ~PF_SYNCWRITE; | 1903 | current->flags &= ~PF_SYNCWRITE; |
| 1904 | up(&inode->i_sem); | 1904 | mutex_unlock(&inode->i_mutex); |
| 1905 | VLDBG(curlun, "fdatasync -> %d\n", rc); | 1905 | VLDBG(curlun, "fdatasync -> %d\n", rc); |
| 1906 | return rc; | 1906 | return rc; |
| 1907 | } | 1907 | } |
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 5c40980a5bd9..c6c279de832e 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c | |||
| @@ -1562,10 +1562,10 @@ restart: | |||
| 1562 | spin_unlock_irq (&dev->lock); | 1562 | spin_unlock_irq (&dev->lock); |
| 1563 | 1563 | ||
| 1564 | /* break link to dcache */ | 1564 | /* break link to dcache */ |
| 1565 | down (&parent->i_sem); | 1565 | mutex_lock (&parent->i_mutex); |
| 1566 | d_delete (dentry); | 1566 | d_delete (dentry); |
| 1567 | dput (dentry); | 1567 | dput (dentry); |
| 1568 | up (&parent->i_sem); | 1568 | mutex_unlock (&parent->i_mutex); |
| 1569 | 1569 | ||
| 1570 | /* fds may still be open */ | 1570 | /* fds may still be open */ |
| 1571 | goto restart; | 1571 | goto restart; |
diff --git a/fs/affs/inode.c b/fs/affs/inode.c index 9ebe881c6786..44d439cb69f4 100644 --- a/fs/affs/inode.c +++ b/fs/affs/inode.c | |||
| @@ -244,10 +244,10 @@ affs_put_inode(struct inode *inode) | |||
| 244 | pr_debug("AFFS: put_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink); | 244 | pr_debug("AFFS: put_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink); |
| 245 | affs_free_prealloc(inode); | 245 | affs_free_prealloc(inode); |
| 246 | if (atomic_read(&inode->i_count) == 1) { | 246 | if (atomic_read(&inode->i_count) == 1) { |
| 247 | down(&inode->i_sem); | 247 | mutex_lock(&inode->i_mutex); |
| 248 | if (inode->i_size != AFFS_I(inode)->mmu_private) | 248 | if (inode->i_size != AFFS_I(inode)->mmu_private) |
| 249 | affs_truncate(inode); | 249 | affs_truncate(inode); |
| 250 | up(&inode->i_sem); | 250 | mutex_unlock(&inode->i_mutex); |
| 251 | } | 251 | } |
| 252 | } | 252 | } |
| 253 | 253 | ||
diff --git a/fs/autofs/root.c b/fs/autofs/root.c index a1ab1c0ed215..808134a5a2fa 100644 --- a/fs/autofs/root.c +++ b/fs/autofs/root.c | |||
| @@ -229,9 +229,9 @@ static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentr | |||
| 229 | dentry->d_flags |= DCACHE_AUTOFS_PENDING; | 229 | dentry->d_flags |= DCACHE_AUTOFS_PENDING; |
| 230 | d_add(dentry, NULL); | 230 | d_add(dentry, NULL); |
| 231 | 231 | ||
| 232 | up(&dir->i_sem); | 232 | mutex_unlock(&dir->i_mutex); |
| 233 | autofs_revalidate(dentry, nd); | 233 | autofs_revalidate(dentry, nd); |
| 234 | down(&dir->i_sem); | 234 | mutex_lock(&dir->i_mutex); |
| 235 | 235 | ||
| 236 | /* | 236 | /* |
| 237 | * If we are still pending, check if we had to handle | 237 | * If we are still pending, check if we had to handle |
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 2241405ffc41..541b19e6fec9 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
| @@ -489,9 +489,9 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s | |||
| 489 | d_add(dentry, NULL); | 489 | d_add(dentry, NULL); |
| 490 | 490 | ||
| 491 | if (dentry->d_op && dentry->d_op->d_revalidate) { | 491 | if (dentry->d_op && dentry->d_op->d_revalidate) { |
| 492 | up(&dir->i_sem); | 492 | mutex_unlock(&dir->i_mutex); |
| 493 | (dentry->d_op->d_revalidate)(dentry, nd); | 493 | (dentry->d_op->d_revalidate)(dentry, nd); |
| 494 | down(&dir->i_sem); | 494 | mutex_lock(&dir->i_mutex); |
| 495 | } | 495 | } |
| 496 | 496 | ||
| 497 | /* | 497 | /* |
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index 2568eb41cb3a..9ccc7d8275b8 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c | |||
| @@ -588,11 +588,11 @@ static ssize_t bm_entry_write(struct file *file, const char __user *buffer, | |||
| 588 | case 2: set_bit(Enabled, &e->flags); | 588 | case 2: set_bit(Enabled, &e->flags); |
| 589 | break; | 589 | break; |
| 590 | case 3: root = dget(file->f_vfsmnt->mnt_sb->s_root); | 590 | case 3: root = dget(file->f_vfsmnt->mnt_sb->s_root); |
| 591 | down(&root->d_inode->i_sem); | 591 | mutex_lock(&root->d_inode->i_mutex); |
| 592 | 592 | ||
| 593 | kill_node(e); | 593 | kill_node(e); |
| 594 | 594 | ||
| 595 | up(&root->d_inode->i_sem); | 595 | mutex_unlock(&root->d_inode->i_mutex); |
| 596 | dput(root); | 596 | dput(root); |
| 597 | break; | 597 | break; |
| 598 | default: return res; | 598 | default: return res; |
| @@ -622,7 +622,7 @@ static ssize_t bm_register_write(struct file *file, const char __user *buffer, | |||
| 622 | return PTR_ERR(e); | 622 | return PTR_ERR(e); |
| 623 | 623 | ||
| 624 | root = dget(sb->s_root); | 624 | root = dget(sb->s_root); |
| 625 | down(&root->d_inode->i_sem); | 625 | mutex_lock(&root->d_inode->i_mutex); |
| 626 | dentry = lookup_one_len(e->name, root, strlen(e->name)); | 626 | dentry = lookup_one_len(e->name, root, strlen(e->name)); |
| 627 | err = PTR_ERR(dentry); | 627 | err = PTR_ERR(dentry); |
| 628 | if (IS_ERR(dentry)) | 628 | if (IS_ERR(dentry)) |
| @@ -658,7 +658,7 @@ static ssize_t bm_register_write(struct file *file, const char __user *buffer, | |||
| 658 | out2: | 658 | out2: |
| 659 | dput(dentry); | 659 | dput(dentry); |
| 660 | out: | 660 | out: |
| 661 | up(&root->d_inode->i_sem); | 661 | mutex_unlock(&root->d_inode->i_mutex); |
| 662 | dput(root); | 662 | dput(root); |
| 663 | 663 | ||
| 664 | if (err) { | 664 | if (err) { |
| @@ -703,12 +703,12 @@ static ssize_t bm_status_write(struct file * file, const char __user * buffer, | |||
| 703 | case 1: enabled = 0; break; | 703 | case 1: enabled = 0; break; |
| 704 | case 2: enabled = 1; break; | 704 | case 2: enabled = 1; break; |
| 705 | case 3: root = dget(file->f_vfsmnt->mnt_sb->s_root); | 705 | case 3: root = dget(file->f_vfsmnt->mnt_sb->s_root); |
| 706 | down(&root->d_inode->i_sem); | 706 | mutex_lock(&root->d_inode->i_mutex); |
| 707 | 707 | ||
| 708 | while (!list_empty(&entries)) | 708 | while (!list_empty(&entries)) |
| 709 | kill_node(list_entry(entries.next, Node, list)); | 709 | kill_node(list_entry(entries.next, Node, list)); |
| 710 | 710 | ||
| 711 | up(&root->d_inode->i_sem); | 711 | mutex_unlock(&root->d_inode->i_mutex); |
| 712 | dput(root); | 712 | dput(root); |
| 713 | default: return res; | 713 | default: return res; |
| 714 | } | 714 | } |
diff --git a/fs/block_dev.c b/fs/block_dev.c index e0df94c37b7e..6e50346fb1ee 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
| @@ -202,7 +202,7 @@ static loff_t block_llseek(struct file *file, loff_t offset, int origin) | |||
| 202 | loff_t size; | 202 | loff_t size; |
| 203 | loff_t retval; | 203 | loff_t retval; |
| 204 | 204 | ||
| 205 | down(&bd_inode->i_sem); | 205 | mutex_lock(&bd_inode->i_mutex); |
| 206 | size = i_size_read(bd_inode); | 206 | size = i_size_read(bd_inode); |
| 207 | 207 | ||
| 208 | switch (origin) { | 208 | switch (origin) { |
| @@ -219,7 +219,7 @@ static loff_t block_llseek(struct file *file, loff_t offset, int origin) | |||
| 219 | } | 219 | } |
| 220 | retval = offset; | 220 | retval = offset; |
| 221 | } | 221 | } |
| 222 | up(&bd_inode->i_sem); | 222 | mutex_unlock(&bd_inode->i_mutex); |
| 223 | return retval; | 223 | return retval; |
| 224 | } | 224 | } |
| 225 | 225 | ||
diff --git a/fs/buffer.c b/fs/buffer.c index 55f0975a9b15..6466bc8a3dc7 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
| @@ -352,11 +352,11 @@ static long do_fsync(unsigned int fd, int datasync) | |||
| 352 | * We need to protect against concurrent writers, | 352 | * We need to protect against concurrent writers, |
| 353 | * which could cause livelocks in fsync_buffers_list | 353 | * which could cause livelocks in fsync_buffers_list |
| 354 | */ | 354 | */ |
| 355 | down(&mapping->host->i_sem); | 355 | mutex_lock(&mapping->host->i_mutex); |
| 356 | err = file->f_op->fsync(file, file->f_dentry, datasync); | 356 | err = file->f_op->fsync(file, file->f_dentry, datasync); |
| 357 | if (!ret) | 357 | if (!ret) |
| 358 | ret = err; | 358 | ret = err; |
| 359 | up(&mapping->host->i_sem); | 359 | mutex_unlock(&mapping->host->i_mutex); |
| 360 | err = filemap_fdatawait(mapping); | 360 | err = filemap_fdatawait(mapping); |
| 361 | if (!ret) | 361 | if (!ret) |
| 362 | ret = err; | 362 | ret = err; |
| @@ -2338,7 +2338,7 @@ int generic_commit_write(struct file *file, struct page *page, | |||
| 2338 | __block_commit_write(inode,page,from,to); | 2338 | __block_commit_write(inode,page,from,to); |
| 2339 | /* | 2339 | /* |
| 2340 | * No need to use i_size_read() here, the i_size | 2340 | * No need to use i_size_read() here, the i_size |
| 2341 | * cannot change under us because we hold i_sem. | 2341 | * cannot change under us because we hold i_mutex. |
| 2342 | */ | 2342 | */ |
| 2343 | if (pos > inode->i_size) { | 2343 | if (pos > inode->i_size) { |
| 2344 | i_size_write(inode, pos); | 2344 | i_size_write(inode, pos); |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 2a13a2bac8f1..e10213b7541e 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
| @@ -860,9 +860,9 @@ static int cifs_oplock_thread(void * dummyarg) | |||
| 860 | DeleteOplockQEntry(oplock_item); | 860 | DeleteOplockQEntry(oplock_item); |
| 861 | /* can not grab inode sem here since it would | 861 | /* can not grab inode sem here since it would |
| 862 | deadlock when oplock received on delete | 862 | deadlock when oplock received on delete |
| 863 | since vfs_unlink holds the i_sem across | 863 | since vfs_unlink holds the i_mutex across |
| 864 | the call */ | 864 | the call */ |
| 865 | /* down(&inode->i_sem);*/ | 865 | /* mutex_lock(&inode->i_mutex);*/ |
| 866 | if (S_ISREG(inode->i_mode)) { | 866 | if (S_ISREG(inode->i_mode)) { |
| 867 | rc = filemap_fdatawrite(inode->i_mapping); | 867 | rc = filemap_fdatawrite(inode->i_mapping); |
| 868 | if(CIFS_I(inode)->clientCanCacheRead == 0) { | 868 | if(CIFS_I(inode)->clientCanCacheRead == 0) { |
| @@ -871,7 +871,7 @@ static int cifs_oplock_thread(void * dummyarg) | |||
| 871 | } | 871 | } |
| 872 | } else | 872 | } else |
| 873 | rc = 0; | 873 | rc = 0; |
| 874 | /* up(&inode->i_sem);*/ | 874 | /* mutex_unlock(&inode->i_mutex);*/ |
| 875 | if (rc) | 875 | if (rc) |
| 876 | CIFS_I(inode)->write_behind_rc = rc; | 876 | CIFS_I(inode)->write_behind_rc = rc; |
| 877 | cFYI(1,("Oplock flush inode %p rc %d",inode,rc)); | 877 | cFYI(1,("Oplock flush inode %p rc %d",inode,rc)); |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 9558f51bca55..3ebce9430f4a 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
| @@ -1040,9 +1040,9 @@ int cifs_revalidate(struct dentry *direntry) | |||
| 1040 | } | 1040 | } |
| 1041 | 1041 | ||
| 1042 | /* can not grab this sem since kernel filesys locking documentation | 1042 | /* can not grab this sem since kernel filesys locking documentation |
| 1043 | indicates i_sem may be taken by the kernel on lookup and rename | 1043 | indicates i_mutex may be taken by the kernel on lookup and rename |
| 1044 | which could deadlock if we grab the i_sem here as well */ | 1044 | which could deadlock if we grab the i_mutex here as well */ |
| 1045 | /* down(&direntry->d_inode->i_sem);*/ | 1045 | /* mutex_lock(&direntry->d_inode->i_mutex);*/ |
| 1046 | /* need to write out dirty pages here */ | 1046 | /* need to write out dirty pages here */ |
| 1047 | if (direntry->d_inode->i_mapping) { | 1047 | if (direntry->d_inode->i_mapping) { |
| 1048 | /* do we need to lock inode until after invalidate completes | 1048 | /* do we need to lock inode until after invalidate completes |
| @@ -1066,7 +1066,7 @@ int cifs_revalidate(struct dentry *direntry) | |||
| 1066 | } | 1066 | } |
| 1067 | } | 1067 | } |
| 1068 | } | 1068 | } |
| 1069 | /* up(&direntry->d_inode->i_sem); */ | 1069 | /* mutex_unlock(&direntry->d_inode->i_mutex); */ |
| 1070 | 1070 | ||
| 1071 | kfree(full_path); | 1071 | kfree(full_path); |
| 1072 | FreeXid(xid); | 1072 | FreeXid(xid); |
diff --git a/fs/coda/dir.c b/fs/coda/dir.c index 2391766e9c7c..8f1a517f8b4e 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c | |||
| @@ -453,7 +453,7 @@ int coda_readdir(struct file *coda_file, void *dirent, filldir_t filldir) | |||
| 453 | coda_vfs_stat.readdir++; | 453 | coda_vfs_stat.readdir++; |
| 454 | 454 | ||
| 455 | host_inode = host_file->f_dentry->d_inode; | 455 | host_inode = host_file->f_dentry->d_inode; |
| 456 | down(&host_inode->i_sem); | 456 | mutex_lock(&host_inode->i_mutex); |
| 457 | host_file->f_pos = coda_file->f_pos; | 457 | host_file->f_pos = coda_file->f_pos; |
| 458 | 458 | ||
| 459 | if (!host_file->f_op->readdir) { | 459 | if (!host_file->f_op->readdir) { |
| @@ -475,7 +475,7 @@ int coda_readdir(struct file *coda_file, void *dirent, filldir_t filldir) | |||
| 475 | } | 475 | } |
| 476 | out: | 476 | out: |
| 477 | coda_file->f_pos = host_file->f_pos; | 477 | coda_file->f_pos = host_file->f_pos; |
| 478 | up(&host_inode->i_sem); | 478 | mutex_unlock(&host_inode->i_mutex); |
| 479 | 479 | ||
| 480 | return ret; | 480 | return ret; |
| 481 | } | 481 | } |
diff --git a/fs/coda/file.c b/fs/coda/file.c index e6bc022568f3..30b4630bd735 100644 --- a/fs/coda/file.c +++ b/fs/coda/file.c | |||
| @@ -77,14 +77,14 @@ coda_file_write(struct file *coda_file, const char __user *buf, size_t count, lo | |||
| 77 | return -EINVAL; | 77 | return -EINVAL; |
| 78 | 78 | ||
| 79 | host_inode = host_file->f_dentry->d_inode; | 79 | host_inode = host_file->f_dentry->d_inode; |
| 80 | down(&coda_inode->i_sem); | 80 | mutex_lock(&coda_inode->i_mutex); |
| 81 | 81 | ||
| 82 | ret = host_file->f_op->write(host_file, buf, count, ppos); | 82 | ret = host_file->f_op->write(host_file, buf, count, ppos); |
| 83 | 83 | ||
| 84 | coda_inode->i_size = host_inode->i_size; | 84 | coda_inode->i_size = host_inode->i_size; |
| 85 | coda_inode->i_blocks = (coda_inode->i_size + 511) >> 9; | 85 | coda_inode->i_blocks = (coda_inode->i_size + 511) >> 9; |
| 86 | coda_inode->i_mtime = coda_inode->i_ctime = CURRENT_TIME_SEC; | 86 | coda_inode->i_mtime = coda_inode->i_ctime = CURRENT_TIME_SEC; |
| 87 | up(&coda_inode->i_sem); | 87 | mutex_unlock(&coda_inode->i_mutex); |
| 88 | 88 | ||
| 89 | return ret; | 89 | return ret; |
| 90 | } | 90 | } |
| @@ -272,9 +272,9 @@ int coda_fsync(struct file *coda_file, struct dentry *coda_dentry, int datasync) | |||
| 272 | if (host_file->f_op && host_file->f_op->fsync) { | 272 | if (host_file->f_op && host_file->f_op->fsync) { |
| 273 | host_dentry = host_file->f_dentry; | 273 | host_dentry = host_file->f_dentry; |
| 274 | host_inode = host_dentry->d_inode; | 274 | host_inode = host_dentry->d_inode; |
| 275 | down(&host_inode->i_sem); | 275 | mutex_lock(&host_inode->i_mutex); |
| 276 | err = host_file->f_op->fsync(host_file, host_dentry, datasync); | 276 | err = host_file->f_op->fsync(host_file, host_dentry, datasync); |
| 277 | up(&host_inode->i_sem); | 277 | mutex_unlock(&host_inode->i_mutex); |
| 278 | } | 278 | } |
| 279 | 279 | ||
| 280 | if ( !err && !datasync ) { | 280 | if ( !err && !datasync ) { |
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index e48b539243a1..b668ec61527e 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c | |||
| @@ -288,10 +288,10 @@ static struct dentry * configfs_lookup(struct inode *dir, | |||
| 288 | 288 | ||
| 289 | /* | 289 | /* |
| 290 | * Only subdirectories count here. Files (CONFIGFS_NOT_PINNED) are | 290 | * Only subdirectories count here. Files (CONFIGFS_NOT_PINNED) are |
| 291 | * attributes and are removed by rmdir(). We recurse, taking i_sem | 291 | * attributes and are removed by rmdir(). We recurse, taking i_mutex |
| 292 | * on all children that are candidates for default detach. If the | 292 | * on all children that are candidates for default detach. If the |
| 293 | * result is clean, then configfs_detach_group() will handle dropping | 293 | * result is clean, then configfs_detach_group() will handle dropping |
| 294 | * i_sem. If there is an error, the caller will clean up the i_sem | 294 | * i_mutex. If there is an error, the caller will clean up the i_mutex |
| 295 | * holders via configfs_detach_rollback(). | 295 | * holders via configfs_detach_rollback(). |
| 296 | */ | 296 | */ |
| 297 | static int configfs_detach_prep(struct dentry *dentry) | 297 | static int configfs_detach_prep(struct dentry *dentry) |
| @@ -309,8 +309,8 @@ static int configfs_detach_prep(struct dentry *dentry) | |||
| 309 | if (sd->s_type & CONFIGFS_NOT_PINNED) | 309 | if (sd->s_type & CONFIGFS_NOT_PINNED) |
| 310 | continue; | 310 | continue; |
| 311 | if (sd->s_type & CONFIGFS_USET_DEFAULT) { | 311 | if (sd->s_type & CONFIGFS_USET_DEFAULT) { |
| 312 | down(&sd->s_dentry->d_inode->i_sem); | 312 | mutex_lock(&sd->s_dentry->d_inode->i_mutex); |
| 313 | /* Mark that we've taken i_sem */ | 313 | /* Mark that we've taken i_mutex */ |
| 314 | sd->s_type |= CONFIGFS_USET_DROPPING; | 314 | sd->s_type |= CONFIGFS_USET_DROPPING; |
| 315 | 315 | ||
| 316 | ret = configfs_detach_prep(sd->s_dentry); | 316 | ret = configfs_detach_prep(sd->s_dentry); |
| @@ -327,7 +327,7 @@ out: | |||
| 327 | } | 327 | } |
| 328 | 328 | ||
| 329 | /* | 329 | /* |
| 330 | * Walk the tree, dropping i_sem wherever CONFIGFS_USET_DROPPING is | 330 | * Walk the tree, dropping i_mutex wherever CONFIGFS_USET_DROPPING is |
| 331 | * set. | 331 | * set. |
| 332 | */ | 332 | */ |
| 333 | static void configfs_detach_rollback(struct dentry *dentry) | 333 | static void configfs_detach_rollback(struct dentry *dentry) |
| @@ -341,7 +341,7 @@ static void configfs_detach_rollback(struct dentry *dentry) | |||
| 341 | 341 | ||
| 342 | if (sd->s_type & CONFIGFS_USET_DROPPING) { | 342 | if (sd->s_type & CONFIGFS_USET_DROPPING) { |
| 343 | sd->s_type &= ~CONFIGFS_USET_DROPPING; | 343 | sd->s_type &= ~CONFIGFS_USET_DROPPING; |
| 344 | up(&sd->s_dentry->d_inode->i_sem); | 344 | mutex_unlock(&sd->s_dentry->d_inode->i_mutex); |
| 345 | } | 345 | } |
| 346 | } | 346 | } |
| 347 | } | 347 | } |
| @@ -424,11 +424,11 @@ static void detach_groups(struct config_group *group) | |||
| 424 | 424 | ||
| 425 | /* | 425 | /* |
| 426 | * From rmdir/unregister, a configfs_detach_prep() pass | 426 | * From rmdir/unregister, a configfs_detach_prep() pass |
| 427 | * has taken our i_sem for us. Drop it. | 427 | * has taken our i_mutex for us. Drop it. |
| 428 | * From mkdir/register cleanup, there is no sem held. | 428 | * From mkdir/register cleanup, there is no sem held. |
| 429 | */ | 429 | */ |
| 430 | if (sd->s_type & CONFIGFS_USET_DROPPING) | 430 | if (sd->s_type & CONFIGFS_USET_DROPPING) |
| 431 | up(&child->d_inode->i_sem); | 431 | mutex_unlock(&child->d_inode->i_mutex); |
| 432 | 432 | ||
| 433 | d_delete(child); | 433 | d_delete(child); |
| 434 | dput(child); | 434 | dput(child); |
| @@ -493,11 +493,11 @@ static int populate_groups(struct config_group *group) | |||
| 493 | /* FYI, we're faking mkdir here | 493 | /* FYI, we're faking mkdir here |
| 494 | * I'm not sure we need this semaphore, as we're called | 494 | * I'm not sure we need this semaphore, as we're called |
| 495 | * from our parent's mkdir. That holds our parent's | 495 | * from our parent's mkdir. That holds our parent's |
| 496 | * i_sem, so afaik lookup cannot continue through our | 496 | * i_mutex, so afaik lookup cannot continue through our |
| 497 | * parent to find us, let alone mess with our tree. | 497 | * parent to find us, let alone mess with our tree. |
| 498 | * That said, taking our i_sem is closer to mkdir | 498 | * That said, taking our i_mutex is closer to mkdir |
| 499 | * emulation, and shouldn't hurt. */ | 499 | * emulation, and shouldn't hurt. */ |
| 500 | down(&dentry->d_inode->i_sem); | 500 | mutex_lock(&dentry->d_inode->i_mutex); |
| 501 | 501 | ||
| 502 | for (i = 0; group->default_groups[i]; i++) { | 502 | for (i = 0; group->default_groups[i]; i++) { |
| 503 | new_group = group->default_groups[i]; | 503 | new_group = group->default_groups[i]; |
| @@ -507,7 +507,7 @@ static int populate_groups(struct config_group *group) | |||
| 507 | break; | 507 | break; |
| 508 | } | 508 | } |
| 509 | 509 | ||
| 510 | up(&dentry->d_inode->i_sem); | 510 | mutex_unlock(&dentry->d_inode->i_mutex); |
| 511 | } | 511 | } |
| 512 | 512 | ||
| 513 | if (ret) | 513 | if (ret) |
| @@ -856,7 +856,7 @@ int configfs_rename_dir(struct config_item * item, const char *new_name) | |||
| 856 | down_write(&configfs_rename_sem); | 856 | down_write(&configfs_rename_sem); |
| 857 | parent = item->parent->dentry; | 857 | parent = item->parent->dentry; |
| 858 | 858 | ||
| 859 | down(&parent->d_inode->i_sem); | 859 | mutex_lock(&parent->d_inode->i_mutex); |
| 860 | 860 | ||
| 861 | new_dentry = lookup_one_len(new_name, parent, strlen(new_name)); | 861 | new_dentry = lookup_one_len(new_name, parent, strlen(new_name)); |
| 862 | if (!IS_ERR(new_dentry)) { | 862 | if (!IS_ERR(new_dentry)) { |
| @@ -872,7 +872,7 @@ int configfs_rename_dir(struct config_item * item, const char *new_name) | |||
| 872 | error = -EEXIST; | 872 | error = -EEXIST; |
| 873 | dput(new_dentry); | 873 | dput(new_dentry); |
| 874 | } | 874 | } |
| 875 | up(&parent->d_inode->i_sem); | 875 | mutex_unlock(&parent->d_inode->i_mutex); |
| 876 | up_write(&configfs_rename_sem); | 876 | up_write(&configfs_rename_sem); |
| 877 | 877 | ||
| 878 | return error; | 878 | return error; |
| @@ -884,9 +884,9 @@ static int configfs_dir_open(struct inode *inode, struct file *file) | |||
| 884 | struct dentry * dentry = file->f_dentry; | 884 | struct dentry * dentry = file->f_dentry; |
| 885 | struct configfs_dirent * parent_sd = dentry->d_fsdata; | 885 | struct configfs_dirent * parent_sd = dentry->d_fsdata; |
| 886 | 886 | ||
| 887 | down(&dentry->d_inode->i_sem); | 887 | mutex_lock(&dentry->d_inode->i_mutex); |
| 888 | file->private_data = configfs_new_dirent(parent_sd, NULL); | 888 | file->private_data = configfs_new_dirent(parent_sd, NULL); |
| 889 | up(&dentry->d_inode->i_sem); | 889 | mutex_unlock(&dentry->d_inode->i_mutex); |
| 890 | 890 | ||
| 891 | return file->private_data ? 0 : -ENOMEM; | 891 | return file->private_data ? 0 : -ENOMEM; |
| 892 | 892 | ||
| @@ -897,9 +897,9 @@ static int configfs_dir_close(struct inode *inode, struct file *file) | |||
| 897 | struct dentry * dentry = file->f_dentry; | 897 | struct dentry * dentry = file->f_dentry; |
| 898 | struct configfs_dirent * cursor = file->private_data; | 898 | struct configfs_dirent * cursor = file->private_data; |
| 899 | 899 | ||
| 900 | down(&dentry->d_inode->i_sem); | 900 | mutex_lock(&dentry->d_inode->i_mutex); |
| 901 | list_del_init(&cursor->s_sibling); | 901 | list_del_init(&cursor->s_sibling); |
| 902 | up(&dentry->d_inode->i_sem); | 902 | mutex_unlock(&dentry->d_inode->i_mutex); |
| 903 | 903 | ||
| 904 | release_configfs_dirent(cursor); | 904 | release_configfs_dirent(cursor); |
| 905 | 905 | ||
| @@ -975,7 +975,7 @@ static loff_t configfs_dir_lseek(struct file * file, loff_t offset, int origin) | |||
| 975 | { | 975 | { |
| 976 | struct dentry * dentry = file->f_dentry; | 976 | struct dentry * dentry = file->f_dentry; |
| 977 | 977 | ||
| 978 | down(&dentry->d_inode->i_sem); | 978 | mutex_lock(&dentry->d_inode->i_mutex); |
| 979 | switch (origin) { | 979 | switch (origin) { |
| 980 | case 1: | 980 | case 1: |
| 981 | offset += file->f_pos; | 981 | offset += file->f_pos; |
| @@ -983,7 +983,7 @@ static loff_t configfs_dir_lseek(struct file * file, loff_t offset, int origin) | |||
| 983 | if (offset >= 0) | 983 | if (offset >= 0) |
| 984 | break; | 984 | break; |
| 985 | default: | 985 | default: |
| 986 | up(&file->f_dentry->d_inode->i_sem); | 986 | mutex_unlock(&file->f_dentry->d_inode->i_mutex); |
| 987 | return -EINVAL; | 987 | return -EINVAL; |
| 988 | } | 988 | } |
| 989 | if (offset != file->f_pos) { | 989 | if (offset != file->f_pos) { |
| @@ -1007,7 +1007,7 @@ static loff_t configfs_dir_lseek(struct file * file, loff_t offset, int origin) | |||
| 1007 | list_add_tail(&cursor->s_sibling, p); | 1007 | list_add_tail(&cursor->s_sibling, p); |
| 1008 | } | 1008 | } |
| 1009 | } | 1009 | } |
| 1010 | up(&dentry->d_inode->i_sem); | 1010 | mutex_unlock(&dentry->d_inode->i_mutex); |
| 1011 | return offset; | 1011 | return offset; |
| 1012 | } | 1012 | } |
| 1013 | 1013 | ||
| @@ -1037,7 +1037,7 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys) | |||
| 1037 | sd = configfs_sb->s_root->d_fsdata; | 1037 | sd = configfs_sb->s_root->d_fsdata; |
| 1038 | link_group(to_config_group(sd->s_element), group); | 1038 | link_group(to_config_group(sd->s_element), group); |
| 1039 | 1039 | ||
| 1040 | down(&configfs_sb->s_root->d_inode->i_sem); | 1040 | mutex_lock(&configfs_sb->s_root->d_inode->i_mutex); |
| 1041 | 1041 | ||
| 1042 | name.name = group->cg_item.ci_name; | 1042 | name.name = group->cg_item.ci_name; |
| 1043 | name.len = strlen(name.name); | 1043 | name.len = strlen(name.name); |
| @@ -1057,7 +1057,7 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys) | |||
| 1057 | else | 1057 | else |
| 1058 | d_delete(dentry); | 1058 | d_delete(dentry); |
| 1059 | 1059 | ||
| 1060 | up(&configfs_sb->s_root->d_inode->i_sem); | 1060 | mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex); |
| 1061 | 1061 | ||
| 1062 | if (dentry) { | 1062 | if (dentry) { |
| 1063 | dput(dentry); | 1063 | dput(dentry); |
| @@ -1079,18 +1079,18 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys) | |||
| 1079 | return; | 1079 | return; |
| 1080 | } | 1080 | } |
| 1081 | 1081 | ||
| 1082 | down(&configfs_sb->s_root->d_inode->i_sem); | 1082 | mutex_lock(&configfs_sb->s_root->d_inode->i_mutex); |
| 1083 | down(&dentry->d_inode->i_sem); | 1083 | mutex_lock(&dentry->d_inode->i_mutex); |
| 1084 | if (configfs_detach_prep(dentry)) { | 1084 | if (configfs_detach_prep(dentry)) { |
| 1085 | printk(KERN_ERR "configfs: Tried to unregister non-empty subsystem!\n"); | 1085 | printk(KERN_ERR "configfs: Tried to unregister non-empty subsystem!\n"); |
| 1086 | } | 1086 | } |
| 1087 | configfs_detach_group(&group->cg_item); | 1087 | configfs_detach_group(&group->cg_item); |
| 1088 | dentry->d_inode->i_flags |= S_DEAD; | 1088 | dentry->d_inode->i_flags |= S_DEAD; |
| 1089 | up(&dentry->d_inode->i_sem); | 1089 | mutex_unlock(&dentry->d_inode->i_mutex); |
| 1090 | 1090 | ||
| 1091 | d_delete(dentry); | 1091 | d_delete(dentry); |
| 1092 | 1092 | ||
| 1093 | up(&configfs_sb->s_root->d_inode->i_sem); | 1093 | mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex); |
| 1094 | 1094 | ||
| 1095 | dput(dentry); | 1095 | dput(dentry); |
| 1096 | 1096 | ||
diff --git a/fs/configfs/file.c b/fs/configfs/file.c index af1ffc9a15c0..c26cd61f13af 100644 --- a/fs/configfs/file.c +++ b/fs/configfs/file.c | |||
| @@ -336,9 +336,9 @@ int configfs_add_file(struct dentry * dir, const struct configfs_attribute * att | |||
| 336 | umode_t mode = (attr->ca_mode & S_IALLUGO) | S_IFREG; | 336 | umode_t mode = (attr->ca_mode & S_IALLUGO) | S_IFREG; |
| 337 | int error = 0; | 337 | int error = 0; |
| 338 | 338 | ||
| 339 | down(&dir->d_inode->i_sem); | 339 | mutex_lock(&dir->d_inode->i_mutex); |
| 340 | error = configfs_make_dirent(parent_sd, NULL, (void *) attr, mode, type); | 340 | error = configfs_make_dirent(parent_sd, NULL, (void *) attr, mode, type); |
| 341 | up(&dir->d_inode->i_sem); | 341 | mutex_unlock(&dir->d_inode->i_mutex); |
| 342 | 342 | ||
| 343 | return error; | 343 | return error; |
| 344 | } | 344 | } |
diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c index 6b274c6d428f..6577c588de9d 100644 --- a/fs/configfs/inode.c +++ b/fs/configfs/inode.c | |||
| @@ -122,7 +122,7 @@ const unsigned char * configfs_get_name(struct configfs_dirent *sd) | |||
| 122 | 122 | ||
| 123 | /* | 123 | /* |
| 124 | * Unhashes the dentry corresponding to given configfs_dirent | 124 | * Unhashes the dentry corresponding to given configfs_dirent |
| 125 | * Called with parent inode's i_sem held. | 125 | * Called with parent inode's i_mutex held. |
| 126 | */ | 126 | */ |
| 127 | void configfs_drop_dentry(struct configfs_dirent * sd, struct dentry * parent) | 127 | void configfs_drop_dentry(struct configfs_dirent * sd, struct dentry * parent) |
| 128 | { | 128 | { |
| @@ -145,7 +145,7 @@ void configfs_hash_and_remove(struct dentry * dir, const char * name) | |||
| 145 | struct configfs_dirent * sd; | 145 | struct configfs_dirent * sd; |
| 146 | struct configfs_dirent * parent_sd = dir->d_fsdata; | 146 | struct configfs_dirent * parent_sd = dir->d_fsdata; |
| 147 | 147 | ||
| 148 | down(&dir->d_inode->i_sem); | 148 | mutex_lock(&dir->d_inode->i_mutex); |
| 149 | list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { | 149 | list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { |
| 150 | if (!sd->s_element) | 150 | if (!sd->s_element) |
| 151 | continue; | 151 | continue; |
| @@ -156,7 +156,7 @@ void configfs_hash_and_remove(struct dentry * dir, const char * name) | |||
| 156 | break; | 156 | break; |
| 157 | } | 157 | } |
| 158 | } | 158 | } |
| 159 | up(&dir->d_inode->i_sem); | 159 | mutex_unlock(&dir->d_inode->i_mutex); |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | 162 | ||
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index a86ac4aeaedb..d4f1a2cddd47 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c | |||
| @@ -146,7 +146,7 @@ static int debugfs_create_by_name(const char *name, mode_t mode, | |||
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | *dentry = NULL; | 148 | *dentry = NULL; |
| 149 | down(&parent->d_inode->i_sem); | 149 | mutex_lock(&parent->d_inode->i_mutex); |
| 150 | *dentry = lookup_one_len(name, parent, strlen(name)); | 150 | *dentry = lookup_one_len(name, parent, strlen(name)); |
| 151 | if (!IS_ERR(dentry)) { | 151 | if (!IS_ERR(dentry)) { |
| 152 | if ((mode & S_IFMT) == S_IFDIR) | 152 | if ((mode & S_IFMT) == S_IFDIR) |
| @@ -155,7 +155,7 @@ static int debugfs_create_by_name(const char *name, mode_t mode, | |||
| 155 | error = debugfs_create(parent->d_inode, *dentry, mode); | 155 | error = debugfs_create(parent->d_inode, *dentry, mode); |
| 156 | } else | 156 | } else |
| 157 | error = PTR_ERR(dentry); | 157 | error = PTR_ERR(dentry); |
| 158 | up(&parent->d_inode->i_sem); | 158 | mutex_unlock(&parent->d_inode->i_mutex); |
| 159 | 159 | ||
| 160 | return error; | 160 | return error; |
| 161 | } | 161 | } |
| @@ -273,7 +273,7 @@ void debugfs_remove(struct dentry *dentry) | |||
| 273 | if (!parent || !parent->d_inode) | 273 | if (!parent || !parent->d_inode) |
| 274 | return; | 274 | return; |
| 275 | 275 | ||
| 276 | down(&parent->d_inode->i_sem); | 276 | mutex_lock(&parent->d_inode->i_mutex); |
| 277 | if (debugfs_positive(dentry)) { | 277 | if (debugfs_positive(dentry)) { |
| 278 | if (dentry->d_inode) { | 278 | if (dentry->d_inode) { |
| 279 | if (S_ISDIR(dentry->d_inode->i_mode)) | 279 | if (S_ISDIR(dentry->d_inode->i_mode)) |
| @@ -283,7 +283,7 @@ void debugfs_remove(struct dentry *dentry) | |||
| 283 | dput(dentry); | 283 | dput(dentry); |
| 284 | } | 284 | } |
| 285 | } | 285 | } |
| 286 | up(&parent->d_inode->i_sem); | 286 | mutex_unlock(&parent->d_inode->i_mutex); |
| 287 | simple_release_fs(&debugfs_mount, &debugfs_mount_count); | 287 | simple_release_fs(&debugfs_mount, &debugfs_mount_count); |
| 288 | } | 288 | } |
| 289 | EXPORT_SYMBOL_GPL(debugfs_remove); | 289 | EXPORT_SYMBOL_GPL(debugfs_remove); |
diff --git a/fs/devfs/base.c b/fs/devfs/base.c index 1274422a5384..b621521e09d4 100644 --- a/fs/devfs/base.c +++ b/fs/devfs/base.c | |||
| @@ -2162,27 +2162,27 @@ static int devfs_d_revalidate_wait(struct dentry *dentry, struct nameidata *nd) | |||
| 2162 | * | 2162 | * |
| 2163 | * make sure that | 2163 | * make sure that |
| 2164 | * d_instantiate always runs under lock | 2164 | * d_instantiate always runs under lock |
| 2165 | * we release i_sem lock before going to sleep | 2165 | * we release i_mutex lock before going to sleep |
| 2166 | * | 2166 | * |
| 2167 | * unfortunately sometimes d_revalidate is called with | 2167 | * unfortunately sometimes d_revalidate is called with |
| 2168 | * and sometimes without i_sem lock held. The following checks | 2168 | * and sometimes without i_mutex lock held. The following checks |
| 2169 | * attempt to deduce when we need to add (and drop resp.) lock | 2169 | * attempt to deduce when we need to add (and drop resp.) lock |
| 2170 | * here. This relies on current (2.6.2) calling coventions: | 2170 | * here. This relies on current (2.6.2) calling coventions: |
| 2171 | * | 2171 | * |
| 2172 | * lookup_hash is always run under i_sem and is passing NULL | 2172 | * lookup_hash is always run under i_mutex and is passing NULL |
| 2173 | * as nd | 2173 | * as nd |
| 2174 | * | 2174 | * |
| 2175 | * open(...,O_CREATE,...) calls _lookup_hash under i_sem | 2175 | * open(...,O_CREATE,...) calls _lookup_hash under i_mutex |
| 2176 | * and sets flags to LOOKUP_OPEN|LOOKUP_CREATE | 2176 | * and sets flags to LOOKUP_OPEN|LOOKUP_CREATE |
| 2177 | * | 2177 | * |
| 2178 | * all other invocations of ->d_revalidate seem to happen | 2178 | * all other invocations of ->d_revalidate seem to happen |
| 2179 | * outside of i_sem | 2179 | * outside of i_mutex |
| 2180 | */ | 2180 | */ |
| 2181 | need_lock = nd && | 2181 | need_lock = nd && |
| 2182 | (!(nd->flags & LOOKUP_CREATE) || (nd->flags & LOOKUP_PARENT)); | 2182 | (!(nd->flags & LOOKUP_CREATE) || (nd->flags & LOOKUP_PARENT)); |
| 2183 | 2183 | ||
| 2184 | if (need_lock) | 2184 | if (need_lock) |
| 2185 | down(&dir->i_sem); | 2185 | mutex_lock(&dir->i_mutex); |
| 2186 | 2186 | ||
| 2187 | if (is_devfsd_or_child(fs_info)) { | 2187 | if (is_devfsd_or_child(fs_info)) { |
| 2188 | devfs_handle_t de = lookup_info->de; | 2188 | devfs_handle_t de = lookup_info->de; |
| @@ -2221,9 +2221,9 @@ static int devfs_d_revalidate_wait(struct dentry *dentry, struct nameidata *nd) | |||
| 2221 | add_wait_queue(&lookup_info->wait_queue, &wait); | 2221 | add_wait_queue(&lookup_info->wait_queue, &wait); |
| 2222 | read_unlock(&parent->u.dir.lock); | 2222 | read_unlock(&parent->u.dir.lock); |
| 2223 | /* at this point it is always (hopefully) locked */ | 2223 | /* at this point it is always (hopefully) locked */ |
| 2224 | up(&dir->i_sem); | 2224 | mutex_unlock(&dir->i_mutex); |
| 2225 | schedule(); | 2225 | schedule(); |
| 2226 | down(&dir->i_sem); | 2226 | mutex_lock(&dir->i_mutex); |
| 2227 | /* | 2227 | /* |
| 2228 | * This does not need nor should remove wait from wait_queue. | 2228 | * This does not need nor should remove wait from wait_queue. |
| 2229 | * Wait queue head is never reused - nothing is ever added to it | 2229 | * Wait queue head is never reused - nothing is ever added to it |
| @@ -2238,7 +2238,7 @@ static int devfs_d_revalidate_wait(struct dentry *dentry, struct nameidata *nd) | |||
| 2238 | 2238 | ||
| 2239 | out: | 2239 | out: |
| 2240 | if (need_lock) | 2240 | if (need_lock) |
| 2241 | up(&dir->i_sem); | 2241 | mutex_unlock(&dir->i_mutex); |
| 2242 | return 1; | 2242 | return 1; |
| 2243 | } /* End Function devfs_d_revalidate_wait */ | 2243 | } /* End Function devfs_d_revalidate_wait */ |
| 2244 | 2244 | ||
| @@ -2284,9 +2284,9 @@ static struct dentry *devfs_lookup(struct inode *dir, struct dentry *dentry, | |||
| 2284 | /* Unlock directory semaphore, which will release any waiters. They | 2284 | /* Unlock directory semaphore, which will release any waiters. They |
| 2285 | will get the hashed dentry, and may be forced to wait for | 2285 | will get the hashed dentry, and may be forced to wait for |
| 2286 | revalidation */ | 2286 | revalidation */ |
| 2287 | up(&dir->i_sem); | 2287 | mutex_unlock(&dir->i_mutex); |
| 2288 | wait_for_devfsd_finished(fs_info); /* If I'm not devfsd, must wait */ | 2288 | wait_for_devfsd_finished(fs_info); /* If I'm not devfsd, must wait */ |
| 2289 | down(&dir->i_sem); /* Grab it again because them's the rules */ | 2289 | mutex_lock(&dir->i_mutex); /* Grab it again because them's the rules */ |
| 2290 | de = lookup_info.de; | 2290 | de = lookup_info.de; |
| 2291 | /* If someone else has been so kind as to make the inode, we go home | 2291 | /* If someone else has been so kind as to make the inode, we go home |
| 2292 | early */ | 2292 | early */ |
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index f2be44d4491f..bfb8a230bac9 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c | |||
| @@ -130,7 +130,7 @@ static struct dentry *get_node(int num) | |||
| 130 | { | 130 | { |
| 131 | char s[12]; | 131 | char s[12]; |
| 132 | struct dentry *root = devpts_root; | 132 | struct dentry *root = devpts_root; |
| 133 | down(&root->d_inode->i_sem); | 133 | mutex_lock(&root->d_inode->i_mutex); |
| 134 | return lookup_one_len(s, root, sprintf(s, "%d", num)); | 134 | return lookup_one_len(s, root, sprintf(s, "%d", num)); |
| 135 | } | 135 | } |
| 136 | 136 | ||
| @@ -161,7 +161,7 @@ int devpts_pty_new(struct tty_struct *tty) | |||
| 161 | if (!IS_ERR(dentry) && !dentry->d_inode) | 161 | if (!IS_ERR(dentry) && !dentry->d_inode) |
| 162 | d_instantiate(dentry, inode); | 162 | d_instantiate(dentry, inode); |
| 163 | 163 | ||
| 164 | up(&devpts_root->d_inode->i_sem); | 164 | mutex_unlock(&devpts_root->d_inode->i_mutex); |
| 165 | 165 | ||
| 166 | return 0; | 166 | return 0; |
| 167 | } | 167 | } |
| @@ -178,7 +178,7 @@ struct tty_struct *devpts_get_tty(int number) | |||
| 178 | dput(dentry); | 178 | dput(dentry); |
| 179 | } | 179 | } |
| 180 | 180 | ||
| 181 | up(&devpts_root->d_inode->i_sem); | 181 | mutex_unlock(&devpts_root->d_inode->i_mutex); |
| 182 | 182 | ||
| 183 | return tty; | 183 | return tty; |
| 184 | } | 184 | } |
| @@ -196,7 +196,7 @@ void devpts_pty_kill(int number) | |||
| 196 | } | 196 | } |
| 197 | dput(dentry); | 197 | dput(dentry); |
| 198 | } | 198 | } |
| 199 | up(&devpts_root->d_inode->i_sem); | 199 | mutex_unlock(&devpts_root->d_inode->i_mutex); |
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | static int __init init_devpts_fs(void) | 202 | static int __init init_devpts_fs(void) |
diff --git a/fs/direct-io.c b/fs/direct-io.c index 3931e7f1e6bf..30dbbd1df511 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c | |||
| @@ -56,7 +56,7 @@ | |||
| 56 | * lock_type is DIO_LOCKING for regular files on direct-IO-naive filesystems. | 56 | * lock_type is DIO_LOCKING for regular files on direct-IO-naive filesystems. |
| 57 | * This determines whether we need to do the fancy locking which prevents | 57 | * This determines whether we need to do the fancy locking which prevents |
| 58 | * direct-IO from being able to read uninitialised disk blocks. If its zero | 58 | * direct-IO from being able to read uninitialised disk blocks. If its zero |
| 59 | * (blockdev) this locking is not done, and if it is DIO_OWN_LOCKING i_sem is | 59 | * (blockdev) this locking is not done, and if it is DIO_OWN_LOCKING i_mutex is |
| 60 | * not held for the entire direct write (taken briefly, initially, during a | 60 | * not held for the entire direct write (taken briefly, initially, during a |
| 61 | * direct read though, but its never held for the duration of a direct-IO). | 61 | * direct read though, but its never held for the duration of a direct-IO). |
| 62 | */ | 62 | */ |
| @@ -930,7 +930,7 @@ out: | |||
| 930 | } | 930 | } |
| 931 | 931 | ||
| 932 | /* | 932 | /* |
| 933 | * Releases both i_sem and i_alloc_sem | 933 | * Releases both i_mutex and i_alloc_sem |
| 934 | */ | 934 | */ |
| 935 | static ssize_t | 935 | static ssize_t |
| 936 | direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode, | 936 | direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode, |
| @@ -1062,11 +1062,11 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode, | |||
| 1062 | 1062 | ||
| 1063 | /* | 1063 | /* |
| 1064 | * All block lookups have been performed. For READ requests | 1064 | * All block lookups have been performed. For READ requests |
| 1065 | * we can let i_sem go now that its achieved its purpose | 1065 | * we can let i_mutex go now that its achieved its purpose |
| 1066 | * of protecting us from looking up uninitialized blocks. | 1066 | * of protecting us from looking up uninitialized blocks. |
| 1067 | */ | 1067 | */ |
| 1068 | if ((rw == READ) && (dio->lock_type == DIO_LOCKING)) | 1068 | if ((rw == READ) && (dio->lock_type == DIO_LOCKING)) |
| 1069 | up(&dio->inode->i_sem); | 1069 | mutex_unlock(&dio->inode->i_mutex); |
| 1070 | 1070 | ||
| 1071 | /* | 1071 | /* |
| 1072 | * OK, all BIOs are submitted, so we can decrement bio_count to truly | 1072 | * OK, all BIOs are submitted, so we can decrement bio_count to truly |
| @@ -1145,18 +1145,18 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode, | |||
| 1145 | * The locking rules are governed by the dio_lock_type parameter. | 1145 | * The locking rules are governed by the dio_lock_type parameter. |
| 1146 | * | 1146 | * |
| 1147 | * DIO_NO_LOCKING (no locking, for raw block device access) | 1147 | * DIO_NO_LOCKING (no locking, for raw block device access) |
| 1148 | * For writes, i_sem is not held on entry; it is never taken. | 1148 | * For writes, i_mutex is not held on entry; it is never taken. |
| 1149 | * | 1149 | * |
| 1150 | * DIO_LOCKING (simple locking for regular files) | 1150 | * DIO_LOCKING (simple locking for regular files) |
| 1151 | * For writes we are called under i_sem and return with i_sem held, even though | 1151 | * For writes we are called under i_mutex and return with i_mutex held, even though |
| 1152 | * it is internally dropped. | 1152 | * it is internally dropped. |
| 1153 | * For reads, i_sem is not held on entry, but it is taken and dropped before | 1153 | * For reads, i_mutex is not held on entry, but it is taken and dropped before |
| 1154 | * returning. | 1154 | * returning. |
| 1155 | * | 1155 | * |
| 1156 | * DIO_OWN_LOCKING (filesystem provides synchronisation and handling of | 1156 | * DIO_OWN_LOCKING (filesystem provides synchronisation and handling of |
| 1157 | * uninitialised data, allowing parallel direct readers and writers) | 1157 | * uninitialised data, allowing parallel direct readers and writers) |
| 1158 | * For writes we are called without i_sem, return without it, never touch it. | 1158 | * For writes we are called without i_mutex, return without it, never touch it. |
| 1159 | * For reads, i_sem is held on entry and will be released before returning. | 1159 | * For reads, i_mutex is held on entry and will be released before returning. |
| 1160 | * | 1160 | * |
| 1161 | * Additional i_alloc_sem locking requirements described inline below. | 1161 | * Additional i_alloc_sem locking requirements described inline below. |
| 1162 | */ | 1162 | */ |
| @@ -1214,11 +1214,11 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, | |||
| 1214 | * For block device access DIO_NO_LOCKING is used, | 1214 | * For block device access DIO_NO_LOCKING is used, |
| 1215 | * neither readers nor writers do any locking at all | 1215 | * neither readers nor writers do any locking at all |
| 1216 | * For regular files using DIO_LOCKING, | 1216 | * For regular files using DIO_LOCKING, |
| 1217 | * readers need to grab i_sem and i_alloc_sem | 1217 | * readers need to grab i_mutex and i_alloc_sem |
| 1218 | * writers need to grab i_alloc_sem only (i_sem is already held) | 1218 | * writers need to grab i_alloc_sem only (i_mutex is already held) |
| 1219 | * For regular files using DIO_OWN_LOCKING, | 1219 | * For regular files using DIO_OWN_LOCKING, |
| 1220 | * neither readers nor writers take any locks here | 1220 | * neither readers nor writers take any locks here |
| 1221 | * (i_sem is already held and release for writers here) | 1221 | * (i_mutex is already held and release for writers here) |
| 1222 | */ | 1222 | */ |
| 1223 | dio->lock_type = dio_lock_type; | 1223 | dio->lock_type = dio_lock_type; |
| 1224 | if (dio_lock_type != DIO_NO_LOCKING) { | 1224 | if (dio_lock_type != DIO_NO_LOCKING) { |
| @@ -1228,7 +1228,7 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, | |||
| 1228 | 1228 | ||
| 1229 | mapping = iocb->ki_filp->f_mapping; | 1229 | mapping = iocb->ki_filp->f_mapping; |
| 1230 | if (dio_lock_type != DIO_OWN_LOCKING) { | 1230 | if (dio_lock_type != DIO_OWN_LOCKING) { |
| 1231 | down(&inode->i_sem); | 1231 | mutex_lock(&inode->i_mutex); |
| 1232 | reader_with_isem = 1; | 1232 | reader_with_isem = 1; |
| 1233 | } | 1233 | } |
| 1234 | 1234 | ||
| @@ -1240,7 +1240,7 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, | |||
| 1240 | } | 1240 | } |
| 1241 | 1241 | ||
| 1242 | if (dio_lock_type == DIO_OWN_LOCKING) { | 1242 | if (dio_lock_type == DIO_OWN_LOCKING) { |
| 1243 | up(&inode->i_sem); | 1243 | mutex_unlock(&inode->i_mutex); |
| 1244 | reader_with_isem = 0; | 1244 | reader_with_isem = 0; |
| 1245 | } | 1245 | } |
| 1246 | } | 1246 | } |
| @@ -1266,7 +1266,7 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, | |||
| 1266 | 1266 | ||
| 1267 | out: | 1267 | out: |
| 1268 | if (reader_with_isem) | 1268 | if (reader_with_isem) |
| 1269 | up(&inode->i_sem); | 1269 | mutex_unlock(&inode->i_mutex); |
| 1270 | if (rw & WRITE) | 1270 | if (rw & WRITE) |
| 1271 | current->flags &= ~PF_SYNCWRITE; | 1271 | current->flags &= ~PF_SYNCWRITE; |
| 1272 | return retval; | 1272 | return retval; |
diff --git a/fs/dquot.c b/fs/dquot.c index 2a62b3dc20ec..cb6d5bfbdfd5 100644 --- a/fs/dquot.c +++ b/fs/dquot.c | |||
| @@ -100,7 +100,7 @@ | |||
| 100 | * operation is just reading pointers from inode (or not using them at all) the | 100 | * operation is just reading pointers from inode (or not using them at all) the |
| 101 | * read lock is enough. If pointers are altered function must hold write lock | 101 | * read lock is enough. If pointers are altered function must hold write lock |
| 102 | * (these locking rules also apply for S_NOQUOTA flag in the inode - note that | 102 | * (these locking rules also apply for S_NOQUOTA flag in the inode - note that |
| 103 | * for altering the flag i_sem is also needed). If operation is holding | 103 | * for altering the flag i_mutex is also needed). If operation is holding |
| 104 | * reference to dquot in other way (e.g. quotactl ops) it must be guarded by | 104 | * reference to dquot in other way (e.g. quotactl ops) it must be guarded by |
| 105 | * dqonoff_sem. | 105 | * dqonoff_sem. |
| 106 | * This locking assures that: | 106 | * This locking assures that: |
| @@ -117,9 +117,9 @@ | |||
| 117 | * spinlock to internal buffers before writing. | 117 | * spinlock to internal buffers before writing. |
| 118 | * | 118 | * |
| 119 | * Lock ordering (including related VFS locks) is the following: | 119 | * Lock ordering (including related VFS locks) is the following: |
| 120 | * i_sem > dqonoff_sem > iprune_sem > journal_lock > dqptr_sem > | 120 | * i_mutex > dqonoff_sem > iprune_sem > journal_lock > dqptr_sem > |
| 121 | * > dquot->dq_lock > dqio_sem | 121 | * > dquot->dq_lock > dqio_sem |
| 122 | * i_sem on quota files is special (it's below dqio_sem) | 122 | * i_mutex on quota files is special (it's below dqio_sem) |
| 123 | */ | 123 | */ |
| 124 | 124 | ||
| 125 | static DEFINE_SPINLOCK(dq_list_lock); | 125 | static DEFINE_SPINLOCK(dq_list_lock); |
| @@ -1369,11 +1369,11 @@ int vfs_quota_off(struct super_block *sb, int type) | |||
| 1369 | /* If quota was reenabled in the meantime, we have | 1369 | /* If quota was reenabled in the meantime, we have |
| 1370 | * nothing to do */ | 1370 | * nothing to do */ |
| 1371 | if (!sb_has_quota_enabled(sb, cnt)) { | 1371 | if (!sb_has_quota_enabled(sb, cnt)) { |
| 1372 | down(&toputinode[cnt]->i_sem); | 1372 | mutex_lock(&toputinode[cnt]->i_mutex); |
| 1373 | toputinode[cnt]->i_flags &= ~(S_IMMUTABLE | | 1373 | toputinode[cnt]->i_flags &= ~(S_IMMUTABLE | |
| 1374 | S_NOATIME | S_NOQUOTA); | 1374 | S_NOATIME | S_NOQUOTA); |
| 1375 | truncate_inode_pages(&toputinode[cnt]->i_data, 0); | 1375 | truncate_inode_pages(&toputinode[cnt]->i_data, 0); |
| 1376 | up(&toputinode[cnt]->i_sem); | 1376 | mutex_unlock(&toputinode[cnt]->i_mutex); |
| 1377 | mark_inode_dirty(toputinode[cnt]); | 1377 | mark_inode_dirty(toputinode[cnt]); |
| 1378 | iput(toputinode[cnt]); | 1378 | iput(toputinode[cnt]); |
| 1379 | } | 1379 | } |
| @@ -1417,7 +1417,7 @@ static int vfs_quota_on_inode(struct inode *inode, int type, int format_id) | |||
| 1417 | write_inode_now(inode, 1); | 1417 | write_inode_now(inode, 1); |
| 1418 | /* And now flush the block cache so that kernel sees the changes */ | 1418 | /* And now flush the block cache so that kernel sees the changes */ |
| 1419 | invalidate_bdev(sb->s_bdev, 0); | 1419 | invalidate_bdev(sb->s_bdev, 0); |
| 1420 | down(&inode->i_sem); | 1420 | mutex_lock(&inode->i_mutex); |
| 1421 | down(&dqopt->dqonoff_sem); | 1421 | down(&dqopt->dqonoff_sem); |
| 1422 | if (sb_has_quota_enabled(sb, type)) { | 1422 | if (sb_has_quota_enabled(sb, type)) { |
| 1423 | error = -EBUSY; | 1423 | error = -EBUSY; |
| @@ -1449,7 +1449,7 @@ static int vfs_quota_on_inode(struct inode *inode, int type, int format_id) | |||
| 1449 | goto out_file_init; | 1449 | goto out_file_init; |
| 1450 | } | 1450 | } |
| 1451 | up(&dqopt->dqio_sem); | 1451 | up(&dqopt->dqio_sem); |
| 1452 | up(&inode->i_sem); | 1452 | mutex_unlock(&inode->i_mutex); |
| 1453 | set_enable_flags(dqopt, type); | 1453 | set_enable_flags(dqopt, type); |
| 1454 | 1454 | ||
| 1455 | add_dquot_ref(sb, type); | 1455 | add_dquot_ref(sb, type); |
| @@ -1470,7 +1470,7 @@ out_lock: | |||
| 1470 | inode->i_flags |= oldflags; | 1470 | inode->i_flags |= oldflags; |
| 1471 | up_write(&dqopt->dqptr_sem); | 1471 | up_write(&dqopt->dqptr_sem); |
| 1472 | } | 1472 | } |
| 1473 | up(&inode->i_sem); | 1473 | mutex_unlock(&inode->i_mutex); |
| 1474 | out_fmt: | 1474 | out_fmt: |
| 1475 | put_quota_format(fmt); | 1475 | put_quota_format(fmt); |
| 1476 | 1476 | ||
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c index c49d6254379a..5bfe40085fbc 100644 --- a/fs/exportfs/expfs.c +++ b/fs/exportfs/expfs.c | |||
| @@ -177,9 +177,9 @@ find_exported_dentry(struct super_block *sb, void *obj, void *parent, | |||
| 177 | struct dentry *ppd; | 177 | struct dentry *ppd; |
| 178 | struct dentry *npd; | 178 | struct dentry *npd; |
| 179 | 179 | ||
| 180 | down(&pd->d_inode->i_sem); | 180 | mutex_lock(&pd->d_inode->i_mutex); |
| 181 | ppd = CALL(nops,get_parent)(pd); | 181 | ppd = CALL(nops,get_parent)(pd); |
| 182 | up(&pd->d_inode->i_sem); | 182 | mutex_unlock(&pd->d_inode->i_mutex); |
| 183 | 183 | ||
| 184 | if (IS_ERR(ppd)) { | 184 | if (IS_ERR(ppd)) { |
| 185 | err = PTR_ERR(ppd); | 185 | err = PTR_ERR(ppd); |
| @@ -201,9 +201,9 @@ find_exported_dentry(struct super_block *sb, void *obj, void *parent, | |||
| 201 | break; | 201 | break; |
| 202 | } | 202 | } |
| 203 | dprintk("find_exported_dentry: found name: %s\n", nbuf); | 203 | dprintk("find_exported_dentry: found name: %s\n", nbuf); |
| 204 | down(&ppd->d_inode->i_sem); | 204 | mutex_lock(&ppd->d_inode->i_mutex); |
| 205 | npd = lookup_one_len(nbuf, ppd, strlen(nbuf)); | 205 | npd = lookup_one_len(nbuf, ppd, strlen(nbuf)); |
| 206 | up(&ppd->d_inode->i_sem); | 206 | mutex_unlock(&ppd->d_inode->i_mutex); |
| 207 | if (IS_ERR(npd)) { | 207 | if (IS_ERR(npd)) { |
| 208 | err = PTR_ERR(npd); | 208 | err = PTR_ERR(npd); |
| 209 | dprintk("find_exported_dentry: lookup failed: %d\n", err); | 209 | dprintk("find_exported_dentry: lookup failed: %d\n", err); |
| @@ -242,9 +242,9 @@ find_exported_dentry(struct super_block *sb, void *obj, void *parent, | |||
| 242 | struct dentry *nresult; | 242 | struct dentry *nresult; |
| 243 | err = CALL(nops,get_name)(target_dir, nbuf, result); | 243 | err = CALL(nops,get_name)(target_dir, nbuf, result); |
| 244 | if (!err) { | 244 | if (!err) { |
| 245 | down(&target_dir->d_inode->i_sem); | 245 | mutex_lock(&target_dir->d_inode->i_mutex); |
| 246 | nresult = lookup_one_len(nbuf, target_dir, strlen(nbuf)); | 246 | nresult = lookup_one_len(nbuf, target_dir, strlen(nbuf)); |
| 247 | up(&target_dir->d_inode->i_sem); | 247 | mutex_unlock(&target_dir->d_inode->i_mutex); |
| 248 | if (!IS_ERR(nresult)) { | 248 | if (!IS_ERR(nresult)) { |
| 249 | if (nresult->d_inode) { | 249 | if (nresult->d_inode) { |
| 250 | dput(result); | 250 | dput(result); |
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index 6af2f4130290..239133d01d91 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c | |||
| @@ -149,7 +149,7 @@ ext2_iset_acl(struct inode *inode, struct posix_acl **i_acl, | |||
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | /* | 151 | /* |
| 152 | * inode->i_sem: don't care | 152 | * inode->i_mutex: don't care |
| 153 | */ | 153 | */ |
| 154 | static struct posix_acl * | 154 | static struct posix_acl * |
| 155 | ext2_get_acl(struct inode *inode, int type) | 155 | ext2_get_acl(struct inode *inode, int type) |
| @@ -211,7 +211,7 @@ ext2_get_acl(struct inode *inode, int type) | |||
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | /* | 213 | /* |
| 214 | * inode->i_sem: down | 214 | * inode->i_mutex: down |
| 215 | */ | 215 | */ |
| 216 | static int | 216 | static int |
| 217 | ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl) | 217 | ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl) |
| @@ -301,8 +301,8 @@ ext2_permission(struct inode *inode, int mask, struct nameidata *nd) | |||
| 301 | /* | 301 | /* |
| 302 | * Initialize the ACLs of a new inode. Called from ext2_new_inode. | 302 | * Initialize the ACLs of a new inode. Called from ext2_new_inode. |
| 303 | * | 303 | * |
| 304 | * dir->i_sem: down | 304 | * dir->i_mutex: down |
| 305 | * inode->i_sem: up (access to inode is still exclusive) | 305 | * inode->i_mutex: up (access to inode is still exclusive) |
| 306 | */ | 306 | */ |
| 307 | int | 307 | int |
| 308 | ext2_init_acl(struct inode *inode, struct inode *dir) | 308 | ext2_init_acl(struct inode *inode, struct inode *dir) |
| @@ -361,7 +361,7 @@ cleanup: | |||
| 361 | * for directories) are added. There are no more bits available in the | 361 | * for directories) are added. There are no more bits available in the |
| 362 | * file mode. | 362 | * file mode. |
| 363 | * | 363 | * |
| 364 | * inode->i_sem: down | 364 | * inode->i_mutex: down |
| 365 | */ | 365 | */ |
| 366 | int | 366 | int |
| 367 | ext2_acl_chmod(struct inode *inode) | 367 | ext2_acl_chmod(struct inode *inode) |
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h index e977f8566d14..00de0a7312a2 100644 --- a/fs/ext2/ext2.h +++ b/fs/ext2/ext2.h | |||
| @@ -53,7 +53,7 @@ struct ext2_inode_info { | |||
| 53 | #ifdef CONFIG_EXT2_FS_XATTR | 53 | #ifdef CONFIG_EXT2_FS_XATTR |
| 54 | /* | 54 | /* |
| 55 | * Extended attributes can be read independently of the main file | 55 | * Extended attributes can be read independently of the main file |
| 56 | * data. Taking i_sem even when reading would cause contention | 56 | * data. Taking i_mutex even when reading would cause contention |
| 57 | * between readers of EAs and writers of regular file data, so | 57 | * between readers of EAs and writers of regular file data, so |
| 58 | * instead we synchronize on xattr_sem when reading or changing | 58 | * instead we synchronize on xattr_sem when reading or changing |
| 59 | * EAs. | 59 | * EAs. |
diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 522fa70dd8ea..8d6819846fc9 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c | |||
| @@ -1152,7 +1152,7 @@ static ssize_t ext2_quota_write(struct super_block *sb, int type, | |||
| 1152 | struct buffer_head tmp_bh; | 1152 | struct buffer_head tmp_bh; |
| 1153 | struct buffer_head *bh; | 1153 | struct buffer_head *bh; |
| 1154 | 1154 | ||
| 1155 | down(&inode->i_sem); | 1155 | mutex_lock(&inode->i_mutex); |
| 1156 | while (towrite > 0) { | 1156 | while (towrite > 0) { |
| 1157 | tocopy = sb->s_blocksize - offset < towrite ? | 1157 | tocopy = sb->s_blocksize - offset < towrite ? |
| 1158 | sb->s_blocksize - offset : towrite; | 1158 | sb->s_blocksize - offset : towrite; |
| @@ -1189,7 +1189,7 @@ out: | |||
| 1189 | inode->i_version++; | 1189 | inode->i_version++; |
| 1190 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 1190 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
| 1191 | mark_inode_dirty(inode); | 1191 | mark_inode_dirty(inode); |
| 1192 | up(&inode->i_sem); | 1192 | mutex_unlock(&inode->i_mutex); |
| 1193 | return len - towrite; | 1193 | return len - towrite; |
| 1194 | } | 1194 | } |
| 1195 | 1195 | ||
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index 0099462d4271..f7a3b5fee274 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c | |||
| @@ -325,7 +325,7 @@ cleanup: | |||
| 325 | /* | 325 | /* |
| 326 | * Inode operation listxattr() | 326 | * Inode operation listxattr() |
| 327 | * | 327 | * |
| 328 | * dentry->d_inode->i_sem: don't care | 328 | * dentry->d_inode->i_mutex: don't care |
| 329 | */ | 329 | */ |
| 330 | ssize_t | 330 | ssize_t |
| 331 | ext2_listxattr(struct dentry *dentry, char *buffer, size_t size) | 331 | ext2_listxattr(struct dentry *dentry, char *buffer, size_t size) |
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c index 3ac38266fc9e..9ed132c96034 100644 --- a/fs/ext3/acl.c +++ b/fs/ext3/acl.c | |||
| @@ -152,7 +152,7 @@ ext3_iset_acl(struct inode *inode, struct posix_acl **i_acl, | |||
| 152 | /* | 152 | /* |
| 153 | * Inode operation get_posix_acl(). | 153 | * Inode operation get_posix_acl(). |
| 154 | * | 154 | * |
| 155 | * inode->i_sem: don't care | 155 | * inode->i_mutex: don't care |
| 156 | */ | 156 | */ |
| 157 | static struct posix_acl * | 157 | static struct posix_acl * |
| 158 | ext3_get_acl(struct inode *inode, int type) | 158 | ext3_get_acl(struct inode *inode, int type) |
| @@ -216,7 +216,7 @@ ext3_get_acl(struct inode *inode, int type) | |||
| 216 | /* | 216 | /* |
| 217 | * Set the access or default ACL of an inode. | 217 | * Set the access or default ACL of an inode. |
| 218 | * | 218 | * |
| 219 | * inode->i_sem: down unless called from ext3_new_inode | 219 | * inode->i_mutex: down unless called from ext3_new_inode |
| 220 | */ | 220 | */ |
| 221 | static int | 221 | static int |
| 222 | ext3_set_acl(handle_t *handle, struct inode *inode, int type, | 222 | ext3_set_acl(handle_t *handle, struct inode *inode, int type, |
| @@ -306,8 +306,8 @@ ext3_permission(struct inode *inode, int mask, struct nameidata *nd) | |||
| 306 | /* | 306 | /* |
| 307 | * Initialize the ACLs of a new inode. Called from ext3_new_inode. | 307 | * Initialize the ACLs of a new inode. Called from ext3_new_inode. |
| 308 | * | 308 | * |
| 309 | * dir->i_sem: down | 309 | * dir->i_mutex: down |
| 310 | * inode->i_sem: up (access to inode is still exclusive) | 310 | * inode->i_mutex: up (access to inode is still exclusive) |
| 311 | */ | 311 | */ |
| 312 | int | 312 | int |
| 313 | ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) | 313 | ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) |
| @@ -368,7 +368,7 @@ cleanup: | |||
| 368 | * for directories) are added. There are no more bits available in the | 368 | * for directories) are added. There are no more bits available in the |
| 369 | * file mode. | 369 | * file mode. |
| 370 | * | 370 | * |
| 371 | * inode->i_sem: down | 371 | * inode->i_mutex: down |
| 372 | */ | 372 | */ |
| 373 | int | 373 | int |
| 374 | ext3_acl_chmod(struct inode *inode) | 374 | ext3_acl_chmod(struct inode *inode) |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 7c45acf94589..56bf76586019 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
| @@ -2150,7 +2150,7 @@ int ext3_force_commit(struct super_block *sb) | |||
| 2150 | 2150 | ||
| 2151 | static void ext3_write_super (struct super_block * sb) | 2151 | static void ext3_write_super (struct super_block * sb) |
| 2152 | { | 2152 | { |
| 2153 | if (down_trylock(&sb->s_lock) == 0) | 2153 | if (mutex_trylock(&sb->s_lock) != 0) |
| 2154 | BUG(); | 2154 | BUG(); |
| 2155 | sb->s_dirt = 0; | 2155 | sb->s_dirt = 0; |
| 2156 | } | 2156 | } |
| @@ -2601,7 +2601,7 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type, | |||
| 2601 | struct buffer_head *bh; | 2601 | struct buffer_head *bh; |
| 2602 | handle_t *handle = journal_current_handle(); | 2602 | handle_t *handle = journal_current_handle(); |
| 2603 | 2603 | ||
| 2604 | down(&inode->i_sem); | 2604 | mutex_lock(&inode->i_mutex); |
| 2605 | while (towrite > 0) { | 2605 | while (towrite > 0) { |
| 2606 | tocopy = sb->s_blocksize - offset < towrite ? | 2606 | tocopy = sb->s_blocksize - offset < towrite ? |
| 2607 | sb->s_blocksize - offset : towrite; | 2607 | sb->s_blocksize - offset : towrite; |
| @@ -2644,7 +2644,7 @@ out: | |||
| 2644 | inode->i_version++; | 2644 | inode->i_version++; |
| 2645 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 2645 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
| 2646 | ext3_mark_inode_dirty(handle, inode); | 2646 | ext3_mark_inode_dirty(handle, inode); |
| 2647 | up(&inode->i_sem); | 2647 | mutex_unlock(&inode->i_mutex); |
| 2648 | return len - towrite; | 2648 | return len - towrite; |
| 2649 | } | 2649 | } |
| 2650 | 2650 | ||
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c index 430de9f63be3..238199d82ce5 100644 --- a/fs/ext3/xattr.c +++ b/fs/ext3/xattr.c | |||
| @@ -140,7 +140,7 @@ ext3_xattr_handler(int name_index) | |||
| 140 | /* | 140 | /* |
| 141 | * Inode operation listxattr() | 141 | * Inode operation listxattr() |
| 142 | * | 142 | * |
| 143 | * dentry->d_inode->i_sem: don't care | 143 | * dentry->d_inode->i_mutex: don't care |
| 144 | */ | 144 | */ |
| 145 | ssize_t | 145 | ssize_t |
| 146 | ext3_listxattr(struct dentry *dentry, char *buffer, size_t size) | 146 | ext3_listxattr(struct dentry *dentry, char *buffer, size_t size) |
diff --git a/fs/fat/dir.c b/fs/fat/dir.c index eef1b81aa294..db0de5c621c7 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c | |||
| @@ -729,13 +729,13 @@ static int fat_dir_ioctl(struct inode * inode, struct file * filp, | |||
| 729 | 729 | ||
| 730 | buf.dirent = d1; | 730 | buf.dirent = d1; |
| 731 | buf.result = 0; | 731 | buf.result = 0; |
| 732 | down(&inode->i_sem); | 732 | mutex_lock(&inode->i_mutex); |
| 733 | ret = -ENOENT; | 733 | ret = -ENOENT; |
| 734 | if (!IS_DEADDIR(inode)) { | 734 | if (!IS_DEADDIR(inode)) { |
| 735 | ret = __fat_readdir(inode, filp, &buf, fat_ioctl_filldir, | 735 | ret = __fat_readdir(inode, filp, &buf, fat_ioctl_filldir, |
| 736 | short_only, both); | 736 | short_only, both); |
| 737 | } | 737 | } |
| 738 | up(&inode->i_sem); | 738 | mutex_unlock(&inode->i_mutex); |
| 739 | if (ret >= 0) | 739 | if (ret >= 0) |
| 740 | ret = buf.result; | 740 | ret = buf.result; |
| 741 | return ret; | 741 | return ret; |
diff --git a/fs/fat/file.c b/fs/fat/file.c index 9b07c328a6fc..d30876cf35f5 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c | |||
| @@ -41,7 +41,7 @@ int fat_generic_ioctl(struct inode *inode, struct file *filp, | |||
| 41 | if (err) | 41 | if (err) |
| 42 | return err; | 42 | return err; |
| 43 | 43 | ||
| 44 | down(&inode->i_sem); | 44 | mutex_lock(&inode->i_mutex); |
| 45 | 45 | ||
| 46 | if (IS_RDONLY(inode)) { | 46 | if (IS_RDONLY(inode)) { |
| 47 | err = -EROFS; | 47 | err = -EROFS; |
| @@ -103,7 +103,7 @@ int fat_generic_ioctl(struct inode *inode, struct file *filp, | |||
| 103 | MSDOS_I(inode)->i_attrs = attr & ATTR_UNUSED; | 103 | MSDOS_I(inode)->i_attrs = attr & ATTR_UNUSED; |
| 104 | mark_inode_dirty(inode); | 104 | mark_inode_dirty(inode); |
| 105 | up: | 105 | up: |
| 106 | up(&inode->i_sem); | 106 | mutex_unlock(&inode->i_mutex); |
| 107 | return err; | 107 | return err; |
| 108 | } | 108 | } |
| 109 | default: | 109 | default: |
| @@ -35,7 +35,7 @@ static int fifo_open(struct inode *inode, struct file *filp) | |||
| 35 | int ret; | 35 | int ret; |
| 36 | 36 | ||
| 37 | ret = -ERESTARTSYS; | 37 | ret = -ERESTARTSYS; |
| 38 | if (down_interruptible(PIPE_SEM(*inode))) | 38 | if (mutex_lock_interruptible(PIPE_MUTEX(*inode))) |
| 39 | goto err_nolock_nocleanup; | 39 | goto err_nolock_nocleanup; |
| 40 | 40 | ||
| 41 | if (!inode->i_pipe) { | 41 | if (!inode->i_pipe) { |
| @@ -119,7 +119,7 @@ static int fifo_open(struct inode *inode, struct file *filp) | |||
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | /* Ok! */ | 121 | /* Ok! */ |
| 122 | up(PIPE_SEM(*inode)); | 122 | mutex_unlock(PIPE_MUTEX(*inode)); |
| 123 | return 0; | 123 | return 0; |
| 124 | 124 | ||
| 125 | err_rd: | 125 | err_rd: |
| @@ -139,7 +139,7 @@ err: | |||
| 139 | free_pipe_info(inode); | 139 | free_pipe_info(inode); |
| 140 | 140 | ||
| 141 | err_nocleanup: | 141 | err_nocleanup: |
| 142 | up(PIPE_SEM(*inode)); | 142 | mutex_unlock(PIPE_MUTEX(*inode)); |
| 143 | 143 | ||
| 144 | err_nolock_nocleanup: | 144 | err_nolock_nocleanup: |
| 145 | return ret; | 145 | return ret; |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 05dedddf4289..63d2980df5c9 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
| @@ -560,9 +560,9 @@ static ssize_t fuse_direct_write(struct file *file, const char __user *buf, | |||
| 560 | struct inode *inode = file->f_dentry->d_inode; | 560 | struct inode *inode = file->f_dentry->d_inode; |
| 561 | ssize_t res; | 561 | ssize_t res; |
| 562 | /* Don't allow parallel writes to the same file */ | 562 | /* Don't allow parallel writes to the same file */ |
| 563 | down(&inode->i_sem); | 563 | mutex_lock(&inode->i_mutex); |
| 564 | res = fuse_direct_io(file, buf, count, ppos, 1); | 564 | res = fuse_direct_io(file, buf, count, ppos, 1); |
| 565 | up(&inode->i_sem); | 565 | mutex_unlock(&inode->i_mutex); |
| 566 | return res; | 566 | return res; |
| 567 | } | 567 | } |
| 568 | 568 | ||
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index d499393a8ae7..050a49276499 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c | |||
| @@ -547,13 +547,13 @@ static int hfs_file_release(struct inode *inode, struct file *file) | |||
| 547 | if (atomic_read(&file->f_count) != 0) | 547 | if (atomic_read(&file->f_count) != 0) |
| 548 | return 0; | 548 | return 0; |
| 549 | if (atomic_dec_and_test(&HFS_I(inode)->opencnt)) { | 549 | if (atomic_dec_and_test(&HFS_I(inode)->opencnt)) { |
| 550 | down(&inode->i_sem); | 550 | mutex_lock(&inode->i_mutex); |
| 551 | hfs_file_truncate(inode); | 551 | hfs_file_truncate(inode); |
| 552 | //if (inode->i_flags & S_DEAD) { | 552 | //if (inode->i_flags & S_DEAD) { |
| 553 | // hfs_delete_cat(inode->i_ino, HFSPLUS_SB(sb).hidden_dir, NULL); | 553 | // hfs_delete_cat(inode->i_ino, HFSPLUS_SB(sb).hidden_dir, NULL); |
| 554 | // hfs_delete_inode(inode); | 554 | // hfs_delete_inode(inode); |
| 555 | //} | 555 | //} |
| 556 | up(&inode->i_sem); | 556 | mutex_unlock(&inode->i_mutex); |
| 557 | } | 557 | } |
| 558 | return 0; | 558 | return 0; |
| 559 | } | 559 | } |
diff --git a/fs/hfsplus/bitmap.c b/fs/hfsplus/bitmap.c index c7d316455fa0..9fb51632303c 100644 --- a/fs/hfsplus/bitmap.c +++ b/fs/hfsplus/bitmap.c | |||
| @@ -29,7 +29,7 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, u32 offset, u32 *ma | |||
| 29 | return size; | 29 | return size; |
| 30 | 30 | ||
| 31 | dprint(DBG_BITMAP, "block_allocate: %u,%u,%u\n", size, offset, len); | 31 | dprint(DBG_BITMAP, "block_allocate: %u,%u,%u\n", size, offset, len); |
| 32 | down(&HFSPLUS_SB(sb).alloc_file->i_sem); | 32 | mutex_lock(&HFSPLUS_SB(sb).alloc_file->i_mutex); |
| 33 | mapping = HFSPLUS_SB(sb).alloc_file->i_mapping; | 33 | mapping = HFSPLUS_SB(sb).alloc_file->i_mapping; |
| 34 | page = read_cache_page(mapping, offset / PAGE_CACHE_BITS, | 34 | page = read_cache_page(mapping, offset / PAGE_CACHE_BITS, |
| 35 | (filler_t *)mapping->a_ops->readpage, NULL); | 35 | (filler_t *)mapping->a_ops->readpage, NULL); |
| @@ -143,7 +143,7 @@ done: | |||
| 143 | sb->s_dirt = 1; | 143 | sb->s_dirt = 1; |
| 144 | dprint(DBG_BITMAP, "-> %u,%u\n", start, *max); | 144 | dprint(DBG_BITMAP, "-> %u,%u\n", start, *max); |
| 145 | out: | 145 | out: |
| 146 | up(&HFSPLUS_SB(sb).alloc_file->i_sem); | 146 | mutex_unlock(&HFSPLUS_SB(sb).alloc_file->i_mutex); |
| 147 | return start; | 147 | return start; |
| 148 | } | 148 | } |
| 149 | 149 | ||
| @@ -164,7 +164,7 @@ int hfsplus_block_free(struct super_block *sb, u32 offset, u32 count) | |||
| 164 | if ((offset + count) > HFSPLUS_SB(sb).total_blocks) | 164 | if ((offset + count) > HFSPLUS_SB(sb).total_blocks) |
| 165 | return -2; | 165 | return -2; |
| 166 | 166 | ||
| 167 | down(&HFSPLUS_SB(sb).alloc_file->i_sem); | 167 | mutex_lock(&HFSPLUS_SB(sb).alloc_file->i_mutex); |
| 168 | mapping = HFSPLUS_SB(sb).alloc_file->i_mapping; | 168 | mapping = HFSPLUS_SB(sb).alloc_file->i_mapping; |
| 169 | pnr = offset / PAGE_CACHE_BITS; | 169 | pnr = offset / PAGE_CACHE_BITS; |
| 170 | page = read_cache_page(mapping, pnr, (filler_t *)mapping->a_ops->readpage, NULL); | 170 | page = read_cache_page(mapping, pnr, (filler_t *)mapping->a_ops->readpage, NULL); |
| @@ -215,7 +215,7 @@ out: | |||
| 215 | kunmap(page); | 215 | kunmap(page); |
| 216 | HFSPLUS_SB(sb).free_blocks += len; | 216 | HFSPLUS_SB(sb).free_blocks += len; |
| 217 | sb->s_dirt = 1; | 217 | sb->s_dirt = 1; |
| 218 | up(&HFSPLUS_SB(sb).alloc_file->i_sem); | 218 | mutex_unlock(&HFSPLUS_SB(sb).alloc_file->i_mutex); |
| 219 | 219 | ||
| 220 | return 0; | 220 | return 0; |
| 221 | } | 221 | } |
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index fc98583cf045..983bcd02ac1c 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c | |||
| @@ -276,13 +276,13 @@ static int hfsplus_file_release(struct inode *inode, struct file *file) | |||
| 276 | if (atomic_read(&file->f_count) != 0) | 276 | if (atomic_read(&file->f_count) != 0) |
| 277 | return 0; | 277 | return 0; |
| 278 | if (atomic_dec_and_test(&HFSPLUS_I(inode).opencnt)) { | 278 | if (atomic_dec_and_test(&HFSPLUS_I(inode).opencnt)) { |
| 279 | down(&inode->i_sem); | 279 | mutex_lock(&inode->i_mutex); |
| 280 | hfsplus_file_truncate(inode); | 280 | hfsplus_file_truncate(inode); |
| 281 | if (inode->i_flags & S_DEAD) { | 281 | if (inode->i_flags & S_DEAD) { |
| 282 | hfsplus_delete_cat(inode->i_ino, HFSPLUS_SB(sb).hidden_dir, NULL); | 282 | hfsplus_delete_cat(inode->i_ino, HFSPLUS_SB(sb).hidden_dir, NULL); |
| 283 | hfsplus_delete_inode(inode); | 283 | hfsplus_delete_inode(inode); |
| 284 | } | 284 | } |
| 285 | up(&inode->i_sem); | 285 | mutex_unlock(&inode->i_mutex); |
| 286 | } | 286 | } |
| 287 | return 0; | 287 | return 0; |
| 288 | } | 288 | } |
diff --git a/fs/hpfs/dir.c b/fs/hpfs/dir.c index 0217c3a04441..5591f9623aa2 100644 --- a/fs/hpfs/dir.c +++ b/fs/hpfs/dir.c | |||
| @@ -32,19 +32,19 @@ static loff_t hpfs_dir_lseek(struct file *filp, loff_t off, int whence) | |||
| 32 | 32 | ||
| 33 | /*printk("dir lseek\n");*/ | 33 | /*printk("dir lseek\n");*/ |
| 34 | if (new_off == 0 || new_off == 1 || new_off == 11 || new_off == 12 || new_off == 13) goto ok; | 34 | if (new_off == 0 || new_off == 1 || new_off == 11 || new_off == 12 || new_off == 13) goto ok; |
| 35 | down(&i->i_sem); | 35 | mutex_lock(&i->i_mutex); |
| 36 | pos = ((loff_t) hpfs_de_as_down_as_possible(s, hpfs_inode->i_dno) << 4) + 1; | 36 | pos = ((loff_t) hpfs_de_as_down_as_possible(s, hpfs_inode->i_dno) << 4) + 1; |
| 37 | while (pos != new_off) { | 37 | while (pos != new_off) { |
| 38 | if (map_pos_dirent(i, &pos, &qbh)) hpfs_brelse4(&qbh); | 38 | if (map_pos_dirent(i, &pos, &qbh)) hpfs_brelse4(&qbh); |
| 39 | else goto fail; | 39 | else goto fail; |
| 40 | if (pos == 12) goto fail; | 40 | if (pos == 12) goto fail; |
| 41 | } | 41 | } |
| 42 | up(&i->i_sem); | 42 | mutex_unlock(&i->i_mutex); |
| 43 | ok: | 43 | ok: |
| 44 | unlock_kernel(); | 44 | unlock_kernel(); |
| 45 | return filp->f_pos = new_off; | 45 | return filp->f_pos = new_off; |
| 46 | fail: | 46 | fail: |
| 47 | up(&i->i_sem); | 47 | mutex_unlock(&i->i_mutex); |
| 48 | /*printk("illegal lseek: %016llx\n", new_off);*/ | 48 | /*printk("illegal lseek: %016llx\n", new_off);*/ |
| 49 | unlock_kernel(); | 49 | unlock_kernel(); |
| 50 | return -ESPIPE; | 50 | return -ESPIPE; |
diff --git a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c index 52930915bad8..a44dc5897399 100644 --- a/fs/hppfs/hppfs_kern.c +++ b/fs/hppfs/hppfs_kern.c | |||
| @@ -171,12 +171,12 @@ static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, | |||
| 171 | 171 | ||
| 172 | err = -ENOMEM; | 172 | err = -ENOMEM; |
| 173 | parent = HPPFS_I(ino)->proc_dentry; | 173 | parent = HPPFS_I(ino)->proc_dentry; |
| 174 | down(&parent->d_inode->i_sem); | 174 | mutex_lock(&parent->d_inode->i_mutex); |
| 175 | proc_dentry = d_lookup(parent, &dentry->d_name); | 175 | proc_dentry = d_lookup(parent, &dentry->d_name); |
| 176 | if(proc_dentry == NULL){ | 176 | if(proc_dentry == NULL){ |
| 177 | proc_dentry = d_alloc(parent, &dentry->d_name); | 177 | proc_dentry = d_alloc(parent, &dentry->d_name); |
| 178 | if(proc_dentry == NULL){ | 178 | if(proc_dentry == NULL){ |
| 179 | up(&parent->d_inode->i_sem); | 179 | mutex_unlock(&parent->d_inode->i_mutex); |
| 180 | goto out; | 180 | goto out; |
| 181 | } | 181 | } |
| 182 | new = (*parent->d_inode->i_op->lookup)(parent->d_inode, | 182 | new = (*parent->d_inode->i_op->lookup)(parent->d_inode, |
| @@ -186,7 +186,7 @@ static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, | |||
| 186 | proc_dentry = new; | 186 | proc_dentry = new; |
| 187 | } | 187 | } |
| 188 | } | 188 | } |
| 189 | up(&parent->d_inode->i_sem); | 189 | mutex_unlock(&parent->d_inode->i_mutex); |
| 190 | 190 | ||
| 191 | if(IS_ERR(proc_dentry)) | 191 | if(IS_ERR(proc_dentry)) |
| 192 | return(proc_dentry); | 192 | return(proc_dentry); |
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 8c41315a6e42..ff1b7d108bd0 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
| @@ -118,7 +118,7 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 118 | 118 | ||
| 119 | vma_len = (loff_t)(vma->vm_end - vma->vm_start); | 119 | vma_len = (loff_t)(vma->vm_end - vma->vm_start); |
| 120 | 120 | ||
| 121 | down(&inode->i_sem); | 121 | mutex_lock(&inode->i_mutex); |
| 122 | file_accessed(file); | 122 | file_accessed(file); |
| 123 | vma->vm_flags |= VM_HUGETLB | VM_RESERVED; | 123 | vma->vm_flags |= VM_HUGETLB | VM_RESERVED; |
| 124 | vma->vm_ops = &hugetlb_vm_ops; | 124 | vma->vm_ops = &hugetlb_vm_ops; |
| @@ -133,7 +133,7 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 133 | if (inode->i_size < len) | 133 | if (inode->i_size < len) |
| 134 | inode->i_size = len; | 134 | inode->i_size = len; |
| 135 | out: | 135 | out: |
| 136 | up(&inode->i_sem); | 136 | mutex_unlock(&inode->i_mutex); |
| 137 | 137 | ||
| 138 | return ret; | 138 | return ret; |
| 139 | } | 139 | } |
diff --git a/fs/inode.c b/fs/inode.c index fd568caf7f74..e08767fd57b0 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
| @@ -192,7 +192,7 @@ void inode_init_once(struct inode *inode) | |||
| 192 | INIT_HLIST_NODE(&inode->i_hash); | 192 | INIT_HLIST_NODE(&inode->i_hash); |
| 193 | INIT_LIST_HEAD(&inode->i_dentry); | 193 | INIT_LIST_HEAD(&inode->i_dentry); |
| 194 | INIT_LIST_HEAD(&inode->i_devices); | 194 | INIT_LIST_HEAD(&inode->i_devices); |
| 195 | sema_init(&inode->i_sem, 1); | 195 | mutex_init(&inode->i_mutex); |
| 196 | init_rwsem(&inode->i_alloc_sem); | 196 | init_rwsem(&inode->i_alloc_sem); |
| 197 | INIT_RADIX_TREE(&inode->i_data.page_tree, GFP_ATOMIC); | 197 | INIT_RADIX_TREE(&inode->i_data.page_tree, GFP_ATOMIC); |
| 198 | rwlock_init(&inode->i_data.tree_lock); | 198 | rwlock_init(&inode->i_data.tree_lock); |
diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c index 2559ee10beda..fc3855a1aef3 100644 --- a/fs/jffs/inode-v23.c +++ b/fs/jffs/inode-v23.c | |||
| @@ -1415,7 +1415,7 @@ jffs_file_write(struct file *filp, const char *buf, size_t count, | |||
| 1415 | * This will never trigger with sane page sizes. leave it in | 1415 | * This will never trigger with sane page sizes. leave it in |
| 1416 | * anyway, since I'm thinking about how to merge larger writes | 1416 | * anyway, since I'm thinking about how to merge larger writes |
| 1417 | * (the current idea is to poke a thread that does the actual | 1417 | * (the current idea is to poke a thread that does the actual |
| 1418 | * I/O and starts by doing a down(&inode->i_sem). then we | 1418 | * I/O and starts by doing a mutex_lock(&inode->i_mutex). then we |
| 1419 | * would need to get the page cache pages and have a list of | 1419 | * would need to get the page cache pages and have a list of |
| 1420 | * I/O requests and do write-merging here. | 1420 | * I/O requests and do write-merging here. |
| 1421 | * -- prumpf | 1421 | * -- prumpf |
diff --git a/fs/jfs/jfs_incore.h b/fs/jfs/jfs_incore.h index c0fd7b3eadc6..dc21a5bd54d4 100644 --- a/fs/jfs/jfs_incore.h +++ b/fs/jfs/jfs_incore.h | |||
| @@ -58,7 +58,7 @@ struct jfs_inode_info { | |||
| 58 | /* | 58 | /* |
| 59 | * rdwrlock serializes xtree between reads & writes and synchronizes | 59 | * rdwrlock serializes xtree between reads & writes and synchronizes |
| 60 | * changes to special inodes. It's use would be redundant on | 60 | * changes to special inodes. It's use would be redundant on |
| 61 | * directories since the i_sem taken in the VFS is sufficient. | 61 | * directories since the i_mutex taken in the VFS is sufficient. |
| 62 | */ | 62 | */ |
| 63 | struct rw_semaphore rdwrlock; | 63 | struct rw_semaphore rdwrlock; |
| 64 | /* | 64 | /* |
| @@ -68,7 +68,7 @@ struct jfs_inode_info { | |||
| 68 | * inode is blocked in txBegin or TxBeginAnon | 68 | * inode is blocked in txBegin or TxBeginAnon |
| 69 | */ | 69 | */ |
| 70 | struct semaphore commit_sem; | 70 | struct semaphore commit_sem; |
| 71 | /* xattr_sem allows us to access the xattrs without taking i_sem */ | 71 | /* xattr_sem allows us to access the xattrs without taking i_mutex */ |
| 72 | struct rw_semaphore xattr_sem; | 72 | struct rw_semaphore xattr_sem; |
| 73 | lid_t xtlid; /* lid of xtree lock on directory */ | 73 | lid_t xtlid; /* lid of xtree lock on directory */ |
| 74 | #ifdef CONFIG_JFS_POSIX_ACL | 74 | #ifdef CONFIG_JFS_POSIX_ACL |
diff --git a/fs/libfs.c b/fs/libfs.c index 9c50523382e7..63c020e6589e 100644 --- a/fs/libfs.c +++ b/fs/libfs.c | |||
| @@ -74,7 +74,7 @@ int dcache_dir_close(struct inode *inode, struct file *file) | |||
| 74 | 74 | ||
| 75 | loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin) | 75 | loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin) |
| 76 | { | 76 | { |
| 77 | down(&file->f_dentry->d_inode->i_sem); | 77 | mutex_lock(&file->f_dentry->d_inode->i_mutex); |
| 78 | switch (origin) { | 78 | switch (origin) { |
| 79 | case 1: | 79 | case 1: |
| 80 | offset += file->f_pos; | 80 | offset += file->f_pos; |
| @@ -82,7 +82,7 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin) | |||
| 82 | if (offset >= 0) | 82 | if (offset >= 0) |
| 83 | break; | 83 | break; |
| 84 | default: | 84 | default: |
| 85 | up(&file->f_dentry->d_inode->i_sem); | 85 | mutex_unlock(&file->f_dentry->d_inode->i_mutex); |
| 86 | return -EINVAL; | 86 | return -EINVAL; |
| 87 | } | 87 | } |
| 88 | if (offset != file->f_pos) { | 88 | if (offset != file->f_pos) { |
| @@ -106,7 +106,7 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin) | |||
| 106 | spin_unlock(&dcache_lock); | 106 | spin_unlock(&dcache_lock); |
| 107 | } | 107 | } |
| 108 | } | 108 | } |
| 109 | up(&file->f_dentry->d_inode->i_sem); | 109 | mutex_unlock(&file->f_dentry->d_inode->i_mutex); |
| 110 | return offset; | 110 | return offset; |
| 111 | } | 111 | } |
| 112 | 112 | ||
| @@ -356,7 +356,7 @@ int simple_commit_write(struct file *file, struct page *page, | |||
| 356 | 356 | ||
| 357 | /* | 357 | /* |
| 358 | * No need to use i_size_read() here, the i_size | 358 | * No need to use i_size_read() here, the i_size |
| 359 | * cannot change under us because we hold the i_sem. | 359 | * cannot change under us because we hold the i_mutex. |
| 360 | */ | 360 | */ |
| 361 | if (pos > inode->i_size) | 361 | if (pos > inode->i_size) |
| 362 | i_size_write(inode, pos); | 362 | i_size_write(inode, pos); |
diff --git a/fs/namei.c b/fs/namei.c index 300eae088d5f..0a8f073435af 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -438,7 +438,7 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s | |||
| 438 | struct dentry * result; | 438 | struct dentry * result; |
| 439 | struct inode *dir = parent->d_inode; | 439 | struct inode *dir = parent->d_inode; |
| 440 | 440 | ||
| 441 | down(&dir->i_sem); | 441 | mutex_lock(&dir->i_mutex); |
| 442 | /* | 442 | /* |
| 443 | * First re-do the cached lookup just in case it was created | 443 | * First re-do the cached lookup just in case it was created |
| 444 | * while we waited for the directory semaphore.. | 444 | * while we waited for the directory semaphore.. |
| @@ -464,7 +464,7 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s | |||
| 464 | else | 464 | else |
| 465 | result = dentry; | 465 | result = dentry; |
| 466 | } | 466 | } |
| 467 | up(&dir->i_sem); | 467 | mutex_unlock(&dir->i_mutex); |
| 468 | return result; | 468 | return result; |
| 469 | } | 469 | } |
| 470 | 470 | ||
| @@ -472,7 +472,7 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s | |||
| 472 | * Uhhuh! Nasty case: the cache was re-populated while | 472 | * Uhhuh! Nasty case: the cache was re-populated while |
| 473 | * we waited on the semaphore. Need to revalidate. | 473 | * we waited on the semaphore. Need to revalidate. |
| 474 | */ | 474 | */ |
| 475 | up(&dir->i_sem); | 475 | mutex_unlock(&dir->i_mutex); |
| 476 | if (result->d_op && result->d_op->d_revalidate) { | 476 | if (result->d_op && result->d_op->d_revalidate) { |
| 477 | if (!result->d_op->d_revalidate(result, nd) && !d_invalidate(result)) { | 477 | if (!result->d_op->d_revalidate(result, nd) && !d_invalidate(result)) { |
| 478 | dput(result); | 478 | dput(result); |
| @@ -1366,7 +1366,7 @@ struct dentry *lock_rename(struct dentry *p1, struct dentry *p2) | |||
| 1366 | struct dentry *p; | 1366 | struct dentry *p; |
| 1367 | 1367 | ||
| 1368 | if (p1 == p2) { | 1368 | if (p1 == p2) { |
| 1369 | down(&p1->d_inode->i_sem); | 1369 | mutex_lock(&p1->d_inode->i_mutex); |
| 1370 | return NULL; | 1370 | return NULL; |
| 1371 | } | 1371 | } |
| 1372 | 1372 | ||
| @@ -1374,30 +1374,30 @@ struct dentry *lock_rename(struct dentry *p1, struct dentry *p2) | |||
| 1374 | 1374 | ||
| 1375 | for (p = p1; p->d_parent != p; p = p->d_parent) { | 1375 | for (p = p1; p->d_parent != p; p = p->d_parent) { |
| 1376 | if (p->d_parent == p2) { | 1376 | if (p->d_parent == p2) { |
| 1377 | down(&p2->d_inode->i_sem); | 1377 | mutex_lock(&p2->d_inode->i_mutex); |
| 1378 | down(&p1->d_inode->i_sem); | 1378 | mutex_lock(&p1->d_inode->i_mutex); |
| 1379 | return p; | 1379 | return p; |
| 1380 | } | 1380 | } |
| 1381 | } | 1381 | } |
| 1382 | 1382 | ||
| 1383 | for (p = p2; p->d_parent != p; p = p->d_parent) { | 1383 | for (p = p2; p->d_parent != p; p = p->d_parent) { |
| 1384 | if (p->d_parent == p1) { | 1384 | if (p->d_parent == p1) { |
| 1385 | down(&p1->d_inode->i_sem); | 1385 | mutex_lock(&p1->d_inode->i_mutex); |
| 1386 | down(&p2->d_inode->i_sem); | 1386 | mutex_lock(&p2->d_inode->i_mutex); |
| 1387 | return p; | 1387 | return p; |
| 1388 | } | 1388 | } |
| 1389 | } | 1389 | } |
| 1390 | 1390 | ||
| 1391 | down(&p1->d_inode->i_sem); | 1391 | mutex_lock(&p1->d_inode->i_mutex); |
| 1392 | down(&p2->d_inode->i_sem); | 1392 | mutex_lock(&p2->d_inode->i_mutex); |
| 1393 | return NULL; | 1393 | return NULL; |
| 1394 | } | 1394 | } |
| 1395 | 1395 | ||
| 1396 | void unlock_rename(struct dentry *p1, struct dentry *p2) | 1396 | void unlock_rename(struct dentry *p1, struct dentry *p2) |
| 1397 | { | 1397 | { |
| 1398 | up(&p1->d_inode->i_sem); | 1398 | mutex_unlock(&p1->d_inode->i_mutex); |
| 1399 | if (p1 != p2) { | 1399 | if (p1 != p2) { |
| 1400 | up(&p2->d_inode->i_sem); | 1400 | mutex_unlock(&p2->d_inode->i_mutex); |
| 1401 | up(&p1->d_inode->i_sb->s_vfs_rename_sem); | 1401 | up(&p1->d_inode->i_sb->s_vfs_rename_sem); |
| 1402 | } | 1402 | } |
| 1403 | } | 1403 | } |
| @@ -1563,14 +1563,14 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) | |||
| 1563 | 1563 | ||
| 1564 | dir = nd->dentry; | 1564 | dir = nd->dentry; |
| 1565 | nd->flags &= ~LOOKUP_PARENT; | 1565 | nd->flags &= ~LOOKUP_PARENT; |
| 1566 | down(&dir->d_inode->i_sem); | 1566 | mutex_lock(&dir->d_inode->i_mutex); |
| 1567 | path.dentry = lookup_hash(nd); | 1567 | path.dentry = lookup_hash(nd); |
| 1568 | path.mnt = nd->mnt; | 1568 | path.mnt = nd->mnt; |
| 1569 | 1569 | ||
| 1570 | do_last: | 1570 | do_last: |
| 1571 | error = PTR_ERR(path.dentry); | 1571 | error = PTR_ERR(path.dentry); |
| 1572 | if (IS_ERR(path.dentry)) { | 1572 | if (IS_ERR(path.dentry)) { |
| 1573 | up(&dir->d_inode->i_sem); | 1573 | mutex_unlock(&dir->d_inode->i_mutex); |
| 1574 | goto exit; | 1574 | goto exit; |
| 1575 | } | 1575 | } |
| 1576 | 1576 | ||
| @@ -1579,7 +1579,7 @@ do_last: | |||
| 1579 | if (!IS_POSIXACL(dir->d_inode)) | 1579 | if (!IS_POSIXACL(dir->d_inode)) |
| 1580 | mode &= ~current->fs->umask; | 1580 | mode &= ~current->fs->umask; |
| 1581 | error = vfs_create(dir->d_inode, path.dentry, mode, nd); | 1581 | error = vfs_create(dir->d_inode, path.dentry, mode, nd); |
| 1582 | up(&dir->d_inode->i_sem); | 1582 | mutex_unlock(&dir->d_inode->i_mutex); |
| 1583 | dput(nd->dentry); | 1583 | dput(nd->dentry); |
| 1584 | nd->dentry = path.dentry; | 1584 | nd->dentry = path.dentry; |
| 1585 | if (error) | 1585 | if (error) |
| @@ -1593,7 +1593,7 @@ do_last: | |||
| 1593 | /* | 1593 | /* |
| 1594 | * It already exists. | 1594 | * It already exists. |
| 1595 | */ | 1595 | */ |
| 1596 | up(&dir->d_inode->i_sem); | 1596 | mutex_unlock(&dir->d_inode->i_mutex); |
| 1597 | 1597 | ||
| 1598 | error = -EEXIST; | 1598 | error = -EEXIST; |
| 1599 | if (flag & O_EXCL) | 1599 | if (flag & O_EXCL) |
| @@ -1665,7 +1665,7 @@ do_link: | |||
| 1665 | goto exit; | 1665 | goto exit; |
| 1666 | } | 1666 | } |
| 1667 | dir = nd->dentry; | 1667 | dir = nd->dentry; |
| 1668 | down(&dir->d_inode->i_sem); | 1668 | mutex_lock(&dir->d_inode->i_mutex); |
| 1669 | path.dentry = lookup_hash(nd); | 1669 | path.dentry = lookup_hash(nd); |
| 1670 | path.mnt = nd->mnt; | 1670 | path.mnt = nd->mnt; |
| 1671 | __putname(nd->last.name); | 1671 | __putname(nd->last.name); |
| @@ -1680,13 +1680,13 @@ do_link: | |||
| 1680 | * Simple function to lookup and return a dentry and create it | 1680 | * Simple function to lookup and return a dentry and create it |
| 1681 | * if it doesn't exist. Is SMP-safe. | 1681 | * if it doesn't exist. Is SMP-safe. |
| 1682 | * | 1682 | * |
| 1683 | * Returns with nd->dentry->d_inode->i_sem locked. | 1683 | * Returns with nd->dentry->d_inode->i_mutex locked. |
| 1684 | */ | 1684 | */ |
| 1685 | struct dentry *lookup_create(struct nameidata *nd, int is_dir) | 1685 | struct dentry *lookup_create(struct nameidata *nd, int is_dir) |
| 1686 | { | 1686 | { |
| 1687 | struct dentry *dentry = ERR_PTR(-EEXIST); | 1687 | struct dentry *dentry = ERR_PTR(-EEXIST); |
| 1688 | 1688 | ||
| 1689 | down(&nd->dentry->d_inode->i_sem); | 1689 | mutex_lock(&nd->dentry->d_inode->i_mutex); |
| 1690 | /* | 1690 | /* |
| 1691 | * Yucky last component or no last component at all? | 1691 | * Yucky last component or no last component at all? |
| 1692 | * (foo/., foo/.., /////) | 1692 | * (foo/., foo/.., /////) |
| @@ -1784,7 +1784,7 @@ asmlinkage long sys_mknod(const char __user * filename, int mode, unsigned dev) | |||
| 1784 | } | 1784 | } |
| 1785 | dput(dentry); | 1785 | dput(dentry); |
| 1786 | } | 1786 | } |
| 1787 | up(&nd.dentry->d_inode->i_sem); | 1787 | mutex_unlock(&nd.dentry->d_inode->i_mutex); |
| 1788 | path_release(&nd); | 1788 | path_release(&nd); |
| 1789 | out: | 1789 | out: |
| 1790 | putname(tmp); | 1790 | putname(tmp); |
| @@ -1836,7 +1836,7 @@ asmlinkage long sys_mkdir(const char __user * pathname, int mode) | |||
| 1836 | error = vfs_mkdir(nd.dentry->d_inode, dentry, mode); | 1836 | error = vfs_mkdir(nd.dentry->d_inode, dentry, mode); |
| 1837 | dput(dentry); | 1837 | dput(dentry); |
| 1838 | } | 1838 | } |
| 1839 | up(&nd.dentry->d_inode->i_sem); | 1839 | mutex_unlock(&nd.dentry->d_inode->i_mutex); |
| 1840 | path_release(&nd); | 1840 | path_release(&nd); |
| 1841 | out: | 1841 | out: |
| 1842 | putname(tmp); | 1842 | putname(tmp); |
| @@ -1885,7 +1885,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 1885 | 1885 | ||
| 1886 | DQUOT_INIT(dir); | 1886 | DQUOT_INIT(dir); |
| 1887 | 1887 | ||
| 1888 | down(&dentry->d_inode->i_sem); | 1888 | mutex_lock(&dentry->d_inode->i_mutex); |
| 1889 | dentry_unhash(dentry); | 1889 | dentry_unhash(dentry); |
| 1890 | if (d_mountpoint(dentry)) | 1890 | if (d_mountpoint(dentry)) |
| 1891 | error = -EBUSY; | 1891 | error = -EBUSY; |
| @@ -1897,7 +1897,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 1897 | dentry->d_inode->i_flags |= S_DEAD; | 1897 | dentry->d_inode->i_flags |= S_DEAD; |
| 1898 | } | 1898 | } |
| 1899 | } | 1899 | } |
| 1900 | up(&dentry->d_inode->i_sem); | 1900 | mutex_unlock(&dentry->d_inode->i_mutex); |
| 1901 | if (!error) { | 1901 | if (!error) { |
| 1902 | d_delete(dentry); | 1902 | d_delete(dentry); |
| 1903 | } | 1903 | } |
| @@ -1932,14 +1932,14 @@ asmlinkage long sys_rmdir(const char __user * pathname) | |||
| 1932 | error = -EBUSY; | 1932 | error = -EBUSY; |
| 1933 | goto exit1; | 1933 | goto exit1; |
| 1934 | } | 1934 | } |
| 1935 | down(&nd.dentry->d_inode->i_sem); | 1935 | mutex_lock(&nd.dentry->d_inode->i_mutex); |
| 1936 | dentry = lookup_hash(&nd); | 1936 | dentry = lookup_hash(&nd); |
| 1937 | error = PTR_ERR(dentry); | 1937 | error = PTR_ERR(dentry); |
| 1938 | if (!IS_ERR(dentry)) { | 1938 | if (!IS_ERR(dentry)) { |
| 1939 | error = vfs_rmdir(nd.dentry->d_inode, dentry); | 1939 | error = vfs_rmdir(nd.dentry->d_inode, dentry); |
| 1940 | dput(dentry); | 1940 | dput(dentry); |
| 1941 | } | 1941 | } |
| 1942 | up(&nd.dentry->d_inode->i_sem); | 1942 | mutex_unlock(&nd.dentry->d_inode->i_mutex); |
| 1943 | exit1: | 1943 | exit1: |
| 1944 | path_release(&nd); | 1944 | path_release(&nd); |
| 1945 | exit: | 1945 | exit: |
| @@ -1959,7 +1959,7 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry) | |||
| 1959 | 1959 | ||
| 1960 | DQUOT_INIT(dir); | 1960 | DQUOT_INIT(dir); |
| 1961 | 1961 | ||
| 1962 | down(&dentry->d_inode->i_sem); | 1962 | mutex_lock(&dentry->d_inode->i_mutex); |
| 1963 | if (d_mountpoint(dentry)) | 1963 | if (d_mountpoint(dentry)) |
| 1964 | error = -EBUSY; | 1964 | error = -EBUSY; |
| 1965 | else { | 1965 | else { |
| @@ -1967,7 +1967,7 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry) | |||
| 1967 | if (!error) | 1967 | if (!error) |
| 1968 | error = dir->i_op->unlink(dir, dentry); | 1968 | error = dir->i_op->unlink(dir, dentry); |
| 1969 | } | 1969 | } |
| 1970 | up(&dentry->d_inode->i_sem); | 1970 | mutex_unlock(&dentry->d_inode->i_mutex); |
| 1971 | 1971 | ||
| 1972 | /* We don't d_delete() NFS sillyrenamed files--they still exist. */ | 1972 | /* We don't d_delete() NFS sillyrenamed files--they still exist. */ |
| 1973 | if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) { | 1973 | if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) { |
| @@ -1979,7 +1979,7 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry) | |||
| 1979 | 1979 | ||
| 1980 | /* | 1980 | /* |
| 1981 | * Make sure that the actual truncation of the file will occur outside its | 1981 | * Make sure that the actual truncation of the file will occur outside its |
| 1982 | * directory's i_sem. Truncate can take a long time if there is a lot of | 1982 | * directory's i_mutex. Truncate can take a long time if there is a lot of |
| 1983 | * writeout happening, and we don't want to prevent access to the directory | 1983 | * writeout happening, and we don't want to prevent access to the directory |
| 1984 | * while waiting on the I/O. | 1984 | * while waiting on the I/O. |
| 1985 | */ | 1985 | */ |
| @@ -2001,7 +2001,7 @@ asmlinkage long sys_unlink(const char __user * pathname) | |||
| 2001 | error = -EISDIR; | 2001 | error = -EISDIR; |
| 2002 | if (nd.last_type != LAST_NORM) | 2002 | if (nd.last_type != LAST_NORM) |
| 2003 | goto exit1; | 2003 | goto exit1; |
| 2004 | down(&nd.dentry->d_inode->i_sem); | 2004 | mutex_lock(&nd.dentry->d_inode->i_mutex); |
| 2005 | dentry = lookup_hash(&nd); | 2005 | dentry = lookup_hash(&nd); |
| 2006 | error = PTR_ERR(dentry); | 2006 | error = PTR_ERR(dentry); |
| 2007 | if (!IS_ERR(dentry)) { | 2007 | if (!IS_ERR(dentry)) { |
| @@ -2015,7 +2015,7 @@ asmlinkage long sys_unlink(const char __user * pathname) | |||
| 2015 | exit2: | 2015 | exit2: |
| 2016 | dput(dentry); | 2016 | dput(dentry); |
| 2017 | } | 2017 | } |
| 2018 | up(&nd.dentry->d_inode->i_sem); | 2018 | mutex_unlock(&nd.dentry->d_inode->i_mutex); |
| 2019 | if (inode) | 2019 | if (inode) |
| 2020 | iput(inode); /* truncate the inode here */ | 2020 | iput(inode); /* truncate the inode here */ |
| 2021 | exit1: | 2021 | exit1: |
| @@ -2075,7 +2075,7 @@ asmlinkage long sys_symlink(const char __user * oldname, const char __user * new | |||
| 2075 | error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO); | 2075 | error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO); |
| 2076 | dput(dentry); | 2076 | dput(dentry); |
| 2077 | } | 2077 | } |
| 2078 | up(&nd.dentry->d_inode->i_sem); | 2078 | mutex_unlock(&nd.dentry->d_inode->i_mutex); |
| 2079 | path_release(&nd); | 2079 | path_release(&nd); |
| 2080 | out: | 2080 | out: |
| 2081 | putname(to); | 2081 | putname(to); |
| @@ -2113,10 +2113,10 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de | |||
| 2113 | if (error) | 2113 | if (error) |
| 2114 | return error; | 2114 | return error; |
| 2115 | 2115 | ||
| 2116 | down(&old_dentry->d_inode->i_sem); | 2116 | mutex_lock(&old_dentry->d_inode->i_mutex); |
| 2117 | DQUOT_INIT(dir); | 2117 | DQUOT_INIT(dir); |
| 2118 | error = dir->i_op->link(old_dentry, dir, new_dentry); | 2118 | error = dir->i_op->link(old_dentry, dir, new_dentry); |
| 2119 | up(&old_dentry->d_inode->i_sem); | 2119 | mutex_unlock(&old_dentry->d_inode->i_mutex); |
| 2120 | if (!error) | 2120 | if (!error) |
| 2121 | fsnotify_create(dir, new_dentry->d_name.name); | 2121 | fsnotify_create(dir, new_dentry->d_name.name); |
| 2122 | return error; | 2122 | return error; |
| @@ -2157,7 +2157,7 @@ asmlinkage long sys_link(const char __user * oldname, const char __user * newnam | |||
| 2157 | error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); | 2157 | error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); |
| 2158 | dput(new_dentry); | 2158 | dput(new_dentry); |
| 2159 | } | 2159 | } |
| 2160 | up(&nd.dentry->d_inode->i_sem); | 2160 | mutex_unlock(&nd.dentry->d_inode->i_mutex); |
| 2161 | out_release: | 2161 | out_release: |
| 2162 | path_release(&nd); | 2162 | path_release(&nd); |
| 2163 | out: | 2163 | out: |
| @@ -2178,7 +2178,7 @@ exit: | |||
| 2178 | * sb->s_vfs_rename_sem. We might be more accurate, but that's another | 2178 | * sb->s_vfs_rename_sem. We might be more accurate, but that's another |
| 2179 | * story. | 2179 | * story. |
| 2180 | * c) we have to lock _three_ objects - parents and victim (if it exists). | 2180 | * c) we have to lock _three_ objects - parents and victim (if it exists). |
| 2181 | * And that - after we got ->i_sem on parents (until then we don't know | 2181 | * And that - after we got ->i_mutex on parents (until then we don't know |
| 2182 | * whether the target exists). Solution: try to be smart with locking | 2182 | * whether the target exists). Solution: try to be smart with locking |
| 2183 | * order for inodes. We rely on the fact that tree topology may change | 2183 | * order for inodes. We rely on the fact that tree topology may change |
| 2184 | * only under ->s_vfs_rename_sem _and_ that parent of the object we | 2184 | * only under ->s_vfs_rename_sem _and_ that parent of the object we |
| @@ -2195,9 +2195,9 @@ exit: | |||
| 2195 | * stuff into VFS), but the former is not going away. Solution: the same | 2195 | * stuff into VFS), but the former is not going away. Solution: the same |
| 2196 | * trick as in rmdir(). | 2196 | * trick as in rmdir(). |
| 2197 | * e) conversion from fhandle to dentry may come in the wrong moment - when | 2197 | * e) conversion from fhandle to dentry may come in the wrong moment - when |
| 2198 | * we are removing the target. Solution: we will have to grab ->i_sem | 2198 | * we are removing the target. Solution: we will have to grab ->i_mutex |
| 2199 | * in the fhandle_to_dentry code. [FIXME - current nfsfh.c relies on | 2199 | * in the fhandle_to_dentry code. [FIXME - current nfsfh.c relies on |
| 2200 | * ->i_sem on parents, which works but leads to some truely excessive | 2200 | * ->i_mutex on parents, which works but leads to some truely excessive |
| 2201 | * locking]. | 2201 | * locking]. |
| 2202 | */ | 2202 | */ |
| 2203 | static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, | 2203 | static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, |
| @@ -2222,7 +2222,7 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, | |||
| 2222 | 2222 | ||
| 2223 | target = new_dentry->d_inode; | 2223 | target = new_dentry->d_inode; |
| 2224 | if (target) { | 2224 | if (target) { |
| 2225 | down(&target->i_sem); | 2225 | mutex_lock(&target->i_mutex); |
| 2226 | dentry_unhash(new_dentry); | 2226 | dentry_unhash(new_dentry); |
| 2227 | } | 2227 | } |
| 2228 | if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) | 2228 | if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) |
| @@ -2232,7 +2232,7 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, | |||
| 2232 | if (target) { | 2232 | if (target) { |
| 2233 | if (!error) | 2233 | if (!error) |
| 2234 | target->i_flags |= S_DEAD; | 2234 | target->i_flags |= S_DEAD; |
| 2235 | up(&target->i_sem); | 2235 | mutex_unlock(&target->i_mutex); |
| 2236 | if (d_unhashed(new_dentry)) | 2236 | if (d_unhashed(new_dentry)) |
| 2237 | d_rehash(new_dentry); | 2237 | d_rehash(new_dentry); |
| 2238 | dput(new_dentry); | 2238 | dput(new_dentry); |
| @@ -2255,7 +2255,7 @@ static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, | |||
| 2255 | dget(new_dentry); | 2255 | dget(new_dentry); |
| 2256 | target = new_dentry->d_inode; | 2256 | target = new_dentry->d_inode; |
| 2257 | if (target) | 2257 | if (target) |
| 2258 | down(&target->i_sem); | 2258 | mutex_lock(&target->i_mutex); |
| 2259 | if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) | 2259 | if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) |
| 2260 | error = -EBUSY; | 2260 | error = -EBUSY; |
| 2261 | else | 2261 | else |
| @@ -2266,7 +2266,7 @@ static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, | |||
| 2266 | d_move(old_dentry, new_dentry); | 2266 | d_move(old_dentry, new_dentry); |
| 2267 | } | 2267 | } |
| 2268 | if (target) | 2268 | if (target) |
| 2269 | up(&target->i_sem); | 2269 | mutex_unlock(&target->i_mutex); |
| 2270 | dput(new_dentry); | 2270 | dput(new_dentry); |
| 2271 | return error; | 2271 | return error; |
| 2272 | } | 2272 | } |
diff --git a/fs/namespace.c b/fs/namespace.c index 3e8fb61ad597..f0e353f5bc30 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
| @@ -814,7 +814,7 @@ static int graft_tree(struct vfsmount *mnt, struct nameidata *nd) | |||
| 814 | return -ENOTDIR; | 814 | return -ENOTDIR; |
| 815 | 815 | ||
| 816 | err = -ENOENT; | 816 | err = -ENOENT; |
| 817 | down(&nd->dentry->d_inode->i_sem); | 817 | mutex_lock(&nd->dentry->d_inode->i_mutex); |
| 818 | if (IS_DEADDIR(nd->dentry->d_inode)) | 818 | if (IS_DEADDIR(nd->dentry->d_inode)) |
| 819 | goto out_unlock; | 819 | goto out_unlock; |
| 820 | 820 | ||
| @@ -826,7 +826,7 @@ static int graft_tree(struct vfsmount *mnt, struct nameidata *nd) | |||
| 826 | if (IS_ROOT(nd->dentry) || !d_unhashed(nd->dentry)) | 826 | if (IS_ROOT(nd->dentry) || !d_unhashed(nd->dentry)) |
| 827 | err = attach_recursive_mnt(mnt, nd, NULL); | 827 | err = attach_recursive_mnt(mnt, nd, NULL); |
| 828 | out_unlock: | 828 | out_unlock: |
| 829 | up(&nd->dentry->d_inode->i_sem); | 829 | mutex_unlock(&nd->dentry->d_inode->i_mutex); |
| 830 | if (!err) | 830 | if (!err) |
| 831 | security_sb_post_addmount(mnt, nd); | 831 | security_sb_post_addmount(mnt, nd); |
| 832 | return err; | 832 | return err; |
| @@ -962,7 +962,7 @@ static int do_move_mount(struct nameidata *nd, char *old_name) | |||
| 962 | goto out; | 962 | goto out; |
| 963 | 963 | ||
| 964 | err = -ENOENT; | 964 | err = -ENOENT; |
| 965 | down(&nd->dentry->d_inode->i_sem); | 965 | mutex_lock(&nd->dentry->d_inode->i_mutex); |
| 966 | if (IS_DEADDIR(nd->dentry->d_inode)) | 966 | if (IS_DEADDIR(nd->dentry->d_inode)) |
| 967 | goto out1; | 967 | goto out1; |
| 968 | 968 | ||
| @@ -1004,7 +1004,7 @@ static int do_move_mount(struct nameidata *nd, char *old_name) | |||
| 1004 | list_del_init(&old_nd.mnt->mnt_expire); | 1004 | list_del_init(&old_nd.mnt->mnt_expire); |
| 1005 | spin_unlock(&vfsmount_lock); | 1005 | spin_unlock(&vfsmount_lock); |
| 1006 | out1: | 1006 | out1: |
| 1007 | up(&nd->dentry->d_inode->i_sem); | 1007 | mutex_unlock(&nd->dentry->d_inode->i_mutex); |
| 1008 | out: | 1008 | out: |
| 1009 | up_write(&namespace_sem); | 1009 | up_write(&namespace_sem); |
| 1010 | if (!err) | 1010 | if (!err) |
| @@ -1573,7 +1573,7 @@ asmlinkage long sys_pivot_root(const char __user * new_root, | |||
| 1573 | user_nd.dentry = dget(current->fs->root); | 1573 | user_nd.dentry = dget(current->fs->root); |
| 1574 | read_unlock(¤t->fs->lock); | 1574 | read_unlock(¤t->fs->lock); |
| 1575 | down_write(&namespace_sem); | 1575 | down_write(&namespace_sem); |
| 1576 | down(&old_nd.dentry->d_inode->i_sem); | 1576 | mutex_lock(&old_nd.dentry->d_inode->i_mutex); |
| 1577 | error = -EINVAL; | 1577 | error = -EINVAL; |
| 1578 | if (IS_MNT_SHARED(old_nd.mnt) || | 1578 | if (IS_MNT_SHARED(old_nd.mnt) || |
| 1579 | IS_MNT_SHARED(new_nd.mnt->mnt_parent) || | 1579 | IS_MNT_SHARED(new_nd.mnt->mnt_parent) || |
| @@ -1626,7 +1626,7 @@ asmlinkage long sys_pivot_root(const char __user * new_root, | |||
| 1626 | path_release(&root_parent); | 1626 | path_release(&root_parent); |
| 1627 | path_release(&parent_nd); | 1627 | path_release(&parent_nd); |
| 1628 | out2: | 1628 | out2: |
| 1629 | up(&old_nd.dentry->d_inode->i_sem); | 1629 | mutex_unlock(&old_nd.dentry->d_inode->i_mutex); |
| 1630 | up_write(&namespace_sem); | 1630 | up_write(&namespace_sem); |
| 1631 | path_release(&user_nd); | 1631 | path_release(&user_nd); |
| 1632 | path_release(&old_nd); | 1632 | path_release(&old_nd); |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index e9255198f767..a1554bead692 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
| @@ -194,7 +194,7 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page) | |||
| 194 | spin_unlock(&inode->i_lock); | 194 | spin_unlock(&inode->i_lock); |
| 195 | /* Ensure consistent page alignment of the data. | 195 | /* Ensure consistent page alignment of the data. |
| 196 | * Note: assumes we have exclusive access to this mapping either | 196 | * Note: assumes we have exclusive access to this mapping either |
| 197 | * through inode->i_sem or some other mechanism. | 197 | * through inode->i_mutex or some other mechanism. |
| 198 | */ | 198 | */ |
| 199 | if (page->index == 0) | 199 | if (page->index == 0) |
| 200 | invalidate_inode_pages2_range(inode->i_mapping, PAGE_CACHE_SIZE, -1); | 200 | invalidate_inode_pages2_range(inode->i_mapping, PAGE_CACHE_SIZE, -1); |
| @@ -573,7 +573,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
| 573 | 573 | ||
| 574 | loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int origin) | 574 | loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int origin) |
| 575 | { | 575 | { |
| 576 | down(&filp->f_dentry->d_inode->i_sem); | 576 | mutex_lock(&filp->f_dentry->d_inode->i_mutex); |
| 577 | switch (origin) { | 577 | switch (origin) { |
| 578 | case 1: | 578 | case 1: |
| 579 | offset += filp->f_pos; | 579 | offset += filp->f_pos; |
| @@ -589,7 +589,7 @@ loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int origin) | |||
| 589 | ((struct nfs_open_context *)filp->private_data)->dir_cookie = 0; | 589 | ((struct nfs_open_context *)filp->private_data)->dir_cookie = 0; |
| 590 | } | 590 | } |
| 591 | out: | 591 | out: |
| 592 | up(&filp->f_dentry->d_inode->i_sem); | 592 | mutex_unlock(&filp->f_dentry->d_inode->i_mutex); |
| 593 | return offset; | 593 | return offset; |
| 594 | } | 594 | } |
| 595 | 595 | ||
| @@ -1001,7 +1001,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
| 1001 | openflags &= ~(O_CREAT|O_TRUNC); | 1001 | openflags &= ~(O_CREAT|O_TRUNC); |
| 1002 | 1002 | ||
| 1003 | /* | 1003 | /* |
| 1004 | * Note: we're not holding inode->i_sem and so may be racing with | 1004 | * Note: we're not holding inode->i_mutex and so may be racing with |
| 1005 | * operations that change the directory. We therefore save the | 1005 | * operations that change the directory. We therefore save the |
| 1006 | * change attribute *before* we do the RPC call. | 1006 | * change attribute *before* we do the RPC call. |
| 1007 | */ | 1007 | */ |
| @@ -1051,7 +1051,7 @@ static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc) | |||
| 1051 | return dentry; | 1051 | return dentry; |
| 1052 | if (!desc->plus || !(entry->fattr->valid & NFS_ATTR_FATTR)) | 1052 | if (!desc->plus || !(entry->fattr->valid & NFS_ATTR_FATTR)) |
| 1053 | return NULL; | 1053 | return NULL; |
| 1054 | /* Note: caller is already holding the dir->i_sem! */ | 1054 | /* Note: caller is already holding the dir->i_mutex! */ |
| 1055 | dentry = d_alloc(parent, &name); | 1055 | dentry = d_alloc(parent, &name); |
| 1056 | if (dentry == NULL) | 1056 | if (dentry == NULL) |
| 1057 | return NULL; | 1057 | return NULL; |
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index 954cf893d50c..be963a133aaa 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c | |||
| @@ -121,9 +121,9 @@ out: | |||
| 121 | static void | 121 | static void |
| 122 | nfsd4_sync_rec_dir(void) | 122 | nfsd4_sync_rec_dir(void) |
| 123 | { | 123 | { |
| 124 | down(&rec_dir.dentry->d_inode->i_sem); | 124 | mutex_lock(&rec_dir.dentry->d_inode->i_mutex); |
| 125 | nfsd_sync_dir(rec_dir.dentry); | 125 | nfsd_sync_dir(rec_dir.dentry); |
| 126 | up(&rec_dir.dentry->d_inode->i_sem); | 126 | mutex_unlock(&rec_dir.dentry->d_inode->i_mutex); |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | int | 129 | int |
| @@ -143,7 +143,7 @@ nfsd4_create_clid_dir(struct nfs4_client *clp) | |||
| 143 | nfs4_save_user(&uid, &gid); | 143 | nfs4_save_user(&uid, &gid); |
| 144 | 144 | ||
| 145 | /* lock the parent */ | 145 | /* lock the parent */ |
| 146 | down(&rec_dir.dentry->d_inode->i_sem); | 146 | mutex_lock(&rec_dir.dentry->d_inode->i_mutex); |
| 147 | 147 | ||
| 148 | dentry = lookup_one_len(dname, rec_dir.dentry, HEXDIR_LEN-1); | 148 | dentry = lookup_one_len(dname, rec_dir.dentry, HEXDIR_LEN-1); |
| 149 | if (IS_ERR(dentry)) { | 149 | if (IS_ERR(dentry)) { |
| @@ -159,7 +159,7 @@ nfsd4_create_clid_dir(struct nfs4_client *clp) | |||
| 159 | out_put: | 159 | out_put: |
| 160 | dput(dentry); | 160 | dput(dentry); |
| 161 | out_unlock: | 161 | out_unlock: |
| 162 | up(&rec_dir.dentry->d_inode->i_sem); | 162 | mutex_unlock(&rec_dir.dentry->d_inode->i_mutex); |
| 163 | if (status == 0) { | 163 | if (status == 0) { |
| 164 | clp->cl_firststate = 1; | 164 | clp->cl_firststate = 1; |
| 165 | nfsd4_sync_rec_dir(); | 165 | nfsd4_sync_rec_dir(); |
| @@ -259,9 +259,9 @@ nfsd4_remove_clid_file(struct dentry *dir, struct dentry *dentry) | |||
| 259 | printk("nfsd4: non-file found in client recovery directory\n"); | 259 | printk("nfsd4: non-file found in client recovery directory\n"); |
| 260 | return -EINVAL; | 260 | return -EINVAL; |
| 261 | } | 261 | } |
| 262 | down(&dir->d_inode->i_sem); | 262 | mutex_lock(&dir->d_inode->i_mutex); |
| 263 | status = vfs_unlink(dir->d_inode, dentry); | 263 | status = vfs_unlink(dir->d_inode, dentry); |
| 264 | up(&dir->d_inode->i_sem); | 264 | mutex_unlock(&dir->d_inode->i_mutex); |
| 265 | return status; | 265 | return status; |
| 266 | } | 266 | } |
| 267 | 267 | ||
| @@ -274,9 +274,9 @@ nfsd4_clear_clid_dir(struct dentry *dir, struct dentry *dentry) | |||
| 274 | * any regular files anyway, just in case the directory was created by | 274 | * any regular files anyway, just in case the directory was created by |
| 275 | * a kernel from the future.... */ | 275 | * a kernel from the future.... */ |
| 276 | nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file); | 276 | nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file); |
| 277 | down(&dir->d_inode->i_sem); | 277 | mutex_lock(&dir->d_inode->i_mutex); |
| 278 | status = vfs_rmdir(dir->d_inode, dentry); | 278 | status = vfs_rmdir(dir->d_inode, dentry); |
| 279 | up(&dir->d_inode->i_sem); | 279 | mutex_unlock(&dir->d_inode->i_mutex); |
| 280 | return status; | 280 | return status; |
| 281 | } | 281 | } |
| 282 | 282 | ||
| @@ -288,9 +288,9 @@ nfsd4_unlink_clid_dir(char *name, int namlen) | |||
| 288 | 288 | ||
| 289 | dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name); | 289 | dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name); |
| 290 | 290 | ||
| 291 | down(&rec_dir.dentry->d_inode->i_sem); | 291 | mutex_lock(&rec_dir.dentry->d_inode->i_mutex); |
| 292 | dentry = lookup_one_len(name, rec_dir.dentry, namlen); | 292 | dentry = lookup_one_len(name, rec_dir.dentry, namlen); |
| 293 | up(&rec_dir.dentry->d_inode->i_sem); | 293 | mutex_unlock(&rec_dir.dentry->d_inode->i_mutex); |
| 294 | if (IS_ERR(dentry)) { | 294 | if (IS_ERR(dentry)) { |
| 295 | status = PTR_ERR(dentry); | 295 | status = PTR_ERR(dentry); |
| 296 | return status; | 296 | return status; |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index df4019f04560..bb36b4304491 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
| @@ -390,12 +390,12 @@ set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl *pacl, char *key) | |||
| 390 | 390 | ||
| 391 | error = -EOPNOTSUPP; | 391 | error = -EOPNOTSUPP; |
| 392 | if (inode->i_op && inode->i_op->setxattr) { | 392 | if (inode->i_op && inode->i_op->setxattr) { |
| 393 | down(&inode->i_sem); | 393 | mutex_lock(&inode->i_mutex); |
| 394 | security_inode_setxattr(dentry, key, buf, len, 0); | 394 | security_inode_setxattr(dentry, key, buf, len, 0); |
| 395 | error = inode->i_op->setxattr(dentry, key, buf, len, 0); | 395 | error = inode->i_op->setxattr(dentry, key, buf, len, 0); |
| 396 | if (!error) | 396 | if (!error) |
| 397 | security_inode_post_setxattr(dentry, key, buf, len, 0); | 397 | security_inode_post_setxattr(dentry, key, buf, len, 0); |
| 398 | up(&inode->i_sem); | 398 | mutex_unlock(&inode->i_mutex); |
| 399 | } | 399 | } |
| 400 | out: | 400 | out: |
| 401 | kfree(buf); | 401 | kfree(buf); |
| @@ -739,9 +739,9 @@ nfsd_sync(struct file *filp) | |||
| 739 | int err; | 739 | int err; |
| 740 | struct inode *inode = filp->f_dentry->d_inode; | 740 | struct inode *inode = filp->f_dentry->d_inode; |
| 741 | dprintk("nfsd: sync file %s\n", filp->f_dentry->d_name.name); | 741 | dprintk("nfsd: sync file %s\n", filp->f_dentry->d_name.name); |
| 742 | down(&inode->i_sem); | 742 | mutex_lock(&inode->i_mutex); |
| 743 | err=nfsd_dosync(filp, filp->f_dentry, filp->f_op); | 743 | err=nfsd_dosync(filp, filp->f_dentry, filp->f_op); |
| 744 | up(&inode->i_sem); | 744 | mutex_unlock(&inode->i_mutex); |
| 745 | 745 | ||
| 746 | return err; | 746 | return err; |
| 747 | } | 747 | } |
| @@ -885,9 +885,9 @@ static void kill_suid(struct dentry *dentry) | |||
| 885 | struct iattr ia; | 885 | struct iattr ia; |
| 886 | ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID; | 886 | ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID; |
| 887 | 887 | ||
| 888 | down(&dentry->d_inode->i_sem); | 888 | mutex_lock(&dentry->d_inode->i_mutex); |
| 889 | notify_change(dentry, &ia); | 889 | notify_change(dentry, &ia); |
| 890 | up(&dentry->d_inode->i_sem); | 890 | mutex_unlock(&dentry->d_inode->i_mutex); |
| 891 | } | 891 | } |
| 892 | 892 | ||
| 893 | static inline int | 893 | static inline int |
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c index eda056bac256..9480a0526cd3 100644 --- a/fs/ntfs/attrib.c +++ b/fs/ntfs/attrib.c | |||
| @@ -1532,7 +1532,7 @@ int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a, | |||
| 1532 | * NOTE to self: No changes in the attribute list are required to move from | 1532 | * NOTE to self: No changes in the attribute list are required to move from |
| 1533 | * a resident to a non-resident attribute. | 1533 | * a resident to a non-resident attribute. |
| 1534 | * | 1534 | * |
| 1535 | * Locking: - The caller must hold i_sem on the inode. | 1535 | * Locking: - The caller must hold i_mutex on the inode. |
| 1536 | */ | 1536 | */ |
| 1537 | int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size) | 1537 | int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size) |
| 1538 | { | 1538 | { |
| @@ -1728,7 +1728,7 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size) | |||
| 1728 | /* | 1728 | /* |
| 1729 | * This needs to be last since the address space operations ->readpage | 1729 | * This needs to be last since the address space operations ->readpage |
| 1730 | * and ->writepage can run concurrently with us as they are not | 1730 | * and ->writepage can run concurrently with us as they are not |
| 1731 | * serialized on i_sem. Note, we are not allowed to fail once we flip | 1731 | * serialized on i_mutex. Note, we are not allowed to fail once we flip |
| 1732 | * this switch, which is another reason to do this last. | 1732 | * this switch, which is another reason to do this last. |
| 1733 | */ | 1733 | */ |
| 1734 | NInoSetNonResident(ni); | 1734 | NInoSetNonResident(ni); |
diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c index 795c3d1930f5..b0690d4c8906 100644 --- a/fs/ntfs/dir.c +++ b/fs/ntfs/dir.c | |||
| @@ -69,7 +69,7 @@ ntfschar I30[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('I'), | |||
| 69 | * work but we don't care for how quickly one can access them. This also fixes | 69 | * work but we don't care for how quickly one can access them. This also fixes |
| 70 | * the dcache aliasing issues. | 70 | * the dcache aliasing issues. |
| 71 | * | 71 | * |
| 72 | * Locking: - Caller must hold i_sem on the directory. | 72 | * Locking: - Caller must hold i_mutex on the directory. |
| 73 | * - Each page cache page in the index allocation mapping must be | 73 | * - Each page cache page in the index allocation mapping must be |
| 74 | * locked whilst being accessed otherwise we may find a corrupt | 74 | * locked whilst being accessed otherwise we may find a corrupt |
| 75 | * page due to it being under ->writepage at the moment which | 75 | * page due to it being under ->writepage at the moment which |
| @@ -1085,11 +1085,11 @@ static inline int ntfs_filldir(ntfs_volume *vol, loff_t fpos, | |||
| 1085 | * While this will return the names in random order this doesn't matter for | 1085 | * While this will return the names in random order this doesn't matter for |
| 1086 | * ->readdir but OTOH results in a faster ->readdir. | 1086 | * ->readdir but OTOH results in a faster ->readdir. |
| 1087 | * | 1087 | * |
| 1088 | * VFS calls ->readdir without BKL but with i_sem held. This protects the VFS | 1088 | * VFS calls ->readdir without BKL but with i_mutex held. This protects the VFS |
| 1089 | * parts (e.g. ->f_pos and ->i_size, and it also protects against directory | 1089 | * parts (e.g. ->f_pos and ->i_size, and it also protects against directory |
| 1090 | * modifications). | 1090 | * modifications). |
| 1091 | * | 1091 | * |
| 1092 | * Locking: - Caller must hold i_sem on the directory. | 1092 | * Locking: - Caller must hold i_mutex on the directory. |
| 1093 | * - Each page cache page in the index allocation mapping must be | 1093 | * - Each page cache page in the index allocation mapping must be |
| 1094 | * locked whilst being accessed otherwise we may find a corrupt | 1094 | * locked whilst being accessed otherwise we may find a corrupt |
| 1095 | * page due to it being under ->writepage at the moment which | 1095 | * page due to it being under ->writepage at the moment which |
| @@ -1520,7 +1520,7 @@ static int ntfs_dir_open(struct inode *vi, struct file *filp) | |||
| 1520 | * Note: In the past @filp could be NULL so we ignore it as we don't need it | 1520 | * Note: In the past @filp could be NULL so we ignore it as we don't need it |
| 1521 | * anyway. | 1521 | * anyway. |
| 1522 | * | 1522 | * |
| 1523 | * Locking: Caller must hold i_sem on the inode. | 1523 | * Locking: Caller must hold i_mutex on the inode. |
| 1524 | * | 1524 | * |
| 1525 | * TODO: We should probably also write all attribute/index inodes associated | 1525 | * TODO: We should probably also write all attribute/index inodes associated |
| 1526 | * with this inode but since we have no simple way of getting to them we ignore | 1526 | * with this inode but since we have no simple way of getting to them we ignore |
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index 727533891813..30f71acdc1cb 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c | |||
| @@ -106,7 +106,7 @@ static int ntfs_file_open(struct inode *vi, struct file *filp) | |||
| 106 | * this is the case, the necessary zeroing will also have happened and that all | 106 | * this is the case, the necessary zeroing will also have happened and that all |
| 107 | * metadata is self-consistent. | 107 | * metadata is self-consistent. |
| 108 | * | 108 | * |
| 109 | * Locking: i_sem on the vfs inode corrseponsind to the ntfs inode @ni must be | 109 | * Locking: i_mutex on the vfs inode corrseponsind to the ntfs inode @ni must be |
| 110 | * held by the caller. | 110 | * held by the caller. |
| 111 | */ | 111 | */ |
| 112 | static int ntfs_attr_extend_initialized(ntfs_inode *ni, const s64 new_init_size, | 112 | static int ntfs_attr_extend_initialized(ntfs_inode *ni, const s64 new_init_size, |
| @@ -473,7 +473,7 @@ static inline int ntfs_submit_bh_for_read(struct buffer_head *bh) | |||
| 473 | * @bytes: number of bytes to be written | 473 | * @bytes: number of bytes to be written |
| 474 | * | 474 | * |
| 475 | * This is called for non-resident attributes from ntfs_file_buffered_write() | 475 | * This is called for non-resident attributes from ntfs_file_buffered_write() |
| 476 | * with i_sem held on the inode (@pages[0]->mapping->host). There are | 476 | * with i_mutex held on the inode (@pages[0]->mapping->host). There are |
| 477 | * @nr_pages pages in @pages which are locked but not kmap()ped. The source | 477 | * @nr_pages pages in @pages which are locked but not kmap()ped. The source |
| 478 | * data has not yet been copied into the @pages. | 478 | * data has not yet been copied into the @pages. |
| 479 | * | 479 | * |
| @@ -1637,7 +1637,7 @@ err_out: | |||
| 1637 | * @pos: byte position in file at which the write begins | 1637 | * @pos: byte position in file at which the write begins |
| 1638 | * @bytes: number of bytes to be written | 1638 | * @bytes: number of bytes to be written |
| 1639 | * | 1639 | * |
| 1640 | * This is called from ntfs_file_buffered_write() with i_sem held on the inode | 1640 | * This is called from ntfs_file_buffered_write() with i_mutex held on the inode |
| 1641 | * (@pages[0]->mapping->host). There are @nr_pages pages in @pages which are | 1641 | * (@pages[0]->mapping->host). There are @nr_pages pages in @pages which are |
| 1642 | * locked but not kmap()ped. The source data has already been copied into the | 1642 | * locked but not kmap()ped. The source data has already been copied into the |
| 1643 | * @page. ntfs_prepare_pages_for_non_resident_write() has been called before | 1643 | * @page. ntfs_prepare_pages_for_non_resident_write() has been called before |
| @@ -1814,7 +1814,7 @@ err_out: | |||
| 1814 | /** | 1814 | /** |
| 1815 | * ntfs_file_buffered_write - | 1815 | * ntfs_file_buffered_write - |
| 1816 | * | 1816 | * |
| 1817 | * Locking: The vfs is holding ->i_sem on the inode. | 1817 | * Locking: The vfs is holding ->i_mutex on the inode. |
| 1818 | */ | 1818 | */ |
| 1819 | static ssize_t ntfs_file_buffered_write(struct kiocb *iocb, | 1819 | static ssize_t ntfs_file_buffered_write(struct kiocb *iocb, |
| 1820 | const struct iovec *iov, unsigned long nr_segs, | 1820 | const struct iovec *iov, unsigned long nr_segs, |
| @@ -2196,9 +2196,9 @@ static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const char __user *buf, | |||
| 2196 | 2196 | ||
| 2197 | BUG_ON(iocb->ki_pos != pos); | 2197 | BUG_ON(iocb->ki_pos != pos); |
| 2198 | 2198 | ||
| 2199 | down(&inode->i_sem); | 2199 | mutex_lock(&inode->i_mutex); |
| 2200 | ret = ntfs_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos); | 2200 | ret = ntfs_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos); |
| 2201 | up(&inode->i_sem); | 2201 | mutex_unlock(&inode->i_mutex); |
| 2202 | if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { | 2202 | if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { |
| 2203 | int err = sync_page_range(inode, mapping, pos, ret); | 2203 | int err = sync_page_range(inode, mapping, pos, ret); |
| 2204 | if (err < 0) | 2204 | if (err < 0) |
| @@ -2221,12 +2221,12 @@ static ssize_t ntfs_file_writev(struct file *file, const struct iovec *iov, | |||
| 2221 | struct kiocb kiocb; | 2221 | struct kiocb kiocb; |
| 2222 | ssize_t ret; | 2222 | ssize_t ret; |
| 2223 | 2223 | ||
| 2224 | down(&inode->i_sem); | 2224 | mutex_lock(&inode->i_mutex); |
| 2225 | init_sync_kiocb(&kiocb, file); | 2225 | init_sync_kiocb(&kiocb, file); |
| 2226 | ret = ntfs_file_aio_write_nolock(&kiocb, iov, nr_segs, ppos); | 2226 | ret = ntfs_file_aio_write_nolock(&kiocb, iov, nr_segs, ppos); |
| 2227 | if (ret == -EIOCBQUEUED) | 2227 | if (ret == -EIOCBQUEUED) |
| 2228 | ret = wait_on_sync_kiocb(&kiocb); | 2228 | ret = wait_on_sync_kiocb(&kiocb); |
| 2229 | up(&inode->i_sem); | 2229 | mutex_unlock(&inode->i_mutex); |
| 2230 | if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { | 2230 | if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { |
| 2231 | int err = sync_page_range(inode, mapping, *ppos - ret, ret); | 2231 | int err = sync_page_range(inode, mapping, *ppos - ret, ret); |
| 2232 | if (err < 0) | 2232 | if (err < 0) |
| @@ -2269,7 +2269,7 @@ static ssize_t ntfs_file_write(struct file *file, const char __user *buf, | |||
| 2269 | * Note: In the past @filp could be NULL so we ignore it as we don't need it | 2269 | * Note: In the past @filp could be NULL so we ignore it as we don't need it |
| 2270 | * anyway. | 2270 | * anyway. |
| 2271 | * | 2271 | * |
| 2272 | * Locking: Caller must hold i_sem on the inode. | 2272 | * Locking: Caller must hold i_mutex on the inode. |
| 2273 | * | 2273 | * |
| 2274 | * TODO: We should probably also write all attribute/index inodes associated | 2274 | * TODO: We should probably also write all attribute/index inodes associated |
| 2275 | * with this inode but since we have no simple way of getting to them we ignore | 2275 | * with this inode but since we have no simple way of getting to them we ignore |
diff --git a/fs/ntfs/index.c b/fs/ntfs/index.c index 8f2d5727546f..9f5427c2d105 100644 --- a/fs/ntfs/index.c +++ b/fs/ntfs/index.c | |||
| @@ -32,7 +32,7 @@ | |||
| 32 | * Allocate a new index context, initialize it with @idx_ni and return it. | 32 | * Allocate a new index context, initialize it with @idx_ni and return it. |
| 33 | * Return NULL if allocation failed. | 33 | * Return NULL if allocation failed. |
| 34 | * | 34 | * |
| 35 | * Locking: Caller must hold i_sem on the index inode. | 35 | * Locking: Caller must hold i_mutex on the index inode. |
| 36 | */ | 36 | */ |
| 37 | ntfs_index_context *ntfs_index_ctx_get(ntfs_inode *idx_ni) | 37 | ntfs_index_context *ntfs_index_ctx_get(ntfs_inode *idx_ni) |
| 38 | { | 38 | { |
| @@ -50,7 +50,7 @@ ntfs_index_context *ntfs_index_ctx_get(ntfs_inode *idx_ni) | |||
| 50 | * | 50 | * |
| 51 | * Release the index context @ictx, releasing all associated resources. | 51 | * Release the index context @ictx, releasing all associated resources. |
| 52 | * | 52 | * |
| 53 | * Locking: Caller must hold i_sem on the index inode. | 53 | * Locking: Caller must hold i_mutex on the index inode. |
| 54 | */ | 54 | */ |
| 55 | void ntfs_index_ctx_put(ntfs_index_context *ictx) | 55 | void ntfs_index_ctx_put(ntfs_index_context *ictx) |
| 56 | { | 56 | { |
| @@ -106,7 +106,7 @@ void ntfs_index_ctx_put(ntfs_index_context *ictx) | |||
| 106 | * or ntfs_index_entry_write() before the call to ntfs_index_ctx_put() to | 106 | * or ntfs_index_entry_write() before the call to ntfs_index_ctx_put() to |
| 107 | * ensure that the changes are written to disk. | 107 | * ensure that the changes are written to disk. |
| 108 | * | 108 | * |
| 109 | * Locking: - Caller must hold i_sem on the index inode. | 109 | * Locking: - Caller must hold i_mutex on the index inode. |
| 110 | * - Each page cache page in the index allocation mapping must be | 110 | * - Each page cache page in the index allocation mapping must be |
| 111 | * locked whilst being accessed otherwise we may find a corrupt | 111 | * locked whilst being accessed otherwise we may find a corrupt |
| 112 | * page due to it being under ->writepage at the moment which | 112 | * page due to it being under ->writepage at the moment which |
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index b24f4c4b2c5c..bda7a08911a5 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c | |||
| @@ -2125,13 +2125,13 @@ void ntfs_put_inode(struct inode *vi) | |||
| 2125 | ntfs_inode *ni = NTFS_I(vi); | 2125 | ntfs_inode *ni = NTFS_I(vi); |
| 2126 | if (NInoIndexAllocPresent(ni)) { | 2126 | if (NInoIndexAllocPresent(ni)) { |
| 2127 | struct inode *bvi = NULL; | 2127 | struct inode *bvi = NULL; |
| 2128 | down(&vi->i_sem); | 2128 | mutex_lock(&vi->i_mutex); |
| 2129 | if (atomic_read(&vi->i_count) == 2) { | 2129 | if (atomic_read(&vi->i_count) == 2) { |
| 2130 | bvi = ni->itype.index.bmp_ino; | 2130 | bvi = ni->itype.index.bmp_ino; |
| 2131 | if (bvi) | 2131 | if (bvi) |
| 2132 | ni->itype.index.bmp_ino = NULL; | 2132 | ni->itype.index.bmp_ino = NULL; |
| 2133 | } | 2133 | } |
| 2134 | up(&vi->i_sem); | 2134 | mutex_unlock(&vi->i_mutex); |
| 2135 | if (bvi) | 2135 | if (bvi) |
| 2136 | iput(bvi); | 2136 | iput(bvi); |
| 2137 | } | 2137 | } |
| @@ -2311,7 +2311,7 @@ static const char *es = " Leaving inconsistent metadata. Unmount and run " | |||
| 2311 | * | 2311 | * |
| 2312 | * Returns 0 on success or -errno on error. | 2312 | * Returns 0 on success or -errno on error. |
| 2313 | * | 2313 | * |
| 2314 | * Called with ->i_sem held. In all but one case ->i_alloc_sem is held for | 2314 | * Called with ->i_mutex held. In all but one case ->i_alloc_sem is held for |
| 2315 | * writing. The only case in the kernel where ->i_alloc_sem is not held is | 2315 | * writing. The only case in the kernel where ->i_alloc_sem is not held is |
| 2316 | * mm/filemap.c::generic_file_buffered_write() where vmtruncate() is called | 2316 | * mm/filemap.c::generic_file_buffered_write() where vmtruncate() is called |
| 2317 | * with the current i_size as the offset. The analogous place in NTFS is in | 2317 | * with the current i_size as the offset. The analogous place in NTFS is in |
| @@ -2831,7 +2831,7 @@ void ntfs_truncate_vfs(struct inode *vi) { | |||
| 2831 | * We also abort all changes of user, group, and mode as we do not implement | 2831 | * We also abort all changes of user, group, and mode as we do not implement |
| 2832 | * the NTFS ACLs yet. | 2832 | * the NTFS ACLs yet. |
| 2833 | * | 2833 | * |
| 2834 | * Called with ->i_sem held. For the ATTR_SIZE (i.e. ->truncate) case, also | 2834 | * Called with ->i_mutex held. For the ATTR_SIZE (i.e. ->truncate) case, also |
| 2835 | * called with ->i_alloc_sem held for writing. | 2835 | * called with ->i_alloc_sem held for writing. |
| 2836 | * | 2836 | * |
| 2837 | * Basically this is a copy of generic notify_change() and inode_setattr() | 2837 | * Basically this is a copy of generic notify_change() and inode_setattr() |
diff --git a/fs/ntfs/namei.c b/fs/ntfs/namei.c index 351dbc3b6e40..5ea9eb93af62 100644 --- a/fs/ntfs/namei.c +++ b/fs/ntfs/namei.c | |||
| @@ -96,7 +96,7 @@ | |||
| 96 | * name. We then convert the name to the current NLS code page, and proceed | 96 | * name. We then convert the name to the current NLS code page, and proceed |
| 97 | * searching for a dentry with this name, etc, as in case 2), above. | 97 | * searching for a dentry with this name, etc, as in case 2), above. |
| 98 | * | 98 | * |
| 99 | * Locking: Caller must hold i_sem on the directory. | 99 | * Locking: Caller must hold i_mutex on the directory. |
| 100 | */ | 100 | */ |
| 101 | static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent, | 101 | static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent, |
| 102 | struct nameidata *nd) | 102 | struct nameidata *nd) |
| @@ -254,7 +254,7 @@ handle_name: | |||
| 254 | nls_name.hash = full_name_hash(nls_name.name, nls_name.len); | 254 | nls_name.hash = full_name_hash(nls_name.name, nls_name.len); |
| 255 | 255 | ||
| 256 | /* | 256 | /* |
| 257 | * Note: No need for dent->d_lock lock as i_sem is held on the | 257 | * Note: No need for dent->d_lock lock as i_mutex is held on the |
| 258 | * parent inode. | 258 | * parent inode. |
| 259 | */ | 259 | */ |
| 260 | 260 | ||
| @@ -374,7 +374,7 @@ struct inode_operations ntfs_dir_inode_ops = { | |||
| 374 | * The code is based on the ext3 ->get_parent() implementation found in | 374 | * The code is based on the ext3 ->get_parent() implementation found in |
| 375 | * fs/ext3/namei.c::ext3_get_parent(). | 375 | * fs/ext3/namei.c::ext3_get_parent(). |
| 376 | * | 376 | * |
| 377 | * Note: ntfs_get_parent() is called with @child_dent->d_inode->i_sem down. | 377 | * Note: ntfs_get_parent() is called with @child_dent->d_inode->i_mutex down. |
| 378 | * | 378 | * |
| 379 | * Return the dentry of the parent directory on success or the error code on | 379 | * Return the dentry of the parent directory on success or the error code on |
| 380 | * error (IS_ERR() is true). | 380 | * error (IS_ERR() is true). |
diff --git a/fs/ntfs/quota.c b/fs/ntfs/quota.c index 833df2a4e9fb..d0ef4182147b 100644 --- a/fs/ntfs/quota.c +++ b/fs/ntfs/quota.c | |||
| @@ -48,7 +48,7 @@ BOOL ntfs_mark_quotas_out_of_date(ntfs_volume *vol) | |||
| 48 | ntfs_error(vol->sb, "Quota inodes are not open."); | 48 | ntfs_error(vol->sb, "Quota inodes are not open."); |
| 49 | return FALSE; | 49 | return FALSE; |
| 50 | } | 50 | } |
| 51 | down(&vol->quota_q_ino->i_sem); | 51 | mutex_lock(&vol->quota_q_ino->i_mutex); |
| 52 | ictx = ntfs_index_ctx_get(NTFS_I(vol->quota_q_ino)); | 52 | ictx = ntfs_index_ctx_get(NTFS_I(vol->quota_q_ino)); |
| 53 | if (!ictx) { | 53 | if (!ictx) { |
| 54 | ntfs_error(vol->sb, "Failed to get index context."); | 54 | ntfs_error(vol->sb, "Failed to get index context."); |
| @@ -98,7 +98,7 @@ BOOL ntfs_mark_quotas_out_of_date(ntfs_volume *vol) | |||
| 98 | ntfs_index_entry_mark_dirty(ictx); | 98 | ntfs_index_entry_mark_dirty(ictx); |
| 99 | set_done: | 99 | set_done: |
| 100 | ntfs_index_ctx_put(ictx); | 100 | ntfs_index_ctx_put(ictx); |
| 101 | up(&vol->quota_q_ino->i_sem); | 101 | mutex_unlock(&vol->quota_q_ino->i_mutex); |
| 102 | /* | 102 | /* |
| 103 | * We set the flag so we do not try to mark the quotas out of date | 103 | * We set the flag so we do not try to mark the quotas out of date |
| 104 | * again on remount. | 104 | * again on remount. |
| @@ -110,7 +110,7 @@ done: | |||
| 110 | err_out: | 110 | err_out: |
| 111 | if (ictx) | 111 | if (ictx) |
| 112 | ntfs_index_ctx_put(ictx); | 112 | ntfs_index_ctx_put(ictx); |
| 113 | up(&vol->quota_q_ino->i_sem); | 113 | mutex_unlock(&vol->quota_q_ino->i_mutex); |
| 114 | return FALSE; | 114 | return FALSE; |
| 115 | } | 115 | } |
| 116 | 116 | ||
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 6c16db9e1a8a..280e383fc84e 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c | |||
| @@ -1213,10 +1213,10 @@ static int check_windows_hibernation_status(ntfs_volume *vol) | |||
| 1213 | * Find the inode number for the hibernation file by looking up the | 1213 | * Find the inode number for the hibernation file by looking up the |
| 1214 | * filename hiberfil.sys in the root directory. | 1214 | * filename hiberfil.sys in the root directory. |
| 1215 | */ | 1215 | */ |
| 1216 | down(&vol->root_ino->i_sem); | 1216 | mutex_lock(&vol->root_ino->i_mutex); |
| 1217 | mref = ntfs_lookup_inode_by_name(NTFS_I(vol->root_ino), hiberfil, 12, | 1217 | mref = ntfs_lookup_inode_by_name(NTFS_I(vol->root_ino), hiberfil, 12, |
| 1218 | &name); | 1218 | &name); |
| 1219 | up(&vol->root_ino->i_sem); | 1219 | mutex_unlock(&vol->root_ino->i_mutex); |
| 1220 | if (IS_ERR_MREF(mref)) { | 1220 | if (IS_ERR_MREF(mref)) { |
| 1221 | ret = MREF_ERR(mref); | 1221 | ret = MREF_ERR(mref); |
| 1222 | /* If the file does not exist, Windows is not hibernated. */ | 1222 | /* If the file does not exist, Windows is not hibernated. */ |
| @@ -1307,10 +1307,10 @@ static BOOL load_and_init_quota(ntfs_volume *vol) | |||
| 1307 | * Find the inode number for the quota file by looking up the filename | 1307 | * Find the inode number for the quota file by looking up the filename |
| 1308 | * $Quota in the extended system files directory $Extend. | 1308 | * $Quota in the extended system files directory $Extend. |
| 1309 | */ | 1309 | */ |
| 1310 | down(&vol->extend_ino->i_sem); | 1310 | mutex_lock(&vol->extend_ino->i_mutex); |
| 1311 | mref = ntfs_lookup_inode_by_name(NTFS_I(vol->extend_ino), Quota, 6, | 1311 | mref = ntfs_lookup_inode_by_name(NTFS_I(vol->extend_ino), Quota, 6, |
| 1312 | &name); | 1312 | &name); |
| 1313 | up(&vol->extend_ino->i_sem); | 1313 | mutex_unlock(&vol->extend_ino->i_mutex); |
| 1314 | if (IS_ERR_MREF(mref)) { | 1314 | if (IS_ERR_MREF(mref)) { |
| 1315 | /* | 1315 | /* |
| 1316 | * If the file does not exist, quotas are disabled and have | 1316 | * If the file does not exist, quotas are disabled and have |
| @@ -1390,10 +1390,10 @@ static BOOL load_and_init_usnjrnl(ntfs_volume *vol) | |||
| 1390 | * Find the inode number for the transaction log file by looking up the | 1390 | * Find the inode number for the transaction log file by looking up the |
| 1391 | * filename $UsnJrnl in the extended system files directory $Extend. | 1391 | * filename $UsnJrnl in the extended system files directory $Extend. |
| 1392 | */ | 1392 | */ |
| 1393 | down(&vol->extend_ino->i_sem); | 1393 | mutex_lock(&vol->extend_ino->i_mutex); |
| 1394 | mref = ntfs_lookup_inode_by_name(NTFS_I(vol->extend_ino), UsnJrnl, 8, | 1394 | mref = ntfs_lookup_inode_by_name(NTFS_I(vol->extend_ino), UsnJrnl, 8, |
| 1395 | &name); | 1395 | &name); |
| 1396 | up(&vol->extend_ino->i_sem); | 1396 | mutex_unlock(&vol->extend_ino->i_mutex); |
| 1397 | if (IS_ERR_MREF(mref)) { | 1397 | if (IS_ERR_MREF(mref)) { |
| 1398 | /* | 1398 | /* |
| 1399 | * If the file does not exist, transaction logging is disabled, | 1399 | * If the file does not exist, transaction logging is disabled, |
| @@ -2312,9 +2312,9 @@ static void ntfs_put_super(struct super_block *sb) | |||
| 2312 | if (!list_empty(&sb->s_dirty)) { | 2312 | if (!list_empty(&sb->s_dirty)) { |
| 2313 | const char *s1, *s2; | 2313 | const char *s1, *s2; |
| 2314 | 2314 | ||
| 2315 | down(&vol->mft_ino->i_sem); | 2315 | mutex_lock(&vol->mft_ino->i_mutex); |
| 2316 | truncate_inode_pages(vol->mft_ino->i_mapping, 0); | 2316 | truncate_inode_pages(vol->mft_ino->i_mapping, 0); |
| 2317 | up(&vol->mft_ino->i_sem); | 2317 | mutex_unlock(&vol->mft_ino->i_mutex); |
| 2318 | write_inode_now(vol->mft_ino, 1); | 2318 | write_inode_now(vol->mft_ino, 1); |
| 2319 | if (!list_empty(&sb->s_dirty)) { | 2319 | if (!list_empty(&sb->s_dirty)) { |
| 2320 | static const char *_s1 = "inodes"; | 2320 | static const char *_s1 = "inodes"; |
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 465f797451ee..6b9812db3779 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
| @@ -966,7 +966,7 @@ static int ocfs2_truncate_log_append(struct ocfs2_super *osb, | |||
| 966 | mlog_entry("start_blk = %"MLFu64", num_clusters = %u\n", start_blk, | 966 | mlog_entry("start_blk = %"MLFu64", num_clusters = %u\n", start_blk, |
| 967 | num_clusters); | 967 | num_clusters); |
| 968 | 968 | ||
| 969 | BUG_ON(!down_trylock(&tl_inode->i_sem)); | 969 | BUG_ON(mutex_trylock(&tl_inode->i_mutex)); |
| 970 | 970 | ||
| 971 | start_cluster = ocfs2_blocks_to_clusters(osb->sb, start_blk); | 971 | start_cluster = ocfs2_blocks_to_clusters(osb->sb, start_blk); |
| 972 | 972 | ||
| @@ -1108,7 +1108,7 @@ bail: | |||
| 1108 | return status; | 1108 | return status; |
| 1109 | } | 1109 | } |
| 1110 | 1110 | ||
| 1111 | /* Expects you to already be holding tl_inode->i_sem */ | 1111 | /* Expects you to already be holding tl_inode->i_mutex */ |
| 1112 | static int __ocfs2_flush_truncate_log(struct ocfs2_super *osb) | 1112 | static int __ocfs2_flush_truncate_log(struct ocfs2_super *osb) |
| 1113 | { | 1113 | { |
| 1114 | int status; | 1114 | int status; |
| @@ -1123,7 +1123,7 @@ static int __ocfs2_flush_truncate_log(struct ocfs2_super *osb) | |||
| 1123 | 1123 | ||
| 1124 | mlog_entry_void(); | 1124 | mlog_entry_void(); |
| 1125 | 1125 | ||
| 1126 | BUG_ON(!down_trylock(&tl_inode->i_sem)); | 1126 | BUG_ON(mutex_trylock(&tl_inode->i_mutex)); |
| 1127 | 1127 | ||
| 1128 | di = (struct ocfs2_dinode *) tl_bh->b_data; | 1128 | di = (struct ocfs2_dinode *) tl_bh->b_data; |
| 1129 | tl = &di->id2.i_dealloc; | 1129 | tl = &di->id2.i_dealloc; |
| @@ -1198,9 +1198,9 @@ int ocfs2_flush_truncate_log(struct ocfs2_super *osb) | |||
| 1198 | int status; | 1198 | int status; |
| 1199 | struct inode *tl_inode = osb->osb_tl_inode; | 1199 | struct inode *tl_inode = osb->osb_tl_inode; |
| 1200 | 1200 | ||
| 1201 | down(&tl_inode->i_sem); | 1201 | mutex_lock(&tl_inode->i_mutex); |
| 1202 | status = __ocfs2_flush_truncate_log(osb); | 1202 | status = __ocfs2_flush_truncate_log(osb); |
| 1203 | up(&tl_inode->i_sem); | 1203 | mutex_unlock(&tl_inode->i_mutex); |
| 1204 | 1204 | ||
| 1205 | return status; | 1205 | return status; |
| 1206 | } | 1206 | } |
| @@ -1363,7 +1363,7 @@ int ocfs2_complete_truncate_log_recovery(struct ocfs2_super *osb, | |||
| 1363 | mlog(0, "cleanup %u records from %"MLFu64"\n", num_recs, | 1363 | mlog(0, "cleanup %u records from %"MLFu64"\n", num_recs, |
| 1364 | tl_copy->i_blkno); | 1364 | tl_copy->i_blkno); |
| 1365 | 1365 | ||
| 1366 | down(&tl_inode->i_sem); | 1366 | mutex_lock(&tl_inode->i_mutex); |
| 1367 | for(i = 0; i < num_recs; i++) { | 1367 | for(i = 0; i < num_recs; i++) { |
| 1368 | if (ocfs2_truncate_log_needs_flush(osb)) { | 1368 | if (ocfs2_truncate_log_needs_flush(osb)) { |
| 1369 | status = __ocfs2_flush_truncate_log(osb); | 1369 | status = __ocfs2_flush_truncate_log(osb); |
| @@ -1395,7 +1395,7 @@ int ocfs2_complete_truncate_log_recovery(struct ocfs2_super *osb, | |||
| 1395 | } | 1395 | } |
| 1396 | 1396 | ||
| 1397 | bail_up: | 1397 | bail_up: |
| 1398 | up(&tl_inode->i_sem); | 1398 | mutex_unlock(&tl_inode->i_mutex); |
| 1399 | 1399 | ||
| 1400 | mlog_exit(status); | 1400 | mlog_exit(status); |
| 1401 | return status; | 1401 | return status; |
| @@ -1840,7 +1840,7 @@ start: | |||
| 1840 | 1840 | ||
| 1841 | mlog(0, "clusters_to_del = %u in this pass\n", clusters_to_del); | 1841 | mlog(0, "clusters_to_del = %u in this pass\n", clusters_to_del); |
| 1842 | 1842 | ||
| 1843 | down(&tl_inode->i_sem); | 1843 | mutex_lock(&tl_inode->i_mutex); |
| 1844 | tl_sem = 1; | 1844 | tl_sem = 1; |
| 1845 | /* ocfs2_truncate_log_needs_flush guarantees us at least one | 1845 | /* ocfs2_truncate_log_needs_flush guarantees us at least one |
| 1846 | * record is free for use. If there isn't any, we flush to get | 1846 | * record is free for use. If there isn't any, we flush to get |
| @@ -1875,7 +1875,7 @@ start: | |||
| 1875 | goto bail; | 1875 | goto bail; |
| 1876 | } | 1876 | } |
| 1877 | 1877 | ||
| 1878 | up(&tl_inode->i_sem); | 1878 | mutex_unlock(&tl_inode->i_mutex); |
| 1879 | tl_sem = 0; | 1879 | tl_sem = 0; |
| 1880 | 1880 | ||
| 1881 | ocfs2_commit_trans(handle); | 1881 | ocfs2_commit_trans(handle); |
| @@ -1890,7 +1890,7 @@ bail: | |||
| 1890 | ocfs2_schedule_truncate_log_flush(osb, 1); | 1890 | ocfs2_schedule_truncate_log_flush(osb, 1); |
| 1891 | 1891 | ||
| 1892 | if (tl_sem) | 1892 | if (tl_sem) |
| 1893 | up(&tl_inode->i_sem); | 1893 | mutex_unlock(&tl_inode->i_mutex); |
| 1894 | 1894 | ||
| 1895 | if (handle) | 1895 | if (handle) |
| 1896 | ocfs2_commit_trans(handle); | 1896 | ocfs2_commit_trans(handle); |
| @@ -1994,7 +1994,7 @@ int ocfs2_prepare_truncate(struct ocfs2_super *osb, | |||
| 1994 | goto bail; | 1994 | goto bail; |
| 1995 | } | 1995 | } |
| 1996 | 1996 | ||
| 1997 | down(&ext_alloc_inode->i_sem); | 1997 | mutex_lock(&ext_alloc_inode->i_mutex); |
| 1998 | (*tc)->tc_ext_alloc_inode = ext_alloc_inode; | 1998 | (*tc)->tc_ext_alloc_inode = ext_alloc_inode; |
| 1999 | 1999 | ||
| 2000 | status = ocfs2_meta_lock(ext_alloc_inode, | 2000 | status = ocfs2_meta_lock(ext_alloc_inode, |
| @@ -2026,7 +2026,7 @@ static void ocfs2_free_truncate_context(struct ocfs2_truncate_context *tc) | |||
| 2026 | if (tc->tc_ext_alloc_locked) | 2026 | if (tc->tc_ext_alloc_locked) |
| 2027 | ocfs2_meta_unlock(tc->tc_ext_alloc_inode, 1); | 2027 | ocfs2_meta_unlock(tc->tc_ext_alloc_inode, 1); |
| 2028 | 2028 | ||
| 2029 | up(&tc->tc_ext_alloc_inode->i_sem); | 2029 | mutex_unlock(&tc->tc_ext_alloc_inode->i_mutex); |
| 2030 | iput(tc->tc_ext_alloc_inode); | 2030 | iput(tc->tc_ext_alloc_inode); |
| 2031 | } | 2031 | } |
| 2032 | 2032 | ||
diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c index 5fd60c105913..cf7828f23361 100644 --- a/fs/ocfs2/cluster/nodemanager.c +++ b/fs/ocfs2/cluster/nodemanager.c | |||
| @@ -653,7 +653,7 @@ static struct config_group *o2nm_cluster_group_make_group(struct config_group *g | |||
| 653 | struct config_group *o2hb_group = NULL, *ret = NULL; | 653 | struct config_group *o2hb_group = NULL, *ret = NULL; |
| 654 | void *defs = NULL; | 654 | void *defs = NULL; |
| 655 | 655 | ||
| 656 | /* this runs under the parent dir's i_sem; there can be only | 656 | /* this runs under the parent dir's i_mutex; there can be only |
| 657 | * one caller in here at a time */ | 657 | * one caller in here at a time */ |
| 658 | if (o2nm_single_cluster) | 658 | if (o2nm_single_cluster) |
| 659 | goto out; /* ENOSPC */ | 659 | goto out; /* ENOSPC */ |
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index 856e20ae8263..57158fa75d91 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c | |||
| @@ -202,7 +202,7 @@ bail: | |||
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | /* | 204 | /* |
| 205 | * NOTE: this should always be called with parent dir i_sem taken. | 205 | * NOTE: this should always be called with parent dir i_mutex taken. |
| 206 | */ | 206 | */ |
| 207 | int ocfs2_find_files_on_disk(const char *name, | 207 | int ocfs2_find_files_on_disk(const char *name, |
| 208 | int namelen, | 208 | int namelen, |
| @@ -245,7 +245,7 @@ leave: | |||
| 245 | * Return 0 if the name does not exist | 245 | * Return 0 if the name does not exist |
| 246 | * Return -EEXIST if the directory contains the name | 246 | * Return -EEXIST if the directory contains the name |
| 247 | * | 247 | * |
| 248 | * Callers should have i_sem + a cluster lock on dir | 248 | * Callers should have i_mutex + a cluster lock on dir |
| 249 | */ | 249 | */ |
| 250 | int ocfs2_check_dir_for_entry(struct inode *dir, | 250 | int ocfs2_check_dir_for_entry(struct inode *dir, |
| 251 | const char *name, | 251 | const char *name, |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 72ae9e3306f4..ca5f9f90d794 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
| @@ -492,7 +492,7 @@ restart_all: | |||
| 492 | } | 492 | } |
| 493 | 493 | ||
| 494 | /* blocks peope in read/write from reading our allocation | 494 | /* blocks peope in read/write from reading our allocation |
| 495 | * until we're done changing it. We depend on i_sem to block | 495 | * until we're done changing it. We depend on i_mutex to block |
| 496 | * other extend/truncate calls while we're here. Ordering wrt | 496 | * other extend/truncate calls while we're here. Ordering wrt |
| 497 | * start_trans is important here -- always do it before! */ | 497 | * start_trans is important here -- always do it before! */ |
| 498 | down_write(&OCFS2_I(inode)->ip_alloc_sem); | 498 | down_write(&OCFS2_I(inode)->ip_alloc_sem); |
| @@ -958,8 +958,8 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, | |||
| 958 | filp->f_flags &= ~O_DIRECT; | 958 | filp->f_flags &= ~O_DIRECT; |
| 959 | #endif | 959 | #endif |
| 960 | 960 | ||
| 961 | down(&inode->i_sem); | 961 | mutex_lock(&inode->i_mutex); |
| 962 | /* to match setattr's i_sem -> i_alloc_sem -> rw_lock ordering */ | 962 | /* to match setattr's i_mutex -> i_alloc_sem -> rw_lock ordering */ |
| 963 | if (filp->f_flags & O_DIRECT) { | 963 | if (filp->f_flags & O_DIRECT) { |
| 964 | have_alloc_sem = 1; | 964 | have_alloc_sem = 1; |
| 965 | down_read(&inode->i_alloc_sem); | 965 | down_read(&inode->i_alloc_sem); |
| @@ -1123,7 +1123,7 @@ out: | |||
| 1123 | up_read(&inode->i_alloc_sem); | 1123 | up_read(&inode->i_alloc_sem); |
| 1124 | if (rw_level != -1) | 1124 | if (rw_level != -1) |
| 1125 | ocfs2_rw_unlock(inode, rw_level); | 1125 | ocfs2_rw_unlock(inode, rw_level); |
| 1126 | up(&inode->i_sem); | 1126 | mutex_unlock(&inode->i_mutex); |
| 1127 | 1127 | ||
| 1128 | mlog_exit(ret); | 1128 | mlog_exit(ret); |
| 1129 | return ret; | 1129 | return ret; |
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index a91ba4dec936..d4ecc0627716 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c | |||
| @@ -485,10 +485,10 @@ static int ocfs2_remove_inode(struct inode *inode, | |||
| 485 | goto bail; | 485 | goto bail; |
| 486 | } | 486 | } |
| 487 | 487 | ||
| 488 | down(&inode_alloc_inode->i_sem); | 488 | mutex_lock(&inode_alloc_inode->i_mutex); |
| 489 | status = ocfs2_meta_lock(inode_alloc_inode, NULL, &inode_alloc_bh, 1); | 489 | status = ocfs2_meta_lock(inode_alloc_inode, NULL, &inode_alloc_bh, 1); |
| 490 | if (status < 0) { | 490 | if (status < 0) { |
| 491 | up(&inode_alloc_inode->i_sem); | 491 | mutex_unlock(&inode_alloc_inode->i_mutex); |
| 492 | 492 | ||
| 493 | mlog_errno(status); | 493 | mlog_errno(status); |
| 494 | goto bail; | 494 | goto bail; |
| @@ -536,7 +536,7 @@ bail_commit: | |||
| 536 | ocfs2_commit_trans(handle); | 536 | ocfs2_commit_trans(handle); |
| 537 | bail_unlock: | 537 | bail_unlock: |
| 538 | ocfs2_meta_unlock(inode_alloc_inode, 1); | 538 | ocfs2_meta_unlock(inode_alloc_inode, 1); |
| 539 | up(&inode_alloc_inode->i_sem); | 539 | mutex_unlock(&inode_alloc_inode->i_mutex); |
| 540 | brelse(inode_alloc_bh); | 540 | brelse(inode_alloc_bh); |
| 541 | bail: | 541 | bail: |
| 542 | iput(inode_alloc_inode); | 542 | iput(inode_alloc_inode); |
| @@ -567,10 +567,10 @@ static int ocfs2_wipe_inode(struct inode *inode, | |||
| 567 | /* Lock the orphan dir. The lock will be held for the entire | 567 | /* Lock the orphan dir. The lock will be held for the entire |
| 568 | * delete_inode operation. We do this now to avoid races with | 568 | * delete_inode operation. We do this now to avoid races with |
| 569 | * recovery completion on other nodes. */ | 569 | * recovery completion on other nodes. */ |
| 570 | down(&orphan_dir_inode->i_sem); | 570 | mutex_lock(&orphan_dir_inode->i_mutex); |
| 571 | status = ocfs2_meta_lock(orphan_dir_inode, NULL, &orphan_dir_bh, 1); | 571 | status = ocfs2_meta_lock(orphan_dir_inode, NULL, &orphan_dir_bh, 1); |
| 572 | if (status < 0) { | 572 | if (status < 0) { |
| 573 | up(&orphan_dir_inode->i_sem); | 573 | mutex_unlock(&orphan_dir_inode->i_mutex); |
| 574 | 574 | ||
| 575 | mlog_errno(status); | 575 | mlog_errno(status); |
| 576 | goto bail; | 576 | goto bail; |
| @@ -593,7 +593,7 @@ static int ocfs2_wipe_inode(struct inode *inode, | |||
| 593 | 593 | ||
| 594 | bail_unlock_dir: | 594 | bail_unlock_dir: |
| 595 | ocfs2_meta_unlock(orphan_dir_inode, 1); | 595 | ocfs2_meta_unlock(orphan_dir_inode, 1); |
| 596 | up(&orphan_dir_inode->i_sem); | 596 | mutex_unlock(&orphan_dir_inode->i_mutex); |
| 597 | brelse(orphan_dir_bh); | 597 | brelse(orphan_dir_bh); |
| 598 | bail: | 598 | bail: |
| 599 | iput(orphan_dir_inode); | 599 | iput(orphan_dir_inode); |
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index 04428042e5e5..303c8d96457f 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c | |||
| @@ -216,7 +216,7 @@ void ocfs2_handle_add_inode(struct ocfs2_journal_handle *handle, | |||
| 216 | atomic_inc(&inode->i_count); | 216 | atomic_inc(&inode->i_count); |
| 217 | 217 | ||
| 218 | /* we're obviously changing it... */ | 218 | /* we're obviously changing it... */ |
| 219 | down(&inode->i_sem); | 219 | mutex_lock(&inode->i_mutex); |
| 220 | 220 | ||
| 221 | /* sanity check */ | 221 | /* sanity check */ |
| 222 | BUG_ON(OCFS2_I(inode)->ip_handle); | 222 | BUG_ON(OCFS2_I(inode)->ip_handle); |
| @@ -241,7 +241,7 @@ static void ocfs2_handle_unlock_inodes(struct ocfs2_journal_handle *handle) | |||
| 241 | OCFS2_I(inode)->ip_handle = NULL; | 241 | OCFS2_I(inode)->ip_handle = NULL; |
| 242 | list_del_init(&OCFS2_I(inode)->ip_handle_list); | 242 | list_del_init(&OCFS2_I(inode)->ip_handle_list); |
| 243 | 243 | ||
| 244 | up(&inode->i_sem); | 244 | mutex_unlock(&inode->i_mutex); |
| 245 | iput(inode); | 245 | iput(inode); |
| 246 | } | 246 | } |
| 247 | } | 247 | } |
| @@ -1433,10 +1433,10 @@ static int ocfs2_recover_orphans(struct ocfs2_super *osb, | |||
| 1433 | goto out; | 1433 | goto out; |
| 1434 | } | 1434 | } |
| 1435 | 1435 | ||
| 1436 | down(&orphan_dir_inode->i_sem); | 1436 | mutex_lock(&orphan_dir_inode->i_mutex); |
| 1437 | status = ocfs2_meta_lock(orphan_dir_inode, NULL, NULL, 0); | 1437 | status = ocfs2_meta_lock(orphan_dir_inode, NULL, NULL, 0); |
| 1438 | if (status < 0) { | 1438 | if (status < 0) { |
| 1439 | up(&orphan_dir_inode->i_sem); | 1439 | mutex_unlock(&orphan_dir_inode->i_mutex); |
| 1440 | mlog_errno(status); | 1440 | mlog_errno(status); |
| 1441 | goto out; | 1441 | goto out; |
| 1442 | } | 1442 | } |
| @@ -1451,7 +1451,7 @@ static int ocfs2_recover_orphans(struct ocfs2_super *osb, | |||
| 1451 | if (!bh) | 1451 | if (!bh) |
| 1452 | status = -EINVAL; | 1452 | status = -EINVAL; |
| 1453 | if (status < 0) { | 1453 | if (status < 0) { |
| 1454 | up(&orphan_dir_inode->i_sem); | 1454 | mutex_unlock(&orphan_dir_inode->i_mutex); |
| 1455 | if (bh) | 1455 | if (bh) |
| 1456 | brelse(bh); | 1456 | brelse(bh); |
| 1457 | mlog_errno(status); | 1457 | mlog_errno(status); |
| @@ -1465,7 +1465,7 @@ static int ocfs2_recover_orphans(struct ocfs2_super *osb, | |||
| 1465 | 1465 | ||
| 1466 | if (!ocfs2_check_dir_entry(orphan_dir_inode, | 1466 | if (!ocfs2_check_dir_entry(orphan_dir_inode, |
| 1467 | de, bh, local)) { | 1467 | de, bh, local)) { |
| 1468 | up(&orphan_dir_inode->i_sem); | 1468 | mutex_unlock(&orphan_dir_inode->i_mutex); |
| 1469 | status = -EINVAL; | 1469 | status = -EINVAL; |
| 1470 | mlog_errno(status); | 1470 | mlog_errno(status); |
| 1471 | brelse(bh); | 1471 | brelse(bh); |
| @@ -1509,7 +1509,7 @@ static int ocfs2_recover_orphans(struct ocfs2_super *osb, | |||
| 1509 | } | 1509 | } |
| 1510 | brelse(bh); | 1510 | brelse(bh); |
| 1511 | } | 1511 | } |
| 1512 | up(&orphan_dir_inode->i_sem); | 1512 | mutex_unlock(&orphan_dir_inode->i_mutex); |
| 1513 | 1513 | ||
| 1514 | ocfs2_meta_unlock(orphan_dir_inode, 0); | 1514 | ocfs2_meta_unlock(orphan_dir_inode, 0); |
| 1515 | have_disk_lock = 0; | 1515 | have_disk_lock = 0; |
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c index fe373a2101d9..149b35181666 100644 --- a/fs/ocfs2/localalloc.c +++ b/fs/ocfs2/localalloc.c | |||
| @@ -334,7 +334,7 @@ int ocfs2_begin_local_alloc_recovery(struct ocfs2_super *osb, | |||
| 334 | goto bail; | 334 | goto bail; |
| 335 | } | 335 | } |
| 336 | 336 | ||
| 337 | down(&inode->i_sem); | 337 | mutex_lock(&inode->i_mutex); |
| 338 | 338 | ||
| 339 | status = ocfs2_read_block(osb, OCFS2_I(inode)->ip_blkno, | 339 | status = ocfs2_read_block(osb, OCFS2_I(inode)->ip_blkno, |
| 340 | &alloc_bh, 0, inode); | 340 | &alloc_bh, 0, inode); |
| @@ -367,7 +367,7 @@ bail: | |||
| 367 | brelse(alloc_bh); | 367 | brelse(alloc_bh); |
| 368 | 368 | ||
| 369 | if (inode) { | 369 | if (inode) { |
| 370 | up(&inode->i_sem); | 370 | mutex_unlock(&inode->i_mutex); |
| 371 | iput(inode); | 371 | iput(inode); |
| 372 | } | 372 | } |
| 373 | 373 | ||
| @@ -446,7 +446,7 @@ bail: | |||
| 446 | 446 | ||
| 447 | /* | 447 | /* |
| 448 | * make sure we've got at least bitswanted contiguous bits in the | 448 | * make sure we've got at least bitswanted contiguous bits in the |
| 449 | * local alloc. You lose them when you drop i_sem. | 449 | * local alloc. You lose them when you drop i_mutex. |
| 450 | * | 450 | * |
| 451 | * We will add ourselves to the transaction passed in, but may start | 451 | * We will add ourselves to the transaction passed in, but may start |
| 452 | * our own in order to shift windows. | 452 | * our own in order to shift windows. |
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 48bf7f0ce544..364d64bd5f10 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
| @@ -169,7 +169,7 @@ static match_table_t tokens = { | |||
| 169 | */ | 169 | */ |
| 170 | static void ocfs2_write_super(struct super_block *sb) | 170 | static void ocfs2_write_super(struct super_block *sb) |
| 171 | { | 171 | { |
| 172 | if (down_trylock(&sb->s_lock) == 0) | 172 | if (mutex_trylock(&sb->s_lock) != 0) |
| 173 | BUG(); | 173 | BUG(); |
| 174 | sb->s_dirt = 0; | 174 | sb->s_dirt = 0; |
| 175 | } | 175 | } |
| @@ -211,9 +211,9 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, | |||
| 211 | newattrs.ia_valid |= ATTR_FILE; | 211 | newattrs.ia_valid |= ATTR_FILE; |
| 212 | } | 212 | } |
| 213 | 213 | ||
| 214 | down(&dentry->d_inode->i_sem); | 214 | mutex_lock(&dentry->d_inode->i_mutex); |
| 215 | err = notify_change(dentry, &newattrs); | 215 | err = notify_change(dentry, &newattrs); |
| 216 | up(&dentry->d_inode->i_sem); | 216 | mutex_unlock(&dentry->d_inode->i_mutex); |
| 217 | return err; | 217 | return err; |
| 218 | } | 218 | } |
| 219 | 219 | ||
| @@ -398,9 +398,9 @@ asmlinkage long sys_utime(char __user * filename, struct utimbuf __user * times) | |||
| 398 | (error = vfs_permission(&nd, MAY_WRITE)) != 0) | 398 | (error = vfs_permission(&nd, MAY_WRITE)) != 0) |
| 399 | goto dput_and_out; | 399 | goto dput_and_out; |
| 400 | } | 400 | } |
| 401 | down(&inode->i_sem); | 401 | mutex_lock(&inode->i_mutex); |
| 402 | error = notify_change(nd.dentry, &newattrs); | 402 | error = notify_change(nd.dentry, &newattrs); |
| 403 | up(&inode->i_sem); | 403 | mutex_unlock(&inode->i_mutex); |
| 404 | dput_and_out: | 404 | dput_and_out: |
| 405 | path_release(&nd); | 405 | path_release(&nd); |
| 406 | out: | 406 | out: |
| @@ -451,9 +451,9 @@ long do_utimes(char __user * filename, struct timeval * times) | |||
| 451 | (error = vfs_permission(&nd, MAY_WRITE)) != 0) | 451 | (error = vfs_permission(&nd, MAY_WRITE)) != 0) |
| 452 | goto dput_and_out; | 452 | goto dput_and_out; |
| 453 | } | 453 | } |
| 454 | down(&inode->i_sem); | 454 | mutex_lock(&inode->i_mutex); |
| 455 | error = notify_change(nd.dentry, &newattrs); | 455 | error = notify_change(nd.dentry, &newattrs); |
| 456 | up(&inode->i_sem); | 456 | mutex_unlock(&inode->i_mutex); |
| 457 | dput_and_out: | 457 | dput_and_out: |
| 458 | path_release(&nd); | 458 | path_release(&nd); |
| 459 | out: | 459 | out: |
| @@ -620,13 +620,13 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode) | |||
| 620 | err = -EPERM; | 620 | err = -EPERM; |
| 621 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | 621 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
| 622 | goto out_putf; | 622 | goto out_putf; |
| 623 | down(&inode->i_sem); | 623 | mutex_lock(&inode->i_mutex); |
| 624 | if (mode == (mode_t) -1) | 624 | if (mode == (mode_t) -1) |
| 625 | mode = inode->i_mode; | 625 | mode = inode->i_mode; |
| 626 | newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); | 626 | newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); |
| 627 | newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; | 627 | newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; |
| 628 | err = notify_change(dentry, &newattrs); | 628 | err = notify_change(dentry, &newattrs); |
| 629 | up(&inode->i_sem); | 629 | mutex_unlock(&inode->i_mutex); |
| 630 | 630 | ||
| 631 | out_putf: | 631 | out_putf: |
| 632 | fput(file); | 632 | fput(file); |
| @@ -654,13 +654,13 @@ asmlinkage long sys_chmod(const char __user * filename, mode_t mode) | |||
| 654 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | 654 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
| 655 | goto dput_and_out; | 655 | goto dput_and_out; |
| 656 | 656 | ||
| 657 | down(&inode->i_sem); | 657 | mutex_lock(&inode->i_mutex); |
| 658 | if (mode == (mode_t) -1) | 658 | if (mode == (mode_t) -1) |
| 659 | mode = inode->i_mode; | 659 | mode = inode->i_mode; |
| 660 | newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); | 660 | newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); |
| 661 | newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; | 661 | newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; |
| 662 | error = notify_change(nd.dentry, &newattrs); | 662 | error = notify_change(nd.dentry, &newattrs); |
| 663 | up(&inode->i_sem); | 663 | mutex_unlock(&inode->i_mutex); |
| 664 | 664 | ||
| 665 | dput_and_out: | 665 | dput_and_out: |
| 666 | path_release(&nd); | 666 | path_release(&nd); |
| @@ -696,9 +696,9 @@ static int chown_common(struct dentry * dentry, uid_t user, gid_t group) | |||
| 696 | } | 696 | } |
| 697 | if (!S_ISDIR(inode->i_mode)) | 697 | if (!S_ISDIR(inode->i_mode)) |
| 698 | newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID; | 698 | newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID; |
| 699 | down(&inode->i_sem); | 699 | mutex_lock(&inode->i_mutex); |
| 700 | error = notify_change(dentry, &newattrs); | 700 | error = notify_change(dentry, &newattrs); |
| 701 | up(&inode->i_sem); | 701 | mutex_unlock(&inode->i_mutex); |
| 702 | out: | 702 | out: |
| 703 | return error; | 703 | return error; |
| 704 | } | 704 | } |
| @@ -44,10 +44,10 @@ void pipe_wait(struct inode * inode) | |||
| 44 | * is considered a noninteractive wait: | 44 | * is considered a noninteractive wait: |
| 45 | */ | 45 | */ |
| 46 | prepare_to_wait(PIPE_WAIT(*inode), &wait, TASK_INTERRUPTIBLE|TASK_NONINTERACTIVE); | 46 | prepare_to_wait(PIPE_WAIT(*inode), &wait, TASK_INTERRUPTIBLE|TASK_NONINTERACTIVE); |
| 47 | up(PIPE_SEM(*inode)); | 47 | mutex_unlock(PIPE_MUTEX(*inode)); |
| 48 | schedule(); | 48 | schedule(); |
| 49 | finish_wait(PIPE_WAIT(*inode), &wait); | 49 | finish_wait(PIPE_WAIT(*inode), &wait); |
| 50 | down(PIPE_SEM(*inode)); | 50 | mutex_lock(PIPE_MUTEX(*inode)); |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | static inline int | 53 | static inline int |
| @@ -136,7 +136,7 @@ pipe_readv(struct file *filp, const struct iovec *_iov, | |||
| 136 | 136 | ||
| 137 | do_wakeup = 0; | 137 | do_wakeup = 0; |
| 138 | ret = 0; | 138 | ret = 0; |
| 139 | down(PIPE_SEM(*inode)); | 139 | mutex_lock(PIPE_MUTEX(*inode)); |
| 140 | info = inode->i_pipe; | 140 | info = inode->i_pipe; |
| 141 | for (;;) { | 141 | for (;;) { |
| 142 | int bufs = info->nrbufs; | 142 | int bufs = info->nrbufs; |
| @@ -200,7 +200,7 @@ pipe_readv(struct file *filp, const struct iovec *_iov, | |||
| 200 | } | 200 | } |
| 201 | pipe_wait(inode); | 201 | pipe_wait(inode); |
| 202 | } | 202 | } |
| 203 | up(PIPE_SEM(*inode)); | 203 | mutex_unlock(PIPE_MUTEX(*inode)); |
| 204 | /* Signal writers asynchronously that there is more room. */ | 204 | /* Signal writers asynchronously that there is more room. */ |
| 205 | if (do_wakeup) { | 205 | if (do_wakeup) { |
| 206 | wake_up_interruptible(PIPE_WAIT(*inode)); | 206 | wake_up_interruptible(PIPE_WAIT(*inode)); |
| @@ -237,7 +237,7 @@ pipe_writev(struct file *filp, const struct iovec *_iov, | |||
| 237 | 237 | ||
| 238 | do_wakeup = 0; | 238 | do_wakeup = 0; |
| 239 | ret = 0; | 239 | ret = 0; |
| 240 | down(PIPE_SEM(*inode)); | 240 | mutex_lock(PIPE_MUTEX(*inode)); |
| 241 | info = inode->i_pipe; | 241 | info = inode->i_pipe; |
| 242 | 242 | ||
| 243 | if (!PIPE_READERS(*inode)) { | 243 | if (!PIPE_READERS(*inode)) { |
| @@ -341,7 +341,7 @@ pipe_writev(struct file *filp, const struct iovec *_iov, | |||
| 341 | PIPE_WAITING_WRITERS(*inode)--; | 341 | PIPE_WAITING_WRITERS(*inode)--; |
| 342 | } | 342 | } |
| 343 | out: | 343 | out: |
| 344 | up(PIPE_SEM(*inode)); | 344 | mutex_unlock(PIPE_MUTEX(*inode)); |
| 345 | if (do_wakeup) { | 345 | if (do_wakeup) { |
| 346 | wake_up_interruptible(PIPE_WAIT(*inode)); | 346 | wake_up_interruptible(PIPE_WAIT(*inode)); |
| 347 | kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN); | 347 | kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN); |
| @@ -381,7 +381,7 @@ pipe_ioctl(struct inode *pino, struct file *filp, | |||
| 381 | 381 | ||
| 382 | switch (cmd) { | 382 | switch (cmd) { |
| 383 | case FIONREAD: | 383 | case FIONREAD: |
| 384 | down(PIPE_SEM(*inode)); | 384 | mutex_lock(PIPE_MUTEX(*inode)); |
| 385 | info = inode->i_pipe; | 385 | info = inode->i_pipe; |
| 386 | count = 0; | 386 | count = 0; |
| 387 | buf = info->curbuf; | 387 | buf = info->curbuf; |
| @@ -390,7 +390,7 @@ pipe_ioctl(struct inode *pino, struct file *filp, | |||
| 390 | count += info->bufs[buf].len; | 390 | count += info->bufs[buf].len; |
| 391 | buf = (buf+1) & (PIPE_BUFFERS-1); | 391 | buf = (buf+1) & (PIPE_BUFFERS-1); |
| 392 | } | 392 | } |
| 393 | up(PIPE_SEM(*inode)); | 393 | mutex_unlock(PIPE_MUTEX(*inode)); |
| 394 | return put_user(count, (int __user *)arg); | 394 | return put_user(count, (int __user *)arg); |
| 395 | default: | 395 | default: |
| 396 | return -EINVAL; | 396 | return -EINVAL; |
| @@ -433,7 +433,7 @@ pipe_poll(struct file *filp, poll_table *wait) | |||
| 433 | static int | 433 | static int |
| 434 | pipe_release(struct inode *inode, int decr, int decw) | 434 | pipe_release(struct inode *inode, int decr, int decw) |
| 435 | { | 435 | { |
| 436 | down(PIPE_SEM(*inode)); | 436 | mutex_lock(PIPE_MUTEX(*inode)); |
| 437 | PIPE_READERS(*inode) -= decr; | 437 | PIPE_READERS(*inode) -= decr; |
| 438 | PIPE_WRITERS(*inode) -= decw; | 438 | PIPE_WRITERS(*inode) -= decw; |
| 439 | if (!PIPE_READERS(*inode) && !PIPE_WRITERS(*inode)) { | 439 | if (!PIPE_READERS(*inode) && !PIPE_WRITERS(*inode)) { |
| @@ -443,7 +443,7 @@ pipe_release(struct inode *inode, int decr, int decw) | |||
| 443 | kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN); | 443 | kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN); |
| 444 | kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT); | 444 | kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT); |
| 445 | } | 445 | } |
| 446 | up(PIPE_SEM(*inode)); | 446 | mutex_unlock(PIPE_MUTEX(*inode)); |
| 447 | 447 | ||
| 448 | return 0; | 448 | return 0; |
| 449 | } | 449 | } |
| @@ -454,9 +454,9 @@ pipe_read_fasync(int fd, struct file *filp, int on) | |||
| 454 | struct inode *inode = filp->f_dentry->d_inode; | 454 | struct inode *inode = filp->f_dentry->d_inode; |
| 455 | int retval; | 455 | int retval; |
| 456 | 456 | ||
| 457 | down(PIPE_SEM(*inode)); | 457 | mutex_lock(PIPE_MUTEX(*inode)); |
| 458 | retval = fasync_helper(fd, filp, on, PIPE_FASYNC_READERS(*inode)); | 458 | retval = fasync_helper(fd, filp, on, PIPE_FASYNC_READERS(*inode)); |
| 459 | up(PIPE_SEM(*inode)); | 459 | mutex_unlock(PIPE_MUTEX(*inode)); |
| 460 | 460 | ||
| 461 | if (retval < 0) | 461 | if (retval < 0) |
| 462 | return retval; | 462 | return retval; |
| @@ -471,9 +471,9 @@ pipe_write_fasync(int fd, struct file *filp, int on) | |||
| 471 | struct inode *inode = filp->f_dentry->d_inode; | 471 | struct inode *inode = filp->f_dentry->d_inode; |
| 472 | int retval; | 472 | int retval; |
| 473 | 473 | ||
| 474 | down(PIPE_SEM(*inode)); | 474 | mutex_lock(PIPE_MUTEX(*inode)); |
| 475 | retval = fasync_helper(fd, filp, on, PIPE_FASYNC_WRITERS(*inode)); | 475 | retval = fasync_helper(fd, filp, on, PIPE_FASYNC_WRITERS(*inode)); |
| 476 | up(PIPE_SEM(*inode)); | 476 | mutex_unlock(PIPE_MUTEX(*inode)); |
| 477 | 477 | ||
| 478 | if (retval < 0) | 478 | if (retval < 0) |
| 479 | return retval; | 479 | return retval; |
| @@ -488,14 +488,14 @@ pipe_rdwr_fasync(int fd, struct file *filp, int on) | |||
| 488 | struct inode *inode = filp->f_dentry->d_inode; | 488 | struct inode *inode = filp->f_dentry->d_inode; |
| 489 | int retval; | 489 | int retval; |
| 490 | 490 | ||
| 491 | down(PIPE_SEM(*inode)); | 491 | mutex_lock(PIPE_MUTEX(*inode)); |
| 492 | 492 | ||
| 493 | retval = fasync_helper(fd, filp, on, PIPE_FASYNC_READERS(*inode)); | 493 | retval = fasync_helper(fd, filp, on, PIPE_FASYNC_READERS(*inode)); |
| 494 | 494 | ||
| 495 | if (retval >= 0) | 495 | if (retval >= 0) |
| 496 | retval = fasync_helper(fd, filp, on, PIPE_FASYNC_WRITERS(*inode)); | 496 | retval = fasync_helper(fd, filp, on, PIPE_FASYNC_WRITERS(*inode)); |
| 497 | 497 | ||
| 498 | up(PIPE_SEM(*inode)); | 498 | mutex_unlock(PIPE_MUTEX(*inode)); |
| 499 | 499 | ||
| 500 | if (retval < 0) | 500 | if (retval < 0) |
| 501 | return retval; | 501 | return retval; |
| @@ -534,9 +534,9 @@ pipe_read_open(struct inode *inode, struct file *filp) | |||
| 534 | { | 534 | { |
| 535 | /* We could have perhaps used atomic_t, but this and friends | 535 | /* We could have perhaps used atomic_t, but this and friends |
| 536 | below are the only places. So it doesn't seem worthwhile. */ | 536 | below are the only places. So it doesn't seem worthwhile. */ |
| 537 | down(PIPE_SEM(*inode)); | 537 | mutex_lock(PIPE_MUTEX(*inode)); |
| 538 | PIPE_READERS(*inode)++; | 538 | PIPE_READERS(*inode)++; |
| 539 | up(PIPE_SEM(*inode)); | 539 | mutex_unlock(PIPE_MUTEX(*inode)); |
| 540 | 540 | ||
| 541 | return 0; | 541 | return 0; |
| 542 | } | 542 | } |
| @@ -544,9 +544,9 @@ pipe_read_open(struct inode *inode, struct file *filp) | |||
| 544 | static int | 544 | static int |
| 545 | pipe_write_open(struct inode *inode, struct file *filp) | 545 | pipe_write_open(struct inode *inode, struct file *filp) |
| 546 | { | 546 | { |
| 547 | down(PIPE_SEM(*inode)); | 547 | mutex_lock(PIPE_MUTEX(*inode)); |
| 548 | PIPE_WRITERS(*inode)++; | 548 | PIPE_WRITERS(*inode)++; |
| 549 | up(PIPE_SEM(*inode)); | 549 | mutex_unlock(PIPE_MUTEX(*inode)); |
| 550 | 550 | ||
| 551 | return 0; | 551 | return 0; |
| 552 | } | 552 | } |
| @@ -554,12 +554,12 @@ pipe_write_open(struct inode *inode, struct file *filp) | |||
| 554 | static int | 554 | static int |
| 555 | pipe_rdwr_open(struct inode *inode, struct file *filp) | 555 | pipe_rdwr_open(struct inode *inode, struct file *filp) |
| 556 | { | 556 | { |
| 557 | down(PIPE_SEM(*inode)); | 557 | mutex_lock(PIPE_MUTEX(*inode)); |
| 558 | if (filp->f_mode & FMODE_READ) | 558 | if (filp->f_mode & FMODE_READ) |
| 559 | PIPE_READERS(*inode)++; | 559 | PIPE_READERS(*inode)++; |
| 560 | if (filp->f_mode & FMODE_WRITE) | 560 | if (filp->f_mode & FMODE_WRITE) |
| 561 | PIPE_WRITERS(*inode)++; | 561 | PIPE_WRITERS(*inode)++; |
| 562 | up(PIPE_SEM(*inode)); | 562 | mutex_unlock(PIPE_MUTEX(*inode)); |
| 563 | 563 | ||
| 564 | return 0; | 564 | return 0; |
| 565 | } | 565 | } |
diff --git a/fs/quota.c b/fs/quota.c index 612e04db4b93..d14d872646d4 100644 --- a/fs/quota.c +++ b/fs/quota.c | |||
| @@ -168,7 +168,7 @@ static void quota_sync_sb(struct super_block *sb, int type) | |||
| 168 | sync_blockdev(sb->s_bdev); | 168 | sync_blockdev(sb->s_bdev); |
| 169 | 169 | ||
| 170 | /* Now when everything is written we can discard the pagecache so | 170 | /* Now when everything is written we can discard the pagecache so |
| 171 | * that userspace sees the changes. We need i_sem and so we could | 171 | * that userspace sees the changes. We need i_mutex and so we could |
| 172 | * not do it inside dqonoff_sem. Moreover we need to be carefull | 172 | * not do it inside dqonoff_sem. Moreover we need to be carefull |
| 173 | * about races with quotaoff() (that is the reason why we have own | 173 | * about races with quotaoff() (that is the reason why we have own |
| 174 | * reference to inode). */ | 174 | * reference to inode). */ |
| @@ -184,9 +184,9 @@ static void quota_sync_sb(struct super_block *sb, int type) | |||
| 184 | up(&sb_dqopt(sb)->dqonoff_sem); | 184 | up(&sb_dqopt(sb)->dqonoff_sem); |
| 185 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 185 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
| 186 | if (discard[cnt]) { | 186 | if (discard[cnt]) { |
| 187 | down(&discard[cnt]->i_sem); | 187 | mutex_lock(&discard[cnt]->i_mutex); |
| 188 | truncate_inode_pages(&discard[cnt]->i_data, 0); | 188 | truncate_inode_pages(&discard[cnt]->i_data, 0); |
| 189 | up(&discard[cnt]->i_sem); | 189 | mutex_unlock(&discard[cnt]->i_mutex); |
| 190 | iput(discard[cnt]); | 190 | iput(discard[cnt]); |
| 191 | } | 191 | } |
| 192 | } | 192 | } |
diff --git a/fs/read_write.c b/fs/read_write.c index df3468a22fea..3f7a1a62165f 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
| @@ -33,7 +33,7 @@ loff_t generic_file_llseek(struct file *file, loff_t offset, int origin) | |||
| 33 | long long retval; | 33 | long long retval; |
| 34 | struct inode *inode = file->f_mapping->host; | 34 | struct inode *inode = file->f_mapping->host; |
| 35 | 35 | ||
| 36 | down(&inode->i_sem); | 36 | mutex_lock(&inode->i_mutex); |
| 37 | switch (origin) { | 37 | switch (origin) { |
| 38 | case 2: | 38 | case 2: |
| 39 | offset += inode->i_size; | 39 | offset += inode->i_size; |
| @@ -49,7 +49,7 @@ loff_t generic_file_llseek(struct file *file, loff_t offset, int origin) | |||
| 49 | } | 49 | } |
| 50 | retval = offset; | 50 | retval = offset; |
| 51 | } | 51 | } |
| 52 | up(&inode->i_sem); | 52 | mutex_unlock(&inode->i_mutex); |
| 53 | return retval; | 53 | return retval; |
| 54 | } | 54 | } |
| 55 | 55 | ||
diff --git a/fs/readdir.c b/fs/readdir.c index b03579bc0210..b6109329b607 100644 --- a/fs/readdir.c +++ b/fs/readdir.c | |||
| @@ -30,13 +30,13 @@ int vfs_readdir(struct file *file, filldir_t filler, void *buf) | |||
| 30 | if (res) | 30 | if (res) |
| 31 | goto out; | 31 | goto out; |
| 32 | 32 | ||
| 33 | down(&inode->i_sem); | 33 | mutex_lock(&inode->i_mutex); |
| 34 | res = -ENOENT; | 34 | res = -ENOENT; |
| 35 | if (!IS_DEADDIR(inode)) { | 35 | if (!IS_DEADDIR(inode)) { |
| 36 | res = file->f_op->readdir(file, buf, filler); | 36 | res = file->f_op->readdir(file, buf, filler); |
| 37 | file_accessed(file); | 37 | file_accessed(file); |
| 38 | } | 38 | } |
| 39 | up(&inode->i_sem); | 39 | mutex_unlock(&inode->i_mutex); |
| 40 | out: | 40 | out: |
| 41 | return res; | 41 | return res; |
| 42 | } | 42 | } |
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index 7892a865b58a..127e7d2cabdd 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c | |||
| @@ -49,7 +49,7 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp) | |||
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | reiserfs_write_lock(inode->i_sb); | 51 | reiserfs_write_lock(inode->i_sb); |
| 52 | down(&inode->i_sem); | 52 | mutex_lock(&inode->i_mutex); |
| 53 | /* freeing preallocation only involves relogging blocks that | 53 | /* freeing preallocation only involves relogging blocks that |
| 54 | * are already in the current transaction. preallocation gets | 54 | * are already in the current transaction. preallocation gets |
| 55 | * freed at the end of each transaction, so it is impossible for | 55 | * freed at the end of each transaction, so it is impossible for |
| @@ -100,7 +100,7 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp) | |||
| 100 | err = reiserfs_truncate_file(inode, 0); | 100 | err = reiserfs_truncate_file(inode, 0); |
| 101 | } | 101 | } |
| 102 | out: | 102 | out: |
| 103 | up(&inode->i_sem); | 103 | mutex_unlock(&inode->i_mutex); |
| 104 | reiserfs_write_unlock(inode->i_sb); | 104 | reiserfs_write_unlock(inode->i_sb); |
| 105 | return err; | 105 | return err; |
| 106 | } | 106 | } |
| @@ -1342,7 +1342,7 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t | |||
| 1342 | if (unlikely(!access_ok(VERIFY_READ, buf, count))) | 1342 | if (unlikely(!access_ok(VERIFY_READ, buf, count))) |
| 1343 | return -EFAULT; | 1343 | return -EFAULT; |
| 1344 | 1344 | ||
| 1345 | down(&inode->i_sem); // locks the entire file for just us | 1345 | mutex_lock(&inode->i_mutex); // locks the entire file for just us |
| 1346 | 1346 | ||
| 1347 | pos = *ppos; | 1347 | pos = *ppos; |
| 1348 | 1348 | ||
| @@ -1532,12 +1532,12 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t | |||
| 1532 | generic_osync_inode(inode, file->f_mapping, | 1532 | generic_osync_inode(inode, file->f_mapping, |
| 1533 | OSYNC_METADATA | OSYNC_DATA); | 1533 | OSYNC_METADATA | OSYNC_DATA); |
| 1534 | 1534 | ||
| 1535 | up(&inode->i_sem); | 1535 | mutex_unlock(&inode->i_mutex); |
| 1536 | reiserfs_async_progress_wait(inode->i_sb); | 1536 | reiserfs_async_progress_wait(inode->i_sb); |
| 1537 | return (already_written != 0) ? already_written : res; | 1537 | return (already_written != 0) ? already_written : res; |
| 1538 | 1538 | ||
| 1539 | out: | 1539 | out: |
| 1540 | up(&inode->i_sem); // unlock the file on exit. | 1540 | mutex_unlock(&inode->i_mutex); // unlock the file on exit. |
| 1541 | return res; | 1541 | return res; |
| 1542 | } | 1542 | } |
| 1543 | 1543 | ||
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index a5e3a0ddbe53..ffa34b861bdb 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
| @@ -40,12 +40,12 @@ void reiserfs_delete_inode(struct inode *inode) | |||
| 40 | 40 | ||
| 41 | /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */ | 41 | /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */ |
| 42 | if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */ | 42 | if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */ |
| 43 | down(&inode->i_sem); | 43 | mutex_lock(&inode->i_mutex); |
| 44 | 44 | ||
| 45 | reiserfs_delete_xattrs(inode); | 45 | reiserfs_delete_xattrs(inode); |
| 46 | 46 | ||
| 47 | if (journal_begin(&th, inode->i_sb, jbegin_count)) { | 47 | if (journal_begin(&th, inode->i_sb, jbegin_count)) { |
| 48 | up(&inode->i_sem); | 48 | mutex_unlock(&inode->i_mutex); |
| 49 | goto out; | 49 | goto out; |
| 50 | } | 50 | } |
| 51 | reiserfs_update_inode_transaction(inode); | 51 | reiserfs_update_inode_transaction(inode); |
| @@ -59,11 +59,11 @@ void reiserfs_delete_inode(struct inode *inode) | |||
| 59 | DQUOT_FREE_INODE(inode); | 59 | DQUOT_FREE_INODE(inode); |
| 60 | 60 | ||
| 61 | if (journal_end(&th, inode->i_sb, jbegin_count)) { | 61 | if (journal_end(&th, inode->i_sb, jbegin_count)) { |
| 62 | up(&inode->i_sem); | 62 | mutex_unlock(&inode->i_mutex); |
| 63 | goto out; | 63 | goto out; |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | up(&inode->i_sem); | 66 | mutex_unlock(&inode->i_mutex); |
| 67 | 67 | ||
| 68 | /* check return value from reiserfs_delete_object after | 68 | /* check return value from reiserfs_delete_object after |
| 69 | * ending the transaction | 69 | * ending the transaction |
| @@ -551,7 +551,7 @@ static int convert_tail_for_hole(struct inode *inode, | |||
| 551 | 551 | ||
| 552 | /* we don't have to make sure the conversion did not happen while | 552 | /* we don't have to make sure the conversion did not happen while |
| 553 | ** we were locking the page because anyone that could convert | 553 | ** we were locking the page because anyone that could convert |
| 554 | ** must first take i_sem. | 554 | ** must first take i_mutex. |
| 555 | ** | 555 | ** |
| 556 | ** We must fix the tail page for writing because it might have buffers | 556 | ** We must fix the tail page for writing because it might have buffers |
| 557 | ** that are mapped, but have a block number of 0. This indicates tail | 557 | ** that are mapped, but have a block number of 0. This indicates tail |
| @@ -586,7 +586,7 @@ static inline int _allocate_block(struct reiserfs_transaction_handle *th, | |||
| 586 | BUG_ON(!th->t_trans_id); | 586 | BUG_ON(!th->t_trans_id); |
| 587 | 587 | ||
| 588 | #ifdef REISERFS_PREALLOCATE | 588 | #ifdef REISERFS_PREALLOCATE |
| 589 | if (!(flags & GET_BLOCK_NO_ISEM)) { | 589 | if (!(flags & GET_BLOCK_NO_IMUX)) { |
| 590 | return reiserfs_new_unf_blocknrs2(th, inode, allocated_block_nr, | 590 | return reiserfs_new_unf_blocknrs2(th, inode, allocated_block_nr, |
| 591 | path, block); | 591 | path, block); |
| 592 | } | 592 | } |
| @@ -2318,7 +2318,7 @@ static int map_block_for_writepage(struct inode *inode, | |||
| 2318 | /* this is where we fill in holes in the file. */ | 2318 | /* this is where we fill in holes in the file. */ |
| 2319 | if (use_get_block) { | 2319 | if (use_get_block) { |
| 2320 | retval = reiserfs_get_block(inode, block, bh_result, | 2320 | retval = reiserfs_get_block(inode, block, bh_result, |
| 2321 | GET_BLOCK_CREATE | GET_BLOCK_NO_ISEM | 2321 | GET_BLOCK_CREATE | GET_BLOCK_NO_IMUX |
| 2322 | | GET_BLOCK_NO_DANGLE); | 2322 | | GET_BLOCK_NO_DANGLE); |
| 2323 | if (!retval) { | 2323 | if (!retval) { |
| 2324 | if (!buffer_mapped(bh_result) | 2324 | if (!buffer_mapped(bh_result) |
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c index 81fc00285f60..ba8bf8df6dc7 100644 --- a/fs/reiserfs/ioctl.c +++ b/fs/reiserfs/ioctl.c | |||
| @@ -120,7 +120,7 @@ static int reiserfs_unpack(struct inode *inode, struct file *filp) | |||
| 120 | /* we need to make sure nobody is changing the file size beneath | 120 | /* we need to make sure nobody is changing the file size beneath |
| 121 | ** us | 121 | ** us |
| 122 | */ | 122 | */ |
| 123 | down(&inode->i_sem); | 123 | mutex_lock(&inode->i_mutex); |
| 124 | 124 | ||
| 125 | write_from = inode->i_size & (blocksize - 1); | 125 | write_from = inode->i_size & (blocksize - 1); |
| 126 | /* if we are on a block boundary, we are already unpacked. */ | 126 | /* if we are on a block boundary, we are already unpacked. */ |
| @@ -156,7 +156,7 @@ static int reiserfs_unpack(struct inode *inode, struct file *filp) | |||
| 156 | page_cache_release(page); | 156 | page_cache_release(page); |
| 157 | 157 | ||
| 158 | out: | 158 | out: |
| 159 | up(&inode->i_sem); | 159 | mutex_unlock(&inode->i_mutex); |
| 160 | reiserfs_write_unlock(inode->i_sb); | 160 | reiserfs_write_unlock(inode->i_sb); |
| 161 | return retval; | 161 | return retval; |
| 162 | } | 162 | } |
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 42afb5bef111..397d9590c8f2 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
| @@ -2211,7 +2211,7 @@ static ssize_t reiserfs_quota_write(struct super_block *sb, int type, | |||
| 2211 | size_t towrite = len; | 2211 | size_t towrite = len; |
| 2212 | struct buffer_head tmp_bh, *bh; | 2212 | struct buffer_head tmp_bh, *bh; |
| 2213 | 2213 | ||
| 2214 | down(&inode->i_sem); | 2214 | mutex_lock(&inode->i_mutex); |
| 2215 | while (towrite > 0) { | 2215 | while (towrite > 0) { |
| 2216 | tocopy = sb->s_blocksize - offset < towrite ? | 2216 | tocopy = sb->s_blocksize - offset < towrite ? |
| 2217 | sb->s_blocksize - offset : towrite; | 2217 | sb->s_blocksize - offset : towrite; |
| @@ -2250,7 +2250,7 @@ static ssize_t reiserfs_quota_write(struct super_block *sb, int type, | |||
| 2250 | inode->i_version++; | 2250 | inode->i_version++; |
| 2251 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 2251 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
| 2252 | mark_inode_dirty(inode); | 2252 | mark_inode_dirty(inode); |
| 2253 | up(&inode->i_sem); | 2253 | mutex_unlock(&inode->i_mutex); |
| 2254 | return len - towrite; | 2254 | return len - towrite; |
| 2255 | } | 2255 | } |
| 2256 | 2256 | ||
diff --git a/fs/reiserfs/tail_conversion.c b/fs/reiserfs/tail_conversion.c index c92e124f628e..196e971c03c9 100644 --- a/fs/reiserfs/tail_conversion.c +++ b/fs/reiserfs/tail_conversion.c | |||
| @@ -205,7 +205,7 @@ int indirect2direct(struct reiserfs_transaction_handle *th, struct inode *p_s_in | |||
| 205 | 1) * p_s_sb->s_blocksize; | 205 | 1) * p_s_sb->s_blocksize; |
| 206 | pos1 = pos; | 206 | pos1 = pos; |
| 207 | 207 | ||
| 208 | // we are protected by i_sem. The tail can not disapper, not | 208 | // we are protected by i_mutex. The tail can not disapper, not |
| 209 | // append can be done either | 209 | // append can be done either |
| 210 | // we are in truncate or packing tail in file_release | 210 | // we are in truncate or packing tail in file_release |
| 211 | 211 | ||
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 02091eaac0b4..f1895f0a278e 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
| @@ -67,11 +67,11 @@ static struct dentry *create_xa_root(struct super_block *sb) | |||
| 67 | goto out; | 67 | goto out; |
| 68 | } else if (!xaroot->d_inode) { | 68 | } else if (!xaroot->d_inode) { |
| 69 | int err; | 69 | int err; |
| 70 | down(&privroot->d_inode->i_sem); | 70 | mutex_lock(&privroot->d_inode->i_mutex); |
| 71 | err = | 71 | err = |
| 72 | privroot->d_inode->i_op->mkdir(privroot->d_inode, xaroot, | 72 | privroot->d_inode->i_op->mkdir(privroot->d_inode, xaroot, |
| 73 | 0700); | 73 | 0700); |
| 74 | up(&privroot->d_inode->i_sem); | 74 | mutex_unlock(&privroot->d_inode->i_mutex); |
| 75 | 75 | ||
| 76 | if (err) { | 76 | if (err) { |
| 77 | dput(xaroot); | 77 | dput(xaroot); |
| @@ -219,7 +219,7 @@ static struct dentry *get_xa_file_dentry(const struct inode *inode, | |||
| 219 | } else if (flags & XATTR_REPLACE || flags & FL_READONLY) { | 219 | } else if (flags & XATTR_REPLACE || flags & FL_READONLY) { |
| 220 | goto out; | 220 | goto out; |
| 221 | } else { | 221 | } else { |
| 222 | /* inode->i_sem is down, so nothing else can try to create | 222 | /* inode->i_mutex is down, so nothing else can try to create |
| 223 | * the same xattr */ | 223 | * the same xattr */ |
| 224 | err = xadir->d_inode->i_op->create(xadir->d_inode, xafile, | 224 | err = xadir->d_inode->i_op->create(xadir->d_inode, xafile, |
| 225 | 0700 | S_IFREG, NULL); | 225 | 0700 | S_IFREG, NULL); |
| @@ -268,7 +268,7 @@ static struct file *open_xa_file(const struct inode *inode, const char *name, | |||
| 268 | * and don't mess with f->f_pos, but the idea is the same. Do some | 268 | * and don't mess with f->f_pos, but the idea is the same. Do some |
| 269 | * action on each and every entry in the directory. | 269 | * action on each and every entry in the directory. |
| 270 | * | 270 | * |
| 271 | * we're called with i_sem held, so there are no worries about the directory | 271 | * we're called with i_mutex held, so there are no worries about the directory |
| 272 | * changing underneath us. | 272 | * changing underneath us. |
| 273 | */ | 273 | */ |
| 274 | static int __xattr_readdir(struct file *filp, void *dirent, filldir_t filldir) | 274 | static int __xattr_readdir(struct file *filp, void *dirent, filldir_t filldir) |
| @@ -426,7 +426,7 @@ int xattr_readdir(struct file *file, filldir_t filler, void *buf) | |||
| 426 | int res = -ENOTDIR; | 426 | int res = -ENOTDIR; |
| 427 | if (!file->f_op || !file->f_op->readdir) | 427 | if (!file->f_op || !file->f_op->readdir) |
| 428 | goto out; | 428 | goto out; |
| 429 | down(&inode->i_sem); | 429 | mutex_lock(&inode->i_mutex); |
| 430 | // down(&inode->i_zombie); | 430 | // down(&inode->i_zombie); |
| 431 | res = -ENOENT; | 431 | res = -ENOENT; |
| 432 | if (!IS_DEADDIR(inode)) { | 432 | if (!IS_DEADDIR(inode)) { |
| @@ -435,7 +435,7 @@ int xattr_readdir(struct file *file, filldir_t filler, void *buf) | |||
| 435 | unlock_kernel(); | 435 | unlock_kernel(); |
| 436 | } | 436 | } |
| 437 | // up(&inode->i_zombie); | 437 | // up(&inode->i_zombie); |
| 438 | up(&inode->i_sem); | 438 | mutex_unlock(&inode->i_mutex); |
| 439 | out: | 439 | out: |
| 440 | return res; | 440 | return res; |
| 441 | } | 441 | } |
| @@ -480,7 +480,7 @@ static inline __u32 xattr_hash(const char *msg, int len) | |||
| 480 | /* Generic extended attribute operations that can be used by xa plugins */ | 480 | /* Generic extended attribute operations that can be used by xa plugins */ |
| 481 | 481 | ||
| 482 | /* | 482 | /* |
| 483 | * inode->i_sem: down | 483 | * inode->i_mutex: down |
| 484 | */ | 484 | */ |
| 485 | int | 485 | int |
| 486 | reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, | 486 | reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, |
| @@ -535,7 +535,7 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, | |||
| 535 | /* Resize it so we're ok to write there */ | 535 | /* Resize it so we're ok to write there */ |
| 536 | newattrs.ia_size = buffer_size; | 536 | newattrs.ia_size = buffer_size; |
| 537 | newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; | 537 | newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; |
| 538 | down(&xinode->i_sem); | 538 | mutex_lock(&xinode->i_mutex); |
| 539 | err = notify_change(fp->f_dentry, &newattrs); | 539 | err = notify_change(fp->f_dentry, &newattrs); |
| 540 | if (err) | 540 | if (err) |
| 541 | goto out_filp; | 541 | goto out_filp; |
| @@ -598,7 +598,7 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, | |||
| 598 | } | 598 | } |
| 599 | 599 | ||
| 600 | out_filp: | 600 | out_filp: |
| 601 | up(&xinode->i_sem); | 601 | mutex_unlock(&xinode->i_mutex); |
| 602 | fput(fp); | 602 | fput(fp); |
| 603 | 603 | ||
| 604 | out: | 604 | out: |
| @@ -606,7 +606,7 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, | |||
| 606 | } | 606 | } |
| 607 | 607 | ||
| 608 | /* | 608 | /* |
| 609 | * inode->i_sem: down | 609 | * inode->i_mutex: down |
| 610 | */ | 610 | */ |
| 611 | int | 611 | int |
| 612 | reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer, | 612 | reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer, |
| @@ -793,7 +793,7 @@ reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen, | |||
| 793 | 793 | ||
| 794 | } | 794 | } |
| 795 | 795 | ||
| 796 | /* This is called w/ inode->i_sem downed */ | 796 | /* This is called w/ inode->i_mutex downed */ |
| 797 | int reiserfs_delete_xattrs(struct inode *inode) | 797 | int reiserfs_delete_xattrs(struct inode *inode) |
| 798 | { | 798 | { |
| 799 | struct file *fp; | 799 | struct file *fp; |
| @@ -946,7 +946,7 @@ int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs) | |||
| 946 | 946 | ||
| 947 | /* | 947 | /* |
| 948 | * Inode operation getxattr() | 948 | * Inode operation getxattr() |
| 949 | * Preliminary locking: we down dentry->d_inode->i_sem | 949 | * Preliminary locking: we down dentry->d_inode->i_mutex |
| 950 | */ | 950 | */ |
| 951 | ssize_t | 951 | ssize_t |
| 952 | reiserfs_getxattr(struct dentry * dentry, const char *name, void *buffer, | 952 | reiserfs_getxattr(struct dentry * dentry, const char *name, void *buffer, |
| @@ -970,7 +970,7 @@ reiserfs_getxattr(struct dentry * dentry, const char *name, void *buffer, | |||
| 970 | /* | 970 | /* |
| 971 | * Inode operation setxattr() | 971 | * Inode operation setxattr() |
| 972 | * | 972 | * |
| 973 | * dentry->d_inode->i_sem down | 973 | * dentry->d_inode->i_mutex down |
| 974 | */ | 974 | */ |
| 975 | int | 975 | int |
| 976 | reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value, | 976 | reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value, |
| @@ -1008,7 +1008,7 @@ reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value, | |||
| 1008 | /* | 1008 | /* |
| 1009 | * Inode operation removexattr() | 1009 | * Inode operation removexattr() |
| 1010 | * | 1010 | * |
| 1011 | * dentry->d_inode->i_sem down | 1011 | * dentry->d_inode->i_mutex down |
| 1012 | */ | 1012 | */ |
| 1013 | int reiserfs_removexattr(struct dentry *dentry, const char *name) | 1013 | int reiserfs_removexattr(struct dentry *dentry, const char *name) |
| 1014 | { | 1014 | { |
| @@ -1091,7 +1091,7 @@ reiserfs_listxattr_filler(void *buf, const char *name, int namelen, | |||
| 1091 | /* | 1091 | /* |
| 1092 | * Inode operation listxattr() | 1092 | * Inode operation listxattr() |
| 1093 | * | 1093 | * |
| 1094 | * Preliminary locking: we down dentry->d_inode->i_sem | 1094 | * Preliminary locking: we down dentry->d_inode->i_mutex |
| 1095 | */ | 1095 | */ |
| 1096 | ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) | 1096 | ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) |
| 1097 | { | 1097 | { |
| @@ -1289,9 +1289,9 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags) | |||
| 1289 | if (!IS_ERR(dentry)) { | 1289 | if (!IS_ERR(dentry)) { |
| 1290 | if (!(mount_flags & MS_RDONLY) && !dentry->d_inode) { | 1290 | if (!(mount_flags & MS_RDONLY) && !dentry->d_inode) { |
| 1291 | struct inode *inode = dentry->d_parent->d_inode; | 1291 | struct inode *inode = dentry->d_parent->d_inode; |
| 1292 | down(&inode->i_sem); | 1292 | mutex_lock(&inode->i_mutex); |
| 1293 | err = inode->i_op->mkdir(inode, dentry, 0700); | 1293 | err = inode->i_op->mkdir(inode, dentry, 0700); |
| 1294 | up(&inode->i_sem); | 1294 | mutex_unlock(&inode->i_mutex); |
| 1295 | if (err) { | 1295 | if (err) { |
| 1296 | dput(dentry); | 1296 | dput(dentry); |
| 1297 | dentry = NULL; | 1297 | dentry = NULL; |
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index a47ac9aac8b2..2dc953504cc0 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c | |||
| @@ -174,7 +174,7 @@ static void *posix_acl_to_disk(const struct posix_acl *acl, size_t * size) | |||
| 174 | /* | 174 | /* |
| 175 | * Inode operation get_posix_acl(). | 175 | * Inode operation get_posix_acl(). |
| 176 | * | 176 | * |
| 177 | * inode->i_sem: down | 177 | * inode->i_mutex: down |
| 178 | * BKL held [before 2.5.x] | 178 | * BKL held [before 2.5.x] |
| 179 | */ | 179 | */ |
| 180 | struct posix_acl *reiserfs_get_acl(struct inode *inode, int type) | 180 | struct posix_acl *reiserfs_get_acl(struct inode *inode, int type) |
| @@ -237,7 +237,7 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type) | |||
| 237 | /* | 237 | /* |
| 238 | * Inode operation set_posix_acl(). | 238 | * Inode operation set_posix_acl(). |
| 239 | * | 239 | * |
| 240 | * inode->i_sem: down | 240 | * inode->i_mutex: down |
| 241 | * BKL held [before 2.5.x] | 241 | * BKL held [before 2.5.x] |
| 242 | */ | 242 | */ |
| 243 | static int | 243 | static int |
| @@ -312,7 +312,7 @@ reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) | |||
| 312 | return error; | 312 | return error; |
| 313 | } | 313 | } |
| 314 | 314 | ||
| 315 | /* dir->i_sem: down, | 315 | /* dir->i_mutex: locked, |
| 316 | * inode is new and not released into the wild yet */ | 316 | * inode is new and not released into the wild yet */ |
| 317 | int | 317 | int |
| 318 | reiserfs_inherit_default_acl(struct inode *dir, struct dentry *dentry, | 318 | reiserfs_inherit_default_acl(struct inode *dir, struct dentry *dentry, |
diff --git a/fs/relayfs/inode.c b/fs/relayfs/inode.c index 7b7f2cb5f0e1..383523011aad 100644 --- a/fs/relayfs/inode.c +++ b/fs/relayfs/inode.c | |||
| @@ -109,7 +109,7 @@ static struct dentry *relayfs_create_entry(const char *name, | |||
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | parent = dget(parent); | 111 | parent = dget(parent); |
| 112 | down(&parent->d_inode->i_sem); | 112 | mutex_lock(&parent->d_inode->i_mutex); |
| 113 | d = lookup_one_len(name, parent, strlen(name)); | 113 | d = lookup_one_len(name, parent, strlen(name)); |
| 114 | if (IS_ERR(d)) { | 114 | if (IS_ERR(d)) { |
| 115 | d = NULL; | 115 | d = NULL; |
| @@ -139,7 +139,7 @@ release_mount: | |||
| 139 | simple_release_fs(&relayfs_mount, &relayfs_mount_count); | 139 | simple_release_fs(&relayfs_mount, &relayfs_mount_count); |
| 140 | 140 | ||
| 141 | exit: | 141 | exit: |
| 142 | up(&parent->d_inode->i_sem); | 142 | mutex_unlock(&parent->d_inode->i_mutex); |
| 143 | dput(parent); | 143 | dput(parent); |
| 144 | return d; | 144 | return d; |
| 145 | } | 145 | } |
| @@ -204,7 +204,7 @@ int relayfs_remove(struct dentry *dentry) | |||
| 204 | return -EINVAL; | 204 | return -EINVAL; |
| 205 | 205 | ||
| 206 | parent = dget(parent); | 206 | parent = dget(parent); |
| 207 | down(&parent->d_inode->i_sem); | 207 | mutex_lock(&parent->d_inode->i_mutex); |
| 208 | if (dentry->d_inode) { | 208 | if (dentry->d_inode) { |
| 209 | if (S_ISDIR(dentry->d_inode->i_mode)) | 209 | if (S_ISDIR(dentry->d_inode->i_mode)) |
| 210 | error = simple_rmdir(parent->d_inode, dentry); | 210 | error = simple_rmdir(parent->d_inode, dentry); |
| @@ -215,7 +215,7 @@ int relayfs_remove(struct dentry *dentry) | |||
| 215 | } | 215 | } |
| 216 | if (!error) | 216 | if (!error) |
| 217 | dput(dentry); | 217 | dput(dentry); |
| 218 | up(&parent->d_inode->i_sem); | 218 | mutex_unlock(&parent->d_inode->i_mutex); |
| 219 | dput(parent); | 219 | dput(parent); |
| 220 | 220 | ||
| 221 | if (!error) | 221 | if (!error) |
| @@ -476,7 +476,7 @@ static ssize_t relay_file_read(struct file *filp, | |||
| 476 | ssize_t ret = 0; | 476 | ssize_t ret = 0; |
| 477 | void *from; | 477 | void *from; |
| 478 | 478 | ||
| 479 | down(&inode->i_sem); | 479 | mutex_lock(&inode->i_mutex); |
| 480 | if(!relay_file_read_avail(buf, *ppos)) | 480 | if(!relay_file_read_avail(buf, *ppos)) |
| 481 | goto out; | 481 | goto out; |
| 482 | 482 | ||
| @@ -494,7 +494,7 @@ static ssize_t relay_file_read(struct file *filp, | |||
| 494 | relay_file_read_consume(buf, read_start, count); | 494 | relay_file_read_consume(buf, read_start, count); |
| 495 | *ppos = relay_file_read_end_pos(buf, read_start, count); | 495 | *ppos = relay_file_read_end_pos(buf, read_start, count); |
| 496 | out: | 496 | out: |
| 497 | up(&inode->i_sem); | 497 | mutex_unlock(&inode->i_mutex); |
| 498 | return ret; | 498 | return ret; |
| 499 | } | 499 | } |
| 500 | 500 | ||
diff --git a/fs/super.c b/fs/super.c index 0a30e51692cf..c177b92419c5 100644 --- a/fs/super.c +++ b/fs/super.c | |||
| @@ -72,7 +72,7 @@ static struct super_block *alloc_super(void) | |||
| 72 | INIT_HLIST_HEAD(&s->s_anon); | 72 | INIT_HLIST_HEAD(&s->s_anon); |
| 73 | INIT_LIST_HEAD(&s->s_inodes); | 73 | INIT_LIST_HEAD(&s->s_inodes); |
| 74 | init_rwsem(&s->s_umount); | 74 | init_rwsem(&s->s_umount); |
| 75 | sema_init(&s->s_lock, 1); | 75 | mutex_init(&s->s_lock); |
| 76 | down_write(&s->s_umount); | 76 | down_write(&s->s_umount); |
| 77 | s->s_count = S_BIAS; | 77 | s->s_count = S_BIAS; |
| 78 | atomic_set(&s->s_active, 1); | 78 | atomic_set(&s->s_active, 1); |
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index d36780382176..49bd219275db 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
| @@ -99,7 +99,7 @@ static int create_dir(struct kobject * k, struct dentry * p, | |||
| 99 | int error; | 99 | int error; |
| 100 | umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; | 100 | umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; |
| 101 | 101 | ||
| 102 | down(&p->d_inode->i_sem); | 102 | mutex_lock(&p->d_inode->i_mutex); |
| 103 | *d = lookup_one_len(n, p, strlen(n)); | 103 | *d = lookup_one_len(n, p, strlen(n)); |
| 104 | if (!IS_ERR(*d)) { | 104 | if (!IS_ERR(*d)) { |
| 105 | error = sysfs_make_dirent(p->d_fsdata, *d, k, mode, SYSFS_DIR); | 105 | error = sysfs_make_dirent(p->d_fsdata, *d, k, mode, SYSFS_DIR); |
| @@ -122,7 +122,7 @@ static int create_dir(struct kobject * k, struct dentry * p, | |||
| 122 | dput(*d); | 122 | dput(*d); |
| 123 | } else | 123 | } else |
| 124 | error = PTR_ERR(*d); | 124 | error = PTR_ERR(*d); |
| 125 | up(&p->d_inode->i_sem); | 125 | mutex_unlock(&p->d_inode->i_mutex); |
| 126 | return error; | 126 | return error; |
| 127 | } | 127 | } |
| 128 | 128 | ||
| @@ -246,7 +246,7 @@ static void remove_dir(struct dentry * d) | |||
| 246 | struct dentry * parent = dget(d->d_parent); | 246 | struct dentry * parent = dget(d->d_parent); |
| 247 | struct sysfs_dirent * sd; | 247 | struct sysfs_dirent * sd; |
| 248 | 248 | ||
| 249 | down(&parent->d_inode->i_sem); | 249 | mutex_lock(&parent->d_inode->i_mutex); |
| 250 | d_delete(d); | 250 | d_delete(d); |
| 251 | sd = d->d_fsdata; | 251 | sd = d->d_fsdata; |
| 252 | list_del_init(&sd->s_sibling); | 252 | list_del_init(&sd->s_sibling); |
| @@ -257,7 +257,7 @@ static void remove_dir(struct dentry * d) | |||
| 257 | pr_debug(" o %s removing done (%d)\n",d->d_name.name, | 257 | pr_debug(" o %s removing done (%d)\n",d->d_name.name, |
| 258 | atomic_read(&d->d_count)); | 258 | atomic_read(&d->d_count)); |
| 259 | 259 | ||
| 260 | up(&parent->d_inode->i_sem); | 260 | mutex_unlock(&parent->d_inode->i_mutex); |
| 261 | dput(parent); | 261 | dput(parent); |
| 262 | } | 262 | } |
| 263 | 263 | ||
| @@ -286,7 +286,7 @@ void sysfs_remove_dir(struct kobject * kobj) | |||
| 286 | return; | 286 | return; |
| 287 | 287 | ||
| 288 | pr_debug("sysfs %s: removing dir\n",dentry->d_name.name); | 288 | pr_debug("sysfs %s: removing dir\n",dentry->d_name.name); |
| 289 | down(&dentry->d_inode->i_sem); | 289 | mutex_lock(&dentry->d_inode->i_mutex); |
| 290 | parent_sd = dentry->d_fsdata; | 290 | parent_sd = dentry->d_fsdata; |
| 291 | list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) { | 291 | list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) { |
| 292 | if (!sd->s_element || !(sd->s_type & SYSFS_NOT_PINNED)) | 292 | if (!sd->s_element || !(sd->s_type & SYSFS_NOT_PINNED)) |
| @@ -295,7 +295,7 @@ void sysfs_remove_dir(struct kobject * kobj) | |||
| 295 | sysfs_drop_dentry(sd, dentry); | 295 | sysfs_drop_dentry(sd, dentry); |
| 296 | sysfs_put(sd); | 296 | sysfs_put(sd); |
| 297 | } | 297 | } |
| 298 | up(&dentry->d_inode->i_sem); | 298 | mutex_unlock(&dentry->d_inode->i_mutex); |
| 299 | 299 | ||
| 300 | remove_dir(dentry); | 300 | remove_dir(dentry); |
| 301 | /** | 301 | /** |
| @@ -318,7 +318,7 @@ int sysfs_rename_dir(struct kobject * kobj, const char *new_name) | |||
| 318 | down_write(&sysfs_rename_sem); | 318 | down_write(&sysfs_rename_sem); |
| 319 | parent = kobj->parent->dentry; | 319 | parent = kobj->parent->dentry; |
| 320 | 320 | ||
| 321 | down(&parent->d_inode->i_sem); | 321 | mutex_lock(&parent->d_inode->i_mutex); |
| 322 | 322 | ||
| 323 | new_dentry = lookup_one_len(new_name, parent, strlen(new_name)); | 323 | new_dentry = lookup_one_len(new_name, parent, strlen(new_name)); |
| 324 | if (!IS_ERR(new_dentry)) { | 324 | if (!IS_ERR(new_dentry)) { |
| @@ -334,7 +334,7 @@ int sysfs_rename_dir(struct kobject * kobj, const char *new_name) | |||
| 334 | error = -EEXIST; | 334 | error = -EEXIST; |
| 335 | dput(new_dentry); | 335 | dput(new_dentry); |
| 336 | } | 336 | } |
| 337 | up(&parent->d_inode->i_sem); | 337 | mutex_unlock(&parent->d_inode->i_mutex); |
| 338 | up_write(&sysfs_rename_sem); | 338 | up_write(&sysfs_rename_sem); |
| 339 | 339 | ||
| 340 | return error; | 340 | return error; |
| @@ -345,9 +345,9 @@ static int sysfs_dir_open(struct inode *inode, struct file *file) | |||
| 345 | struct dentry * dentry = file->f_dentry; | 345 | struct dentry * dentry = file->f_dentry; |
| 346 | struct sysfs_dirent * parent_sd = dentry->d_fsdata; | 346 | struct sysfs_dirent * parent_sd = dentry->d_fsdata; |
| 347 | 347 | ||
| 348 | down(&dentry->d_inode->i_sem); | 348 | mutex_lock(&dentry->d_inode->i_mutex); |
| 349 | file->private_data = sysfs_new_dirent(parent_sd, NULL); | 349 | file->private_data = sysfs_new_dirent(parent_sd, NULL); |
| 350 | up(&dentry->d_inode->i_sem); | 350 | mutex_unlock(&dentry->d_inode->i_mutex); |
| 351 | 351 | ||
| 352 | return file->private_data ? 0 : -ENOMEM; | 352 | return file->private_data ? 0 : -ENOMEM; |
| 353 | 353 | ||
| @@ -358,9 +358,9 @@ static int sysfs_dir_close(struct inode *inode, struct file *file) | |||
| 358 | struct dentry * dentry = file->f_dentry; | 358 | struct dentry * dentry = file->f_dentry; |
| 359 | struct sysfs_dirent * cursor = file->private_data; | 359 | struct sysfs_dirent * cursor = file->private_data; |
| 360 | 360 | ||
| 361 | down(&dentry->d_inode->i_sem); | 361 | mutex_lock(&dentry->d_inode->i_mutex); |
| 362 | list_del_init(&cursor->s_sibling); | 362 | list_del_init(&cursor->s_sibling); |
| 363 | up(&dentry->d_inode->i_sem); | 363 | mutex_unlock(&dentry->d_inode->i_mutex); |
| 364 | 364 | ||
| 365 | release_sysfs_dirent(cursor); | 365 | release_sysfs_dirent(cursor); |
| 366 | 366 | ||
| @@ -436,7 +436,7 @@ static loff_t sysfs_dir_lseek(struct file * file, loff_t offset, int origin) | |||
| 436 | { | 436 | { |
| 437 | struct dentry * dentry = file->f_dentry; | 437 | struct dentry * dentry = file->f_dentry; |
| 438 | 438 | ||
| 439 | down(&dentry->d_inode->i_sem); | 439 | mutex_lock(&dentry->d_inode->i_mutex); |
| 440 | switch (origin) { | 440 | switch (origin) { |
| 441 | case 1: | 441 | case 1: |
| 442 | offset += file->f_pos; | 442 | offset += file->f_pos; |
| @@ -444,7 +444,7 @@ static loff_t sysfs_dir_lseek(struct file * file, loff_t offset, int origin) | |||
| 444 | if (offset >= 0) | 444 | if (offset >= 0) |
| 445 | break; | 445 | break; |
| 446 | default: | 446 | default: |
| 447 | up(&file->f_dentry->d_inode->i_sem); | 447 | mutex_unlock(&file->f_dentry->d_inode->i_mutex); |
| 448 | return -EINVAL; | 448 | return -EINVAL; |
| 449 | } | 449 | } |
| 450 | if (offset != file->f_pos) { | 450 | if (offset != file->f_pos) { |
| @@ -468,7 +468,7 @@ static loff_t sysfs_dir_lseek(struct file * file, loff_t offset, int origin) | |||
| 468 | list_add_tail(&cursor->s_sibling, p); | 468 | list_add_tail(&cursor->s_sibling, p); |
| 469 | } | 469 | } |
| 470 | } | 470 | } |
| 471 | up(&dentry->d_inode->i_sem); | 471 | mutex_unlock(&dentry->d_inode->i_mutex); |
| 472 | return offset; | 472 | return offset; |
| 473 | } | 473 | } |
| 474 | 474 | ||
| @@ -483,4 +483,3 @@ struct file_operations sysfs_dir_operations = { | |||
| 483 | EXPORT_SYMBOL_GPL(sysfs_create_dir); | 483 | EXPORT_SYMBOL_GPL(sysfs_create_dir); |
| 484 | EXPORT_SYMBOL_GPL(sysfs_remove_dir); | 484 | EXPORT_SYMBOL_GPL(sysfs_remove_dir); |
| 485 | EXPORT_SYMBOL_GPL(sysfs_rename_dir); | 485 | EXPORT_SYMBOL_GPL(sysfs_rename_dir); |
| 486 | |||
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 4013d7905e84..d0e3d8495165 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
| @@ -364,9 +364,9 @@ int sysfs_add_file(struct dentry * dir, const struct attribute * attr, int type) | |||
| 364 | umode_t mode = (attr->mode & S_IALLUGO) | S_IFREG; | 364 | umode_t mode = (attr->mode & S_IALLUGO) | S_IFREG; |
| 365 | int error = 0; | 365 | int error = 0; |
| 366 | 366 | ||
| 367 | down(&dir->d_inode->i_sem); | 367 | mutex_lock(&dir->d_inode->i_mutex); |
| 368 | error = sysfs_make_dirent(parent_sd, NULL, (void *) attr, mode, type); | 368 | error = sysfs_make_dirent(parent_sd, NULL, (void *) attr, mode, type); |
| 369 | up(&dir->d_inode->i_sem); | 369 | mutex_unlock(&dir->d_inode->i_mutex); |
| 370 | 370 | ||
| 371 | return error; | 371 | return error; |
| 372 | } | 372 | } |
| @@ -398,7 +398,7 @@ int sysfs_update_file(struct kobject * kobj, const struct attribute * attr) | |||
| 398 | struct dentry * victim; | 398 | struct dentry * victim; |
| 399 | int res = -ENOENT; | 399 | int res = -ENOENT; |
| 400 | 400 | ||
| 401 | down(&dir->d_inode->i_sem); | 401 | mutex_lock(&dir->d_inode->i_mutex); |
| 402 | victim = lookup_one_len(attr->name, dir, strlen(attr->name)); | 402 | victim = lookup_one_len(attr->name, dir, strlen(attr->name)); |
| 403 | if (!IS_ERR(victim)) { | 403 | if (!IS_ERR(victim)) { |
| 404 | /* make sure dentry is really there */ | 404 | /* make sure dentry is really there */ |
| @@ -420,7 +420,7 @@ int sysfs_update_file(struct kobject * kobj, const struct attribute * attr) | |||
| 420 | */ | 420 | */ |
| 421 | dput(victim); | 421 | dput(victim); |
| 422 | } | 422 | } |
| 423 | up(&dir->d_inode->i_sem); | 423 | mutex_unlock(&dir->d_inode->i_mutex); |
| 424 | 424 | ||
| 425 | return res; | 425 | return res; |
| 426 | } | 426 | } |
| @@ -441,22 +441,22 @@ int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode) | |||
| 441 | struct iattr newattrs; | 441 | struct iattr newattrs; |
| 442 | int res = -ENOENT; | 442 | int res = -ENOENT; |
| 443 | 443 | ||
| 444 | down(&dir->d_inode->i_sem); | 444 | mutex_lock(&dir->d_inode->i_mutex); |
| 445 | victim = lookup_one_len(attr->name, dir, strlen(attr->name)); | 445 | victim = lookup_one_len(attr->name, dir, strlen(attr->name)); |
| 446 | if (!IS_ERR(victim)) { | 446 | if (!IS_ERR(victim)) { |
| 447 | if (victim->d_inode && | 447 | if (victim->d_inode && |
| 448 | (victim->d_parent->d_inode == dir->d_inode)) { | 448 | (victim->d_parent->d_inode == dir->d_inode)) { |
| 449 | inode = victim->d_inode; | 449 | inode = victim->d_inode; |
| 450 | down(&inode->i_sem); | 450 | mutex_lock(&inode->i_mutex); |
| 451 | newattrs.ia_mode = (mode & S_IALLUGO) | | 451 | newattrs.ia_mode = (mode & S_IALLUGO) | |
| 452 | (inode->i_mode & ~S_IALLUGO); | 452 | (inode->i_mode & ~S_IALLUGO); |
| 453 | newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; | 453 | newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; |
| 454 | res = notify_change(victim, &newattrs); | 454 | res = notify_change(victim, &newattrs); |
| 455 | up(&inode->i_sem); | 455 | mutex_unlock(&inode->i_mutex); |
| 456 | } | 456 | } |
| 457 | dput(victim); | 457 | dput(victim); |
| 458 | } | 458 | } |
| 459 | up(&dir->d_inode->i_sem); | 459 | mutex_unlock(&dir->d_inode->i_mutex); |
| 460 | 460 | ||
| 461 | return res; | 461 | return res; |
| 462 | } | 462 | } |
| @@ -480,4 +480,3 @@ void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr) | |||
| 480 | EXPORT_SYMBOL_GPL(sysfs_create_file); | 480 | EXPORT_SYMBOL_GPL(sysfs_create_file); |
| 481 | EXPORT_SYMBOL_GPL(sysfs_remove_file); | 481 | EXPORT_SYMBOL_GPL(sysfs_remove_file); |
| 482 | EXPORT_SYMBOL_GPL(sysfs_update_file); | 482 | EXPORT_SYMBOL_GPL(sysfs_update_file); |
| 483 | |||
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c index 970a33f03299..c3133219941c 100644 --- a/fs/sysfs/inode.c +++ b/fs/sysfs/inode.c | |||
| @@ -201,7 +201,7 @@ const unsigned char * sysfs_get_name(struct sysfs_dirent *sd) | |||
| 201 | 201 | ||
| 202 | /* | 202 | /* |
| 203 | * Unhashes the dentry corresponding to given sysfs_dirent | 203 | * Unhashes the dentry corresponding to given sysfs_dirent |
| 204 | * Called with parent inode's i_sem held. | 204 | * Called with parent inode's i_mutex held. |
| 205 | */ | 205 | */ |
| 206 | void sysfs_drop_dentry(struct sysfs_dirent * sd, struct dentry * parent) | 206 | void sysfs_drop_dentry(struct sysfs_dirent * sd, struct dentry * parent) |
| 207 | { | 207 | { |
| @@ -232,7 +232,7 @@ void sysfs_hash_and_remove(struct dentry * dir, const char * name) | |||
| 232 | /* no inode means this hasn't been made visible yet */ | 232 | /* no inode means this hasn't been made visible yet */ |
| 233 | return; | 233 | return; |
| 234 | 234 | ||
| 235 | down(&dir->d_inode->i_sem); | 235 | mutex_lock(&dir->d_inode->i_mutex); |
| 236 | list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { | 236 | list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { |
| 237 | if (!sd->s_element) | 237 | if (!sd->s_element) |
| 238 | continue; | 238 | continue; |
| @@ -243,7 +243,5 @@ void sysfs_hash_and_remove(struct dentry * dir, const char * name) | |||
| 243 | break; | 243 | break; |
| 244 | } | 244 | } |
| 245 | } | 245 | } |
| 246 | up(&dir->d_inode->i_sem); | 246 | mutex_unlock(&dir->d_inode->i_mutex); |
| 247 | } | 247 | } |
| 248 | |||
| 249 | |||
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index de402fa915f2..e38d6338a20d 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c | |||
| @@ -86,9 +86,9 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char | |||
| 86 | 86 | ||
| 87 | BUG_ON(!kobj || !kobj->dentry || !name); | 87 | BUG_ON(!kobj || !kobj->dentry || !name); |
| 88 | 88 | ||
| 89 | down(&dentry->d_inode->i_sem); | 89 | mutex_lock(&dentry->d_inode->i_mutex); |
| 90 | error = sysfs_add_link(dentry, name, target); | 90 | error = sysfs_add_link(dentry, name, target); |
| 91 | up(&dentry->d_inode->i_sem); | 91 | mutex_unlock(&dentry->d_inode->i_mutex); |
| 92 | return error; | 92 | return error; |
| 93 | } | 93 | } |
| 94 | 94 | ||
| @@ -177,4 +177,3 @@ struct inode_operations sysfs_symlink_inode_operations = { | |||
| 177 | 177 | ||
| 178 | EXPORT_SYMBOL_GPL(sysfs_create_link); | 178 | EXPORT_SYMBOL_GPL(sysfs_create_link); |
| 179 | EXPORT_SYMBOL_GPL(sysfs_remove_link); | 179 | EXPORT_SYMBOL_GPL(sysfs_remove_link); |
| 180 | |||
diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 2ba11a9aa995..e9a42c711a9e 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c | |||
| @@ -1275,7 +1275,7 @@ static ssize_t ufs_quota_write(struct super_block *sb, int type, | |||
| 1275 | size_t towrite = len; | 1275 | size_t towrite = len; |
| 1276 | struct buffer_head *bh; | 1276 | struct buffer_head *bh; |
| 1277 | 1277 | ||
| 1278 | down(&inode->i_sem); | 1278 | mutex_lock(&inode->i_mutex); |
| 1279 | while (towrite > 0) { | 1279 | while (towrite > 0) { |
| 1280 | tocopy = sb->s_blocksize - offset < towrite ? | 1280 | tocopy = sb->s_blocksize - offset < towrite ? |
| 1281 | sb->s_blocksize - offset : towrite; | 1281 | sb->s_blocksize - offset : towrite; |
| @@ -1297,7 +1297,7 @@ static ssize_t ufs_quota_write(struct super_block *sb, int type, | |||
| 1297 | } | 1297 | } |
| 1298 | out: | 1298 | out: |
| 1299 | if (len == towrite) { | 1299 | if (len == towrite) { |
| 1300 | up(&inode->i_sem); | 1300 | mutex_unlock(&inode->i_mutex); |
| 1301 | return err; | 1301 | return err; |
| 1302 | } | 1302 | } |
| 1303 | if (inode->i_size < off+len-towrite) | 1303 | if (inode->i_size < off+len-towrite) |
| @@ -1305,7 +1305,7 @@ out: | |||
| 1305 | inode->i_version++; | 1305 | inode->i_version++; |
| 1306 | inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; | 1306 | inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; |
| 1307 | mark_inode_dirty(inode); | 1307 | mark_inode_dirty(inode); |
| 1308 | up(&inode->i_sem); | 1308 | mutex_unlock(&inode->i_mutex); |
| 1309 | return len - towrite; | 1309 | return len - towrite; |
| 1310 | } | 1310 | } |
| 1311 | 1311 | ||
diff --git a/fs/xattr.c b/fs/xattr.c index bcc2156d4d28..386a532ee5a9 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
| @@ -51,7 +51,7 @@ setxattr(struct dentry *d, char __user *name, void __user *value, | |||
| 51 | } | 51 | } |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | down(&d->d_inode->i_sem); | 54 | mutex_lock(&d->d_inode->i_mutex); |
| 55 | error = security_inode_setxattr(d, kname, kvalue, size, flags); | 55 | error = security_inode_setxattr(d, kname, kvalue, size, flags); |
| 56 | if (error) | 56 | if (error) |
| 57 | goto out; | 57 | goto out; |
| @@ -73,7 +73,7 @@ setxattr(struct dentry *d, char __user *name, void __user *value, | |||
| 73 | fsnotify_xattr(d); | 73 | fsnotify_xattr(d); |
| 74 | } | 74 | } |
| 75 | out: | 75 | out: |
| 76 | up(&d->d_inode->i_sem); | 76 | mutex_unlock(&d->d_inode->i_mutex); |
| 77 | kfree(kvalue); | 77 | kfree(kvalue); |
| 78 | return error; | 78 | return error; |
| 79 | } | 79 | } |
| @@ -323,9 +323,9 @@ removexattr(struct dentry *d, char __user *name) | |||
| 323 | error = security_inode_removexattr(d, kname); | 323 | error = security_inode_removexattr(d, kname); |
| 324 | if (error) | 324 | if (error) |
| 325 | goto out; | 325 | goto out; |
| 326 | down(&d->d_inode->i_sem); | 326 | mutex_lock(&d->d_inode->i_mutex); |
| 327 | error = d->d_inode->i_op->removexattr(d, kname); | 327 | error = d->d_inode->i_op->removexattr(d, kname); |
| 328 | up(&d->d_inode->i_sem); | 328 | mutex_unlock(&d->d_inode->i_mutex); |
| 329 | if (!error) | 329 | if (!error) |
| 330 | fsnotify_xattr(d); | 330 | fsnotify_xattr(d); |
| 331 | } | 331 | } |
diff --git a/fs/xfs/linux-2.6/mutex.h b/fs/xfs/linux-2.6/mutex.h index ce773d89a923..d3369b6ca168 100644 --- a/fs/xfs/linux-2.6/mutex.h +++ b/fs/xfs/linux-2.6/mutex.h | |||
| @@ -19,7 +19,7 @@ | |||
| 19 | #define __XFS_SUPPORT_MUTEX_H__ | 19 | #define __XFS_SUPPORT_MUTEX_H__ |
| 20 | 20 | ||
| 21 | #include <linux/spinlock.h> | 21 | #include <linux/spinlock.h> |
| 22 | #include <asm/semaphore.h> | 22 | #include <linux/mutex.h> |
| 23 | 23 | ||
| 24 | /* | 24 | /* |
| 25 | * Map the mutex'es from IRIX to Linux semaphores. | 25 | * Map the mutex'es from IRIX to Linux semaphores. |
| @@ -28,12 +28,8 @@ | |||
| 28 | * callers. | 28 | * callers. |
| 29 | */ | 29 | */ |
| 30 | #define MUTEX_DEFAULT 0x0 | 30 | #define MUTEX_DEFAULT 0x0 |
| 31 | typedef struct semaphore mutex_t; | ||
| 32 | 31 | ||
| 33 | #define mutex_init(lock, type, name) sema_init(lock, 1) | 32 | typedef struct mutex mutex_t; |
| 34 | #define mutex_destroy(lock) sema_init(lock, -99) | 33 | //#define mutex_destroy(lock) do{}while(0) |
| 35 | #define mutex_lock(lock, num) down(lock) | ||
| 36 | #define mutex_trylock(lock) (down_trylock(lock) ? 0 : 1) | ||
| 37 | #define mutex_unlock(lock) up(lock) | ||
| 38 | 34 | ||
| 39 | #endif /* __XFS_SUPPORT_MUTEX_H__ */ | 35 | #endif /* __XFS_SUPPORT_MUTEX_H__ */ |
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 14215a7db59f..41c478bb1ffc 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
| @@ -203,7 +203,7 @@ validate_fields( | |||
| 203 | ip->i_nlink = va.va_nlink; | 203 | ip->i_nlink = va.va_nlink; |
| 204 | ip->i_blocks = va.va_nblocks; | 204 | ip->i_blocks = va.va_nblocks; |
| 205 | 205 | ||
| 206 | /* we're under i_sem so i_size can't change under us */ | 206 | /* we're under i_mutex so i_size can't change under us */ |
| 207 | if (i_size_read(ip) != va.va_size) | 207 | if (i_size_read(ip) != va.va_size) |
| 208 | i_size_write(ip, va.va_size); | 208 | i_size_write(ip, va.va_size); |
| 209 | } | 209 | } |
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 279e9bc92aba..5675117ef227 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c | |||
| @@ -254,7 +254,7 @@ xfs_read( | |||
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | if (unlikely(ioflags & IO_ISDIRECT)) | 256 | if (unlikely(ioflags & IO_ISDIRECT)) |
| 257 | down(&inode->i_sem); | 257 | mutex_lock(&inode->i_mutex); |
| 258 | xfs_ilock(ip, XFS_IOLOCK_SHARED); | 258 | xfs_ilock(ip, XFS_IOLOCK_SHARED); |
| 259 | 259 | ||
| 260 | if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) && | 260 | if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) && |
| @@ -286,7 +286,7 @@ xfs_read( | |||
| 286 | 286 | ||
| 287 | unlock_isem: | 287 | unlock_isem: |
| 288 | if (unlikely(ioflags & IO_ISDIRECT)) | 288 | if (unlikely(ioflags & IO_ISDIRECT)) |
| 289 | up(&inode->i_sem); | 289 | mutex_unlock(&inode->i_mutex); |
| 290 | return ret; | 290 | return ret; |
| 291 | } | 291 | } |
| 292 | 292 | ||
| @@ -655,7 +655,7 @@ relock: | |||
| 655 | iolock = XFS_IOLOCK_EXCL; | 655 | iolock = XFS_IOLOCK_EXCL; |
| 656 | locktype = VRWLOCK_WRITE; | 656 | locktype = VRWLOCK_WRITE; |
| 657 | 657 | ||
| 658 | down(&inode->i_sem); | 658 | mutex_lock(&inode->i_mutex); |
| 659 | } else { | 659 | } else { |
| 660 | iolock = XFS_IOLOCK_SHARED; | 660 | iolock = XFS_IOLOCK_SHARED; |
| 661 | locktype = VRWLOCK_WRITE_DIRECT; | 661 | locktype = VRWLOCK_WRITE_DIRECT; |
| @@ -686,7 +686,7 @@ start: | |||
| 686 | int dmflags = FILP_DELAY_FLAG(file); | 686 | int dmflags = FILP_DELAY_FLAG(file); |
| 687 | 687 | ||
| 688 | if (need_isem) | 688 | if (need_isem) |
| 689 | dmflags |= DM_FLAGS_ISEM; | 689 | dmflags |= DM_FLAGS_IMUX; |
| 690 | 690 | ||
| 691 | xfs_iunlock(xip, XFS_ILOCK_EXCL); | 691 | xfs_iunlock(xip, XFS_ILOCK_EXCL); |
| 692 | error = XFS_SEND_DATA(xip->i_mount, DM_EVENT_WRITE, vp, | 692 | error = XFS_SEND_DATA(xip->i_mount, DM_EVENT_WRITE, vp, |
| @@ -772,7 +772,7 @@ retry: | |||
| 772 | if (need_isem) { | 772 | if (need_isem) { |
| 773 | /* demote the lock now the cached pages are gone */ | 773 | /* demote the lock now the cached pages are gone */ |
| 774 | XFS_ILOCK_DEMOTE(mp, io, XFS_IOLOCK_EXCL); | 774 | XFS_ILOCK_DEMOTE(mp, io, XFS_IOLOCK_EXCL); |
| 775 | up(&inode->i_sem); | 775 | mutex_unlock(&inode->i_mutex); |
| 776 | 776 | ||
| 777 | iolock = XFS_IOLOCK_SHARED; | 777 | iolock = XFS_IOLOCK_SHARED; |
| 778 | locktype = VRWLOCK_WRITE_DIRECT; | 778 | locktype = VRWLOCK_WRITE_DIRECT; |
| @@ -817,14 +817,14 @@ retry: | |||
| 817 | 817 | ||
| 818 | xfs_rwunlock(bdp, locktype); | 818 | xfs_rwunlock(bdp, locktype); |
| 819 | if (need_isem) | 819 | if (need_isem) |
| 820 | up(&inode->i_sem); | 820 | mutex_unlock(&inode->i_mutex); |
| 821 | error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp, | 821 | error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp, |
| 822 | DM_RIGHT_NULL, vp, DM_RIGHT_NULL, NULL, NULL, | 822 | DM_RIGHT_NULL, vp, DM_RIGHT_NULL, NULL, NULL, |
| 823 | 0, 0, 0); /* Delay flag intentionally unused */ | 823 | 0, 0, 0); /* Delay flag intentionally unused */ |
| 824 | if (error) | 824 | if (error) |
| 825 | goto out_nounlocks; | 825 | goto out_nounlocks; |
| 826 | if (need_isem) | 826 | if (need_isem) |
| 827 | down(&inode->i_sem); | 827 | mutex_lock(&inode->i_mutex); |
| 828 | xfs_rwlock(bdp, locktype); | 828 | xfs_rwlock(bdp, locktype); |
| 829 | pos = xip->i_d.di_size; | 829 | pos = xip->i_d.di_size; |
| 830 | ret = 0; | 830 | ret = 0; |
| @@ -926,7 +926,7 @@ retry: | |||
| 926 | 926 | ||
| 927 | xfs_rwunlock(bdp, locktype); | 927 | xfs_rwunlock(bdp, locktype); |
| 928 | if (need_isem) | 928 | if (need_isem) |
| 929 | up(&inode->i_sem); | 929 | mutex_unlock(&inode->i_mutex); |
| 930 | 930 | ||
| 931 | error = sync_page_range(inode, mapping, pos, ret); | 931 | error = sync_page_range(inode, mapping, pos, ret); |
| 932 | if (!error) | 932 | if (!error) |
| @@ -938,7 +938,7 @@ retry: | |||
| 938 | xfs_rwunlock(bdp, locktype); | 938 | xfs_rwunlock(bdp, locktype); |
| 939 | out_unlock_isem: | 939 | out_unlock_isem: |
| 940 | if (need_isem) | 940 | if (need_isem) |
| 941 | up(&inode->i_sem); | 941 | mutex_unlock(&inode->i_mutex); |
| 942 | out_nounlocks: | 942 | out_nounlocks: |
| 943 | return -error; | 943 | return -error; |
| 944 | } | 944 | } |
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c index 00b5043dfa5a..772ac48329ea 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c | |||
| @@ -104,7 +104,7 @@ xfs_qm_dqinit( | |||
| 104 | */ | 104 | */ |
| 105 | if (brandnewdquot) { | 105 | if (brandnewdquot) { |
| 106 | dqp->dq_flnext = dqp->dq_flprev = dqp; | 106 | dqp->dq_flnext = dqp->dq_flprev = dqp; |
| 107 | mutex_init(&dqp->q_qlock, MUTEX_DEFAULT, "xdq"); | 107 | mutex_init(&dqp->q_qlock); |
| 108 | initnsema(&dqp->q_flock, 1, "fdq"); | 108 | initnsema(&dqp->q_flock, 1, "fdq"); |
| 109 | sv_init(&dqp->q_pinwait, SV_DEFAULT, "pdq"); | 109 | sv_init(&dqp->q_pinwait, SV_DEFAULT, "pdq"); |
| 110 | 110 | ||
| @@ -1382,7 +1382,7 @@ void | |||
| 1382 | xfs_dqlock( | 1382 | xfs_dqlock( |
| 1383 | xfs_dquot_t *dqp) | 1383 | xfs_dquot_t *dqp) |
| 1384 | { | 1384 | { |
| 1385 | mutex_lock(&(dqp->q_qlock), PINOD); | 1385 | mutex_lock(&(dqp->q_qlock)); |
| 1386 | } | 1386 | } |
| 1387 | 1387 | ||
| 1388 | void | 1388 | void |
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 5328a2937127..bb6991a7a617 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c | |||
| @@ -167,7 +167,7 @@ xfs_Gqm_init(void) | |||
| 167 | xqm->qm_dqfree_ratio = XFS_QM_DQFREE_RATIO; | 167 | xqm->qm_dqfree_ratio = XFS_QM_DQFREE_RATIO; |
| 168 | xqm->qm_nrefs = 0; | 168 | xqm->qm_nrefs = 0; |
| 169 | #ifdef DEBUG | 169 | #ifdef DEBUG |
| 170 | mutex_init(&qcheck_lock, MUTEX_DEFAULT, "qchk"); | 170 | xfs_mutex_init(&qcheck_lock, MUTEX_DEFAULT, "qchk"); |
| 171 | #endif | 171 | #endif |
| 172 | return xqm; | 172 | return xqm; |
| 173 | } | 173 | } |
| @@ -1166,7 +1166,7 @@ xfs_qm_init_quotainfo( | |||
| 1166 | qinf->qi_dqreclaims = 0; | 1166 | qinf->qi_dqreclaims = 0; |
| 1167 | 1167 | ||
| 1168 | /* mutex used to serialize quotaoffs */ | 1168 | /* mutex used to serialize quotaoffs */ |
| 1169 | mutex_init(&qinf->qi_quotaofflock, MUTEX_DEFAULT, "qoff"); | 1169 | mutex_init(&qinf->qi_quotaofflock); |
| 1170 | 1170 | ||
| 1171 | /* Precalc some constants */ | 1171 | /* Precalc some constants */ |
| 1172 | qinf->qi_dqchunklen = XFS_FSB_TO_BB(mp, XFS_DQUOT_CLUSTER_SIZE_FSB); | 1172 | qinf->qi_dqchunklen = XFS_FSB_TO_BB(mp, XFS_DQUOT_CLUSTER_SIZE_FSB); |
| @@ -1285,7 +1285,7 @@ xfs_qm_list_init( | |||
| 1285 | char *str, | 1285 | char *str, |
| 1286 | int n) | 1286 | int n) |
| 1287 | { | 1287 | { |
| 1288 | mutex_init(&list->qh_lock, MUTEX_DEFAULT, str); | 1288 | mutex_init(&list->qh_lock); |
| 1289 | list->qh_next = NULL; | 1289 | list->qh_next = NULL; |
| 1290 | list->qh_version = 0; | 1290 | list->qh_version = 0; |
| 1291 | list->qh_nelems = 0; | 1291 | list->qh_nelems = 0; |
| @@ -2762,7 +2762,7 @@ STATIC void | |||
| 2762 | xfs_qm_freelist_init(xfs_frlist_t *ql) | 2762 | xfs_qm_freelist_init(xfs_frlist_t *ql) |
| 2763 | { | 2763 | { |
| 2764 | ql->qh_next = ql->qh_prev = (xfs_dquot_t *) ql; | 2764 | ql->qh_next = ql->qh_prev = (xfs_dquot_t *) ql; |
| 2765 | mutex_init(&ql->qh_lock, MUTEX_DEFAULT, "dqf"); | 2765 | mutex_init(&ql->qh_lock); |
| 2766 | ql->qh_version = 0; | 2766 | ql->qh_version = 0; |
| 2767 | ql->qh_nelems = 0; | 2767 | ql->qh_nelems = 0; |
| 2768 | } | 2768 | } |
| @@ -2772,7 +2772,7 @@ xfs_qm_freelist_destroy(xfs_frlist_t *ql) | |||
| 2772 | { | 2772 | { |
| 2773 | xfs_dquot_t *dqp, *nextdqp; | 2773 | xfs_dquot_t *dqp, *nextdqp; |
| 2774 | 2774 | ||
| 2775 | mutex_lock(&ql->qh_lock, PINOD); | 2775 | mutex_lock(&ql->qh_lock); |
| 2776 | for (dqp = ql->qh_next; | 2776 | for (dqp = ql->qh_next; |
| 2777 | dqp != (xfs_dquot_t *)ql; ) { | 2777 | dqp != (xfs_dquot_t *)ql; ) { |
| 2778 | xfs_dqlock(dqp); | 2778 | xfs_dqlock(dqp); |
diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/quota/xfs_qm.h index 12da259f2fcb..4568deb6da86 100644 --- a/fs/xfs/quota/xfs_qm.h +++ b/fs/xfs/quota/xfs_qm.h | |||
| @@ -165,7 +165,7 @@ typedef struct xfs_dquot_acct { | |||
| 165 | #define XFS_QM_IWARNLIMIT 5 | 165 | #define XFS_QM_IWARNLIMIT 5 |
| 166 | #define XFS_QM_RTBWARNLIMIT 5 | 166 | #define XFS_QM_RTBWARNLIMIT 5 |
| 167 | 167 | ||
| 168 | #define XFS_QM_LOCK(xqm) (mutex_lock(&xqm##_lock, PINOD)) | 168 | #define XFS_QM_LOCK(xqm) (mutex_lock(&xqm##_lock)) |
| 169 | #define XFS_QM_UNLOCK(xqm) (mutex_unlock(&xqm##_lock)) | 169 | #define XFS_QM_UNLOCK(xqm) (mutex_unlock(&xqm##_lock)) |
| 170 | #define XFS_QM_HOLD(xqm) ((xqm)->qm_nrefs++) | 170 | #define XFS_QM_HOLD(xqm) ((xqm)->qm_nrefs++) |
| 171 | #define XFS_QM_RELE(xqm) ((xqm)->qm_nrefs--) | 171 | #define XFS_QM_RELE(xqm) ((xqm)->qm_nrefs--) |
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c index d9d2993de435..90402a1c3983 100644 --- a/fs/xfs/quota/xfs_qm_bhv.c +++ b/fs/xfs/quota/xfs_qm_bhv.c | |||
| @@ -363,7 +363,7 @@ xfs_qm_init(void) | |||
| 363 | KERN_INFO "SGI XFS Quota Management subsystem\n"; | 363 | KERN_INFO "SGI XFS Quota Management subsystem\n"; |
| 364 | 364 | ||
| 365 | printk(message); | 365 | printk(message); |
| 366 | mutex_init(&xfs_Gqm_lock, MUTEX_DEFAULT, "xfs_qmlock"); | 366 | mutex_init(&xfs_Gqm_lock); |
| 367 | vfs_bhv_set_custom(&xfs_qmops, &xfs_qmcore_xfs); | 367 | vfs_bhv_set_custom(&xfs_qmops, &xfs_qmcore_xfs); |
| 368 | xfs_qm_init_procfs(); | 368 | xfs_qm_init_procfs(); |
| 369 | } | 369 | } |
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c index 24690e1af659..86a1d09f48d5 100644 --- a/fs/xfs/quota/xfs_qm_syscalls.c +++ b/fs/xfs/quota/xfs_qm_syscalls.c | |||
| @@ -233,7 +233,7 @@ xfs_qm_scall_quotaoff( | |||
| 233 | */ | 233 | */ |
| 234 | ASSERT(mp->m_quotainfo); | 234 | ASSERT(mp->m_quotainfo); |
| 235 | if (mp->m_quotainfo) | 235 | if (mp->m_quotainfo) |
| 236 | mutex_lock(&(XFS_QI_QOFFLOCK(mp)), PINOD); | 236 | mutex_lock(&(XFS_QI_QOFFLOCK(mp))); |
| 237 | 237 | ||
| 238 | ASSERT(mp->m_quotainfo); | 238 | ASSERT(mp->m_quotainfo); |
| 239 | 239 | ||
| @@ -508,7 +508,7 @@ xfs_qm_scall_quotaon( | |||
| 508 | /* | 508 | /* |
| 509 | * Switch on quota enforcement in core. | 509 | * Switch on quota enforcement in core. |
| 510 | */ | 510 | */ |
| 511 | mutex_lock(&(XFS_QI_QOFFLOCK(mp)), PINOD); | 511 | mutex_lock(&(XFS_QI_QOFFLOCK(mp))); |
| 512 | mp->m_qflags |= (flags & XFS_ALL_QUOTA_ENFD); | 512 | mp->m_qflags |= (flags & XFS_ALL_QUOTA_ENFD); |
| 513 | mutex_unlock(&(XFS_QI_QOFFLOCK(mp))); | 513 | mutex_unlock(&(XFS_QI_QOFFLOCK(mp))); |
| 514 | 514 | ||
| @@ -617,7 +617,7 @@ xfs_qm_scall_setqlim( | |||
| 617 | * a quotaoff from happening). (XXXThis doesn't currently happen | 617 | * a quotaoff from happening). (XXXThis doesn't currently happen |
| 618 | * because we take the vfslock before calling xfs_qm_sysent). | 618 | * because we take the vfslock before calling xfs_qm_sysent). |
| 619 | */ | 619 | */ |
| 620 | mutex_lock(&(XFS_QI_QOFFLOCK(mp)), PINOD); | 620 | mutex_lock(&(XFS_QI_QOFFLOCK(mp))); |
| 621 | 621 | ||
| 622 | /* | 622 | /* |
| 623 | * Get the dquot (locked), and join it to the transaction. | 623 | * Get the dquot (locked), and join it to the transaction. |
| @@ -1426,7 +1426,7 @@ xfs_qm_internalqcheck( | |||
| 1426 | xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE | XFS_LOG_SYNC); | 1426 | xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE | XFS_LOG_SYNC); |
| 1427 | XFS_bflush(mp->m_ddev_targp); | 1427 | XFS_bflush(mp->m_ddev_targp); |
| 1428 | 1428 | ||
| 1429 | mutex_lock(&qcheck_lock, PINOD); | 1429 | mutex_lock(&qcheck_lock); |
| 1430 | /* There should be absolutely no quota activity while this | 1430 | /* There should be absolutely no quota activity while this |
| 1431 | is going on. */ | 1431 | is going on. */ |
| 1432 | qmtest_udqtab = kmem_zalloc(qmtest_hashmask * | 1432 | qmtest_udqtab = kmem_zalloc(qmtest_hashmask * |
diff --git a/fs/xfs/quota/xfs_quota_priv.h b/fs/xfs/quota/xfs_quota_priv.h index 7a9f3beb818c..b7ddd04aae32 100644 --- a/fs/xfs/quota/xfs_quota_priv.h +++ b/fs/xfs/quota/xfs_quota_priv.h | |||
| @@ -51,7 +51,7 @@ | |||
| 51 | #define XFS_QI_MPLNEXT(mp) ((mp)->m_quotainfo->qi_dqlist.qh_next) | 51 | #define XFS_QI_MPLNEXT(mp) ((mp)->m_quotainfo->qi_dqlist.qh_next) |
| 52 | #define XFS_QI_MPLNDQUOTS(mp) ((mp)->m_quotainfo->qi_dqlist.qh_nelems) | 52 | #define XFS_QI_MPLNDQUOTS(mp) ((mp)->m_quotainfo->qi_dqlist.qh_nelems) |
| 53 | 53 | ||
| 54 | #define XQMLCK(h) (mutex_lock(&((h)->qh_lock), PINOD)) | 54 | #define XQMLCK(h) (mutex_lock(&((h)->qh_lock))) |
| 55 | #define XQMUNLCK(h) (mutex_unlock(&((h)->qh_lock))) | 55 | #define XQMUNLCK(h) (mutex_unlock(&((h)->qh_lock))) |
| 56 | #ifdef DEBUG | 56 | #ifdef DEBUG |
| 57 | struct xfs_dqhash; | 57 | struct xfs_dqhash; |
diff --git a/fs/xfs/support/uuid.c b/fs/xfs/support/uuid.c index 70ce40914c8a..69ec4f540c3a 100644 --- a/fs/xfs/support/uuid.c +++ b/fs/xfs/support/uuid.c | |||
| @@ -24,7 +24,7 @@ static uuid_t *uuid_table; | |||
| 24 | void | 24 | void |
| 25 | uuid_init(void) | 25 | uuid_init(void) |
| 26 | { | 26 | { |
| 27 | mutex_init(&uuid_monitor, MUTEX_DEFAULT, "uuid_monitor"); | 27 | mutex_init(&uuid_monitor); |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | /* | 30 | /* |
| @@ -94,7 +94,7 @@ uuid_table_insert(uuid_t *uuid) | |||
| 94 | { | 94 | { |
| 95 | int i, hole; | 95 | int i, hole; |
| 96 | 96 | ||
| 97 | mutex_lock(&uuid_monitor, PVFS); | 97 | mutex_lock(&uuid_monitor); |
| 98 | for (i = 0, hole = -1; i < uuid_table_size; i++) { | 98 | for (i = 0, hole = -1; i < uuid_table_size; i++) { |
| 99 | if (uuid_is_nil(&uuid_table[i])) { | 99 | if (uuid_is_nil(&uuid_table[i])) { |
| 100 | hole = i; | 100 | hole = i; |
| @@ -122,7 +122,7 @@ uuid_table_remove(uuid_t *uuid) | |||
| 122 | { | 122 | { |
| 123 | int i; | 123 | int i; |
| 124 | 124 | ||
| 125 | mutex_lock(&uuid_monitor, PVFS); | 125 | mutex_lock(&uuid_monitor); |
| 126 | for (i = 0; i < uuid_table_size; i++) { | 126 | for (i = 0; i < uuid_table_size; i++) { |
| 127 | if (uuid_is_nil(&uuid_table[i])) | 127 | if (uuid_is_nil(&uuid_table[i])) |
| 128 | continue; | 128 | continue; |
diff --git a/fs/xfs/xfs_dmapi.h b/fs/xfs/xfs_dmapi.h index 864bf6955689..b4c7f2bc55a0 100644 --- a/fs/xfs/xfs_dmapi.h +++ b/fs/xfs/xfs_dmapi.h | |||
| @@ -152,7 +152,7 @@ typedef enum { | |||
| 152 | 152 | ||
| 153 | #define DM_FLAGS_NDELAY 0x001 /* return EAGAIN after dm_pending() */ | 153 | #define DM_FLAGS_NDELAY 0x001 /* return EAGAIN after dm_pending() */ |
| 154 | #define DM_FLAGS_UNWANTED 0x002 /* event not in fsys dm_eventset_t */ | 154 | #define DM_FLAGS_UNWANTED 0x002 /* event not in fsys dm_eventset_t */ |
| 155 | #define DM_FLAGS_ISEM 0x004 /* thread holds i_sem */ | 155 | #define DM_FLAGS_IMUX 0x004 /* thread holds i_mutex */ |
| 156 | #define DM_FLAGS_IALLOCSEM_RD 0x010 /* thread holds i_alloc_sem rd */ | 156 | #define DM_FLAGS_IALLOCSEM_RD 0x010 /* thread holds i_alloc_sem rd */ |
| 157 | #define DM_FLAGS_IALLOCSEM_WR 0x020 /* thread holds i_alloc_sem wr */ | 157 | #define DM_FLAGS_IALLOCSEM_WR 0x020 /* thread holds i_alloc_sem wr */ |
| 158 | 158 | ||
| @@ -161,21 +161,21 @@ typedef enum { | |||
| 161 | */ | 161 | */ |
| 162 | #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) | 162 | #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) |
| 163 | #define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \ | 163 | #define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \ |
| 164 | DM_FLAGS_ISEM : 0) | 164 | DM_FLAGS_IMUX : 0) |
| 165 | #define DM_SEM_FLAG_WR (DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_ISEM) | 165 | #define DM_SEM_FLAG_WR (DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_IMUX) |
| 166 | #endif | 166 | #endif |
| 167 | 167 | ||
| 168 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) && \ | 168 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) && \ |
| 169 | (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)) | 169 | (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)) |
| 170 | #define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \ | 170 | #define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \ |
| 171 | DM_FLAGS_IALLOCSEM_RD : DM_FLAGS_ISEM) | 171 | DM_FLAGS_IALLOCSEM_RD : DM_FLAGS_IMUX) |
| 172 | #define DM_SEM_FLAG_WR (DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_ISEM) | 172 | #define DM_SEM_FLAG_WR (DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_IMUX) |
| 173 | #endif | 173 | #endif |
| 174 | 174 | ||
| 175 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,21) | 175 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,21) |
| 176 | #define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \ | 176 | #define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \ |
| 177 | 0 : DM_FLAGS_ISEM) | 177 | 0 : DM_FLAGS_IMUX) |
| 178 | #define DM_SEM_FLAG_WR (DM_FLAGS_ISEM) | 178 | #define DM_SEM_FLAG_WR (DM_FLAGS_IMUX) |
| 179 | #endif | 179 | #endif |
| 180 | 180 | ||
| 181 | 181 | ||
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 541d5dd474be..303af86739bf 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
| @@ -117,7 +117,7 @@ xfs_mount_init(void) | |||
| 117 | 117 | ||
| 118 | AIL_LOCKINIT(&mp->m_ail_lock, "xfs_ail"); | 118 | AIL_LOCKINIT(&mp->m_ail_lock, "xfs_ail"); |
| 119 | spinlock_init(&mp->m_sb_lock, "xfs_sb"); | 119 | spinlock_init(&mp->m_sb_lock, "xfs_sb"); |
| 120 | mutex_init(&mp->m_ilock, MUTEX_DEFAULT, "xfs_ilock"); | 120 | mutex_init(&mp->m_ilock); |
| 121 | initnsema(&mp->m_growlock, 1, "xfs_grow"); | 121 | initnsema(&mp->m_growlock, 1, "xfs_grow"); |
| 122 | /* | 122 | /* |
| 123 | * Initialize the AIL. | 123 | * Initialize the AIL. |
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 08b2e0a5d807..3432fd5a3986 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h | |||
| @@ -533,7 +533,7 @@ typedef struct xfs_mod_sb { | |||
| 533 | int msb_delta; /* Change to make to specified field */ | 533 | int msb_delta; /* Change to make to specified field */ |
| 534 | } xfs_mod_sb_t; | 534 | } xfs_mod_sb_t; |
| 535 | 535 | ||
| 536 | #define XFS_MOUNT_ILOCK(mp) mutex_lock(&((mp)->m_ilock), PINOD) | 536 | #define XFS_MOUNT_ILOCK(mp) mutex_lock(&((mp)->m_ilock)) |
| 537 | #define XFS_MOUNT_IUNLOCK(mp) mutex_unlock(&((mp)->m_ilock)) | 537 | #define XFS_MOUNT_IUNLOCK(mp) mutex_unlock(&((mp)->m_ilock)) |
| 538 | #define XFS_SB_LOCK(mp) mutex_spinlock(&(mp)->m_sb_lock) | 538 | #define XFS_SB_LOCK(mp) mutex_spinlock(&(mp)->m_sb_lock) |
| 539 | #define XFS_SB_UNLOCK(mp,s) mutex_spinunlock(&(mp)->m_sb_lock,(s)) | 539 | #define XFS_SB_UNLOCK(mp,s) mutex_spinunlock(&(mp)->m_sb_lock,(s)) |
diff --git a/include/asm-alpha/atomic.h b/include/asm-alpha/atomic.h index cb03bbe92cdf..fc77f7413083 100644 --- a/include/asm-alpha/atomic.h +++ b/include/asm-alpha/atomic.h | |||
| @@ -176,6 +176,7 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v) | |||
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) | 178 | #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) |
| 179 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | ||
| 179 | 180 | ||
| 180 | #define atomic_add_unless(v, a, u) \ | 181 | #define atomic_add_unless(v, a, u) \ |
| 181 | ({ \ | 182 | ({ \ |
diff --git a/include/asm-alpha/mutex.h b/include/asm-alpha/mutex.h new file mode 100644 index 000000000000..458c1f7fbc18 --- /dev/null +++ b/include/asm-alpha/mutex.h | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | /* | ||
| 2 | * Pull in the generic implementation for the mutex fastpath. | ||
| 3 | * | ||
| 4 | * TODO: implement optimized primitives instead, or leave the generic | ||
| 5 | * implementation in place, or pick the atomic_xchg() based generic | ||
| 6 | * implementation. (see asm-generic/mutex-xchg.h for details) | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <asm-generic/mutex-dec.h> | ||
diff --git a/include/asm-arm/atomic.h b/include/asm-arm/atomic.h index f72b63309bc5..3d7283d84405 100644 --- a/include/asm-arm/atomic.h +++ b/include/asm-arm/atomic.h | |||
| @@ -175,6 +175,8 @@ static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr) | |||
| 175 | 175 | ||
| 176 | #endif /* __LINUX_ARM_ARCH__ */ | 176 | #endif /* __LINUX_ARM_ARCH__ */ |
| 177 | 177 | ||
| 178 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | ||
| 179 | |||
| 178 | static inline int atomic_add_unless(atomic_t *v, int a, int u) | 180 | static inline int atomic_add_unless(atomic_t *v, int a, int u) |
| 179 | { | 181 | { |
| 180 | int c, old; | 182 | int c, old; |
diff --git a/include/asm-arm/mutex.h b/include/asm-arm/mutex.h new file mode 100644 index 000000000000..6caa59f1f595 --- /dev/null +++ b/include/asm-arm/mutex.h | |||
| @@ -0,0 +1,128 @@ | |||
| 1 | /* | ||
| 2 | * include/asm-arm/mutex.h | ||
| 3 | * | ||
| 4 | * ARM optimized mutex locking primitives | ||
| 5 | * | ||
| 6 | * Please look into asm-generic/mutex-xchg.h for a formal definition. | ||
| 7 | */ | ||
| 8 | #ifndef _ASM_MUTEX_H | ||
| 9 | #define _ASM_MUTEX_H | ||
| 10 | |||
| 11 | #if __LINUX_ARM_ARCH__ < 6 | ||
| 12 | /* On pre-ARMv6 hardware the swp based implementation is the most efficient. */ | ||
| 13 | # include <asm-generic/mutex-xchg.h> | ||
| 14 | #else | ||
| 15 | |||
| 16 | /* | ||
| 17 | * Attempting to lock a mutex on ARMv6+ can be done with a bastardized | ||
| 18 | * atomic decrement (it is not a reliable atomic decrement but it satisfies | ||
| 19 | * the defined semantics for our purpose, while being smaller and faster | ||
| 20 | * than a real atomic decrement or atomic swap. The idea is to attempt | ||
| 21 | * decrementing the lock value only once. If once decremented it isn't zero, | ||
| 22 | * or if its store-back fails due to a dispute on the exclusive store, we | ||
| 23 | * simply bail out immediately through the slow path where the lock will be | ||
| 24 | * reattempted until it succeeds. | ||
| 25 | */ | ||
| 26 | #define __mutex_fastpath_lock(count, fail_fn) \ | ||
| 27 | do { \ | ||
| 28 | int __ex_flag, __res; \ | ||
| 29 | \ | ||
| 30 | typecheck(atomic_t *, count); \ | ||
| 31 | typecheck_fn(fastcall void (*)(atomic_t *), fail_fn); \ | ||
| 32 | \ | ||
| 33 | __asm__ ( \ | ||
| 34 | "ldrex %0, [%2] \n" \ | ||
| 35 | "sub %0, %0, #1 \n" \ | ||
| 36 | "strex %1, %0, [%2] \n" \ | ||
| 37 | \ | ||
| 38 | : "=&r" (__res), "=&r" (__ex_flag) \ | ||
| 39 | : "r" (&(count)->counter) \ | ||
| 40 | : "cc","memory" ); \ | ||
| 41 | \ | ||
| 42 | if (unlikely(__res || __ex_flag)) \ | ||
| 43 | fail_fn(count); \ | ||
| 44 | } while (0) | ||
| 45 | |||
| 46 | #define __mutex_fastpath_lock_retval(count, fail_fn) \ | ||
| 47 | ({ \ | ||
| 48 | int __ex_flag, __res; \ | ||
| 49 | \ | ||
| 50 | typecheck(atomic_t *, count); \ | ||
| 51 | typecheck_fn(fastcall int (*)(atomic_t *), fail_fn); \ | ||
| 52 | \ | ||
| 53 | __asm__ ( \ | ||
| 54 | "ldrex %0, [%2] \n" \ | ||
| 55 | "sub %0, %0, #1 \n" \ | ||
| 56 | "strex %1, %0, [%2] \n" \ | ||
| 57 | \ | ||
| 58 | : "=&r" (__res), "=&r" (__ex_flag) \ | ||
| 59 | : "r" (&(count)->counter) \ | ||
| 60 | : "cc","memory" ); \ | ||
| 61 | \ | ||
| 62 | __res |= __ex_flag; \ | ||
| 63 | if (unlikely(__res != 0)) \ | ||
| 64 | __res = fail_fn(count); \ | ||
| 65 | __res; \ | ||
| 66 | }) | ||
| 67 | |||
| 68 | /* | ||
| 69 | * Same trick is used for the unlock fast path. However the original value, | ||
| 70 | * rather than the result, is used to test for success in order to have | ||
| 71 | * better generated assembly. | ||
| 72 | */ | ||
| 73 | #define __mutex_fastpath_unlock(count, fail_fn) \ | ||
| 74 | do { \ | ||
| 75 | int __ex_flag, __res, __orig; \ | ||
| 76 | \ | ||
| 77 | typecheck(atomic_t *, count); \ | ||
| 78 | typecheck_fn(fastcall void (*)(atomic_t *), fail_fn); \ | ||
| 79 | \ | ||
| 80 | __asm__ ( \ | ||
| 81 | "ldrex %0, [%3] \n" \ | ||
| 82 | "add %1, %0, #1 \n" \ | ||
| 83 | "strex %2, %1, [%3] \n" \ | ||
| 84 | \ | ||
| 85 | : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag) \ | ||
| 86 | : "r" (&(count)->counter) \ | ||
| 87 | : "cc","memory" ); \ | ||
| 88 | \ | ||
| 89 | if (unlikely(__orig || __ex_flag)) \ | ||
| 90 | fail_fn(count); \ | ||
| 91 | } while (0) | ||
| 92 | |||
| 93 | /* | ||
| 94 | * If the unlock was done on a contended lock, or if the unlock simply fails | ||
| 95 | * then the mutex remains locked. | ||
| 96 | */ | ||
| 97 | #define __mutex_slowpath_needs_to_unlock() 1 | ||
| 98 | |||
| 99 | /* | ||
| 100 | * For __mutex_fastpath_trylock we use another construct which could be | ||
| 101 | * described as a "single value cmpxchg". | ||
| 102 | * | ||
| 103 | * This provides the needed trylock semantics like cmpxchg would, but it is | ||
| 104 | * lighter and less generic than a true cmpxchg implementation. | ||
| 105 | */ | ||
| 106 | static inline int | ||
| 107 | __mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *)) | ||
| 108 | { | ||
| 109 | int __ex_flag, __res, __orig; | ||
| 110 | |||
| 111 | __asm__ ( | ||
| 112 | |||
| 113 | "1: ldrex %0, [%3] \n" | ||
| 114 | "subs %1, %0, #1 \n" | ||
| 115 | "strexeq %2, %1, [%3] \n" | ||
| 116 | "movlt %0, #0 \n" | ||
| 117 | "cmpeq %2, #0 \n" | ||
| 118 | "bgt 1b \n" | ||
| 119 | |||
| 120 | : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag) | ||
| 121 | : "r" (&count->counter) | ||
| 122 | : "cc", "memory" ); | ||
| 123 | |||
| 124 | return __orig; | ||
| 125 | } | ||
| 126 | |||
| 127 | #endif | ||
| 128 | #endif | ||
diff --git a/include/asm-arm26/atomic.h b/include/asm-arm26/atomic.h index 3074b0e76343..1552c8653990 100644 --- a/include/asm-arm26/atomic.h +++ b/include/asm-arm26/atomic.h | |||
| @@ -76,6 +76,8 @@ static inline int atomic_cmpxchg(atomic_t *v, int old, int new) | |||
| 76 | return ret; | 76 | return ret; |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | ||
| 80 | |||
| 79 | static inline int atomic_add_unless(atomic_t *v, int a, int u) | 81 | static inline int atomic_add_unless(atomic_t *v, int a, int u) |
| 80 | { | 82 | { |
| 81 | int ret; | 83 | int ret; |
diff --git a/include/asm-cris/atomic.h b/include/asm-cris/atomic.h index 2df2c7aa19b7..0b51a87e5532 100644 --- a/include/asm-cris/atomic.h +++ b/include/asm-cris/atomic.h | |||
| @@ -136,6 +136,8 @@ static inline int atomic_cmpxchg(atomic_t *v, int old, int new) | |||
| 136 | return ret; | 136 | return ret; |
| 137 | } | 137 | } |
| 138 | 138 | ||
| 139 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | ||
| 140 | |||
| 139 | static inline int atomic_add_unless(atomic_t *v, int a, int u) | 141 | static inline int atomic_add_unless(atomic_t *v, int a, int u) |
| 140 | { | 142 | { |
| 141 | int ret; | 143 | int ret; |
diff --git a/include/asm-cris/mutex.h b/include/asm-cris/mutex.h new file mode 100644 index 000000000000..458c1f7fbc18 --- /dev/null +++ b/include/asm-cris/mutex.h | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | /* | ||
| 2 | * Pull in the generic implementation for the mutex fastpath. | ||
| 3 | * | ||
| 4 | * TODO: implement optimized primitives instead, or leave the generic | ||
| 5 | * implementation in place, or pick the atomic_xchg() based generic | ||
| 6 | * implementation. (see asm-generic/mutex-xchg.h for details) | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <asm-generic/mutex-dec.h> | ||
diff --git a/include/asm-frv/atomic.h b/include/asm-frv/atomic.h index 9c9e9499cfd8..a59f684b4f33 100644 --- a/include/asm-frv/atomic.h +++ b/include/asm-frv/atomic.h | |||
| @@ -328,6 +328,7 @@ extern uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new); | |||
| 328 | #endif | 328 | #endif |
| 329 | 329 | ||
| 330 | #define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new)) | 330 | #define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new)) |
| 331 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | ||
| 331 | 332 | ||
| 332 | #define atomic_add_unless(v, a, u) \ | 333 | #define atomic_add_unless(v, a, u) \ |
| 333 | ({ \ | 334 | ({ \ |
diff --git a/include/asm-frv/mutex.h b/include/asm-frv/mutex.h new file mode 100644 index 000000000000..458c1f7fbc18 --- /dev/null +++ b/include/asm-frv/mutex.h | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | /* | ||
| 2 | * Pull in the generic implementation for the mutex fastpath. | ||
| 3 | * | ||
| 4 | * TODO: implement optimized primitives instead, or leave the generic | ||
| 5 | * implementation in place, or pick the atomic_xchg() based generic | ||
| 6 | * implementation. (see asm-generic/mutex-xchg.h for details) | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <asm-generic/mutex-dec.h> | ||
diff --git a/include/asm-generic/mutex-dec.h b/include/asm-generic/mutex-dec.h new file mode 100644 index 000000000000..74b18cda169f --- /dev/null +++ b/include/asm-generic/mutex-dec.h | |||
| @@ -0,0 +1,110 @@ | |||
| 1 | /* | ||
| 2 | * asm-generic/mutex-dec.h | ||
| 3 | * | ||
| 4 | * Generic implementation of the mutex fastpath, based on atomic | ||
| 5 | * decrement/increment. | ||
| 6 | */ | ||
| 7 | #ifndef _ASM_GENERIC_MUTEX_DEC_H | ||
| 8 | #define _ASM_GENERIC_MUTEX_DEC_H | ||
| 9 | |||
| 10 | /** | ||
| 11 | * __mutex_fastpath_lock - try to take the lock by moving the count | ||
| 12 | * from 1 to a 0 value | ||
| 13 | * @count: pointer of type atomic_t | ||
| 14 | * @fail_fn: function to call if the original value was not 1 | ||
| 15 | * | ||
| 16 | * Change the count from 1 to a value lower than 1, and call <fail_fn> if | ||
| 17 | * it wasn't 1 originally. This function MUST leave the value lower than | ||
| 18 | * 1 even when the "1" assertion wasn't true. | ||
| 19 | */ | ||
| 20 | #define __mutex_fastpath_lock(count, fail_fn) \ | ||
| 21 | do { \ | ||
| 22 | if (unlikely(atomic_dec_return(count) < 0)) \ | ||
| 23 | fail_fn(count); \ | ||
| 24 | else \ | ||
| 25 | smp_mb(); \ | ||
| 26 | } while (0) | ||
| 27 | |||
| 28 | /** | ||
| 29 | * __mutex_fastpath_lock_retval - try to take the lock by moving the count | ||
| 30 | * from 1 to a 0 value | ||
| 31 | * @count: pointer of type atomic_t | ||
| 32 | * @fail_fn: function to call if the original value was not 1 | ||
| 33 | * | ||
| 34 | * Change the count from 1 to a value lower than 1, and call <fail_fn> if | ||
| 35 | * it wasn't 1 originally. This function returns 0 if the fastpath succeeds, | ||
| 36 | * or anything the slow path function returns. | ||
| 37 | */ | ||
| 38 | static inline int | ||
| 39 | __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *)) | ||
| 40 | { | ||
| 41 | if (unlikely(atomic_dec_return(count) < 0)) | ||
| 42 | return fail_fn(count); | ||
| 43 | else { | ||
| 44 | smp_mb(); | ||
| 45 | return 0; | ||
| 46 | } | ||
| 47 | } | ||
| 48 | |||
| 49 | /** | ||
| 50 | * __mutex_fastpath_unlock - try to promote the count from 0 to 1 | ||
| 51 | * @count: pointer of type atomic_t | ||
| 52 | * @fail_fn: function to call if the original value was not 0 | ||
| 53 | * | ||
| 54 | * Try to promote the count from 0 to 1. If it wasn't 0, call <fail_fn>. | ||
| 55 | * In the failure case, this function is allowed to either set the value to | ||
| 56 | * 1, or to set it to a value lower than 1. | ||
| 57 | * | ||
| 58 | * If the implementation sets it to a value of lower than 1, then the | ||
| 59 | * __mutex_slowpath_needs_to_unlock() macro needs to return 1, it needs | ||
| 60 | * to return 0 otherwise. | ||
| 61 | */ | ||
| 62 | #define __mutex_fastpath_unlock(count, fail_fn) \ | ||
| 63 | do { \ | ||
| 64 | smp_mb(); \ | ||
| 65 | if (unlikely(atomic_inc_return(count) <= 0)) \ | ||
| 66 | fail_fn(count); \ | ||
| 67 | } while (0) | ||
| 68 | |||
| 69 | #define __mutex_slowpath_needs_to_unlock() 1 | ||
| 70 | |||
| 71 | /** | ||
| 72 | * __mutex_fastpath_trylock - try to acquire the mutex, without waiting | ||
| 73 | * | ||
| 74 | * @count: pointer of type atomic_t | ||
| 75 | * @fail_fn: fallback function | ||
| 76 | * | ||
| 77 | * Change the count from 1 to a value lower than 1, and return 0 (failure) | ||
| 78 | * if it wasn't 1 originally, or return 1 (success) otherwise. This function | ||
| 79 | * MUST leave the value lower than 1 even when the "1" assertion wasn't true. | ||
| 80 | * Additionally, if the value was < 0 originally, this function must not leave | ||
| 81 | * it to 0 on failure. | ||
| 82 | * | ||
| 83 | * If the architecture has no effective trylock variant, it should call the | ||
| 84 | * <fail_fn> spinlock-based trylock variant unconditionally. | ||
| 85 | */ | ||
| 86 | static inline int | ||
| 87 | __mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *)) | ||
| 88 | { | ||
| 89 | /* | ||
| 90 | * We have two variants here. The cmpxchg based one is the best one | ||
| 91 | * because it never induce a false contention state. It is included | ||
| 92 | * here because architectures using the inc/dec algorithms over the | ||
| 93 | * xchg ones are much more likely to support cmpxchg natively. | ||
| 94 | * | ||
| 95 | * If not we fall back to the spinlock based variant - that is | ||
| 96 | * just as efficient (and simpler) as a 'destructive' probing of | ||
| 97 | * the mutex state would be. | ||
| 98 | */ | ||
| 99 | #ifdef __HAVE_ARCH_CMPXCHG | ||
| 100 | if (likely(atomic_cmpxchg(count, 1, 0)) == 1) { | ||
| 101 | smp_mb(); | ||
| 102 | return 1; | ||
| 103 | } | ||
| 104 | return 0; | ||
| 105 | #else | ||
| 106 | return fail_fn(count); | ||
| 107 | #endif | ||
| 108 | } | ||
| 109 | |||
| 110 | #endif | ||
diff --git a/include/asm-generic/mutex-null.h b/include/asm-generic/mutex-null.h new file mode 100644 index 000000000000..5cf8b7ce0c45 --- /dev/null +++ b/include/asm-generic/mutex-null.h | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | /* | ||
| 2 | * asm-generic/mutex-null.h | ||
| 3 | * | ||
| 4 | * Generic implementation of the mutex fastpath, based on NOP :-) | ||
| 5 | * | ||
| 6 | * This is used by the mutex-debugging infrastructure, but it can also | ||
| 7 | * be used by architectures that (for whatever reason) want to use the | ||
| 8 | * spinlock based slowpath. | ||
| 9 | */ | ||
| 10 | #ifndef _ASM_GENERIC_MUTEX_NULL_H | ||
| 11 | #define _ASM_GENERIC_MUTEX_NULL_H | ||
| 12 | |||
| 13 | /* extra parameter only needed for mutex debugging: */ | ||
| 14 | #ifndef __IP__ | ||
| 15 | # define __IP__ | ||
| 16 | #endif | ||
| 17 | |||
| 18 | #define __mutex_fastpath_lock(count, fail_fn) fail_fn(count __RET_IP__) | ||
| 19 | #define __mutex_fastpath_lock_retval(count, fail_fn) fail_fn(count __RET_IP__) | ||
| 20 | #define __mutex_fastpath_unlock(count, fail_fn) fail_fn(count __RET_IP__) | ||
| 21 | #define __mutex_fastpath_trylock(count, fail_fn) fail_fn(count) | ||
| 22 | #define __mutex_slowpath_needs_to_unlock() 1 | ||
| 23 | |||
| 24 | #endif | ||
diff --git a/include/asm-generic/mutex-xchg.h b/include/asm-generic/mutex-xchg.h new file mode 100644 index 000000000000..1d24f47e6c48 --- /dev/null +++ b/include/asm-generic/mutex-xchg.h | |||
| @@ -0,0 +1,117 @@ | |||
| 1 | /* | ||
| 2 | * asm-generic/mutex-xchg.h | ||
| 3 | * | ||
| 4 | * Generic implementation of the mutex fastpath, based on xchg(). | ||
| 5 | * | ||
| 6 | * NOTE: An xchg based implementation is less optimal than an atomic | ||
| 7 | * decrement/increment based implementation. If your architecture | ||
| 8 | * has a reasonable atomic dec/inc then you should probably use | ||
| 9 | * asm-generic/mutex-dec.h instead, or you could open-code an | ||
| 10 | * optimized version in asm/mutex.h. | ||
| 11 | */ | ||
| 12 | #ifndef _ASM_GENERIC_MUTEX_XCHG_H | ||
| 13 | #define _ASM_GENERIC_MUTEX_XCHG_H | ||
| 14 | |||
| 15 | /** | ||
| 16 | * __mutex_fastpath_lock - try to take the lock by moving the count | ||
| 17 | * from 1 to a 0 value | ||
| 18 | * @count: pointer of type atomic_t | ||
| 19 | * @fail_fn: function to call if the original value was not 1 | ||
| 20 | * | ||
| 21 | * Change the count from 1 to a value lower than 1, and call <fail_fn> if it | ||
| 22 | * wasn't 1 originally. This function MUST leave the value lower than 1 | ||
| 23 | * even when the "1" assertion wasn't true. | ||
| 24 | */ | ||
| 25 | #define __mutex_fastpath_lock(count, fail_fn) \ | ||
| 26 | do { \ | ||
| 27 | if (unlikely(atomic_xchg(count, 0) != 1)) \ | ||
| 28 | fail_fn(count); \ | ||
| 29 | else \ | ||
| 30 | smp_mb(); \ | ||
| 31 | } while (0) | ||
| 32 | |||
| 33 | |||
| 34 | /** | ||
| 35 | * __mutex_fastpath_lock_retval - try to take the lock by moving the count | ||
| 36 | * from 1 to a 0 value | ||
| 37 | * @count: pointer of type atomic_t | ||
| 38 | * @fail_fn: function to call if the original value was not 1 | ||
| 39 | * | ||
| 40 | * Change the count from 1 to a value lower than 1, and call <fail_fn> if it | ||
| 41 | * wasn't 1 originally. This function returns 0 if the fastpath succeeds, | ||
| 42 | * or anything the slow path function returns | ||
| 43 | */ | ||
| 44 | static inline int | ||
| 45 | __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *)) | ||
| 46 | { | ||
| 47 | if (unlikely(atomic_xchg(count, 0) != 1)) | ||
| 48 | return fail_fn(count); | ||
| 49 | else { | ||
| 50 | smp_mb(); | ||
| 51 | return 0; | ||
| 52 | } | ||
| 53 | } | ||
| 54 | |||
| 55 | /** | ||
| 56 | * __mutex_fastpath_unlock - try to promote the mutex from 0 to 1 | ||
| 57 | * @count: pointer of type atomic_t | ||
| 58 | * @fail_fn: function to call if the original value was not 0 | ||
| 59 | * | ||
| 60 | * try to promote the mutex from 0 to 1. if it wasn't 0, call <function> | ||
| 61 | * In the failure case, this function is allowed to either set the value to | ||
| 62 | * 1, or to set it to a value lower than one. | ||
| 63 | * If the implementation sets it to a value of lower than one, the | ||
| 64 | * __mutex_slowpath_needs_to_unlock() macro needs to return 1, it needs | ||
| 65 | * to return 0 otherwise. | ||
| 66 | */ | ||
| 67 | #define __mutex_fastpath_unlock(count, fail_fn) \ | ||
| 68 | do { \ | ||
| 69 | smp_mb(); \ | ||
| 70 | if (unlikely(atomic_xchg(count, 1) != 0)) \ | ||
| 71 | fail_fn(count); \ | ||
| 72 | } while (0) | ||
| 73 | |||
| 74 | #define __mutex_slowpath_needs_to_unlock() 0 | ||
| 75 | |||
| 76 | /** | ||
| 77 | * __mutex_fastpath_trylock - try to acquire the mutex, without waiting | ||
| 78 | * | ||
| 79 | * @count: pointer of type atomic_t | ||
| 80 | * @fail_fn: spinlock based trylock implementation | ||
| 81 | * | ||
| 82 | * Change the count from 1 to a value lower than 1, and return 0 (failure) | ||
| 83 | * if it wasn't 1 originally, or return 1 (success) otherwise. This function | ||
| 84 | * MUST leave the value lower than 1 even when the "1" assertion wasn't true. | ||
| 85 | * Additionally, if the value was < 0 originally, this function must not leave | ||
| 86 | * it to 0 on failure. | ||
| 87 | * | ||
| 88 | * If the architecture has no effective trylock variant, it should call the | ||
| 89 | * <fail_fn> spinlock-based trylock variant unconditionally. | ||
| 90 | */ | ||
| 91 | static inline int | ||
| 92 | __mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *)) | ||
| 93 | { | ||
| 94 | int prev = atomic_xchg(count, 0); | ||
| 95 | |||
| 96 | if (unlikely(prev < 0)) { | ||
| 97 | /* | ||
| 98 | * The lock was marked contended so we must restore that | ||
| 99 | * state. If while doing so we get back a prev value of 1 | ||
| 100 | * then we just own it. | ||
| 101 | * | ||
| 102 | * [ In the rare case of the mutex going to 1, to 0, to -1 | ||
| 103 | * and then back to 0 in this few-instructions window, | ||
| 104 | * this has the potential to trigger the slowpath for the | ||
| 105 | * owner's unlock path needlessly, but that's not a problem | ||
| 106 | * in practice. ] | ||
| 107 | */ | ||
| 108 | prev = atomic_xchg(count, prev); | ||
| 109 | if (prev < 0) | ||
| 110 | prev = 0; | ||
| 111 | } | ||
| 112 | smp_mb(); | ||
| 113 | |||
| 114 | return prev; | ||
| 115 | } | ||
| 116 | |||
| 117 | #endif | ||
diff --git a/include/asm-h8300/atomic.h b/include/asm-h8300/atomic.h index d891541e89c3..21f54428c86b 100644 --- a/include/asm-h8300/atomic.h +++ b/include/asm-h8300/atomic.h | |||
| @@ -95,6 +95,8 @@ static inline int atomic_cmpxchg(atomic_t *v, int old, int new) | |||
| 95 | return ret; | 95 | return ret; |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | ||
| 99 | |||
| 98 | static inline int atomic_add_unless(atomic_t *v, int a, int u) | 100 | static inline int atomic_add_unless(atomic_t *v, int a, int u) |
| 99 | { | 101 | { |
| 100 | int ret; | 102 | int ret; |
diff --git a/include/asm-h8300/mutex.h b/include/asm-h8300/mutex.h new file mode 100644 index 000000000000..458c1f7fbc18 --- /dev/null +++ b/include/asm-h8300/mutex.h | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | /* | ||
| 2 | * Pull in the generic implementation for the mutex fastpath. | ||
| 3 | * | ||
| 4 | * TODO: implement optimized primitives instead, or leave the generic | ||
| 5 | * implementation in place, or pick the atomic_xchg() based generic | ||
| 6 | * implementation. (see asm-generic/mutex-xchg.h for details) | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <asm-generic/mutex-dec.h> | ||
diff --git a/include/asm-i386/atomic.h b/include/asm-i386/atomic.h index 7a5472d77091..de649d3aa2d4 100644 --- a/include/asm-i386/atomic.h +++ b/include/asm-i386/atomic.h | |||
| @@ -216,6 +216,7 @@ static __inline__ int atomic_sub_return(int i, atomic_t *v) | |||
| 216 | } | 216 | } |
| 217 | 217 | ||
| 218 | #define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new)) | 218 | #define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new)) |
| 219 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | ||
| 219 | 220 | ||
| 220 | /** | 221 | /** |
| 221 | * atomic_add_unless - add unless the number is a given value | 222 | * atomic_add_unless - add unless the number is a given value |
diff --git a/include/asm-i386/mutex.h b/include/asm-i386/mutex.h new file mode 100644 index 000000000000..4e5e3de1b9a6 --- /dev/null +++ b/include/asm-i386/mutex.h | |||
| @@ -0,0 +1,124 @@ | |||
| 1 | /* | ||
| 2 | * Assembly implementation of the mutex fastpath, based on atomic | ||
| 3 | * decrement/increment. | ||
| 4 | * | ||
| 5 | * started by Ingo Molnar: | ||
| 6 | * | ||
| 7 | * Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com> | ||
| 8 | */ | ||
| 9 | #ifndef _ASM_MUTEX_H | ||
| 10 | #define _ASM_MUTEX_H | ||
| 11 | |||
| 12 | /** | ||
| 13 | * __mutex_fastpath_lock - try to take the lock by moving the count | ||
| 14 | * from 1 to a 0 value | ||
| 15 | * @count: pointer of type atomic_t | ||
| 16 | * @fn: function to call if the original value was not 1 | ||
| 17 | * | ||
| 18 | * Change the count from 1 to a value lower than 1, and call <fn> if it | ||
| 19 | * wasn't 1 originally. This function MUST leave the value lower than 1 | ||
| 20 | * even when the "1" assertion wasn't true. | ||
| 21 | */ | ||
| 22 | #define __mutex_fastpath_lock(count, fail_fn) \ | ||
| 23 | do { \ | ||
| 24 | unsigned int dummy; \ | ||
| 25 | \ | ||
| 26 | typecheck(atomic_t *, count); \ | ||
| 27 | typecheck_fn(fastcall void (*)(atomic_t *), fail_fn); \ | ||
| 28 | \ | ||
| 29 | __asm__ __volatile__( \ | ||
| 30 | LOCK " decl (%%eax) \n" \ | ||
| 31 | " js "#fail_fn" \n" \ | ||
| 32 | \ | ||
| 33 | :"=a" (dummy) \ | ||
| 34 | : "a" (count) \ | ||
| 35 | : "memory", "ecx", "edx"); \ | ||
| 36 | } while (0) | ||
| 37 | |||
| 38 | |||
| 39 | /** | ||
| 40 | * __mutex_fastpath_lock_retval - try to take the lock by moving the count | ||
| 41 | * from 1 to a 0 value | ||
| 42 | * @count: pointer of type atomic_t | ||
| 43 | * @fail_fn: function to call if the original value was not 1 | ||
| 44 | * | ||
| 45 | * Change the count from 1 to a value lower than 1, and call <fail_fn> if it | ||
| 46 | * wasn't 1 originally. This function returns 0 if the fastpath succeeds, | ||
| 47 | * or anything the slow path function returns | ||
| 48 | */ | ||
| 49 | static inline int | ||
| 50 | __mutex_fastpath_lock_retval(atomic_t *count, | ||
| 51 | int fastcall (*fail_fn)(atomic_t *)) | ||
| 52 | { | ||
| 53 | if (unlikely(atomic_dec_return(count) < 0)) | ||
| 54 | return fail_fn(count); | ||
| 55 | else | ||
| 56 | return 0; | ||
| 57 | } | ||
| 58 | |||
| 59 | /** | ||
| 60 | * __mutex_fastpath_unlock - try to promote the mutex from 0 to 1 | ||
| 61 | * @count: pointer of type atomic_t | ||
| 62 | * @fail_fn: function to call if the original value was not 0 | ||
| 63 | * | ||
| 64 | * try to promote the mutex from 0 to 1. if it wasn't 0, call <fail_fn>. | ||
| 65 | * In the failure case, this function is allowed to either set the value | ||
| 66 | * to 1, or to set it to a value lower than 1. | ||
| 67 | * | ||
| 68 | * If the implementation sets it to a value of lower than 1, the | ||
| 69 | * __mutex_slowpath_needs_to_unlock() macro needs to return 1, it needs | ||
| 70 | * to return 0 otherwise. | ||
| 71 | */ | ||
| 72 | #define __mutex_fastpath_unlock(count, fail_fn) \ | ||
| 73 | do { \ | ||
| 74 | unsigned int dummy; \ | ||
| 75 | \ | ||
| 76 | typecheck(atomic_t *, count); \ | ||
| 77 | typecheck_fn(fastcall void (*)(atomic_t *), fail_fn); \ | ||
| 78 | \ | ||
| 79 | __asm__ __volatile__( \ | ||
| 80 | LOCK " incl (%%eax) \n" \ | ||
| 81 | " jle "#fail_fn" \n" \ | ||
| 82 | \ | ||
| 83 | :"=a" (dummy) \ | ||
| 84 | : "a" (count) \ | ||
| 85 | : "memory", "ecx", "edx"); \ | ||
| 86 | } while (0) | ||
| 87 | |||
| 88 | #define __mutex_slowpath_needs_to_unlock() 1 | ||
| 89 | |||
| 90 | /** | ||
| 91 | * __mutex_fastpath_trylock - try to acquire the mutex, without waiting | ||
| 92 | * | ||
| 93 | * @count: pointer of type atomic_t | ||
| 94 | * @fail_fn: fallback function | ||
| 95 | * | ||
| 96 | * Change the count from 1 to a value lower than 1, and return 0 (failure) | ||
| 97 | * if it wasn't 1 originally, or return 1 (success) otherwise. This function | ||
| 98 | * MUST leave the value lower than 1 even when the "1" assertion wasn't true. | ||
| 99 | * Additionally, if the value was < 0 originally, this function must not leave | ||
| 100 | * it to 0 on failure. | ||
| 101 | */ | ||
| 102 | static inline int | ||
| 103 | __mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *)) | ||
| 104 | { | ||
| 105 | /* | ||
| 106 | * We have two variants here. The cmpxchg based one is the best one | ||
| 107 | * because it never induce a false contention state. It is included | ||
| 108 | * here because architectures using the inc/dec algorithms over the | ||
| 109 | * xchg ones are much more likely to support cmpxchg natively. | ||
| 110 | * | ||
| 111 | * If not we fall back to the spinlock based variant - that is | ||
| 112 | * just as efficient (and simpler) as a 'destructive' probing of | ||
| 113 | * the mutex state would be. | ||
| 114 | */ | ||
| 115 | #ifdef __HAVE_ARCH_CMPXCHG | ||
| 116 | if (likely(atomic_cmpxchg(count, 1, 0)) == 1) | ||
| 117 | return 1; | ||
| 118 | return 0; | ||
| 119 | #else | ||
| 120 | return fail_fn(count); | ||
| 121 | #endif | ||
| 122 | } | ||
| 123 | |||
| 124 | #endif | ||
diff --git a/include/asm-ia64/atomic.h b/include/asm-ia64/atomic.h index 15cf7984c48e..d3e0dfa99e1f 100644 --- a/include/asm-ia64/atomic.h +++ b/include/asm-ia64/atomic.h | |||
| @@ -89,6 +89,7 @@ ia64_atomic64_sub (__s64 i, atomic64_t *v) | |||
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | #define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new)) | 91 | #define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new)) |
| 92 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | ||
| 92 | 93 | ||
| 93 | #define atomic_add_unless(v, a, u) \ | 94 | #define atomic_add_unless(v, a, u) \ |
| 94 | ({ \ | 95 | ({ \ |
diff --git a/include/asm-ia64/mutex.h b/include/asm-ia64/mutex.h new file mode 100644 index 000000000000..458c1f7fbc18 --- /dev/null +++ b/include/asm-ia64/mutex.h | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | /* | ||
| 2 | * Pull in the generic implementation for the mutex fastpath. | ||
| 3 | * | ||
| 4 | * TODO: implement optimized primitives instead, or leave the generic | ||
| 5 | * implementation in place, or pick the atomic_xchg() based generic | ||
| 6 | * implementation. (see asm-generic/mutex-xchg.h for details) | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <asm-generic/mutex-dec.h> | ||
diff --git a/include/asm-m32r/atomic.h b/include/asm-m32r/atomic.h index 70761278b6cb..3122fe106f05 100644 --- a/include/asm-m32r/atomic.h +++ b/include/asm-m32r/atomic.h | |||
| @@ -243,6 +243,7 @@ static __inline__ int atomic_dec_return(atomic_t *v) | |||
| 243 | #define atomic_add_negative(i,v) (atomic_add_return((i), (v)) < 0) | 243 | #define atomic_add_negative(i,v) (atomic_add_return((i), (v)) < 0) |
| 244 | 244 | ||
| 245 | #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) | 245 | #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) |
| 246 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | ||
| 246 | 247 | ||
| 247 | /** | 248 | /** |
| 248 | * atomic_add_unless - add unless the number is a given value | 249 | * atomic_add_unless - add unless the number is a given value |
diff --git a/include/asm-m32r/mutex.h b/include/asm-m32r/mutex.h new file mode 100644 index 000000000000..458c1f7fbc18 --- /dev/null +++ b/include/asm-m32r/mutex.h | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | /* | ||
| 2 | * Pull in the generic implementation for the mutex fastpath. | ||
| 3 | * | ||
| 4 | * TODO: implement optimized primitives instead, or leave the generic | ||
| 5 | * implementation in place, or pick the atomic_xchg() based generic | ||
| 6 | * implementation. (see asm-generic/mutex-xchg.h for details) | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <asm-generic/mutex-dec.h> | ||
diff --git a/include/asm-m68k/atomic.h b/include/asm-m68k/atomic.h index b8a4e75d679d..a4a84d5c65d5 100644 --- a/include/asm-m68k/atomic.h +++ b/include/asm-m68k/atomic.h | |||
| @@ -140,6 +140,7 @@ static inline void atomic_set_mask(unsigned long mask, unsigned long *v) | |||
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) | 142 | #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) |
| 143 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | ||
| 143 | 144 | ||
| 144 | #define atomic_add_unless(v, a, u) \ | 145 | #define atomic_add_unless(v, a, u) \ |
| 145 | ({ \ | 146 | ({ \ |
diff --git a/include/asm-m68k/mutex.h b/include/asm-m68k/mutex.h new file mode 100644 index 000000000000..458c1f7fbc18 --- /dev/null +++ b/include/asm-m68k/mutex.h | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | /* | ||
| 2 | * Pull in the generic implementation for the mutex fastpath. | ||
| 3 | * | ||
| 4 | * TODO: implement optimized primitives instead, or leave the generic | ||
| 5 | * implementation in place, or pick the atomic_xchg() based generic | ||
| 6 | * implementation. (see asm-generic/mutex-xchg.h for details) | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <asm-generic/mutex-dec.h> | ||
diff --git a/include/asm-m68knommu/atomic.h b/include/asm-m68knommu/atomic.h index 1702dbe9318c..6c4e4b63e454 100644 --- a/include/asm-m68knommu/atomic.h +++ b/include/asm-m68knommu/atomic.h | |||
| @@ -129,6 +129,7 @@ static inline int atomic_sub_return(int i, atomic_t * v) | |||
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) | 131 | #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) |
| 132 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | ||
| 132 | 133 | ||
| 133 | #define atomic_add_unless(v, a, u) \ | 134 | #define atomic_add_unless(v, a, u) \ |
| 134 | ({ \ | 135 | ({ \ |
diff --git a/include/asm-m68knommu/mutex.h b/include/asm-m68knommu/mutex.h new file mode 100644 index 000000000000..458c1f7fbc18 --- /dev/null +++ b/include/asm-m68knommu/mutex.h | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | /* | ||
| 2 | * Pull in the generic implementation for the mutex fastpath. | ||
| 3 | * | ||
| 4 | * TODO: implement optimized primitives instead, or leave the generic | ||
| 5 | * implementation in place, or pick the atomic_xchg() based generic | ||
| 6 | * implementation. (see asm-generic/mutex-xchg.h for details) | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <asm-generic/mutex-dec.h> | ||
diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h index 92256e43a938..94a95872d727 100644 --- a/include/asm-mips/atomic.h +++ b/include/asm-mips/atomic.h | |||
| @@ -289,6 +289,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) | |||
| 289 | } | 289 | } |
| 290 | 290 | ||
| 291 | #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) | 291 | #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) |
| 292 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | ||
| 292 | 293 | ||
| 293 | /** | 294 | /** |
| 294 | * atomic_add_unless - add unless the number is a given value | 295 | * atomic_add_unless - add unless the number is a given value |
diff --git a/include/asm-mips/mutex.h b/include/asm-mips/mutex.h new file mode 100644 index 000000000000..458c1f7fbc18 --- /dev/null +++ b/include/asm-mips/mutex.h | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | /* | ||
| 2 | * Pull in the generic implementation for the mutex fastpath. | ||
| 3 | * | ||
| 4 | * TODO: implement optimized primitives instead, or leave the generic | ||
| 5 | * implementation in place, or pick the atomic_xchg() based generic | ||
| 6 | * implementation. (see asm-generic/mutex-xchg.h for details) | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <asm-generic/mutex-dec.h> | ||
diff --git a/include/asm-parisc/atomic.h b/include/asm-parisc/atomic.h index 64ebd086c40d..2ca56d34aaad 100644 --- a/include/asm-parisc/atomic.h +++ b/include/asm-parisc/atomic.h | |||
| @@ -165,6 +165,7 @@ static __inline__ int atomic_read(const atomic_t *v) | |||
| 165 | 165 | ||
| 166 | /* exported interface */ | 166 | /* exported interface */ |
| 167 | #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) | 167 | #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) |
| 168 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | ||
| 168 | 169 | ||
| 169 | /** | 170 | /** |
| 170 | * atomic_add_unless - add unless the number is a given value | 171 | * atomic_add_unless - add unless the number is a given value |
diff --git a/include/asm-parisc/mutex.h b/include/asm-parisc/mutex.h new file mode 100644 index 000000000000..458c1f7fbc18 --- /dev/null +++ b/include/asm-parisc/mutex.h | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | /* | ||
| 2 | * Pull in the generic implementation for the mutex fastpath. | ||
| 3 | * | ||
| 4 | * TODO: implement optimized primitives instead, or leave the generic | ||
| 5 | * implementation in place, or pick the atomic_xchg() based generic | ||
| 6 | * implementation. (see asm-generic/mutex-xchg.h for details) | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <asm-generic/mutex-dec.h> | ||
diff --git a/include/asm-powerpc/atomic.h b/include/asm-powerpc/atomic.h index ae395a0632a6..248f9aec959c 100644 --- a/include/asm-powerpc/atomic.h +++ b/include/asm-powerpc/atomic.h | |||
| @@ -165,6 +165,7 @@ static __inline__ int atomic_dec_return(atomic_t *v) | |||
| 165 | } | 165 | } |
| 166 | 166 | ||
| 167 | #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) | 167 | #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) |
| 168 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | ||
| 168 | 169 | ||
| 169 | /** | 170 | /** |
| 170 | * atomic_add_unless - add unless the number is a given value | 171 | * atomic_add_unless - add unless the number is a given value |
diff --git a/include/asm-powerpc/mutex.h b/include/asm-powerpc/mutex.h new file mode 100644 index 000000000000..458c1f7fbc18 --- /dev/null +++ b/include/asm-powerpc/mutex.h | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | /* | ||
| 2 | * Pull in the generic implementation for the mutex fastpath. | ||
| 3 | * | ||
| 4 | * TODO: implement optimized primitives instead, or leave the generic | ||
| 5 | * implementation in place, or pick the atomic_xchg() based generic | ||
| 6 | * implementation. (see asm-generic/mutex-xchg.h for details) | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <asm-generic/mutex-dec.h> | ||
diff --git a/include/asm-s390/atomic.h b/include/asm-s390/atomic.h index d82aedf616fe..be6fefe223d6 100644 --- a/include/asm-s390/atomic.h +++ b/include/asm-s390/atomic.h | |||
| @@ -75,6 +75,8 @@ static __inline__ void atomic_set_mask(unsigned long mask, atomic_t * v) | |||
| 75 | __CS_LOOP(v, mask, "or"); | 75 | __CS_LOOP(v, mask, "or"); |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | ||
| 79 | |||
| 78 | static __inline__ int atomic_cmpxchg(atomic_t *v, int old, int new) | 80 | static __inline__ int atomic_cmpxchg(atomic_t *v, int old, int new) |
| 79 | { | 81 | { |
| 80 | __asm__ __volatile__(" cs %0,%3,0(%2)\n" | 82 | __asm__ __volatile__(" cs %0,%3,0(%2)\n" |
diff --git a/include/asm-s390/mutex.h b/include/asm-s390/mutex.h new file mode 100644 index 000000000000..458c1f7fbc18 --- /dev/null +++ b/include/asm-s390/mutex.h | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | /* | ||
| 2 | * Pull in the generic implementation for the mutex fastpath. | ||
| 3 | * | ||
| 4 | * TODO: implement optimized primitives instead, or leave the generic | ||
| 5 | * implementation in place, or pick the atomic_xchg() based generic | ||
| 6 | * implementation. (see asm-generic/mutex-xchg.h for details) | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <asm-generic/mutex-dec.h> | ||
diff --git a/include/asm-sh/atomic.h b/include/asm-sh/atomic.h index 618d8e0de348..fb627de217f2 100644 --- a/include/asm-sh/atomic.h +++ b/include/asm-sh/atomic.h | |||
| @@ -101,6 +101,8 @@ static inline int atomic_cmpxchg(atomic_t *v, int old, int new) | |||
| 101 | return ret; | 101 | return ret; |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | ||
| 105 | |||
| 104 | static inline int atomic_add_unless(atomic_t *v, int a, int u) | 106 | static inline int atomic_add_unless(atomic_t *v, int a, int u) |
| 105 | { | 107 | { |
| 106 | int ret; | 108 | int ret; |
diff --git a/include/asm-sh/mutex.h b/include/asm-sh/mutex.h new file mode 100644 index 000000000000..458c1f7fbc18 --- /dev/null +++ b/include/asm-sh/mutex.h | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | /* | ||
| 2 | * Pull in the generic implementation for the mutex fastpath. | ||
| 3 | * | ||
| 4 | * TODO: implement optimized primitives instead, or leave the generic | ||
| 5 | * implementation in place, or pick the atomic_xchg() based generic | ||
| 6 | * implementation. (see asm-generic/mutex-xchg.h for details) | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <asm-generic/mutex-dec.h> | ||
diff --git a/include/asm-sh64/atomic.h b/include/asm-sh64/atomic.h index f3ce5c0df13a..28f2ea9b567b 100644 --- a/include/asm-sh64/atomic.h +++ b/include/asm-sh64/atomic.h | |||
| @@ -113,6 +113,8 @@ static inline int atomic_cmpxchg(atomic_t *v, int old, int new) | |||
| 113 | return ret; | 113 | return ret; |
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | ||
| 117 | |||
| 116 | static inline int atomic_add_unless(atomic_t *v, int a, int u) | 118 | static inline int atomic_add_unless(atomic_t *v, int a, int u) |
| 117 | { | 119 | { |
| 118 | int ret; | 120 | int ret; |
diff --git a/include/asm-sh64/mutex.h b/include/asm-sh64/mutex.h new file mode 100644 index 000000000000..458c1f7fbc18 --- /dev/null +++ b/include/asm-sh64/mutex.h | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | /* | ||
| 2 | * Pull in the generic implementation for the mutex fastpath. | ||
| 3 | * | ||
| 4 | * TODO: implement optimized primitives instead, or leave the generic | ||
| 5 | * implementation in place, or pick the atomic_xchg() based generic | ||
| 6 | * implementation. (see asm-generic/mutex-xchg.h for details) | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <asm-generic/mutex-dec.h> | ||
diff --git a/include/asm-sparc/atomic.h b/include/asm-sparc/atomic.h index accb4967e9d2..e1033170bd3a 100644 --- a/include/asm-sparc/atomic.h +++ b/include/asm-sparc/atomic.h | |||
| @@ -20,6 +20,7 @@ typedef struct { volatile int counter; } atomic_t; | |||
| 20 | 20 | ||
| 21 | extern int __atomic_add_return(int, atomic_t *); | 21 | extern int __atomic_add_return(int, atomic_t *); |
| 22 | extern int atomic_cmpxchg(atomic_t *, int, int); | 22 | extern int atomic_cmpxchg(atomic_t *, int, int); |
| 23 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | ||
| 23 | extern int atomic_add_unless(atomic_t *, int, int); | 24 | extern int atomic_add_unless(atomic_t *, int, int); |
| 24 | extern void atomic_set(atomic_t *, int); | 25 | extern void atomic_set(atomic_t *, int); |
| 25 | 26 | ||
diff --git a/include/asm-sparc/mutex.h b/include/asm-sparc/mutex.h new file mode 100644 index 000000000000..458c1f7fbc18 --- /dev/null +++ b/include/asm-sparc/mutex.h | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | /* | ||
| 2 | * Pull in the generic implementation for the mutex fastpath. | ||
| 3 | * | ||
| 4 | * TODO: implement optimized primitives instead, or leave the generic | ||
| 5 | * implementation in place, or pick the atomic_xchg() based generic | ||
| 6 | * implementation. (see asm-generic/mutex-xchg.h for details) | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <asm-generic/mutex-dec.h> | ||
diff --git a/include/asm-sparc64/atomic.h b/include/asm-sparc64/atomic.h index 11f5aa5d108c..25256bdc8aae 100644 --- a/include/asm-sparc64/atomic.h +++ b/include/asm-sparc64/atomic.h | |||
| @@ -72,6 +72,7 @@ extern int atomic64_sub_ret(int, atomic64_t *); | |||
| 72 | #define atomic64_add_negative(i, v) (atomic64_add_ret(i, v) < 0) | 72 | #define atomic64_add_negative(i, v) (atomic64_add_ret(i, v) < 0) |
| 73 | 73 | ||
| 74 | #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) | 74 | #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) |
| 75 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | ||
| 75 | 76 | ||
| 76 | #define atomic_add_unless(v, a, u) \ | 77 | #define atomic_add_unless(v, a, u) \ |
| 77 | ({ \ | 78 | ({ \ |
diff --git a/include/asm-sparc64/mutex.h b/include/asm-sparc64/mutex.h new file mode 100644 index 000000000000..458c1f7fbc18 --- /dev/null +++ b/include/asm-sparc64/mutex.h | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | /* | ||
| 2 | * Pull in the generic implementation for the mutex fastpath. | ||
| 3 | * | ||
| 4 | * TODO: implement optimized primitives instead, or leave the generic | ||
| 5 | * implementation in place, or pick the atomic_xchg() based generic | ||
| 6 | * implementation. (see asm-generic/mutex-xchg.h for details) | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <asm-generic/mutex-dec.h> | ||
diff --git a/include/asm-um/mutex.h b/include/asm-um/mutex.h new file mode 100644 index 000000000000..458c1f7fbc18 --- /dev/null +++ b/include/asm-um/mutex.h | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | /* | ||
| 2 | * Pull in the generic implementation for the mutex fastpath. | ||
| 3 | * | ||
| 4 | * TODO: implement optimized primitives instead, or leave the generic | ||
| 5 | * implementation in place, or pick the atomic_xchg() based generic | ||
| 6 | * implementation. (see asm-generic/mutex-xchg.h for details) | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <asm-generic/mutex-dec.h> | ||
diff --git a/include/asm-v850/atomic.h b/include/asm-v850/atomic.h index f5b9ab6f4e70..166df00457ea 100644 --- a/include/asm-v850/atomic.h +++ b/include/asm-v850/atomic.h | |||
| @@ -104,6 +104,8 @@ static inline int atomic_cmpxchg(atomic_t *v, int old, int new) | |||
| 104 | return ret; | 104 | return ret; |
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | ||
| 108 | |||
| 107 | static inline int atomic_add_unless(atomic_t *v, int a, int u) | 109 | static inline int atomic_add_unless(atomic_t *v, int a, int u) |
| 108 | { | 110 | { |
| 109 | int ret; | 111 | int ret; |
diff --git a/include/asm-v850/mutex.h b/include/asm-v850/mutex.h new file mode 100644 index 000000000000..458c1f7fbc18 --- /dev/null +++ b/include/asm-v850/mutex.h | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | /* | ||
| 2 | * Pull in the generic implementation for the mutex fastpath. | ||
| 3 | * | ||
| 4 | * TODO: implement optimized primitives instead, or leave the generic | ||
| 5 | * implementation in place, or pick the atomic_xchg() based generic | ||
| 6 | * implementation. (see asm-generic/mutex-xchg.h for details) | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <asm-generic/mutex-dec.h> | ||
diff --git a/include/asm-x86_64/atomic.h b/include/asm-x86_64/atomic.h index 72eb071488c7..6b540237a2f8 100644 --- a/include/asm-x86_64/atomic.h +++ b/include/asm-x86_64/atomic.h | |||
| @@ -389,6 +389,7 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t *v) | |||
| 389 | #define atomic64_dec_return(v) (atomic64_sub_return(1,v)) | 389 | #define atomic64_dec_return(v) (atomic64_sub_return(1,v)) |
| 390 | 390 | ||
| 391 | #define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new)) | 391 | #define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new)) |
| 392 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | ||
| 392 | 393 | ||
| 393 | /** | 394 | /** |
| 394 | * atomic_add_unless - add unless the number is a given value | 395 | * atomic_add_unless - add unless the number is a given value |
diff --git a/include/asm-x86_64/mutex.h b/include/asm-x86_64/mutex.h new file mode 100644 index 000000000000..818abfd262d1 --- /dev/null +++ b/include/asm-x86_64/mutex.h | |||
| @@ -0,0 +1,113 @@ | |||
| 1 | /* | ||
| 2 | * Assembly implementation of the mutex fastpath, based on atomic | ||
| 3 | * decrement/increment. | ||
| 4 | * | ||
| 5 | * started by Ingo Molnar: | ||
| 6 | * | ||
| 7 | * Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com> | ||
| 8 | */ | ||
| 9 | #ifndef _ASM_MUTEX_H | ||
| 10 | #define _ASM_MUTEX_H | ||
| 11 | |||
| 12 | /** | ||
| 13 | * __mutex_fastpath_lock - decrement and call function if negative | ||
| 14 | * @v: pointer of type atomic_t | ||
| 15 | * @fail_fn: function to call if the result is negative | ||
| 16 | * | ||
| 17 | * Atomically decrements @v and calls <fail_fn> if the result is negative. | ||
| 18 | */ | ||
| 19 | #define __mutex_fastpath_lock(v, fail_fn) \ | ||
| 20 | do { \ | ||
| 21 | unsigned long dummy; \ | ||
| 22 | \ | ||
| 23 | typecheck(atomic_t *, v); \ | ||
| 24 | typecheck_fn(fastcall void (*)(atomic_t *), fail_fn); \ | ||
| 25 | \ | ||
| 26 | __asm__ __volatile__( \ | ||
| 27 | LOCK " decl (%%rdi) \n" \ | ||
| 28 | " js 2f \n" \ | ||
| 29 | "1: \n" \ | ||
| 30 | \ | ||
| 31 | LOCK_SECTION_START("") \ | ||
| 32 | "2: call "#fail_fn" \n" \ | ||
| 33 | " jmp 1b \n" \ | ||
| 34 | LOCK_SECTION_END \ | ||
| 35 | \ | ||
| 36 | :"=D" (dummy) \ | ||
| 37 | : "D" (v) \ | ||
| 38 | : "rax", "rsi", "rdx", "rcx", \ | ||
| 39 | "r8", "r9", "r10", "r11", "memory"); \ | ||
| 40 | } while (0) | ||
| 41 | |||
| 42 | /** | ||
| 43 | * __mutex_fastpath_lock_retval - try to take the lock by moving the count | ||
| 44 | * from 1 to a 0 value | ||
| 45 | * @count: pointer of type atomic_t | ||
| 46 | * @fail_fn: function to call if the original value was not 1 | ||
| 47 | * | ||
| 48 | * Change the count from 1 to a value lower than 1, and call <fail_fn> if | ||
| 49 | * it wasn't 1 originally. This function returns 0 if the fastpath succeeds, | ||
| 50 | * or anything the slow path function returns | ||
| 51 | */ | ||
| 52 | static inline int | ||
| 53 | __mutex_fastpath_lock_retval(atomic_t *count, | ||
| 54 | int fastcall (*fail_fn)(atomic_t *)) | ||
| 55 | { | ||
| 56 | if (unlikely(atomic_dec_return(count) < 0)) | ||
| 57 | return fail_fn(count); | ||
| 58 | else | ||
| 59 | return 0; | ||
| 60 | } | ||
| 61 | |||
| 62 | /** | ||
| 63 | * __mutex_fastpath_unlock - increment and call function if nonpositive | ||
| 64 | * @v: pointer of type atomic_t | ||
| 65 | * @fail_fn: function to call if the result is nonpositive | ||
| 66 | * | ||
| 67 | * Atomically increments @v and calls <fail_fn> if the result is nonpositive. | ||
| 68 | */ | ||
| 69 | #define __mutex_fastpath_unlock(v, fail_fn) \ | ||
| 70 | do { \ | ||
| 71 | unsigned long dummy; \ | ||
| 72 | \ | ||
| 73 | typecheck(atomic_t *, v); \ | ||
| 74 | typecheck_fn(fastcall void (*)(atomic_t *), fail_fn); \ | ||
| 75 | \ | ||
| 76 | __asm__ __volatile__( \ | ||
| 77 | LOCK " incl (%%rdi) \n" \ | ||
| 78 | " jle 2f \n" \ | ||
| 79 | "1: \n" \ | ||
| 80 | \ | ||
| 81 | LOCK_SECTION_START("") \ | ||
| 82 | "2: call "#fail_fn" \n" \ | ||
| 83 | " jmp 1b \n" \ | ||
| 84 | LOCK_SECTION_END \ | ||
| 85 | \ | ||
| 86 | :"=D" (dummy) \ | ||
| 87 | : "D" (v) \ | ||
| 88 | : "rax", "rsi", "rdx", "rcx", \ | ||
| 89 | "r8", "r9", "r10", "r11", "memory"); \ | ||
| 90 | } while (0) | ||
| 91 | |||
| 92 | #define __mutex_slowpath_needs_to_unlock() 1 | ||
| 93 | |||
| 94 | /** | ||
| 95 | * __mutex_fastpath_trylock - try to acquire the mutex, without waiting | ||
| 96 | * | ||
| 97 | * @count: pointer of type atomic_t | ||
| 98 | * @fail_fn: fallback function | ||
| 99 | * | ||
| 100 | * Change the count from 1 to 0 and return 1 (success), or return 0 (failure) | ||
| 101 | * if it wasn't 1 originally. [the fallback function is never used on | ||
| 102 | * x86_64, because all x86_64 CPUs have a CMPXCHG instruction.] | ||
| 103 | */ | ||
| 104 | static inline int | ||
| 105 | __mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *)) | ||
| 106 | { | ||
| 107 | if (likely(atomic_cmpxchg(count, 1, 0)) == 1) | ||
| 108 | return 1; | ||
| 109 | else | ||
| 110 | return 0; | ||
| 111 | } | ||
| 112 | |||
| 113 | #endif | ||
diff --git a/include/asm-xtensa/atomic.h b/include/asm-xtensa/atomic.h index e2ce06b101ad..fe105a123924 100644 --- a/include/asm-xtensa/atomic.h +++ b/include/asm-xtensa/atomic.h | |||
| @@ -224,6 +224,7 @@ static inline int atomic_sub_return(int i, atomic_t * v) | |||
| 224 | #define atomic_add_negative(i,v) (atomic_add_return((i),(v)) < 0) | 224 | #define atomic_add_negative(i,v) (atomic_add_return((i),(v)) < 0) |
| 225 | 225 | ||
| 226 | #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) | 226 | #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) |
| 227 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | ||
| 227 | 228 | ||
| 228 | /** | 229 | /** |
| 229 | * atomic_add_unless - add unless the number is a given value | 230 | * atomic_add_unless - add unless the number is a given value |
diff --git a/include/asm-xtensa/mutex.h b/include/asm-xtensa/mutex.h new file mode 100644 index 000000000000..458c1f7fbc18 --- /dev/null +++ b/include/asm-xtensa/mutex.h | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | /* | ||
| 2 | * Pull in the generic implementation for the mutex fastpath. | ||
| 3 | * | ||
| 4 | * TODO: implement optimized primitives instead, or leave the generic | ||
| 5 | * implementation in place, or pick the atomic_xchg() based generic | ||
| 6 | * implementation. (see asm-generic/mutex-xchg.h for details) | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <asm-generic/mutex-dec.h> | ||
diff --git a/include/linux/ext3_fs_i.h b/include/linux/ext3_fs_i.h index 2914f7b07156..e71dd98dbcae 100644 --- a/include/linux/ext3_fs_i.h +++ b/include/linux/ext3_fs_i.h | |||
| @@ -87,7 +87,7 @@ struct ext3_inode_info { | |||
| 87 | #ifdef CONFIG_EXT3_FS_XATTR | 87 | #ifdef CONFIG_EXT3_FS_XATTR |
| 88 | /* | 88 | /* |
| 89 | * Extended attributes can be read independently of the main file | 89 | * Extended attributes can be read independently of the main file |
| 90 | * data. Taking i_sem even when reading would cause contention | 90 | * data. Taking i_mutex even when reading would cause contention |
| 91 | * between readers of EAs and writers of regular file data, so | 91 | * between readers of EAs and writers of regular file data, so |
| 92 | * instead we synchronize on xattr_sem when reading or changing | 92 | * instead we synchronize on xattr_sem when reading or changing |
| 93 | * EAs. | 93 | * EAs. |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 4c82219b0fae..92ae3e2067b0 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
| @@ -219,6 +219,7 @@ extern int dir_notify_enable; | |||
| 219 | #include <linux/prio_tree.h> | 219 | #include <linux/prio_tree.h> |
| 220 | #include <linux/init.h> | 220 | #include <linux/init.h> |
| 221 | #include <linux/sched.h> | 221 | #include <linux/sched.h> |
| 222 | #include <linux/mutex.h> | ||
| 222 | 223 | ||
| 223 | #include <asm/atomic.h> | 224 | #include <asm/atomic.h> |
| 224 | #include <asm/semaphore.h> | 225 | #include <asm/semaphore.h> |
| @@ -484,7 +485,7 @@ struct inode { | |||
| 484 | unsigned long i_blocks; | 485 | unsigned long i_blocks; |
| 485 | unsigned short i_bytes; | 486 | unsigned short i_bytes; |
| 486 | spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */ | 487 | spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */ |
| 487 | struct semaphore i_sem; | 488 | struct mutex i_mutex; |
| 488 | struct rw_semaphore i_alloc_sem; | 489 | struct rw_semaphore i_alloc_sem; |
| 489 | struct inode_operations *i_op; | 490 | struct inode_operations *i_op; |
| 490 | struct file_operations *i_fop; /* former ->i_op->default_file_ops */ | 491 | struct file_operations *i_fop; /* former ->i_op->default_file_ops */ |
| @@ -820,7 +821,7 @@ struct super_block { | |||
| 820 | unsigned long s_magic; | 821 | unsigned long s_magic; |
| 821 | struct dentry *s_root; | 822 | struct dentry *s_root; |
| 822 | struct rw_semaphore s_umount; | 823 | struct rw_semaphore s_umount; |
| 823 | struct semaphore s_lock; | 824 | struct mutex s_lock; |
| 824 | int s_count; | 825 | int s_count; |
| 825 | int s_syncing; | 826 | int s_syncing; |
| 826 | int s_need_sync_fs; | 827 | int s_need_sync_fs; |
| @@ -892,13 +893,13 @@ static inline int has_fs_excl(void) | |||
| 892 | static inline void lock_super(struct super_block * sb) | 893 | static inline void lock_super(struct super_block * sb) |
| 893 | { | 894 | { |
| 894 | get_fs_excl(); | 895 | get_fs_excl(); |
| 895 | down(&sb->s_lock); | 896 | mutex_lock(&sb->s_lock); |
| 896 | } | 897 | } |
| 897 | 898 | ||
| 898 | static inline void unlock_super(struct super_block * sb) | 899 | static inline void unlock_super(struct super_block * sb) |
| 899 | { | 900 | { |
| 900 | put_fs_excl(); | 901 | put_fs_excl(); |
| 901 | up(&sb->s_lock); | 902 | mutex_unlock(&sb->s_lock); |
| 902 | } | 903 | } |
| 903 | 904 | ||
| 904 | /* | 905 | /* |
| @@ -1191,7 +1192,7 @@ int sync_inode(struct inode *inode, struct writeback_control *wbc); | |||
| 1191 | * directory. The name should be stored in the @name (with the | 1192 | * directory. The name should be stored in the @name (with the |
| 1192 | * understanding that it is already pointing to a a %NAME_MAX+1 sized | 1193 | * understanding that it is already pointing to a a %NAME_MAX+1 sized |
| 1193 | * buffer. get_name() should return %0 on success, a negative error code | 1194 | * buffer. get_name() should return %0 on success, a negative error code |
| 1194 | * or error. @get_name will be called without @parent->i_sem held. | 1195 | * or error. @get_name will be called without @parent->i_mutex held. |
| 1195 | * | 1196 | * |
| 1196 | * get_parent: | 1197 | * get_parent: |
| 1197 | * @get_parent should find the parent directory for the given @child which | 1198 | * @get_parent should find the parent directory for the given @child which |
| @@ -1213,7 +1214,7 @@ int sync_inode(struct inode *inode, struct writeback_control *wbc); | |||
| 1213 | * nfsd_find_fh_dentry() in either the @obj or @parent parameters. | 1214 | * nfsd_find_fh_dentry() in either the @obj or @parent parameters. |
| 1214 | * | 1215 | * |
| 1215 | * Locking rules: | 1216 | * Locking rules: |
| 1216 | * get_parent is called with child->d_inode->i_sem down | 1217 | * get_parent is called with child->d_inode->i_mutex down |
| 1217 | * get_name is not (which is possibly inconsistent) | 1218 | * get_name is not (which is possibly inconsistent) |
| 1218 | */ | 1219 | */ |
| 1219 | 1220 | ||
diff --git a/include/linux/ide.h b/include/linux/ide.h index ef8d0cbb832f..9a8c05dbe4f3 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/bio.h> | 18 | #include <linux/bio.h> |
| 19 | #include <linux/device.h> | 19 | #include <linux/device.h> |
| 20 | #include <linux/pci.h> | 20 | #include <linux/pci.h> |
| 21 | #include <linux/completion.h> | ||
| 21 | #include <asm/byteorder.h> | 22 | #include <asm/byteorder.h> |
| 22 | #include <asm/system.h> | 23 | #include <asm/system.h> |
| 23 | #include <asm/io.h> | 24 | #include <asm/io.h> |
| @@ -638,7 +639,7 @@ typedef struct ide_drive_s { | |||
| 638 | int crc_count; /* crc counter to reduce drive speed */ | 639 | int crc_count; /* crc counter to reduce drive speed */ |
| 639 | struct list_head list; | 640 | struct list_head list; |
| 640 | struct device gendev; | 641 | struct device gendev; |
| 641 | struct semaphore gendev_rel_sem; /* to deal with device release() */ | 642 | struct completion gendev_rel_comp; /* to deal with device release() */ |
| 642 | } ide_drive_t; | 643 | } ide_drive_t; |
| 643 | 644 | ||
| 644 | #define to_ide_device(dev)container_of(dev, ide_drive_t, gendev) | 645 | #define to_ide_device(dev)container_of(dev, ide_drive_t, gendev) |
| @@ -794,7 +795,7 @@ typedef struct hwif_s { | |||
| 794 | unsigned sg_mapped : 1; /* sg_table and sg_nents are ready */ | 795 | unsigned sg_mapped : 1; /* sg_table and sg_nents are ready */ |
| 795 | 796 | ||
| 796 | struct device gendev; | 797 | struct device gendev; |
| 797 | struct semaphore gendev_rel_sem; /* To deal with device release() */ | 798 | struct completion gendev_rel_comp; /* To deal with device release() */ |
| 798 | 799 | ||
| 799 | void *hwif_data; /* extra hwif data */ | 800 | void *hwif_data; /* extra hwif data */ |
| 800 | 801 | ||
diff --git a/include/linux/jffs2_fs_i.h b/include/linux/jffs2_fs_i.h index ef85ab56302b..ad565bf9dcc1 100644 --- a/include/linux/jffs2_fs_i.h +++ b/include/linux/jffs2_fs_i.h | |||
| @@ -8,11 +8,11 @@ | |||
| 8 | #include <asm/semaphore.h> | 8 | #include <asm/semaphore.h> |
| 9 | 9 | ||
| 10 | struct jffs2_inode_info { | 10 | struct jffs2_inode_info { |
| 11 | /* We need an internal semaphore similar to inode->i_sem. | 11 | /* We need an internal mutex similar to inode->i_mutex. |
| 12 | Unfortunately, we can't used the existing one, because | 12 | Unfortunately, we can't used the existing one, because |
| 13 | either the GC would deadlock, or we'd have to release it | 13 | either the GC would deadlock, or we'd have to release it |
| 14 | before letting GC proceed. Or we'd have to put ugliness | 14 | before letting GC proceed. Or we'd have to put ugliness |
| 15 | into the GC code so it didn't attempt to obtain the i_sem | 15 | into the GC code so it didn't attempt to obtain the i_mutex |
| 16 | for the inode(s) which are already locked */ | 16 | for the inode(s) which are already locked */ |
| 17 | struct semaphore sem; | 17 | struct semaphore sem; |
| 18 | 18 | ||
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index ca7ff8fdd090..d0e6ca3b00ef 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
| @@ -286,6 +286,15 @@ extern void dump_stack(void); | |||
| 286 | 1; \ | 286 | 1; \ |
| 287 | }) | 287 | }) |
| 288 | 288 | ||
| 289 | /* | ||
| 290 | * Check at compile time that 'function' is a certain type, or is a pointer | ||
| 291 | * to that type (needs to use typedef for the function type.) | ||
| 292 | */ | ||
| 293 | #define typecheck_fn(type,function) \ | ||
| 294 | ({ typeof(type) __tmp = function; \ | ||
| 295 | (void)__tmp; \ | ||
| 296 | }) | ||
| 297 | |||
| 289 | #endif /* __KERNEL__ */ | 298 | #endif /* __KERNEL__ */ |
| 290 | 299 | ||
| 291 | #define SI_LOAD_SHIFT 16 | 300 | #define SI_LOAD_SHIFT 16 |
diff --git a/include/linux/loop.h b/include/linux/loop.h index 40f63c9879d2..f96506782ebe 100644 --- a/include/linux/loop.h +++ b/include/linux/loop.h | |||
| @@ -58,9 +58,9 @@ struct loop_device { | |||
| 58 | struct bio *lo_bio; | 58 | struct bio *lo_bio; |
| 59 | struct bio *lo_biotail; | 59 | struct bio *lo_biotail; |
| 60 | int lo_state; | 60 | int lo_state; |
| 61 | struct semaphore lo_sem; | 61 | struct completion lo_done; |
| 62 | struct completion lo_bh_done; | ||
| 62 | struct semaphore lo_ctl_mutex; | 63 | struct semaphore lo_ctl_mutex; |
| 63 | struct semaphore lo_bh_mutex; | ||
| 64 | int lo_pending; | 64 | int lo_pending; |
| 65 | 65 | ||
| 66 | request_queue_t *lo_queue; | 66 | request_queue_t *lo_queue; |
diff --git a/include/linux/mm.h b/include/linux/mm.h index df80e63903b5..3f1fafc0245e 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/rbtree.h> | 13 | #include <linux/rbtree.h> |
| 14 | #include <linux/prio_tree.h> | 14 | #include <linux/prio_tree.h> |
| 15 | #include <linux/fs.h> | 15 | #include <linux/fs.h> |
| 16 | #include <linux/mutex.h> | ||
| 16 | 17 | ||
| 17 | struct mempolicy; | 18 | struct mempolicy; |
| 18 | struct anon_vma; | 19 | struct anon_vma; |
| @@ -1024,6 +1025,9 @@ static inline void vm_stat_account(struct mm_struct *mm, | |||
| 1024 | static inline void | 1025 | static inline void |
| 1025 | kernel_map_pages(struct page *page, int numpages, int enable) | 1026 | kernel_map_pages(struct page *page, int numpages, int enable) |
| 1026 | { | 1027 | { |
| 1028 | if (!PageHighMem(page) && !enable) | ||
| 1029 | mutex_debug_check_no_locks_freed(page_address(page), | ||
| 1030 | page_address(page + numpages)); | ||
| 1027 | } | 1031 | } |
| 1028 | #endif | 1032 | #endif |
| 1029 | 1033 | ||
diff --git a/include/linux/mutex-debug.h b/include/linux/mutex-debug.h new file mode 100644 index 000000000000..0ccd8f983b50 --- /dev/null +++ b/include/linux/mutex-debug.h | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | #ifndef __LINUX_MUTEX_DEBUG_H | ||
| 2 | #define __LINUX_MUTEX_DEBUG_H | ||
| 3 | |||
| 4 | /* | ||
| 5 | * Mutexes - debugging helpers: | ||
| 6 | */ | ||
| 7 | |||
| 8 | #define __DEBUG_MUTEX_INITIALIZER(lockname) \ | ||
| 9 | , .held_list = LIST_HEAD_INIT(lockname.held_list), \ | ||
| 10 | .name = #lockname , .magic = &lockname | ||
| 11 | |||
| 12 | #define mutex_init(sem) __mutex_init(sem, __FUNCTION__) | ||
| 13 | |||
| 14 | extern void FASTCALL(mutex_destroy(struct mutex *lock)); | ||
| 15 | |||
| 16 | extern void mutex_debug_show_all_locks(void); | ||
| 17 | extern void mutex_debug_show_held_locks(struct task_struct *filter); | ||
| 18 | extern void mutex_debug_check_no_locks_held(struct task_struct *task); | ||
| 19 | extern void mutex_debug_check_no_locks_freed(const void *from, const void *to); | ||
| 20 | |||
| 21 | #endif | ||
diff --git a/include/linux/mutex.h b/include/linux/mutex.h new file mode 100644 index 000000000000..9bce0fee68d4 --- /dev/null +++ b/include/linux/mutex.h | |||
| @@ -0,0 +1,119 @@ | |||
| 1 | /* | ||
| 2 | * Mutexes: blocking mutual exclusion locks | ||
| 3 | * | ||
| 4 | * started by Ingo Molnar: | ||
| 5 | * | ||
| 6 | * Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com> | ||
| 7 | * | ||
| 8 | * This file contains the main data structure and API definitions. | ||
| 9 | */ | ||
| 10 | #ifndef __LINUX_MUTEX_H | ||
| 11 | #define __LINUX_MUTEX_H | ||
| 12 | |||
| 13 | #include <linux/list.h> | ||
| 14 | #include <linux/spinlock_types.h> | ||
| 15 | |||
| 16 | #include <asm/atomic.h> | ||
| 17 | |||
| 18 | /* | ||
| 19 | * Simple, straightforward mutexes with strict semantics: | ||
| 20 | * | ||
| 21 | * - only one task can hold the mutex at a time | ||
| 22 | * - only the owner can unlock the mutex | ||
| 23 | * - multiple unlocks are not permitted | ||
| 24 | * - recursive locking is not permitted | ||
| 25 | * - a mutex object must be initialized via the API | ||
| 26 | * - a mutex object must not be initialized via memset or copying | ||
| 27 | * - task may not exit with mutex held | ||
| 28 | * - memory areas where held locks reside must not be freed | ||
| 29 | * - held mutexes must not be reinitialized | ||
| 30 | * - mutexes may not be used in irq contexts | ||
| 31 | * | ||
| 32 | * These semantics are fully enforced when DEBUG_MUTEXES is | ||
| 33 | * enabled. Furthermore, besides enforcing the above rules, the mutex | ||
| 34 | * debugging code also implements a number of additional features | ||
| 35 | * that make lock debugging easier and faster: | ||
| 36 | * | ||
| 37 | * - uses symbolic names of mutexes, whenever they are printed in debug output | ||
| 38 | * - point-of-acquire tracking, symbolic lookup of function names | ||
| 39 | * - list of all locks held in the system, printout of them | ||
| 40 | * - owner tracking | ||
| 41 | * - detects self-recursing locks and prints out all relevant info | ||
| 42 | * - detects multi-task circular deadlocks and prints out all affected | ||
| 43 | * locks and tasks (and only those tasks) | ||
| 44 | */ | ||
| 45 | struct mutex { | ||
| 46 | /* 1: unlocked, 0: locked, negative: locked, possible waiters */ | ||
| 47 | atomic_t count; | ||
| 48 | spinlock_t wait_lock; | ||
| 49 | struct list_head wait_list; | ||
| 50 | #ifdef CONFIG_DEBUG_MUTEXES | ||
| 51 | struct thread_info *owner; | ||
| 52 | struct list_head held_list; | ||
| 53 | unsigned long acquire_ip; | ||
| 54 | const char *name; | ||
| 55 | void *magic; | ||
| 56 | #endif | ||
| 57 | }; | ||
| 58 | |||
| 59 | /* | ||
| 60 | * This is the control structure for tasks blocked on mutex, | ||
| 61 | * which resides on the blocked task's kernel stack: | ||
| 62 | */ | ||
| 63 | struct mutex_waiter { | ||
| 64 | struct list_head list; | ||
| 65 | struct task_struct *task; | ||
| 66 | #ifdef CONFIG_DEBUG_MUTEXES | ||
| 67 | struct mutex *lock; | ||
| 68 | void *magic; | ||
| 69 | #endif | ||
| 70 | }; | ||
| 71 | |||
| 72 | #ifdef CONFIG_DEBUG_MUTEXES | ||
| 73 | # include <linux/mutex-debug.h> | ||
| 74 | #else | ||
| 75 | # define __DEBUG_MUTEX_INITIALIZER(lockname) | ||
| 76 | # define mutex_init(mutex) __mutex_init(mutex, NULL) | ||
| 77 | # define mutex_destroy(mutex) do { } while (0) | ||
| 78 | # define mutex_debug_show_all_locks() do { } while (0) | ||
| 79 | # define mutex_debug_show_held_locks(p) do { } while (0) | ||
| 80 | # define mutex_debug_check_no_locks_held(task) do { } while (0) | ||
| 81 | # define mutex_debug_check_no_locks_freed(from, to) do { } while (0) | ||
| 82 | #endif | ||
| 83 | |||
| 84 | #define __MUTEX_INITIALIZER(lockname) \ | ||
| 85 | { .count = ATOMIC_INIT(1) \ | ||
| 86 | , .wait_lock = SPIN_LOCK_UNLOCKED \ | ||
| 87 | , .wait_list = LIST_HEAD_INIT(lockname.wait_list) \ | ||
| 88 | __DEBUG_MUTEX_INITIALIZER(lockname) } | ||
| 89 | |||
| 90 | #define DEFINE_MUTEX(mutexname) \ | ||
| 91 | struct mutex mutexname = __MUTEX_INITIALIZER(mutexname) | ||
| 92 | |||
| 93 | extern void fastcall __mutex_init(struct mutex *lock, const char *name); | ||
| 94 | |||
| 95 | /*** | ||
| 96 | * mutex_is_locked - is the mutex locked | ||
| 97 | * @lock: the mutex to be queried | ||
| 98 | * | ||
| 99 | * Returns 1 if the mutex is locked, 0 if unlocked. | ||
| 100 | */ | ||
| 101 | static inline int fastcall mutex_is_locked(struct mutex *lock) | ||
| 102 | { | ||
| 103 | return atomic_read(&lock->count) != 1; | ||
| 104 | } | ||
| 105 | |||
| 106 | /* | ||
| 107 | * See kernel/mutex.c for detailed documentation of these APIs. | ||
| 108 | * Also see Documentation/mutex-design.txt. | ||
| 109 | */ | ||
| 110 | extern void fastcall mutex_lock(struct mutex *lock); | ||
| 111 | extern int fastcall mutex_lock_interruptible(struct mutex *lock); | ||
| 112 | /* | ||
| 113 | * NOTE: mutex_trylock() follows the spin_trylock() convention, | ||
| 114 | * not the down_trylock() convention! | ||
| 115 | */ | ||
| 116 | extern int fastcall mutex_trylock(struct mutex *lock); | ||
| 117 | extern void fastcall mutex_unlock(struct mutex *lock); | ||
| 118 | |||
| 119 | #endif | ||
diff --git a/include/linux/nfsd/nfsfh.h b/include/linux/nfsd/nfsfh.h index bb842ea41033..0798b7781a6e 100644 --- a/include/linux/nfsd/nfsfh.h +++ b/include/linux/nfsd/nfsfh.h | |||
| @@ -294,7 +294,7 @@ fill_post_wcc(struct svc_fh *fhp) | |||
| 294 | /* | 294 | /* |
| 295 | * Lock a file handle/inode | 295 | * Lock a file handle/inode |
| 296 | * NOTE: both fh_lock and fh_unlock are done "by hand" in | 296 | * NOTE: both fh_lock and fh_unlock are done "by hand" in |
| 297 | * vfs.c:nfsd_rename as it needs to grab 2 i_sem's at once | 297 | * vfs.c:nfsd_rename as it needs to grab 2 i_mutex's at once |
| 298 | * so, any changes here should be reflected there. | 298 | * so, any changes here should be reflected there. |
| 299 | */ | 299 | */ |
| 300 | static inline void | 300 | static inline void |
| @@ -317,7 +317,7 @@ fh_lock(struct svc_fh *fhp) | |||
| 317 | } | 317 | } |
| 318 | 318 | ||
| 319 | inode = dentry->d_inode; | 319 | inode = dentry->d_inode; |
| 320 | down(&inode->i_sem); | 320 | mutex_lock(&inode->i_mutex); |
| 321 | fill_pre_wcc(fhp); | 321 | fill_pre_wcc(fhp); |
| 322 | fhp->fh_locked = 1; | 322 | fhp->fh_locked = 1; |
| 323 | } | 323 | } |
| @@ -333,7 +333,7 @@ fh_unlock(struct svc_fh *fhp) | |||
| 333 | 333 | ||
| 334 | if (fhp->fh_locked) { | 334 | if (fhp->fh_locked) { |
| 335 | fill_post_wcc(fhp); | 335 | fill_post_wcc(fhp); |
| 336 | up(&fhp->fh_dentry->d_inode->i_sem); | 336 | mutex_unlock(&fhp->fh_dentry->d_inode->i_mutex); |
| 337 | fhp->fh_locked = 0; | 337 | fhp->fh_locked = 0; |
| 338 | } | 338 | } |
| 339 | } | 339 | } |
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index 1767073df26f..b12e59c75752 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h | |||
| @@ -37,7 +37,7 @@ struct pipe_inode_info { | |||
| 37 | memory allocation, whereas PIPE_BUF makes atomicity guarantees. */ | 37 | memory allocation, whereas PIPE_BUF makes atomicity guarantees. */ |
| 38 | #define PIPE_SIZE PAGE_SIZE | 38 | #define PIPE_SIZE PAGE_SIZE |
| 39 | 39 | ||
| 40 | #define PIPE_SEM(inode) (&(inode).i_sem) | 40 | #define PIPE_MUTEX(inode) (&(inode).i_mutex) |
| 41 | #define PIPE_WAIT(inode) (&(inode).i_pipe->wait) | 41 | #define PIPE_WAIT(inode) (&(inode).i_pipe->wait) |
| 42 | #define PIPE_READERS(inode) ((inode).i_pipe->readers) | 42 | #define PIPE_READERS(inode) ((inode).i_pipe->readers) |
| 43 | #define PIPE_WRITERS(inode) ((inode).i_pipe->writers) | 43 | #define PIPE_WRITERS(inode) ((inode).i_pipe->writers) |
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h index 001ab82df051..e276c5ba2bb7 100644 --- a/include/linux/reiserfs_fs.h +++ b/include/linux/reiserfs_fs.h | |||
| @@ -1857,7 +1857,7 @@ void padd_item(char *item, int total_length, int length); | |||
| 1857 | #define GET_BLOCK_CREATE 1 /* add anything you need to find block */ | 1857 | #define GET_BLOCK_CREATE 1 /* add anything you need to find block */ |
| 1858 | #define GET_BLOCK_NO_HOLE 2 /* return -ENOENT for file holes */ | 1858 | #define GET_BLOCK_NO_HOLE 2 /* return -ENOENT for file holes */ |
| 1859 | #define GET_BLOCK_READ_DIRECT 4 /* read the tail if indirect item not found */ | 1859 | #define GET_BLOCK_READ_DIRECT 4 /* read the tail if indirect item not found */ |
| 1860 | #define GET_BLOCK_NO_ISEM 8 /* i_sem is not held, don't preallocate */ | 1860 | #define GET_BLOCK_NO_IMUX 8 /* i_mutex is not held, don't preallocate */ |
| 1861 | #define GET_BLOCK_NO_DANGLE 16 /* don't leave any transactions running */ | 1861 | #define GET_BLOCK_NO_DANGLE 16 /* don't leave any transactions running */ |
| 1862 | 1862 | ||
| 1863 | int restart_transaction(struct reiserfs_transaction_handle *th, | 1863 | int restart_transaction(struct reiserfs_transaction_handle *th, |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 78eb92ae4d94..85b53f87c703 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
| @@ -817,6 +817,11 @@ struct task_struct { | |||
| 817 | /* Protection of proc_dentry: nesting proc_lock, dcache_lock, write_lock_irq(&tasklist_lock); */ | 817 | /* Protection of proc_dentry: nesting proc_lock, dcache_lock, write_lock_irq(&tasklist_lock); */ |
| 818 | spinlock_t proc_lock; | 818 | spinlock_t proc_lock; |
| 819 | 819 | ||
| 820 | #ifdef CONFIG_DEBUG_MUTEXES | ||
| 821 | /* mutex deadlock detection */ | ||
| 822 | struct mutex_waiter *blocked_on; | ||
| 823 | #endif | ||
| 824 | |||
| 820 | /* journalling filesystem info */ | 825 | /* journalling filesystem info */ |
| 821 | void *journal_info; | 826 | void *journal_info; |
| 822 | 827 | ||
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index c8943b53d8e6..a8aa6152eea6 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c | |||
| @@ -660,7 +660,7 @@ asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode, | |||
| 660 | if (fd < 0) | 660 | if (fd < 0) |
| 661 | goto out_putname; | 661 | goto out_putname; |
| 662 | 662 | ||
| 663 | down(&mqueue_mnt->mnt_root->d_inode->i_sem); | 663 | mutex_lock(&mqueue_mnt->mnt_root->d_inode->i_mutex); |
| 664 | dentry = lookup_one_len(name, mqueue_mnt->mnt_root, strlen(name)); | 664 | dentry = lookup_one_len(name, mqueue_mnt->mnt_root, strlen(name)); |
| 665 | if (IS_ERR(dentry)) { | 665 | if (IS_ERR(dentry)) { |
| 666 | error = PTR_ERR(dentry); | 666 | error = PTR_ERR(dentry); |
| @@ -697,7 +697,7 @@ out_putfd: | |||
| 697 | out_err: | 697 | out_err: |
| 698 | fd = error; | 698 | fd = error; |
| 699 | out_upsem: | 699 | out_upsem: |
| 700 | up(&mqueue_mnt->mnt_root->d_inode->i_sem); | 700 | mutex_unlock(&mqueue_mnt->mnt_root->d_inode->i_mutex); |
| 701 | out_putname: | 701 | out_putname: |
| 702 | putname(name); | 702 | putname(name); |
| 703 | return fd; | 703 | return fd; |
| @@ -714,7 +714,7 @@ asmlinkage long sys_mq_unlink(const char __user *u_name) | |||
| 714 | if (IS_ERR(name)) | 714 | if (IS_ERR(name)) |
| 715 | return PTR_ERR(name); | 715 | return PTR_ERR(name); |
| 716 | 716 | ||
| 717 | down(&mqueue_mnt->mnt_root->d_inode->i_sem); | 717 | mutex_lock(&mqueue_mnt->mnt_root->d_inode->i_mutex); |
| 718 | dentry = lookup_one_len(name, mqueue_mnt->mnt_root, strlen(name)); | 718 | dentry = lookup_one_len(name, mqueue_mnt->mnt_root, strlen(name)); |
| 719 | if (IS_ERR(dentry)) { | 719 | if (IS_ERR(dentry)) { |
| 720 | err = PTR_ERR(dentry); | 720 | err = PTR_ERR(dentry); |
| @@ -735,7 +735,7 @@ out_err: | |||
| 735 | dput(dentry); | 735 | dput(dentry); |
| 736 | 736 | ||
| 737 | out_unlock: | 737 | out_unlock: |
| 738 | up(&mqueue_mnt->mnt_root->d_inode->i_sem); | 738 | mutex_unlock(&mqueue_mnt->mnt_root->d_inode->i_mutex); |
| 739 | putname(name); | 739 | putname(name); |
| 740 | if (inode) | 740 | if (inode) |
| 741 | iput(inode); | 741 | iput(inode); |
diff --git a/kernel/Makefile b/kernel/Makefile index 4f5a1453093a..a940bac02837 100644 --- a/kernel/Makefile +++ b/kernel/Makefile | |||
| @@ -7,8 +7,9 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \ | |||
| 7 | sysctl.o capability.o ptrace.o timer.o user.o \ | 7 | sysctl.o capability.o ptrace.o timer.o user.o \ |
| 8 | signal.o sys.o kmod.o workqueue.o pid.o \ | 8 | signal.o sys.o kmod.o workqueue.o pid.o \ |
| 9 | rcupdate.o intermodule.o extable.o params.o posix-timers.o \ | 9 | rcupdate.o intermodule.o extable.o params.o posix-timers.o \ |
| 10 | kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o | 10 | kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o |
| 11 | 11 | ||
| 12 | obj-$(CONFIG_DEBUG_MUTEXES) += mutex-debug.o | ||
| 12 | obj-$(CONFIG_FUTEX) += futex.o | 13 | obj-$(CONFIG_FUTEX) += futex.o |
| 13 | obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o | 14 | obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o |
| 14 | obj-$(CONFIG_SMP) += cpu.o spinlock.o | 15 | obj-$(CONFIG_SMP) += cpu.o spinlock.o |
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index eab64e23bcae..2a75e44e1a41 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
| @@ -1513,7 +1513,7 @@ static int cpuset_add_file(struct dentry *dir, const struct cftype *cft) | |||
| 1513 | struct dentry *dentry; | 1513 | struct dentry *dentry; |
| 1514 | int error; | 1514 | int error; |
| 1515 | 1515 | ||
| 1516 | down(&dir->d_inode->i_sem); | 1516 | mutex_lock(&dir->d_inode->i_mutex); |
| 1517 | dentry = cpuset_get_dentry(dir, cft->name); | 1517 | dentry = cpuset_get_dentry(dir, cft->name); |
| 1518 | if (!IS_ERR(dentry)) { | 1518 | if (!IS_ERR(dentry)) { |
| 1519 | error = cpuset_create_file(dentry, 0644 | S_IFREG); | 1519 | error = cpuset_create_file(dentry, 0644 | S_IFREG); |
| @@ -1522,7 +1522,7 @@ static int cpuset_add_file(struct dentry *dir, const struct cftype *cft) | |||
| 1522 | dput(dentry); | 1522 | dput(dentry); |
| 1523 | } else | 1523 | } else |
| 1524 | error = PTR_ERR(dentry); | 1524 | error = PTR_ERR(dentry); |
| 1525 | up(&dir->d_inode->i_sem); | 1525 | mutex_unlock(&dir->d_inode->i_mutex); |
| 1526 | return error; | 1526 | return error; |
| 1527 | } | 1527 | } |
| 1528 | 1528 | ||
| @@ -1793,7 +1793,7 @@ static long cpuset_create(struct cpuset *parent, const char *name, int mode) | |||
| 1793 | 1793 | ||
| 1794 | /* | 1794 | /* |
| 1795 | * Release manage_sem before cpuset_populate_dir() because it | 1795 | * Release manage_sem before cpuset_populate_dir() because it |
| 1796 | * will down() this new directory's i_sem and if we race with | 1796 | * will down() this new directory's i_mutex and if we race with |
| 1797 | * another mkdir, we might deadlock. | 1797 | * another mkdir, we might deadlock. |
| 1798 | */ | 1798 | */ |
| 1799 | up(&manage_sem); | 1799 | up(&manage_sem); |
| @@ -1812,7 +1812,7 @@ static int cpuset_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
| 1812 | { | 1812 | { |
| 1813 | struct cpuset *c_parent = dentry->d_parent->d_fsdata; | 1813 | struct cpuset *c_parent = dentry->d_parent->d_fsdata; |
| 1814 | 1814 | ||
| 1815 | /* the vfs holds inode->i_sem already */ | 1815 | /* the vfs holds inode->i_mutex already */ |
| 1816 | return cpuset_create(c_parent, dentry->d_name.name, mode | S_IFDIR); | 1816 | return cpuset_create(c_parent, dentry->d_name.name, mode | S_IFDIR); |
| 1817 | } | 1817 | } |
| 1818 | 1818 | ||
| @@ -1823,7 +1823,7 @@ static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry) | |||
| 1823 | struct cpuset *parent; | 1823 | struct cpuset *parent; |
| 1824 | char *pathbuf = NULL; | 1824 | char *pathbuf = NULL; |
| 1825 | 1825 | ||
| 1826 | /* the vfs holds both inode->i_sem already */ | 1826 | /* the vfs holds both inode->i_mutex already */ |
| 1827 | 1827 | ||
| 1828 | down(&manage_sem); | 1828 | down(&manage_sem); |
| 1829 | cpuset_update_task_memory_state(); | 1829 | cpuset_update_task_memory_state(); |
diff --git a/kernel/exit.c b/kernel/exit.c index caceabf3f230..309a46fa16f8 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <linux/syscalls.h> | 29 | #include <linux/syscalls.h> |
| 30 | #include <linux/signal.h> | 30 | #include <linux/signal.h> |
| 31 | #include <linux/cn_proc.h> | 31 | #include <linux/cn_proc.h> |
| 32 | #include <linux/mutex.h> | ||
| 32 | 33 | ||
| 33 | #include <asm/uaccess.h> | 34 | #include <asm/uaccess.h> |
| 34 | #include <asm/unistd.h> | 35 | #include <asm/unistd.h> |
| @@ -869,6 +870,10 @@ fastcall NORET_TYPE void do_exit(long code) | |||
| 869 | mpol_free(tsk->mempolicy); | 870 | mpol_free(tsk->mempolicy); |
| 870 | tsk->mempolicy = NULL; | 871 | tsk->mempolicy = NULL; |
| 871 | #endif | 872 | #endif |
| 873 | /* | ||
| 874 | * If DEBUG_MUTEXES is on, make sure we are holding no locks: | ||
| 875 | */ | ||
| 876 | mutex_debug_check_no_locks_held(tsk); | ||
| 872 | 877 | ||
| 873 | /* PF_DEAD causes final put_task_struct after we schedule. */ | 878 | /* PF_DEAD causes final put_task_struct after we schedule. */ |
| 874 | preempt_disable(); | 879 | preempt_disable(); |
diff --git a/kernel/fork.c b/kernel/fork.c index 72e3252c6763..b18d64554feb 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
| @@ -979,6 +979,10 @@ static task_t *copy_process(unsigned long clone_flags, | |||
| 979 | } | 979 | } |
| 980 | #endif | 980 | #endif |
| 981 | 981 | ||
| 982 | #ifdef CONFIG_DEBUG_MUTEXES | ||
| 983 | p->blocked_on = NULL; /* not blocked yet */ | ||
| 984 | #endif | ||
| 985 | |||
| 982 | p->tgid = p->pid; | 986 | p->tgid = p->pid; |
| 983 | if (clone_flags & CLONE_THREAD) | 987 | if (clone_flags & CLONE_THREAD) |
| 984 | p->tgid = current->tgid; | 988 | p->tgid = current->tgid; |
diff --git a/kernel/mutex-debug.c b/kernel/mutex-debug.c new file mode 100644 index 000000000000..4fcb051a8b9e --- /dev/null +++ b/kernel/mutex-debug.c | |||
| @@ -0,0 +1,464 @@ | |||
| 1 | /* | ||
| 2 | * kernel/mutex-debug.c | ||
| 3 | * | ||
| 4 | * Debugging code for mutexes | ||
| 5 | * | ||
| 6 | * Started by Ingo Molnar: | ||
| 7 | * | ||
| 8 | * Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com> | ||
| 9 | * | ||
| 10 | * lock debugging, locking tree, deadlock detection started by: | ||
| 11 | * | ||
| 12 | * Copyright (C) 2004, LynuxWorks, Inc., Igor Manyilov, Bill Huey | ||
| 13 | * Released under the General Public License (GPL). | ||
| 14 | */ | ||
| 15 | #include <linux/mutex.h> | ||
| 16 | #include <linux/sched.h> | ||
| 17 | #include <linux/delay.h> | ||
| 18 | #include <linux/module.h> | ||
| 19 | #include <linux/spinlock.h> | ||
| 20 | #include <linux/kallsyms.h> | ||
| 21 | #include <linux/interrupt.h> | ||
| 22 | |||
| 23 | #include <asm/mutex.h> | ||
| 24 | |||
| 25 | #include "mutex-debug.h" | ||
| 26 | |||
| 27 | /* | ||
| 28 | * We need a global lock when we walk through the multi-process | ||
| 29 | * lock tree. Only used in the deadlock-debugging case. | ||
| 30 | */ | ||
| 31 | DEFINE_SPINLOCK(debug_mutex_lock); | ||
| 32 | |||
| 33 | /* | ||
| 34 | * All locks held by all tasks, in a single global list: | ||
| 35 | */ | ||
| 36 | LIST_HEAD(debug_mutex_held_locks); | ||
| 37 | |||
| 38 | /* | ||
| 39 | * In the debug case we carry the caller's instruction pointer into | ||
| 40 | * other functions, but we dont want the function argument overhead | ||
| 41 | * in the nondebug case - hence these macros: | ||
| 42 | */ | ||
| 43 | #define __IP_DECL__ , unsigned long ip | ||
| 44 | #define __IP__ , ip | ||
| 45 | #define __RET_IP__ , (unsigned long)__builtin_return_address(0) | ||
| 46 | |||
| 47 | /* | ||
| 48 | * "mutex debugging enabled" flag. We turn it off when we detect | ||
| 49 | * the first problem because we dont want to recurse back | ||
| 50 | * into the tracing code when doing error printk or | ||
| 51 | * executing a BUG(): | ||
| 52 | */ | ||
| 53 | int debug_mutex_on = 1; | ||
| 54 | |||
| 55 | static void printk_task(struct task_struct *p) | ||
| 56 | { | ||
| 57 | if (p) | ||
| 58 | printk("%16s:%5d [%p, %3d]", p->comm, p->pid, p, p->prio); | ||
| 59 | else | ||
| 60 | printk("<none>"); | ||
| 61 | } | ||
| 62 | |||
| 63 | static void printk_ti(struct thread_info *ti) | ||
| 64 | { | ||
| 65 | if (ti) | ||
| 66 | printk_task(ti->task); | ||
| 67 | else | ||
| 68 | printk("<none>"); | ||
| 69 | } | ||
| 70 | |||
| 71 | static void printk_task_short(struct task_struct *p) | ||
| 72 | { | ||
| 73 | if (p) | ||
| 74 | printk("%s/%d [%p, %3d]", p->comm, p->pid, p, p->prio); | ||
| 75 | else | ||
| 76 | printk("<none>"); | ||
| 77 | } | ||
| 78 | |||
| 79 | static void printk_lock(struct mutex *lock, int print_owner) | ||
| 80 | { | ||
| 81 | printk(" [%p] {%s}\n", lock, lock->name); | ||
| 82 | |||
| 83 | if (print_owner && lock->owner) { | ||
| 84 | printk(".. held by: "); | ||
| 85 | printk_ti(lock->owner); | ||
| 86 | printk("\n"); | ||
| 87 | } | ||
| 88 | if (lock->owner) { | ||
| 89 | printk("... acquired at: "); | ||
| 90 | print_symbol("%s\n", lock->acquire_ip); | ||
| 91 | } | ||
| 92 | } | ||
| 93 | |||
| 94 | /* | ||
| 95 | * printk locks held by a task: | ||
| 96 | */ | ||
| 97 | static void show_task_locks(struct task_struct *p) | ||
| 98 | { | ||
| 99 | switch (p->state) { | ||
| 100 | case TASK_RUNNING: printk("R"); break; | ||
| 101 | case TASK_INTERRUPTIBLE: printk("S"); break; | ||
| 102 | case TASK_UNINTERRUPTIBLE: printk("D"); break; | ||
| 103 | case TASK_STOPPED: printk("T"); break; | ||
| 104 | case EXIT_ZOMBIE: printk("Z"); break; | ||
| 105 | case EXIT_DEAD: printk("X"); break; | ||
| 106 | default: printk("?"); break; | ||
| 107 | } | ||
| 108 | printk_task(p); | ||
| 109 | if (p->blocked_on) { | ||
| 110 | struct mutex *lock = p->blocked_on->lock; | ||
| 111 | |||
| 112 | printk(" blocked on mutex:"); | ||
| 113 | printk_lock(lock, 1); | ||
| 114 | } else | ||
| 115 | printk(" (not blocked on mutex)\n"); | ||
| 116 | } | ||
| 117 | |||
| 118 | /* | ||
| 119 | * printk all locks held in the system (if filter == NULL), | ||
| 120 | * or all locks belonging to a single task (if filter != NULL): | ||
| 121 | */ | ||
| 122 | void show_held_locks(struct task_struct *filter) | ||
| 123 | { | ||
| 124 | struct list_head *curr, *cursor = NULL; | ||
| 125 | struct mutex *lock; | ||
| 126 | struct thread_info *t; | ||
| 127 | unsigned long flags; | ||
| 128 | int count = 0; | ||
| 129 | |||
| 130 | if (filter) { | ||
| 131 | printk("------------------------------\n"); | ||
| 132 | printk("| showing all locks held by: | ("); | ||
| 133 | printk_task_short(filter); | ||
| 134 | printk("):\n"); | ||
| 135 | printk("------------------------------\n"); | ||
| 136 | } else { | ||
| 137 | printk("---------------------------\n"); | ||
| 138 | printk("| showing all locks held: |\n"); | ||
| 139 | printk("---------------------------\n"); | ||
| 140 | } | ||
| 141 | |||
| 142 | /* | ||
| 143 | * Play safe and acquire the global trace lock. We | ||
| 144 | * cannot printk with that lock held so we iterate | ||
| 145 | * very carefully: | ||
| 146 | */ | ||
| 147 | next: | ||
| 148 | debug_spin_lock_save(&debug_mutex_lock, flags); | ||
| 149 | list_for_each(curr, &debug_mutex_held_locks) { | ||
| 150 | if (cursor && curr != cursor) | ||
| 151 | continue; | ||
| 152 | lock = list_entry(curr, struct mutex, held_list); | ||
| 153 | t = lock->owner; | ||
| 154 | if (filter && (t != filter->thread_info)) | ||
| 155 | continue; | ||
| 156 | count++; | ||
| 157 | cursor = curr->next; | ||
| 158 | debug_spin_lock_restore(&debug_mutex_lock, flags); | ||
| 159 | |||
| 160 | printk("\n#%03d: ", count); | ||
| 161 | printk_lock(lock, filter ? 0 : 1); | ||
| 162 | goto next; | ||
| 163 | } | ||
| 164 | debug_spin_lock_restore(&debug_mutex_lock, flags); | ||
| 165 | printk("\n"); | ||
| 166 | } | ||
| 167 | |||
| 168 | void mutex_debug_show_all_locks(void) | ||
| 169 | { | ||
| 170 | struct task_struct *g, *p; | ||
| 171 | int count = 10; | ||
| 172 | int unlock = 1; | ||
| 173 | |||
| 174 | printk("\nShowing all blocking locks in the system:\n"); | ||
| 175 | |||
| 176 | /* | ||
| 177 | * Here we try to get the tasklist_lock as hard as possible, | ||
| 178 | * if not successful after 2 seconds we ignore it (but keep | ||
| 179 | * trying). This is to enable a debug printout even if a | ||
| 180 | * tasklist_lock-holding task deadlocks or crashes. | ||
| 181 | */ | ||
| 182 | retry: | ||
| 183 | if (!read_trylock(&tasklist_lock)) { | ||
| 184 | if (count == 10) | ||
| 185 | printk("hm, tasklist_lock locked, retrying... "); | ||
| 186 | if (count) { | ||
| 187 | count--; | ||
| 188 | printk(" #%d", 10-count); | ||
| 189 | mdelay(200); | ||
| 190 | goto retry; | ||
| 191 | } | ||
| 192 | printk(" ignoring it.\n"); | ||
| 193 | unlock = 0; | ||
| 194 | } | ||
| 195 | if (count != 10) | ||
| 196 | printk(" locked it.\n"); | ||
| 197 | |||
| 198 | do_each_thread(g, p) { | ||
| 199 | show_task_locks(p); | ||
| 200 | if (!unlock) | ||
| 201 | if (read_trylock(&tasklist_lock)) | ||
| 202 | unlock = 1; | ||
| 203 | } while_each_thread(g, p); | ||
| 204 | |||
| 205 | printk("\n"); | ||
| 206 | show_held_locks(NULL); | ||
| 207 | printk("=============================================\n\n"); | ||
| 208 | |||
| 209 | if (unlock) | ||
| 210 | read_unlock(&tasklist_lock); | ||
| 211 | } | ||
| 212 | |||
| 213 | static void report_deadlock(struct task_struct *task, struct mutex *lock, | ||
| 214 | struct mutex *lockblk, unsigned long ip) | ||
| 215 | { | ||
| 216 | printk("\n%s/%d is trying to acquire this lock:\n", | ||
| 217 | current->comm, current->pid); | ||
| 218 | printk_lock(lock, 1); | ||
| 219 | printk("... trying at: "); | ||
| 220 | print_symbol("%s\n", ip); | ||
| 221 | show_held_locks(current); | ||
| 222 | |||
| 223 | if (lockblk) { | ||
| 224 | printk("but %s/%d is deadlocking current task %s/%d!\n\n", | ||
| 225 | task->comm, task->pid, current->comm, current->pid); | ||
| 226 | printk("\n%s/%d is blocked on this lock:\n", | ||
| 227 | task->comm, task->pid); | ||
| 228 | printk_lock(lockblk, 1); | ||
| 229 | |||
| 230 | show_held_locks(task); | ||
| 231 | |||
| 232 | printk("\n%s/%d's [blocked] stackdump:\n\n", | ||
| 233 | task->comm, task->pid); | ||
| 234 | show_stack(task, NULL); | ||
| 235 | } | ||
| 236 | |||
| 237 | printk("\n%s/%d's [current] stackdump:\n\n", | ||
| 238 | current->comm, current->pid); | ||
| 239 | dump_stack(); | ||
| 240 | mutex_debug_show_all_locks(); | ||
| 241 | printk("[ turning off deadlock detection. Please report this. ]\n\n"); | ||
| 242 | local_irq_disable(); | ||
| 243 | } | ||
| 244 | |||
| 245 | /* | ||
| 246 | * Recursively check for mutex deadlocks: | ||
| 247 | */ | ||
| 248 | static int check_deadlock(struct mutex *lock, int depth, | ||
| 249 | struct thread_info *ti, unsigned long ip) | ||
| 250 | { | ||
| 251 | struct mutex *lockblk; | ||
| 252 | struct task_struct *task; | ||
| 253 | |||
| 254 | if (!debug_mutex_on) | ||
| 255 | return 0; | ||
| 256 | |||
| 257 | ti = lock->owner; | ||
| 258 | if (!ti) | ||
| 259 | return 0; | ||
| 260 | |||
| 261 | task = ti->task; | ||
| 262 | lockblk = NULL; | ||
| 263 | if (task->blocked_on) | ||
| 264 | lockblk = task->blocked_on->lock; | ||
| 265 | |||
| 266 | /* Self-deadlock: */ | ||
| 267 | if (current == task) { | ||
| 268 | DEBUG_OFF(); | ||
| 269 | if (depth) | ||
| 270 | return 1; | ||
| 271 | printk("\n==========================================\n"); | ||
| 272 | printk( "[ BUG: lock recursion deadlock detected! |\n"); | ||
| 273 | printk( "------------------------------------------\n"); | ||
| 274 | report_deadlock(task, lock, NULL, ip); | ||
| 275 | return 0; | ||
| 276 | } | ||
| 277 | |||
| 278 | /* Ugh, something corrupted the lock data structure? */ | ||
| 279 | if (depth > 20) { | ||
| 280 | DEBUG_OFF(); | ||
| 281 | printk("\n===========================================\n"); | ||
| 282 | printk( "[ BUG: infinite lock dependency detected!? |\n"); | ||
| 283 | printk( "-------------------------------------------\n"); | ||
| 284 | report_deadlock(task, lock, lockblk, ip); | ||
| 285 | return 0; | ||
| 286 | } | ||
| 287 | |||
| 288 | /* Recursively check for dependencies: */ | ||
| 289 | if (lockblk && check_deadlock(lockblk, depth+1, ti, ip)) { | ||
| 290 | printk("\n============================================\n"); | ||
| 291 | printk( "[ BUG: circular locking deadlock detected! ]\n"); | ||
| 292 | printk( "--------------------------------------------\n"); | ||
| 293 | report_deadlock(task, lock, lockblk, ip); | ||
| 294 | return 0; | ||
| 295 | } | ||
| 296 | return 0; | ||
| 297 | } | ||
| 298 | |||
| 299 | /* | ||
| 300 | * Called when a task exits, this function checks whether the | ||
| 301 | * task is holding any locks, and reports the first one if so: | ||
| 302 | */ | ||
| 303 | void mutex_debug_check_no_locks_held(struct task_struct *task) | ||
| 304 | { | ||
| 305 | struct list_head *curr, *next; | ||
| 306 | struct thread_info *t; | ||
| 307 | unsigned long flags; | ||
| 308 | struct mutex *lock; | ||
| 309 | |||
| 310 | if (!debug_mutex_on) | ||
| 311 | return; | ||
| 312 | |||
| 313 | debug_spin_lock_save(&debug_mutex_lock, flags); | ||
| 314 | list_for_each_safe(curr, next, &debug_mutex_held_locks) { | ||
| 315 | lock = list_entry(curr, struct mutex, held_list); | ||
| 316 | t = lock->owner; | ||
| 317 | if (t != task->thread_info) | ||
| 318 | continue; | ||
| 319 | list_del_init(curr); | ||
| 320 | DEBUG_OFF(); | ||
| 321 | debug_spin_lock_restore(&debug_mutex_lock, flags); | ||
| 322 | |||
| 323 | printk("BUG: %s/%d, lock held at task exit time!\n", | ||
| 324 | task->comm, task->pid); | ||
| 325 | printk_lock(lock, 1); | ||
| 326 | if (lock->owner != task->thread_info) | ||
| 327 | printk("exiting task is not even the owner??\n"); | ||
| 328 | return; | ||
| 329 | } | ||
| 330 | debug_spin_lock_restore(&debug_mutex_lock, flags); | ||
| 331 | } | ||
| 332 | |||
| 333 | /* | ||
| 334 | * Called when kernel memory is freed (or unmapped), or if a mutex | ||
| 335 | * is destroyed or reinitialized - this code checks whether there is | ||
| 336 | * any held lock in the memory range of <from> to <to>: | ||
| 337 | */ | ||
| 338 | void mutex_debug_check_no_locks_freed(const void *from, const void *to) | ||
| 339 | { | ||
| 340 | struct list_head *curr, *next; | ||
| 341 | unsigned long flags; | ||
| 342 | struct mutex *lock; | ||
| 343 | void *lock_addr; | ||
| 344 | |||
| 345 | if (!debug_mutex_on) | ||
| 346 | return; | ||
| 347 | |||
| 348 | debug_spin_lock_save(&debug_mutex_lock, flags); | ||
| 349 | list_for_each_safe(curr, next, &debug_mutex_held_locks) { | ||
| 350 | lock = list_entry(curr, struct mutex, held_list); | ||
| 351 | lock_addr = lock; | ||
| 352 | if (lock_addr < from || lock_addr >= to) | ||
| 353 | continue; | ||
| 354 | list_del_init(curr); | ||
| 355 | DEBUG_OFF(); | ||
| 356 | debug_spin_lock_restore(&debug_mutex_lock, flags); | ||
| 357 | |||
| 358 | printk("BUG: %s/%d, active lock [%p(%p-%p)] freed!\n", | ||
| 359 | current->comm, current->pid, lock, from, to); | ||
| 360 | dump_stack(); | ||
| 361 | printk_lock(lock, 1); | ||
| 362 | if (lock->owner != current_thread_info()) | ||
| 363 | printk("freeing task is not even the owner??\n"); | ||
| 364 | return; | ||
| 365 | } | ||
| 366 | debug_spin_lock_restore(&debug_mutex_lock, flags); | ||
| 367 | } | ||
| 368 | |||
| 369 | /* | ||
| 370 | * Must be called with lock->wait_lock held. | ||
| 371 | */ | ||
| 372 | void debug_mutex_set_owner(struct mutex *lock, | ||
| 373 | struct thread_info *new_owner __IP_DECL__) | ||
| 374 | { | ||
| 375 | lock->owner = new_owner; | ||
| 376 | DEBUG_WARN_ON(!list_empty(&lock->held_list)); | ||
| 377 | if (debug_mutex_on) { | ||
| 378 | list_add_tail(&lock->held_list, &debug_mutex_held_locks); | ||
| 379 | lock->acquire_ip = ip; | ||
| 380 | } | ||
| 381 | } | ||
| 382 | |||
| 383 | void debug_mutex_init_waiter(struct mutex_waiter *waiter) | ||
| 384 | { | ||
| 385 | memset(waiter, 0x11, sizeof(*waiter)); | ||
| 386 | waiter->magic = waiter; | ||
| 387 | INIT_LIST_HEAD(&waiter->list); | ||
| 388 | } | ||
| 389 | |||
| 390 | void debug_mutex_wake_waiter(struct mutex *lock, struct mutex_waiter *waiter) | ||
| 391 | { | ||
| 392 | SMP_DEBUG_WARN_ON(!spin_is_locked(&lock->wait_lock)); | ||
| 393 | DEBUG_WARN_ON(list_empty(&lock->wait_list)); | ||
| 394 | DEBUG_WARN_ON(waiter->magic != waiter); | ||
| 395 | DEBUG_WARN_ON(list_empty(&waiter->list)); | ||
| 396 | } | ||
| 397 | |||
| 398 | void debug_mutex_free_waiter(struct mutex_waiter *waiter) | ||
| 399 | { | ||
| 400 | DEBUG_WARN_ON(!list_empty(&waiter->list)); | ||
| 401 | memset(waiter, 0x22, sizeof(*waiter)); | ||
| 402 | } | ||
| 403 | |||
| 404 | void debug_mutex_add_waiter(struct mutex *lock, struct mutex_waiter *waiter, | ||
| 405 | struct thread_info *ti __IP_DECL__) | ||
| 406 | { | ||
| 407 | SMP_DEBUG_WARN_ON(!spin_is_locked(&lock->wait_lock)); | ||
| 408 | check_deadlock(lock, 0, ti, ip); | ||
| 409 | /* Mark the current thread as blocked on the lock: */ | ||
| 410 | ti->task->blocked_on = waiter; | ||
| 411 | waiter->lock = lock; | ||
| 412 | } | ||
| 413 | |||
| 414 | void mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter, | ||
| 415 | struct thread_info *ti) | ||
| 416 | { | ||
| 417 | DEBUG_WARN_ON(list_empty(&waiter->list)); | ||
| 418 | DEBUG_WARN_ON(waiter->task != ti->task); | ||
| 419 | DEBUG_WARN_ON(ti->task->blocked_on != waiter); | ||
| 420 | ti->task->blocked_on = NULL; | ||
| 421 | |||
| 422 | list_del_init(&waiter->list); | ||
| 423 | waiter->task = NULL; | ||
| 424 | } | ||
| 425 | |||
| 426 | void debug_mutex_unlock(struct mutex *lock) | ||
| 427 | { | ||
| 428 | DEBUG_WARN_ON(lock->magic != lock); | ||
| 429 | DEBUG_WARN_ON(!lock->wait_list.prev && !lock->wait_list.next); | ||
| 430 | DEBUG_WARN_ON(lock->owner != current_thread_info()); | ||
| 431 | if (debug_mutex_on) { | ||
| 432 | DEBUG_WARN_ON(list_empty(&lock->held_list)); | ||
| 433 | list_del_init(&lock->held_list); | ||
| 434 | } | ||
| 435 | } | ||
| 436 | |||
| 437 | void debug_mutex_init(struct mutex *lock, const char *name) | ||
| 438 | { | ||
| 439 | /* | ||
| 440 | * Make sure we are not reinitializing a held lock: | ||
| 441 | */ | ||
| 442 | mutex_debug_check_no_locks_freed((void *)lock, (void *)(lock + 1)); | ||
| 443 | lock->owner = NULL; | ||
| 444 | INIT_LIST_HEAD(&lock->held_list); | ||
| 445 | lock->name = name; | ||
| 446 | lock->magic = lock; | ||
| 447 | } | ||
| 448 | |||
| 449 | /*** | ||
| 450 | * mutex_destroy - mark a mutex unusable | ||
| 451 | * @lock: the mutex to be destroyed | ||
| 452 | * | ||
| 453 | * This function marks the mutex uninitialized, and any subsequent | ||
| 454 | * use of the mutex is forbidden. The mutex must not be locked when | ||
| 455 | * this function is called. | ||
| 456 | */ | ||
| 457 | void fastcall mutex_destroy(struct mutex *lock) | ||
| 458 | { | ||
| 459 | DEBUG_WARN_ON(mutex_is_locked(lock)); | ||
| 460 | lock->magic = NULL; | ||
| 461 | } | ||
| 462 | |||
| 463 | EXPORT_SYMBOL_GPL(mutex_destroy); | ||
| 464 | |||
diff --git a/kernel/mutex-debug.h b/kernel/mutex-debug.h new file mode 100644 index 000000000000..fd384050acb1 --- /dev/null +++ b/kernel/mutex-debug.h | |||
| @@ -0,0 +1,134 @@ | |||
| 1 | /* | ||
| 2 | * Mutexes: blocking mutual exclusion locks | ||
| 3 | * | ||
| 4 | * started by Ingo Molnar: | ||
| 5 | * | ||
| 6 | * Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com> | ||
| 7 | * | ||
| 8 | * This file contains mutex debugging related internal declarations, | ||
| 9 | * prototypes and inline functions, for the CONFIG_DEBUG_MUTEXES case. | ||
| 10 | * More details are in kernel/mutex-debug.c. | ||
| 11 | */ | ||
| 12 | |||
| 13 | extern spinlock_t debug_mutex_lock; | ||
| 14 | extern struct list_head debug_mutex_held_locks; | ||
| 15 | extern int debug_mutex_on; | ||
| 16 | |||
| 17 | /* | ||
| 18 | * In the debug case we carry the caller's instruction pointer into | ||
| 19 | * other functions, but we dont want the function argument overhead | ||
| 20 | * in the nondebug case - hence these macros: | ||
| 21 | */ | ||
| 22 | #define __IP_DECL__ , unsigned long ip | ||
| 23 | #define __IP__ , ip | ||
| 24 | #define __RET_IP__ , (unsigned long)__builtin_return_address(0) | ||
| 25 | |||
| 26 | /* | ||
| 27 | * This must be called with lock->wait_lock held. | ||
| 28 | */ | ||
| 29 | extern void debug_mutex_set_owner(struct mutex *lock, | ||
| 30 | struct thread_info *new_owner __IP_DECL__); | ||
| 31 | |||
| 32 | static inline void debug_mutex_clear_owner(struct mutex *lock) | ||
| 33 | { | ||
| 34 | lock->owner = NULL; | ||
| 35 | } | ||
| 36 | |||
| 37 | extern void debug_mutex_init_waiter(struct mutex_waiter *waiter); | ||
| 38 | extern void debug_mutex_wake_waiter(struct mutex *lock, | ||
| 39 | struct mutex_waiter *waiter); | ||
| 40 | extern void debug_mutex_free_waiter(struct mutex_waiter *waiter); | ||
| 41 | extern void debug_mutex_add_waiter(struct mutex *lock, | ||
| 42 | struct mutex_waiter *waiter, | ||
| 43 | struct thread_info *ti __IP_DECL__); | ||
| 44 | extern void mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter, | ||
| 45 | struct thread_info *ti); | ||
| 46 | extern void debug_mutex_unlock(struct mutex *lock); | ||
| 47 | extern void debug_mutex_init(struct mutex *lock, const char *name); | ||
| 48 | |||
| 49 | #define debug_spin_lock(lock) \ | ||
| 50 | do { \ | ||
| 51 | local_irq_disable(); \ | ||
| 52 | if (debug_mutex_on) \ | ||
| 53 | spin_lock(lock); \ | ||
| 54 | } while (0) | ||
| 55 | |||
| 56 | #define debug_spin_unlock(lock) \ | ||
| 57 | do { \ | ||
| 58 | if (debug_mutex_on) \ | ||
| 59 | spin_unlock(lock); \ | ||
| 60 | local_irq_enable(); \ | ||
| 61 | preempt_check_resched(); \ | ||
| 62 | } while (0) | ||
| 63 | |||
| 64 | #define debug_spin_lock_save(lock, flags) \ | ||
| 65 | do { \ | ||
| 66 | local_irq_save(flags); \ | ||
| 67 | if (debug_mutex_on) \ | ||
| 68 | spin_lock(lock); \ | ||
| 69 | } while (0) | ||
| 70 | |||
| 71 | #define debug_spin_lock_restore(lock, flags) \ | ||
| 72 | do { \ | ||
| 73 | if (debug_mutex_on) \ | ||
| 74 | spin_unlock(lock); \ | ||
| 75 | local_irq_restore(flags); \ | ||
| 76 | preempt_check_resched(); \ | ||
| 77 | } while (0) | ||
| 78 | |||
| 79 | #define spin_lock_mutex(lock) \ | ||
| 80 | do { \ | ||
| 81 | struct mutex *l = container_of(lock, struct mutex, wait_lock); \ | ||
| 82 | \ | ||
| 83 | DEBUG_WARN_ON(in_interrupt()); \ | ||
| 84 | debug_spin_lock(&debug_mutex_lock); \ | ||
| 85 | spin_lock(lock); \ | ||
| 86 | DEBUG_WARN_ON(l->magic != l); \ | ||
| 87 | } while (0) | ||
| 88 | |||
| 89 | #define spin_unlock_mutex(lock) \ | ||
| 90 | do { \ | ||
| 91 | spin_unlock(lock); \ | ||
| 92 | debug_spin_unlock(&debug_mutex_lock); \ | ||
| 93 | } while (0) | ||
| 94 | |||
| 95 | #define DEBUG_OFF() \ | ||
| 96 | do { \ | ||
| 97 | if (debug_mutex_on) { \ | ||
| 98 | debug_mutex_on = 0; \ | ||
| 99 | console_verbose(); \ | ||
| 100 | if (spin_is_locked(&debug_mutex_lock)) \ | ||
| 101 | spin_unlock(&debug_mutex_lock); \ | ||
| 102 | } \ | ||
| 103 | } while (0) | ||
| 104 | |||
| 105 | #define DEBUG_BUG() \ | ||
| 106 | do { \ | ||
| 107 | if (debug_mutex_on) { \ | ||
| 108 | DEBUG_OFF(); \ | ||
| 109 | BUG(); \ | ||
| 110 | } \ | ||
| 111 | } while (0) | ||
| 112 | |||
| 113 | #define DEBUG_WARN_ON(c) \ | ||
| 114 | do { \ | ||
| 115 | if (unlikely(c && debug_mutex_on)) { \ | ||
| 116 | DEBUG_OFF(); \ | ||
| 117 | WARN_ON(1); \ | ||
| 118 | } \ | ||
| 119 | } while (0) | ||
| 120 | |||
| 121 | # define DEBUG_BUG_ON(c) \ | ||
| 122 | do { \ | ||
| 123 | if (unlikely(c)) \ | ||
| 124 | DEBUG_BUG(); \ | ||
| 125 | } while (0) | ||
| 126 | |||
| 127 | #ifdef CONFIG_SMP | ||
| 128 | # define SMP_DEBUG_WARN_ON(c) DEBUG_WARN_ON(c) | ||
| 129 | # define SMP_DEBUG_BUG_ON(c) DEBUG_BUG_ON(c) | ||
| 130 | #else | ||
| 131 | # define SMP_DEBUG_WARN_ON(c) do { } while (0) | ||
| 132 | # define SMP_DEBUG_BUG_ON(c) do { } while (0) | ||
| 133 | #endif | ||
| 134 | |||
diff --git a/kernel/mutex.c b/kernel/mutex.c new file mode 100644 index 000000000000..7eb960661441 --- /dev/null +++ b/kernel/mutex.c | |||
| @@ -0,0 +1,325 @@ | |||
| 1 | /* | ||
| 2 | * kernel/mutex.c | ||
| 3 | * | ||
| 4 | * Mutexes: blocking mutual exclusion locks | ||
| 5 | * | ||
| 6 | * Started by Ingo Molnar: | ||
| 7 | * | ||
| 8 | * Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com> | ||
| 9 | * | ||
| 10 | * Many thanks to Arjan van de Ven, Thomas Gleixner, Steven Rostedt and | ||
| 11 | * David Howells for suggestions and improvements. | ||
| 12 | * | ||
| 13 | * Also see Documentation/mutex-design.txt. | ||
| 14 | */ | ||
| 15 | #include <linux/mutex.h> | ||
| 16 | #include <linux/sched.h> | ||
| 17 | #include <linux/module.h> | ||
| 18 | #include <linux/spinlock.h> | ||
| 19 | #include <linux/interrupt.h> | ||
| 20 | |||
| 21 | /* | ||
| 22 | * In the DEBUG case we are using the "NULL fastpath" for mutexes, | ||
| 23 | * which forces all calls into the slowpath: | ||
| 24 | */ | ||
| 25 | #ifdef CONFIG_DEBUG_MUTEXES | ||
| 26 | # include "mutex-debug.h" | ||
| 27 | # include <asm-generic/mutex-null.h> | ||
| 28 | #else | ||
| 29 | # include "mutex.h" | ||
| 30 | # include <asm/mutex.h> | ||
| 31 | #endif | ||
| 32 | |||
| 33 | /*** | ||
| 34 | * mutex_init - initialize the mutex | ||
| 35 | * @lock: the mutex to be initialized | ||
| 36 | * | ||
| 37 | * Initialize the mutex to unlocked state. | ||
| 38 | * | ||
| 39 | * It is not allowed to initialize an already locked mutex. | ||
| 40 | */ | ||
| 41 | void fastcall __mutex_init(struct mutex *lock, const char *name) | ||
| 42 | { | ||
| 43 | atomic_set(&lock->count, 1); | ||
| 44 | spin_lock_init(&lock->wait_lock); | ||
| 45 | INIT_LIST_HEAD(&lock->wait_list); | ||
| 46 | |||
| 47 | debug_mutex_init(lock, name); | ||
| 48 | } | ||
| 49 | |||
| 50 | EXPORT_SYMBOL(__mutex_init); | ||
| 51 | |||
| 52 | /* | ||
| 53 | * We split the mutex lock/unlock logic into separate fastpath and | ||
| 54 | * slowpath functions, to reduce the register pressure on the fastpath. | ||
| 55 | * We also put the fastpath first in the kernel image, to make sure the | ||
| 56 | * branch is predicted by the CPU as default-untaken. | ||
| 57 | */ | ||
| 58 | static void fastcall noinline __sched | ||
| 59 | __mutex_lock_slowpath(atomic_t *lock_count __IP_DECL__); | ||
| 60 | |||
| 61 | /*** | ||
| 62 | * mutex_lock - acquire the mutex | ||
| 63 | * @lock: the mutex to be acquired | ||
| 64 | * | ||
| 65 | * Lock the mutex exclusively for this task. If the mutex is not | ||
| 66 | * available right now, it will sleep until it can get it. | ||
| 67 | * | ||
| 68 | * The mutex must later on be released by the same task that | ||
| 69 | * acquired it. Recursive locking is not allowed. The task | ||
| 70 | * may not exit without first unlocking the mutex. Also, kernel | ||
| 71 | * memory where the mutex resides mutex must not be freed with | ||
| 72 | * the mutex still locked. The mutex must first be initialized | ||
| 73 | * (or statically defined) before it can be locked. memset()-ing | ||
| 74 | * the mutex to 0 is not allowed. | ||
| 75 | * | ||
| 76 | * ( The CONFIG_DEBUG_MUTEXES .config option turns on debugging | ||
| 77 | * checks that will enforce the restrictions and will also do | ||
| 78 | * deadlock debugging. ) | ||
| 79 | * | ||
| 80 | * This function is similar to (but not equivalent to) down(). | ||
| 81 | */ | ||
| 82 | void fastcall __sched mutex_lock(struct mutex *lock) | ||
| 83 | { | ||
| 84 | /* | ||
| 85 | * The locking fastpath is the 1->0 transition from | ||
| 86 | * 'unlocked' into 'locked' state. | ||
| 87 | * | ||
| 88 | * NOTE: if asm/mutex.h is included, then some architectures | ||
| 89 | * rely on mutex_lock() having _no other code_ here but this | ||
| 90 | * fastpath. That allows the assembly fastpath to do | ||
| 91 | * tail-merging optimizations. (If you want to put testcode | ||
| 92 | * here, do it under #ifndef CONFIG_MUTEX_DEBUG.) | ||
| 93 | */ | ||
| 94 | __mutex_fastpath_lock(&lock->count, __mutex_lock_slowpath); | ||
| 95 | } | ||
| 96 | |||
| 97 | EXPORT_SYMBOL(mutex_lock); | ||
| 98 | |||
| 99 | static void fastcall noinline __sched | ||
| 100 | __mutex_unlock_slowpath(atomic_t *lock_count __IP_DECL__); | ||
| 101 | |||
| 102 | /*** | ||
| 103 | * mutex_unlock - release the mutex | ||
| 104 | * @lock: the mutex to be released | ||
| 105 | * | ||
| 106 | * Unlock a mutex that has been locked by this task previously. | ||
| 107 | * | ||
| 108 | * This function must not be used in interrupt context. Unlocking | ||
| 109 | * of a not locked mutex is not allowed. | ||
| 110 | * | ||
| 111 | * This function is similar to (but not equivalent to) up(). | ||
| 112 | */ | ||
| 113 | void fastcall __sched mutex_unlock(struct mutex *lock) | ||
| 114 | { | ||
| 115 | /* | ||
| 116 | * The unlocking fastpath is the 0->1 transition from 'locked' | ||
| 117 | * into 'unlocked' state: | ||
| 118 | * | ||
| 119 | * NOTE: no other code must be here - see mutex_lock() . | ||
| 120 | */ | ||
| 121 | __mutex_fastpath_unlock(&lock->count, __mutex_unlock_slowpath); | ||
| 122 | } | ||
| 123 | |||
| 124 | EXPORT_SYMBOL(mutex_unlock); | ||
| 125 | |||
| 126 | /* | ||
| 127 | * Lock a mutex (possibly interruptible), slowpath: | ||
| 128 | */ | ||
| 129 | static inline int __sched | ||
| 130 | __mutex_lock_common(struct mutex *lock, long state __IP_DECL__) | ||
| 131 | { | ||
| 132 | struct task_struct *task = current; | ||
| 133 | struct mutex_waiter waiter; | ||
| 134 | unsigned int old_val; | ||
| 135 | |||
| 136 | debug_mutex_init_waiter(&waiter); | ||
| 137 | |||
| 138 | spin_lock_mutex(&lock->wait_lock); | ||
| 139 | |||
| 140 | debug_mutex_add_waiter(lock, &waiter, task->thread_info, ip); | ||
| 141 | |||
| 142 | /* add waiting tasks to the end of the waitqueue (FIFO): */ | ||
| 143 | list_add_tail(&waiter.list, &lock->wait_list); | ||
| 144 | waiter.task = task; | ||
| 145 | |||
| 146 | for (;;) { | ||
| 147 | /* | ||
| 148 | * Lets try to take the lock again - this is needed even if | ||
| 149 | * we get here for the first time (shortly after failing to | ||
| 150 | * acquire the lock), to make sure that we get a wakeup once | ||
| 151 | * it's unlocked. Later on, if we sleep, this is the | ||
| 152 | * operation that gives us the lock. We xchg it to -1, so | ||
| 153 | * that when we release the lock, we properly wake up the | ||
| 154 | * other waiters: | ||
| 155 | */ | ||
| 156 | old_val = atomic_xchg(&lock->count, -1); | ||
| 157 | if (old_val == 1) | ||
| 158 | break; | ||
| 159 | |||
| 160 | /* | ||
| 161 | * got a signal? (This code gets eliminated in the | ||
| 162 | * TASK_UNINTERRUPTIBLE case.) | ||
| 163 | */ | ||
| 164 | if (unlikely(state == TASK_INTERRUPTIBLE && | ||
| 165 | signal_pending(task))) { | ||
| 166 | mutex_remove_waiter(lock, &waiter, task->thread_info); | ||
| 167 | spin_unlock_mutex(&lock->wait_lock); | ||
| 168 | |||
| 169 | debug_mutex_free_waiter(&waiter); | ||
| 170 | return -EINTR; | ||
| 171 | } | ||
| 172 | __set_task_state(task, state); | ||
| 173 | |||
| 174 | /* didnt get the lock, go to sleep: */ | ||
| 175 | spin_unlock_mutex(&lock->wait_lock); | ||
| 176 | schedule(); | ||
| 177 | spin_lock_mutex(&lock->wait_lock); | ||
| 178 | } | ||
| 179 | |||
| 180 | /* got the lock - rejoice! */ | ||
| 181 | mutex_remove_waiter(lock, &waiter, task->thread_info); | ||
| 182 | debug_mutex_set_owner(lock, task->thread_info __IP__); | ||
| 183 | |||
| 184 | /* set it to 0 if there are no waiters left: */ | ||
| 185 | if (likely(list_empty(&lock->wait_list))) | ||
| 186 | atomic_set(&lock->count, 0); | ||
| 187 | |||
| 188 | spin_unlock_mutex(&lock->wait_lock); | ||
| 189 | |||
| 190 | debug_mutex_free_waiter(&waiter); | ||
| 191 | |||
| 192 | DEBUG_WARN_ON(list_empty(&lock->held_list)); | ||
| 193 | DEBUG_WARN_ON(lock->owner != task->thread_info); | ||
| 194 | |||
| 195 | return 0; | ||
| 196 | } | ||
| 197 | |||
| 198 | static void fastcall noinline __sched | ||
| 199 | __mutex_lock_slowpath(atomic_t *lock_count __IP_DECL__) | ||
| 200 | { | ||
| 201 | struct mutex *lock = container_of(lock_count, struct mutex, count); | ||
| 202 | |||
| 203 | __mutex_lock_common(lock, TASK_UNINTERRUPTIBLE __IP__); | ||
| 204 | } | ||
| 205 | |||
| 206 | /* | ||
| 207 | * Release the lock, slowpath: | ||
| 208 | */ | ||
| 209 | static fastcall noinline void | ||
| 210 | __mutex_unlock_slowpath(atomic_t *lock_count __IP_DECL__) | ||
| 211 | { | ||
| 212 | struct mutex *lock = container_of(lock_count, struct mutex, count); | ||
| 213 | |||
| 214 | DEBUG_WARN_ON(lock->owner != current_thread_info()); | ||
| 215 | |||
| 216 | spin_lock_mutex(&lock->wait_lock); | ||
| 217 | |||
| 218 | /* | ||
| 219 | * some architectures leave the lock unlocked in the fastpath failure | ||
| 220 | * case, others need to leave it locked. In the later case we have to | ||
| 221 | * unlock it here | ||
| 222 | */ | ||
| 223 | if (__mutex_slowpath_needs_to_unlock()) | ||
| 224 | atomic_set(&lock->count, 1); | ||
| 225 | |||
| 226 | debug_mutex_unlock(lock); | ||
| 227 | |||
| 228 | if (!list_empty(&lock->wait_list)) { | ||
| 229 | /* get the first entry from the wait-list: */ | ||
| 230 | struct mutex_waiter *waiter = | ||
| 231 | list_entry(lock->wait_list.next, | ||
| 232 | struct mutex_waiter, list); | ||
| 233 | |||
| 234 | debug_mutex_wake_waiter(lock, waiter); | ||
| 235 | |||
| 236 | wake_up_process(waiter->task); | ||
| 237 | } | ||
| 238 | |||
| 239 | debug_mutex_clear_owner(lock); | ||
| 240 | |||
| 241 | spin_unlock_mutex(&lock->wait_lock); | ||
| 242 | } | ||
| 243 | |||
| 244 | /* | ||
| 245 | * Here come the less common (and hence less performance-critical) APIs: | ||
| 246 | * mutex_lock_interruptible() and mutex_trylock(). | ||
| 247 | */ | ||
| 248 | static int fastcall noinline __sched | ||
| 249 | __mutex_lock_interruptible_slowpath(atomic_t *lock_count __IP_DECL__); | ||
| 250 | |||
| 251 | /*** | ||
| 252 | * mutex_lock_interruptible - acquire the mutex, interruptable | ||
| 253 | * @lock: the mutex to be acquired | ||
| 254 | * | ||
| 255 | * Lock the mutex like mutex_lock(), and return 0 if the mutex has | ||
| 256 | * been acquired or sleep until the mutex becomes available. If a | ||
| 257 | * signal arrives while waiting for the lock then this function | ||
| 258 | * returns -EINTR. | ||
| 259 | * | ||
| 260 | * This function is similar to (but not equivalent to) down_interruptible(). | ||
| 261 | */ | ||
| 262 | int fastcall __sched mutex_lock_interruptible(struct mutex *lock) | ||
| 263 | { | ||
| 264 | /* NOTE: no other code must be here - see mutex_lock() */ | ||
| 265 | return __mutex_fastpath_lock_retval | ||
| 266 | (&lock->count, __mutex_lock_interruptible_slowpath); | ||
| 267 | } | ||
| 268 | |||
| 269 | EXPORT_SYMBOL(mutex_lock_interruptible); | ||
| 270 | |||
| 271 | static int fastcall noinline __sched | ||
| 272 | __mutex_lock_interruptible_slowpath(atomic_t *lock_count __IP_DECL__) | ||
| 273 | { | ||
| 274 | struct mutex *lock = container_of(lock_count, struct mutex, count); | ||
| 275 | |||
| 276 | return __mutex_lock_common(lock, TASK_INTERRUPTIBLE __IP__); | ||
| 277 | } | ||
| 278 | |||
| 279 | /* | ||
| 280 | * Spinlock based trylock, we take the spinlock and check whether we | ||
| 281 | * can get the lock: | ||
| 282 | */ | ||
| 283 | static inline int __mutex_trylock_slowpath(atomic_t *lock_count) | ||
| 284 | { | ||
| 285 | struct mutex *lock = container_of(lock_count, struct mutex, count); | ||
| 286 | int prev; | ||
| 287 | |||
| 288 | spin_lock_mutex(&lock->wait_lock); | ||
| 289 | |||
| 290 | prev = atomic_xchg(&lock->count, -1); | ||
| 291 | if (likely(prev == 1)) | ||
| 292 | debug_mutex_set_owner(lock, current_thread_info() __RET_IP__); | ||
| 293 | /* Set it back to 0 if there are no waiters: */ | ||
| 294 | if (likely(list_empty(&lock->wait_list))) | ||
| 295 | atomic_set(&lock->count, 0); | ||
| 296 | |||
| 297 | spin_unlock_mutex(&lock->wait_lock); | ||
| 298 | |||
| 299 | return prev == 1; | ||
| 300 | } | ||
| 301 | |||
| 302 | /*** | ||
| 303 | * mutex_trylock - try acquire the mutex, without waiting | ||
| 304 | * @lock: the mutex to be acquired | ||
| 305 | * | ||
| 306 | * Try to acquire the mutex atomically. Returns 1 if the mutex | ||
| 307 | * has been acquired successfully, and 0 on contention. | ||
| 308 | * | ||
| 309 | * NOTE: this function follows the spin_trylock() convention, so | ||
| 310 | * it is negated to the down_trylock() return values! Be careful | ||
| 311 | * about this when converting semaphore users to mutexes. | ||
| 312 | * | ||
| 313 | * This function must not be used in interrupt context. The | ||
| 314 | * mutex must be released by the same task that acquired it. | ||
| 315 | */ | ||
| 316 | int fastcall mutex_trylock(struct mutex *lock) | ||
| 317 | { | ||
| 318 | return __mutex_fastpath_trylock(&lock->count, | ||
| 319 | __mutex_trylock_slowpath); | ||
| 320 | } | ||
| 321 | |||
| 322 | EXPORT_SYMBOL(mutex_trylock); | ||
| 323 | |||
| 324 | |||
| 325 | |||
diff --git a/kernel/mutex.h b/kernel/mutex.h new file mode 100644 index 000000000000..00fe84e7b672 --- /dev/null +++ b/kernel/mutex.h | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | /* | ||
| 2 | * Mutexes: blocking mutual exclusion locks | ||
| 3 | * | ||
| 4 | * started by Ingo Molnar: | ||
| 5 | * | ||
| 6 | * Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com> | ||
| 7 | * | ||
| 8 | * This file contains mutex debugging related internal prototypes, for the | ||
| 9 | * !CONFIG_DEBUG_MUTEXES case. Most of them are NOPs: | ||
| 10 | */ | ||
| 11 | |||
| 12 | #define spin_lock_mutex(lock) spin_lock(lock) | ||
| 13 | #define spin_unlock_mutex(lock) spin_unlock(lock) | ||
| 14 | #define mutex_remove_waiter(lock, waiter, ti) \ | ||
| 15 | __list_del((waiter)->list.prev, (waiter)->list.next) | ||
| 16 | |||
| 17 | #define DEBUG_WARN_ON(c) do { } while (0) | ||
| 18 | #define debug_mutex_set_owner(lock, new_owner) do { } while (0) | ||
| 19 | #define debug_mutex_clear_owner(lock) do { } while (0) | ||
| 20 | #define debug_mutex_init_waiter(waiter) do { } while (0) | ||
| 21 | #define debug_mutex_wake_waiter(lock, waiter) do { } while (0) | ||
| 22 | #define debug_mutex_free_waiter(waiter) do { } while (0) | ||
| 23 | #define debug_mutex_add_waiter(lock, waiter, ti, ip) do { } while (0) | ||
| 24 | #define debug_mutex_unlock(lock) do { } while (0) | ||
| 25 | #define debug_mutex_init(lock, name) do { } while (0) | ||
| 26 | |||
| 27 | /* | ||
| 28 | * Return-address parameters/declarations. They are very useful for | ||
| 29 | * debugging, but add overhead in the !DEBUG case - so we go the | ||
| 30 | * trouble of using this not too elegant but zero-cost solution: | ||
| 31 | */ | ||
| 32 | #define __IP_DECL__ | ||
| 33 | #define __IP__ | ||
| 34 | #define __RET_IP__ | ||
| 35 | |||
diff --git a/kernel/sched.c b/kernel/sched.c index 92733091154c..34a945bcc022 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
| @@ -4386,6 +4386,7 @@ void show_state(void) | |||
| 4386 | } while_each_thread(g, p); | 4386 | } while_each_thread(g, p); |
| 4387 | 4387 | ||
| 4388 | read_unlock(&tasklist_lock); | 4388 | read_unlock(&tasklist_lock); |
| 4389 | mutex_debug_show_all_locks(); | ||
| 4389 | } | 4390 | } |
| 4390 | 4391 | ||
| 4391 | /** | 4392 | /** |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index c48260fb8fd9..1fcd856edec1 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
| @@ -95,6 +95,14 @@ config DEBUG_PREEMPT | |||
| 95 | if kernel code uses it in a preemption-unsafe way. Also, the kernel | 95 | if kernel code uses it in a preemption-unsafe way. Also, the kernel |
| 96 | will detect preemption count underflows. | 96 | will detect preemption count underflows. |
| 97 | 97 | ||
| 98 | config DEBUG_MUTEXES | ||
| 99 | bool "Mutex debugging, deadlock detection" | ||
| 100 | default y | ||
| 101 | depends on DEBUG_KERNEL | ||
| 102 | help | ||
| 103 | This allows mutex semantics violations and mutex related deadlocks | ||
| 104 | (lockups) to be detected and reported automatically. | ||
| 105 | |||
| 98 | config DEBUG_SPINLOCK | 106 | config DEBUG_SPINLOCK |
| 99 | bool "Spinlock debugging" | 107 | bool "Spinlock debugging" |
| 100 | depends on DEBUG_KERNEL | 108 | depends on DEBUG_KERNEL |
diff --git a/mm/filemap.c b/mm/filemap.c index 478f4c74cc31..5fca2737c971 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
| @@ -61,7 +61,7 @@ generic_file_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, | |||
| 61 | * ->swap_lock (exclusive_swap_page, others) | 61 | * ->swap_lock (exclusive_swap_page, others) |
| 62 | * ->mapping->tree_lock | 62 | * ->mapping->tree_lock |
| 63 | * | 63 | * |
| 64 | * ->i_sem | 64 | * ->i_mutex |
| 65 | * ->i_mmap_lock (truncate->unmap_mapping_range) | 65 | * ->i_mmap_lock (truncate->unmap_mapping_range) |
| 66 | * | 66 | * |
| 67 | * ->mmap_sem | 67 | * ->mmap_sem |
| @@ -73,9 +73,9 @@ generic_file_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, | |||
| 73 | * ->lock_page (access_process_vm) | 73 | * ->lock_page (access_process_vm) |
| 74 | * | 74 | * |
| 75 | * ->mmap_sem | 75 | * ->mmap_sem |
| 76 | * ->i_sem (msync) | 76 | * ->i_mutex (msync) |
| 77 | * | 77 | * |
| 78 | * ->i_sem | 78 | * ->i_mutex |
| 79 | * ->i_alloc_sem (various) | 79 | * ->i_alloc_sem (various) |
| 80 | * | 80 | * |
| 81 | * ->inode_lock | 81 | * ->inode_lock |
| @@ -276,7 +276,7 @@ static int wait_on_page_writeback_range(struct address_space *mapping, | |||
| 276 | * integrity" operation. It waits upon in-flight writeout before starting and | 276 | * integrity" operation. It waits upon in-flight writeout before starting and |
| 277 | * waiting upon new writeout. If there was an IO error, return it. | 277 | * waiting upon new writeout. If there was an IO error, return it. |
| 278 | * | 278 | * |
| 279 | * We need to re-take i_sem during the generic_osync_inode list walk because | 279 | * We need to re-take i_mutex during the generic_osync_inode list walk because |
| 280 | * it is otherwise livelockable. | 280 | * it is otherwise livelockable. |
| 281 | */ | 281 | */ |
| 282 | int sync_page_range(struct inode *inode, struct address_space *mapping, | 282 | int sync_page_range(struct inode *inode, struct address_space *mapping, |
| @@ -290,9 +290,9 @@ int sync_page_range(struct inode *inode, struct address_space *mapping, | |||
| 290 | return 0; | 290 | return 0; |
| 291 | ret = filemap_fdatawrite_range(mapping, pos, pos + count - 1); | 291 | ret = filemap_fdatawrite_range(mapping, pos, pos + count - 1); |
| 292 | if (ret == 0) { | 292 | if (ret == 0) { |
| 293 | down(&inode->i_sem); | 293 | mutex_lock(&inode->i_mutex); |
| 294 | ret = generic_osync_inode(inode, mapping, OSYNC_METADATA); | 294 | ret = generic_osync_inode(inode, mapping, OSYNC_METADATA); |
| 295 | up(&inode->i_sem); | 295 | mutex_unlock(&inode->i_mutex); |
| 296 | } | 296 | } |
| 297 | if (ret == 0) | 297 | if (ret == 0) |
| 298 | ret = wait_on_page_writeback_range(mapping, start, end); | 298 | ret = wait_on_page_writeback_range(mapping, start, end); |
| @@ -301,7 +301,7 @@ int sync_page_range(struct inode *inode, struct address_space *mapping, | |||
| 301 | EXPORT_SYMBOL(sync_page_range); | 301 | EXPORT_SYMBOL(sync_page_range); |
| 302 | 302 | ||
| 303 | /* | 303 | /* |
| 304 | * Note: Holding i_sem across sync_page_range_nolock is not a good idea | 304 | * Note: Holding i_mutex across sync_page_range_nolock is not a good idea |
| 305 | * as it forces O_SYNC writers to different parts of the same file | 305 | * as it forces O_SYNC writers to different parts of the same file |
| 306 | * to be serialised right until io completion. | 306 | * to be serialised right until io completion. |
| 307 | */ | 307 | */ |
| @@ -1892,7 +1892,7 @@ generic_file_direct_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 1892 | /* | 1892 | /* |
| 1893 | * Sync the fs metadata but not the minor inode changes and | 1893 | * Sync the fs metadata but not the minor inode changes and |
| 1894 | * of course not the data as we did direct DMA for the IO. | 1894 | * of course not the data as we did direct DMA for the IO. |
| 1895 | * i_sem is held, which protects generic_osync_inode() from | 1895 | * i_mutex is held, which protects generic_osync_inode() from |
| 1896 | * livelocking. | 1896 | * livelocking. |
| 1897 | */ | 1897 | */ |
| 1898 | if (written >= 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { | 1898 | if (written >= 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { |
| @@ -2195,10 +2195,10 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const char __user *buf, | |||
| 2195 | 2195 | ||
| 2196 | BUG_ON(iocb->ki_pos != pos); | 2196 | BUG_ON(iocb->ki_pos != pos); |
| 2197 | 2197 | ||
| 2198 | down(&inode->i_sem); | 2198 | mutex_lock(&inode->i_mutex); |
| 2199 | ret = __generic_file_aio_write_nolock(iocb, &local_iov, 1, | 2199 | ret = __generic_file_aio_write_nolock(iocb, &local_iov, 1, |
| 2200 | &iocb->ki_pos); | 2200 | &iocb->ki_pos); |
| 2201 | up(&inode->i_sem); | 2201 | mutex_unlock(&inode->i_mutex); |
| 2202 | 2202 | ||
| 2203 | if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { | 2203 | if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { |
| 2204 | ssize_t err; | 2204 | ssize_t err; |
| @@ -2220,9 +2220,9 @@ ssize_t generic_file_write(struct file *file, const char __user *buf, | |||
| 2220 | struct iovec local_iov = { .iov_base = (void __user *)buf, | 2220 | struct iovec local_iov = { .iov_base = (void __user *)buf, |
| 2221 | .iov_len = count }; | 2221 | .iov_len = count }; |
| 2222 | 2222 | ||
| 2223 | down(&inode->i_sem); | 2223 | mutex_lock(&inode->i_mutex); |
| 2224 | ret = __generic_file_write_nolock(file, &local_iov, 1, ppos); | 2224 | ret = __generic_file_write_nolock(file, &local_iov, 1, ppos); |
| 2225 | up(&inode->i_sem); | 2225 | mutex_unlock(&inode->i_mutex); |
| 2226 | 2226 | ||
| 2227 | if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { | 2227 | if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { |
| 2228 | ssize_t err; | 2228 | ssize_t err; |
| @@ -2256,9 +2256,9 @@ ssize_t generic_file_writev(struct file *file, const struct iovec *iov, | |||
| 2256 | struct inode *inode = mapping->host; | 2256 | struct inode *inode = mapping->host; |
| 2257 | ssize_t ret; | 2257 | ssize_t ret; |
| 2258 | 2258 | ||
| 2259 | down(&inode->i_sem); | 2259 | mutex_lock(&inode->i_mutex); |
| 2260 | ret = __generic_file_write_nolock(file, iov, nr_segs, ppos); | 2260 | ret = __generic_file_write_nolock(file, iov, nr_segs, ppos); |
| 2261 | up(&inode->i_sem); | 2261 | mutex_unlock(&inode->i_mutex); |
| 2262 | 2262 | ||
| 2263 | if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { | 2263 | if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { |
| 2264 | int err; | 2264 | int err; |
| @@ -2272,7 +2272,7 @@ ssize_t generic_file_writev(struct file *file, const struct iovec *iov, | |||
| 2272 | EXPORT_SYMBOL(generic_file_writev); | 2272 | EXPORT_SYMBOL(generic_file_writev); |
| 2273 | 2273 | ||
| 2274 | /* | 2274 | /* |
| 2275 | * Called under i_sem for writes to S_ISREG files. Returns -EIO if something | 2275 | * Called under i_mutex for writes to S_ISREG files. Returns -EIO if something |
| 2276 | * went wrong during pagecache shootdown. | 2276 | * went wrong during pagecache shootdown. |
| 2277 | */ | 2277 | */ |
| 2278 | static ssize_t | 2278 | static ssize_t |
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c index 9cf687e4a29a..e2b34e95913e 100644 --- a/mm/filemap_xip.c +++ b/mm/filemap_xip.c | |||
| @@ -338,7 +338,7 @@ __xip_file_write(struct file *filp, const char __user *buf, | |||
| 338 | *ppos = pos; | 338 | *ppos = pos; |
| 339 | /* | 339 | /* |
| 340 | * No need to use i_size_read() here, the i_size | 340 | * No need to use i_size_read() here, the i_size |
| 341 | * cannot change under us because we hold i_sem. | 341 | * cannot change under us because we hold i_mutex. |
| 342 | */ | 342 | */ |
| 343 | if (pos > inode->i_size) { | 343 | if (pos > inode->i_size) { |
| 344 | i_size_write(inode, pos); | 344 | i_size_write(inode, pos); |
| @@ -358,7 +358,7 @@ xip_file_write(struct file *filp, const char __user *buf, size_t len, | |||
| 358 | loff_t pos; | 358 | loff_t pos; |
| 359 | ssize_t ret; | 359 | ssize_t ret; |
| 360 | 360 | ||
| 361 | down(&inode->i_sem); | 361 | mutex_lock(&inode->i_mutex); |
| 362 | 362 | ||
| 363 | if (!access_ok(VERIFY_READ, buf, len)) { | 363 | if (!access_ok(VERIFY_READ, buf, len)) { |
| 364 | ret=-EFAULT; | 364 | ret=-EFAULT; |
| @@ -390,7 +390,7 @@ xip_file_write(struct file *filp, const char __user *buf, size_t len, | |||
| 390 | out_backing: | 390 | out_backing: |
| 391 | current->backing_dev_info = NULL; | 391 | current->backing_dev_info = NULL; |
| 392 | out_up: | 392 | out_up: |
| 393 | up(&inode->i_sem); | 393 | mutex_unlock(&inode->i_mutex); |
| 394 | return ret; | 394 | return ret; |
| 395 | } | 395 | } |
| 396 | EXPORT_SYMBOL_GPL(xip_file_write); | 396 | EXPORT_SYMBOL_GPL(xip_file_write); |
diff --git a/mm/memory.c b/mm/memory.c index 3944fec38012..7a11ddd5060f 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
| @@ -1784,13 +1784,13 @@ int vmtruncate_range(struct inode *inode, loff_t offset, loff_t end) | |||
| 1784 | if (!inode->i_op || !inode->i_op->truncate_range) | 1784 | if (!inode->i_op || !inode->i_op->truncate_range) |
| 1785 | return -ENOSYS; | 1785 | return -ENOSYS; |
| 1786 | 1786 | ||
| 1787 | down(&inode->i_sem); | 1787 | mutex_lock(&inode->i_mutex); |
| 1788 | down_write(&inode->i_alloc_sem); | 1788 | down_write(&inode->i_alloc_sem); |
| 1789 | unmap_mapping_range(mapping, offset, (end - offset), 1); | 1789 | unmap_mapping_range(mapping, offset, (end - offset), 1); |
| 1790 | truncate_inode_pages_range(mapping, offset, end); | 1790 | truncate_inode_pages_range(mapping, offset, end); |
| 1791 | inode->i_op->truncate_range(inode, offset, end); | 1791 | inode->i_op->truncate_range(inode, offset, end); |
| 1792 | up_write(&inode->i_alloc_sem); | 1792 | up_write(&inode->i_alloc_sem); |
| 1793 | up(&inode->i_sem); | 1793 | mutex_unlock(&inode->i_mutex); |
| 1794 | 1794 | ||
| 1795 | return 0; | 1795 | return 0; |
| 1796 | } | 1796 | } |
diff --git a/mm/msync.c b/mm/msync.c index 1b5b6f662dcf..3563a56e1a51 100644 --- a/mm/msync.c +++ b/mm/msync.c | |||
| @@ -137,7 +137,7 @@ static int msync_interval(struct vm_area_struct *vma, | |||
| 137 | ret = filemap_fdatawrite(mapping); | 137 | ret = filemap_fdatawrite(mapping); |
| 138 | if (file->f_op && file->f_op->fsync) { | 138 | if (file->f_op && file->f_op->fsync) { |
| 139 | /* | 139 | /* |
| 140 | * We don't take i_sem here because mmap_sem | 140 | * We don't take i_mutex here because mmap_sem |
| 141 | * is already held. | 141 | * is already held. |
| 142 | */ | 142 | */ |
| 143 | err = file->f_op->fsync(file,file->f_dentry,1); | 143 | err = file->f_op->fsync(file,file->f_dentry,1); |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index e0e84924171b..a5e6891f7bb6 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
| @@ -415,6 +415,9 @@ static void __free_pages_ok(struct page *page, unsigned int order) | |||
| 415 | int reserved = 0; | 415 | int reserved = 0; |
| 416 | 416 | ||
| 417 | arch_free_page(page, order); | 417 | arch_free_page(page, order); |
| 418 | if (!PageHighMem(page)) | ||
| 419 | mutex_debug_check_no_locks_freed(page_address(page), | ||
| 420 | page_address(page+(1<<order))); | ||
| 418 | 421 | ||
| 419 | #ifndef CONFIG_MMU | 422 | #ifndef CONFIG_MMU |
| 420 | for (i = 1 ; i < (1 << order) ; ++i) | 423 | for (i = 1 ; i < (1 << order) ; ++i) |
| @@ -20,13 +20,13 @@ | |||
| 20 | /* | 20 | /* |
| 21 | * Lock ordering in mm: | 21 | * Lock ordering in mm: |
| 22 | * | 22 | * |
| 23 | * inode->i_sem (while writing or truncating, not reading or faulting) | 23 | * inode->i_mutex (while writing or truncating, not reading or faulting) |
| 24 | * inode->i_alloc_sem | 24 | * inode->i_alloc_sem |
| 25 | * | 25 | * |
| 26 | * When a page fault occurs in writing from user to file, down_read | 26 | * When a page fault occurs in writing from user to file, down_read |
| 27 | * of mmap_sem nests within i_sem; in sys_msync, i_sem nests within | 27 | * of mmap_sem nests within i_mutex; in sys_msync, i_mutex nests within |
| 28 | * down_read of mmap_sem; i_sem and down_write of mmap_sem are never | 28 | * down_read of mmap_sem; i_mutex and down_write of mmap_sem are never |
| 29 | * taken together; in truncation, i_sem is taken outermost. | 29 | * taken together; in truncation, i_mutex is taken outermost. |
| 30 | * | 30 | * |
| 31 | * mm->mmap_sem | 31 | * mm->mmap_sem |
| 32 | * page->flags PG_locked (lock_page) | 32 | * page->flags PG_locked (lock_page) |
diff --git a/mm/shmem.c b/mm/shmem.c index a1f2f02af724..343b3c0937e5 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
| @@ -1370,7 +1370,7 @@ shmem_file_write(struct file *file, const char __user *buf, size_t count, loff_t | |||
| 1370 | if (!access_ok(VERIFY_READ, buf, count)) | 1370 | if (!access_ok(VERIFY_READ, buf, count)) |
| 1371 | return -EFAULT; | 1371 | return -EFAULT; |
| 1372 | 1372 | ||
| 1373 | down(&inode->i_sem); | 1373 | mutex_lock(&inode->i_mutex); |
| 1374 | 1374 | ||
| 1375 | pos = *ppos; | 1375 | pos = *ppos; |
| 1376 | written = 0; | 1376 | written = 0; |
| @@ -1455,7 +1455,7 @@ shmem_file_write(struct file *file, const char __user *buf, size_t count, loff_t | |||
| 1455 | if (written) | 1455 | if (written) |
| 1456 | err = written; | 1456 | err = written; |
| 1457 | out: | 1457 | out: |
| 1458 | up(&inode->i_sem); | 1458 | mutex_unlock(&inode->i_mutex); |
| 1459 | return err; | 1459 | return err; |
| 1460 | } | 1460 | } |
| 1461 | 1461 | ||
| @@ -1491,7 +1491,7 @@ static void do_shmem_file_read(struct file *filp, loff_t *ppos, read_descriptor_ | |||
| 1491 | 1491 | ||
| 1492 | /* | 1492 | /* |
| 1493 | * We must evaluate after, since reads (unlike writes) | 1493 | * We must evaluate after, since reads (unlike writes) |
| 1494 | * are called without i_sem protection against truncate | 1494 | * are called without i_mutex protection against truncate |
| 1495 | */ | 1495 | */ |
| 1496 | nr = PAGE_CACHE_SIZE; | 1496 | nr = PAGE_CACHE_SIZE; |
| 1497 | i_size = i_size_read(inode); | 1497 | i_size = i_size_read(inode); |
| @@ -3071,6 +3071,7 @@ void kfree(const void *objp) | |||
| 3071 | local_irq_save(flags); | 3071 | local_irq_save(flags); |
| 3072 | kfree_debugcheck(objp); | 3072 | kfree_debugcheck(objp); |
| 3073 | c = page_get_cache(virt_to_page(objp)); | 3073 | c = page_get_cache(virt_to_page(objp)); |
| 3074 | mutex_debug_check_no_locks_freed(objp, objp+obj_reallen(c)); | ||
| 3074 | __cache_free(c, (void *)objp); | 3075 | __cache_free(c, (void *)objp); |
| 3075 | local_irq_restore(flags); | 3076 | local_irq_restore(flags); |
| 3076 | } | 3077 | } |
diff --git a/mm/swapfile.c b/mm/swapfile.c index 80f948a2028b..6544565a7c0f 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c | |||
| @@ -1187,9 +1187,9 @@ asmlinkage long sys_swapoff(const char __user * specialfile) | |||
| 1187 | set_blocksize(bdev, p->old_block_size); | 1187 | set_blocksize(bdev, p->old_block_size); |
| 1188 | bd_release(bdev); | 1188 | bd_release(bdev); |
| 1189 | } else { | 1189 | } else { |
| 1190 | down(&inode->i_sem); | 1190 | mutex_lock(&inode->i_mutex); |
| 1191 | inode->i_flags &= ~S_SWAPFILE; | 1191 | inode->i_flags &= ~S_SWAPFILE; |
| 1192 | up(&inode->i_sem); | 1192 | mutex_unlock(&inode->i_mutex); |
| 1193 | } | 1193 | } |
| 1194 | filp_close(swap_file, NULL); | 1194 | filp_close(swap_file, NULL); |
| 1195 | err = 0; | 1195 | err = 0; |
| @@ -1406,7 +1406,7 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags) | |||
| 1406 | p->bdev = bdev; | 1406 | p->bdev = bdev; |
| 1407 | } else if (S_ISREG(inode->i_mode)) { | 1407 | } else if (S_ISREG(inode->i_mode)) { |
| 1408 | p->bdev = inode->i_sb->s_bdev; | 1408 | p->bdev = inode->i_sb->s_bdev; |
| 1409 | down(&inode->i_sem); | 1409 | mutex_lock(&inode->i_mutex); |
| 1410 | did_down = 1; | 1410 | did_down = 1; |
| 1411 | if (IS_SWAPFILE(inode)) { | 1411 | if (IS_SWAPFILE(inode)) { |
| 1412 | error = -EBUSY; | 1412 | error = -EBUSY; |
| @@ -1596,7 +1596,7 @@ out: | |||
| 1596 | if (did_down) { | 1596 | if (did_down) { |
| 1597 | if (!error) | 1597 | if (!error) |
| 1598 | inode->i_flags |= S_SWAPFILE; | 1598 | inode->i_flags |= S_SWAPFILE; |
| 1599 | up(&inode->i_sem); | 1599 | mutex_unlock(&inode->i_mutex); |
| 1600 | } | 1600 | } |
| 1601 | return error; | 1601 | return error; |
| 1602 | } | 1602 | } |
diff --git a/mm/truncate.c b/mm/truncate.c index b1a463d0fe71..6cb3fff25f67 100644 --- a/mm/truncate.c +++ b/mm/truncate.c | |||
| @@ -196,7 +196,7 @@ EXPORT_SYMBOL(truncate_inode_pages_range); | |||
| 196 | * @mapping: mapping to truncate | 196 | * @mapping: mapping to truncate |
| 197 | * @lstart: offset from which to truncate | 197 | * @lstart: offset from which to truncate |
| 198 | * | 198 | * |
| 199 | * Called under (and serialised by) inode->i_sem. | 199 | * Called under (and serialised by) inode->i_mutex. |
| 200 | */ | 200 | */ |
| 201 | void truncate_inode_pages(struct address_space *mapping, loff_t lstart) | 201 | void truncate_inode_pages(struct address_space *mapping, loff_t lstart) |
| 202 | { | 202 | { |
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index e14c1cae7460..9764c80ab0b2 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
| @@ -69,13 +69,13 @@ rpc_timeout_upcall_queue(void *data) | |||
| 69 | struct rpc_inode *rpci = (struct rpc_inode *)data; | 69 | struct rpc_inode *rpci = (struct rpc_inode *)data; |
| 70 | struct inode *inode = &rpci->vfs_inode; | 70 | struct inode *inode = &rpci->vfs_inode; |
| 71 | 71 | ||
| 72 | down(&inode->i_sem); | 72 | mutex_lock(&inode->i_mutex); |
| 73 | if (rpci->ops == NULL) | 73 | if (rpci->ops == NULL) |
| 74 | goto out; | 74 | goto out; |
| 75 | if (rpci->nreaders == 0 && !list_empty(&rpci->pipe)) | 75 | if (rpci->nreaders == 0 && !list_empty(&rpci->pipe)) |
| 76 | __rpc_purge_upcall(inode, -ETIMEDOUT); | 76 | __rpc_purge_upcall(inode, -ETIMEDOUT); |
| 77 | out: | 77 | out: |
| 78 | up(&inode->i_sem); | 78 | mutex_unlock(&inode->i_mutex); |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | int | 81 | int |
| @@ -84,7 +84,7 @@ rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg) | |||
| 84 | struct rpc_inode *rpci = RPC_I(inode); | 84 | struct rpc_inode *rpci = RPC_I(inode); |
| 85 | int res = -EPIPE; | 85 | int res = -EPIPE; |
| 86 | 86 | ||
| 87 | down(&inode->i_sem); | 87 | mutex_lock(&inode->i_mutex); |
| 88 | if (rpci->ops == NULL) | 88 | if (rpci->ops == NULL) |
| 89 | goto out; | 89 | goto out; |
| 90 | if (rpci->nreaders) { | 90 | if (rpci->nreaders) { |
| @@ -100,7 +100,7 @@ rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg) | |||
| 100 | res = 0; | 100 | res = 0; |
| 101 | } | 101 | } |
| 102 | out: | 102 | out: |
| 103 | up(&inode->i_sem); | 103 | mutex_unlock(&inode->i_mutex); |
| 104 | wake_up(&rpci->waitq); | 104 | wake_up(&rpci->waitq); |
| 105 | return res; | 105 | return res; |
| 106 | } | 106 | } |
| @@ -116,7 +116,7 @@ rpc_close_pipes(struct inode *inode) | |||
| 116 | { | 116 | { |
| 117 | struct rpc_inode *rpci = RPC_I(inode); | 117 | struct rpc_inode *rpci = RPC_I(inode); |
| 118 | 118 | ||
| 119 | down(&inode->i_sem); | 119 | mutex_lock(&inode->i_mutex); |
| 120 | if (rpci->ops != NULL) { | 120 | if (rpci->ops != NULL) { |
| 121 | rpci->nreaders = 0; | 121 | rpci->nreaders = 0; |
| 122 | __rpc_purge_list(rpci, &rpci->in_upcall, -EPIPE); | 122 | __rpc_purge_list(rpci, &rpci->in_upcall, -EPIPE); |
| @@ -127,7 +127,7 @@ rpc_close_pipes(struct inode *inode) | |||
| 127 | rpci->ops = NULL; | 127 | rpci->ops = NULL; |
| 128 | } | 128 | } |
| 129 | rpc_inode_setowner(inode, NULL); | 129 | rpc_inode_setowner(inode, NULL); |
| 130 | up(&inode->i_sem); | 130 | mutex_unlock(&inode->i_mutex); |
| 131 | cancel_delayed_work(&rpci->queue_timeout); | 131 | cancel_delayed_work(&rpci->queue_timeout); |
| 132 | flush_scheduled_work(); | 132 | flush_scheduled_work(); |
| 133 | } | 133 | } |
| @@ -154,7 +154,7 @@ rpc_pipe_open(struct inode *inode, struct file *filp) | |||
| 154 | struct rpc_inode *rpci = RPC_I(inode); | 154 | struct rpc_inode *rpci = RPC_I(inode); |
| 155 | int res = -ENXIO; | 155 | int res = -ENXIO; |
| 156 | 156 | ||
| 157 | down(&inode->i_sem); | 157 | mutex_lock(&inode->i_mutex); |
| 158 | if (rpci->ops != NULL) { | 158 | if (rpci->ops != NULL) { |
| 159 | if (filp->f_mode & FMODE_READ) | 159 | if (filp->f_mode & FMODE_READ) |
| 160 | rpci->nreaders ++; | 160 | rpci->nreaders ++; |
| @@ -162,7 +162,7 @@ rpc_pipe_open(struct inode *inode, struct file *filp) | |||
| 162 | rpci->nwriters ++; | 162 | rpci->nwriters ++; |
| 163 | res = 0; | 163 | res = 0; |
| 164 | } | 164 | } |
| 165 | up(&inode->i_sem); | 165 | mutex_unlock(&inode->i_mutex); |
| 166 | return res; | 166 | return res; |
| 167 | } | 167 | } |
| 168 | 168 | ||
| @@ -172,7 +172,7 @@ rpc_pipe_release(struct inode *inode, struct file *filp) | |||
| 172 | struct rpc_inode *rpci = RPC_I(inode); | 172 | struct rpc_inode *rpci = RPC_I(inode); |
| 173 | struct rpc_pipe_msg *msg; | 173 | struct rpc_pipe_msg *msg; |
| 174 | 174 | ||
| 175 | down(&inode->i_sem); | 175 | mutex_lock(&inode->i_mutex); |
| 176 | if (rpci->ops == NULL) | 176 | if (rpci->ops == NULL) |
| 177 | goto out; | 177 | goto out; |
| 178 | msg = (struct rpc_pipe_msg *)filp->private_data; | 178 | msg = (struct rpc_pipe_msg *)filp->private_data; |
| @@ -190,7 +190,7 @@ rpc_pipe_release(struct inode *inode, struct file *filp) | |||
| 190 | if (rpci->ops->release_pipe) | 190 | if (rpci->ops->release_pipe) |
| 191 | rpci->ops->release_pipe(inode); | 191 | rpci->ops->release_pipe(inode); |
| 192 | out: | 192 | out: |
| 193 | up(&inode->i_sem); | 193 | mutex_unlock(&inode->i_mutex); |
| 194 | return 0; | 194 | return 0; |
| 195 | } | 195 | } |
| 196 | 196 | ||
| @@ -202,7 +202,7 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset) | |||
| 202 | struct rpc_pipe_msg *msg; | 202 | struct rpc_pipe_msg *msg; |
| 203 | int res = 0; | 203 | int res = 0; |
| 204 | 204 | ||
| 205 | down(&inode->i_sem); | 205 | mutex_lock(&inode->i_mutex); |
| 206 | if (rpci->ops == NULL) { | 206 | if (rpci->ops == NULL) { |
| 207 | res = -EPIPE; | 207 | res = -EPIPE; |
| 208 | goto out_unlock; | 208 | goto out_unlock; |
| @@ -229,7 +229,7 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset) | |||
| 229 | rpci->ops->destroy_msg(msg); | 229 | rpci->ops->destroy_msg(msg); |
| 230 | } | 230 | } |
| 231 | out_unlock: | 231 | out_unlock: |
| 232 | up(&inode->i_sem); | 232 | mutex_unlock(&inode->i_mutex); |
| 233 | return res; | 233 | return res; |
| 234 | } | 234 | } |
| 235 | 235 | ||
| @@ -240,11 +240,11 @@ rpc_pipe_write(struct file *filp, const char __user *buf, size_t len, loff_t *of | |||
| 240 | struct rpc_inode *rpci = RPC_I(inode); | 240 | struct rpc_inode *rpci = RPC_I(inode); |
| 241 | int res; | 241 | int res; |
| 242 | 242 | ||
| 243 | down(&inode->i_sem); | 243 | mutex_lock(&inode->i_mutex); |
| 244 | res = -EPIPE; | 244 | res = -EPIPE; |
| 245 | if (rpci->ops != NULL) | 245 | if (rpci->ops != NULL) |
| 246 | res = rpci->ops->downcall(filp, buf, len); | 246 | res = rpci->ops->downcall(filp, buf, len); |
| 247 | up(&inode->i_sem); | 247 | mutex_unlock(&inode->i_mutex); |
| 248 | return res; | 248 | return res; |
| 249 | } | 249 | } |
| 250 | 250 | ||
| @@ -322,7 +322,7 @@ rpc_info_open(struct inode *inode, struct file *file) | |||
| 322 | 322 | ||
| 323 | if (!ret) { | 323 | if (!ret) { |
| 324 | struct seq_file *m = file->private_data; | 324 | struct seq_file *m = file->private_data; |
| 325 | down(&inode->i_sem); | 325 | mutex_lock(&inode->i_mutex); |
| 326 | clnt = RPC_I(inode)->private; | 326 | clnt = RPC_I(inode)->private; |
| 327 | if (clnt) { | 327 | if (clnt) { |
| 328 | atomic_inc(&clnt->cl_users); | 328 | atomic_inc(&clnt->cl_users); |
| @@ -331,7 +331,7 @@ rpc_info_open(struct inode *inode, struct file *file) | |||
| 331 | single_release(inode, file); | 331 | single_release(inode, file); |
| 332 | ret = -EINVAL; | 332 | ret = -EINVAL; |
| 333 | } | 333 | } |
| 334 | up(&inode->i_sem); | 334 | mutex_unlock(&inode->i_mutex); |
| 335 | } | 335 | } |
| 336 | return ret; | 336 | return ret; |
| 337 | } | 337 | } |
| @@ -491,7 +491,7 @@ rpc_depopulate(struct dentry *parent) | |||
| 491 | struct dentry *dentry, *dvec[10]; | 491 | struct dentry *dentry, *dvec[10]; |
| 492 | int n = 0; | 492 | int n = 0; |
| 493 | 493 | ||
| 494 | down(&dir->i_sem); | 494 | mutex_lock(&dir->i_mutex); |
| 495 | repeat: | 495 | repeat: |
| 496 | spin_lock(&dcache_lock); | 496 | spin_lock(&dcache_lock); |
| 497 | list_for_each_safe(pos, next, &parent->d_subdirs) { | 497 | list_for_each_safe(pos, next, &parent->d_subdirs) { |
| @@ -519,7 +519,7 @@ repeat: | |||
| 519 | } while (n); | 519 | } while (n); |
| 520 | goto repeat; | 520 | goto repeat; |
| 521 | } | 521 | } |
| 522 | up(&dir->i_sem); | 522 | mutex_unlock(&dir->i_mutex); |
| 523 | } | 523 | } |
| 524 | 524 | ||
| 525 | static int | 525 | static int |
| @@ -532,7 +532,7 @@ rpc_populate(struct dentry *parent, | |||
| 532 | struct dentry *dentry; | 532 | struct dentry *dentry; |
| 533 | int mode, i; | 533 | int mode, i; |
| 534 | 534 | ||
| 535 | down(&dir->i_sem); | 535 | mutex_lock(&dir->i_mutex); |
| 536 | for (i = start; i < eof; i++) { | 536 | for (i = start; i < eof; i++) { |
| 537 | dentry = d_alloc_name(parent, files[i].name); | 537 | dentry = d_alloc_name(parent, files[i].name); |
| 538 | if (!dentry) | 538 | if (!dentry) |
| @@ -552,10 +552,10 @@ rpc_populate(struct dentry *parent, | |||
| 552 | dir->i_nlink++; | 552 | dir->i_nlink++; |
| 553 | d_add(dentry, inode); | 553 | d_add(dentry, inode); |
| 554 | } | 554 | } |
| 555 | up(&dir->i_sem); | 555 | mutex_unlock(&dir->i_mutex); |
| 556 | return 0; | 556 | return 0; |
| 557 | out_bad: | 557 | out_bad: |
| 558 | up(&dir->i_sem); | 558 | mutex_unlock(&dir->i_mutex); |
| 559 | printk(KERN_WARNING "%s: %s failed to populate directory %s\n", | 559 | printk(KERN_WARNING "%s: %s failed to populate directory %s\n", |
| 560 | __FILE__, __FUNCTION__, parent->d_name.name); | 560 | __FILE__, __FUNCTION__, parent->d_name.name); |
| 561 | return -ENOMEM; | 561 | return -ENOMEM; |
| @@ -609,7 +609,7 @@ rpc_lookup_negative(char *path, struct nameidata *nd) | |||
| 609 | if ((error = rpc_lookup_parent(path, nd)) != 0) | 609 | if ((error = rpc_lookup_parent(path, nd)) != 0) |
| 610 | return ERR_PTR(error); | 610 | return ERR_PTR(error); |
| 611 | dir = nd->dentry->d_inode; | 611 | dir = nd->dentry->d_inode; |
| 612 | down(&dir->i_sem); | 612 | mutex_lock(&dir->i_mutex); |
| 613 | dentry = lookup_hash(nd); | 613 | dentry = lookup_hash(nd); |
| 614 | if (IS_ERR(dentry)) | 614 | if (IS_ERR(dentry)) |
| 615 | goto out_err; | 615 | goto out_err; |
| @@ -620,7 +620,7 @@ rpc_lookup_negative(char *path, struct nameidata *nd) | |||
| 620 | } | 620 | } |
| 621 | return dentry; | 621 | return dentry; |
| 622 | out_err: | 622 | out_err: |
| 623 | up(&dir->i_sem); | 623 | mutex_unlock(&dir->i_mutex); |
| 624 | rpc_release_path(nd); | 624 | rpc_release_path(nd); |
| 625 | return dentry; | 625 | return dentry; |
| 626 | } | 626 | } |
| @@ -646,7 +646,7 @@ rpc_mkdir(char *path, struct rpc_clnt *rpc_client) | |||
| 646 | if (error) | 646 | if (error) |
| 647 | goto err_depopulate; | 647 | goto err_depopulate; |
| 648 | out: | 648 | out: |
| 649 | up(&dir->i_sem); | 649 | mutex_unlock(&dir->i_mutex); |
| 650 | rpc_release_path(&nd); | 650 | rpc_release_path(&nd); |
| 651 | return dentry; | 651 | return dentry; |
| 652 | err_depopulate: | 652 | err_depopulate: |
| @@ -671,7 +671,7 @@ rpc_rmdir(char *path) | |||
| 671 | if ((error = rpc_lookup_parent(path, &nd)) != 0) | 671 | if ((error = rpc_lookup_parent(path, &nd)) != 0) |
| 672 | return error; | 672 | return error; |
| 673 | dir = nd.dentry->d_inode; | 673 | dir = nd.dentry->d_inode; |
| 674 | down(&dir->i_sem); | 674 | mutex_lock(&dir->i_mutex); |
| 675 | dentry = lookup_hash(&nd); | 675 | dentry = lookup_hash(&nd); |
| 676 | if (IS_ERR(dentry)) { | 676 | if (IS_ERR(dentry)) { |
| 677 | error = PTR_ERR(dentry); | 677 | error = PTR_ERR(dentry); |
| @@ -681,7 +681,7 @@ rpc_rmdir(char *path) | |||
| 681 | error = __rpc_rmdir(dir, dentry); | 681 | error = __rpc_rmdir(dir, dentry); |
| 682 | dput(dentry); | 682 | dput(dentry); |
| 683 | out_release: | 683 | out_release: |
| 684 | up(&dir->i_sem); | 684 | mutex_unlock(&dir->i_mutex); |
| 685 | rpc_release_path(&nd); | 685 | rpc_release_path(&nd); |
| 686 | return error; | 686 | return error; |
| 687 | } | 687 | } |
| @@ -710,7 +710,7 @@ rpc_mkpipe(char *path, void *private, struct rpc_pipe_ops *ops, int flags) | |||
| 710 | rpci->ops = ops; | 710 | rpci->ops = ops; |
| 711 | inode_dir_notify(dir, DN_CREATE); | 711 | inode_dir_notify(dir, DN_CREATE); |
| 712 | out: | 712 | out: |
| 713 | up(&dir->i_sem); | 713 | mutex_unlock(&dir->i_mutex); |
| 714 | rpc_release_path(&nd); | 714 | rpc_release_path(&nd); |
| 715 | return dentry; | 715 | return dentry; |
| 716 | err_dput: | 716 | err_dput: |
| @@ -732,7 +732,7 @@ rpc_unlink(char *path) | |||
| 732 | if ((error = rpc_lookup_parent(path, &nd)) != 0) | 732 | if ((error = rpc_lookup_parent(path, &nd)) != 0) |
| 733 | return error; | 733 | return error; |
| 734 | dir = nd.dentry->d_inode; | 734 | dir = nd.dentry->d_inode; |
| 735 | down(&dir->i_sem); | 735 | mutex_lock(&dir->i_mutex); |
| 736 | dentry = lookup_hash(&nd); | 736 | dentry = lookup_hash(&nd); |
| 737 | if (IS_ERR(dentry)) { | 737 | if (IS_ERR(dentry)) { |
| 738 | error = PTR_ERR(dentry); | 738 | error = PTR_ERR(dentry); |
| @@ -746,7 +746,7 @@ rpc_unlink(char *path) | |||
| 746 | dput(dentry); | 746 | dput(dentry); |
| 747 | inode_dir_notify(dir, DN_DELETE); | 747 | inode_dir_notify(dir, DN_DELETE); |
| 748 | out_release: | 748 | out_release: |
| 749 | up(&dir->i_sem); | 749 | mutex_unlock(&dir->i_mutex); |
| 750 | rpc_release_path(&nd); | 750 | rpc_release_path(&nd); |
| 751 | return error; | 751 | return error; |
| 752 | } | 752 | } |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 5f6ae79b8b16..1b5989b1b670 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
| @@ -784,7 +784,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
| 784 | err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0); | 784 | err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0); |
| 785 | if (err) | 785 | if (err) |
| 786 | goto out_mknod_dput; | 786 | goto out_mknod_dput; |
| 787 | up(&nd.dentry->d_inode->i_sem); | 787 | mutex_unlock(&nd.dentry->d_inode->i_mutex); |
| 788 | dput(nd.dentry); | 788 | dput(nd.dentry); |
| 789 | nd.dentry = dentry; | 789 | nd.dentry = dentry; |
| 790 | 790 | ||
| @@ -823,7 +823,7 @@ out: | |||
| 823 | out_mknod_dput: | 823 | out_mknod_dput: |
| 824 | dput(dentry); | 824 | dput(dentry); |
| 825 | out_mknod_unlock: | 825 | out_mknod_unlock: |
| 826 | up(&nd.dentry->d_inode->i_sem); | 826 | mutex_unlock(&nd.dentry->d_inode->i_mutex); |
| 827 | path_release(&nd); | 827 | path_release(&nd); |
| 828 | out_mknod_parent: | 828 | out_mknod_parent: |
| 829 | if (err==-EEXIST) | 829 | if (err==-EEXIST) |
diff --git a/security/inode.c b/security/inode.c index a5964502ae30..0f77b0223662 100644 --- a/security/inode.c +++ b/security/inode.c | |||
| @@ -172,7 +172,7 @@ static int create_by_name(const char *name, mode_t mode, | |||
| 172 | return -EFAULT; | 172 | return -EFAULT; |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | down(&parent->d_inode->i_sem); | 175 | mutex_lock(&parent->d_inode->i_mutex); |
| 176 | *dentry = lookup_one_len(name, parent, strlen(name)); | 176 | *dentry = lookup_one_len(name, parent, strlen(name)); |
| 177 | if (!IS_ERR(dentry)) { | 177 | if (!IS_ERR(dentry)) { |
| 178 | if ((mode & S_IFMT) == S_IFDIR) | 178 | if ((mode & S_IFMT) == S_IFDIR) |
| @@ -181,7 +181,7 @@ static int create_by_name(const char *name, mode_t mode, | |||
| 181 | error = create(parent->d_inode, *dentry, mode); | 181 | error = create(parent->d_inode, *dentry, mode); |
| 182 | } else | 182 | } else |
| 183 | error = PTR_ERR(dentry); | 183 | error = PTR_ERR(dentry); |
| 184 | up(&parent->d_inode->i_sem); | 184 | mutex_unlock(&parent->d_inode->i_mutex); |
| 185 | 185 | ||
| 186 | return error; | 186 | return error; |
| 187 | } | 187 | } |
| @@ -302,7 +302,7 @@ void securityfs_remove(struct dentry *dentry) | |||
| 302 | if (!parent || !parent->d_inode) | 302 | if (!parent || !parent->d_inode) |
| 303 | return; | 303 | return; |
| 304 | 304 | ||
| 305 | down(&parent->d_inode->i_sem); | 305 | mutex_lock(&parent->d_inode->i_mutex); |
| 306 | if (positive(dentry)) { | 306 | if (positive(dentry)) { |
| 307 | if (dentry->d_inode) { | 307 | if (dentry->d_inode) { |
| 308 | if (S_ISDIR(dentry->d_inode->i_mode)) | 308 | if (S_ISDIR(dentry->d_inode->i_mode)) |
| @@ -312,7 +312,7 @@ void securityfs_remove(struct dentry *dentry) | |||
| 312 | dput(dentry); | 312 | dput(dentry); |
| 313 | } | 313 | } |
| 314 | } | 314 | } |
| 315 | up(&parent->d_inode->i_sem); | 315 | mutex_unlock(&parent->d_inode->i_mutex); |
| 316 | simple_release_fs(&mount, &mount_count); | 316 | simple_release_fs(&mount, &mount_count); |
| 317 | } | 317 | } |
| 318 | EXPORT_SYMBOL_GPL(securityfs_remove); | 318 | EXPORT_SYMBOL_GPL(securityfs_remove); |
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 16df1246a131..7fd072392c7e 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c | |||
| @@ -2135,9 +2135,7 @@ static ssize_t snd_pcm_oss_write(struct file *file, const char __user *buf, size | |||
| 2135 | substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK]; | 2135 | substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK]; |
| 2136 | if (substream == NULL) | 2136 | if (substream == NULL) |
| 2137 | return -ENXIO; | 2137 | return -ENXIO; |
| 2138 | up(&file->f_dentry->d_inode->i_sem); | ||
| 2139 | result = snd_pcm_oss_write1(substream, buf, count); | 2138 | result = snd_pcm_oss_write1(substream, buf, count); |
| 2140 | down(&file->f_dentry->d_inode->i_sem); | ||
| 2141 | #ifdef OSS_DEBUG | 2139 | #ifdef OSS_DEBUG |
| 2142 | printk("pcm_oss: write %li bytes (wrote %li bytes)\n", (long)count, (long)result); | 2140 | printk("pcm_oss: write %li bytes (wrote %li bytes)\n", (long)count, (long)result); |
| 2143 | #endif | 2141 | #endif |
diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c index 9ee6c177db0c..40b4f679c80e 100644 --- a/sound/core/seq/seq_memory.c +++ b/sound/core/seq/seq_memory.c | |||
| @@ -32,10 +32,6 @@ | |||
| 32 | #include "seq_info.h" | 32 | #include "seq_info.h" |
| 33 | #include "seq_lock.h" | 33 | #include "seq_lock.h" |
| 34 | 34 | ||
| 35 | /* semaphore in struct file record */ | ||
| 36 | #define semaphore_of(fp) ((fp)->f_dentry->d_inode->i_sem) | ||
| 37 | |||
| 38 | |||
| 39 | static inline int snd_seq_pool_available(struct snd_seq_pool *pool) | 35 | static inline int snd_seq_pool_available(struct snd_seq_pool *pool) |
| 40 | { | 36 | { |
| 41 | return pool->total_elements - atomic_read(&pool->counter); | 37 | return pool->total_elements - atomic_read(&pool->counter); |
